+
+
+#include "win-utils.h"
+#include "cci_debugging.h"
+
+#pragma warning (disable : 4996)
+
+#define UUID_SIZE 128
+
+char* clientPrefix = "CCAPI_CLIENT_";
+char* serverPrefix = "CCS_LISTEN_";
+unsigned char* pszProtocolSequence = "ncalrpc";
+
+#define MAX_TIMESTAMP 40
+char _ts[MAX_TIMESTAMP];
+
+char* clientEndpoint(const char* UUID) {
+ char* _clientEndpoint = (char*)malloc(strlen(UUID) + strlen(clientPrefix) + 2);
+ strcpy(_clientEndpoint, clientPrefix);
+ strncat(_clientEndpoint, UUID, UUID_SIZE);
+// cci_debug_printf("%s returning %s", __FUNCTION__, _clientEndpoint);
+ return _clientEndpoint;
+ }
+
+char* serverEndpoint(const char* user) {
+ char* _serverEndpoint = (char*)malloc(strlen(user) + strlen(serverPrefix) + 2);
+ strcpy(_serverEndpoint, serverPrefix);
+ strncat(_serverEndpoint, user, UUID_SIZE);
+ return _serverEndpoint;
+ }
+
+char* timestamp() {
+ SYSTEMTIME _stime;
+ GetSystemTime(&_stime);
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &_stime, "HH:mm:ss", _ts, sizeof(_ts)-1);
+ return _ts;
+ }
diff --git a/krb5-1.21.3/src/ccapi/common/win/win-utils.h b/krb5-1.21.3/src/ccapi/common/win/win-utils.h
new file mode 100644
index 00000000..41cab24d
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/common/win/win-utils.h
@@ -0,0 +1,55 @@
+/* ccapi/common/win/win-utils.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 _win_utils_h
+#define _win_utils_h
+
+#ifndef TRUE
+#define TRUE (1==1)
+#endif
+
+#ifndef FALSE
+#define FALSE (1==0)
+#endif
+
+static enum ccapiMsgType {
+ CCMSG_INVALID = 0,
+ CCMSG_CONNECT,
+ CCMSG_REQUEST,
+ CCMSG_CONNECT_REPLY,
+ CCMSG_REQUEST_REPLY,
+ CCMSG_DISCONNECT,
+ CCMSG_LISTEN,
+ CCMSG_PING,
+ CCMSG_QUIT
+ };
+
+char* clientEndpoint(const char* UUID);
+char* serverEndpoint(const char* UUID);
+extern unsigned char* pszProtocolSequence;
+
+char* timestamp();
+
+#endif // _win_utils_h
\ No newline at end of file
diff --git a/krb5-1.21.3/src/ccapi/deps b/krb5-1.21.3/src/ccapi/deps
new file mode 100644
index 00000000..2feac3c9
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/deps
@@ -0,0 +1 @@
+# No dependencies here.
diff --git a/krb5-1.21.3/src/ccapi/doc/CCAPI-Windows-Design.html b/krb5-1.21.3/src/ccapi/doc/CCAPI-Windows-Design.html
new file mode 100644
index 00000000..dd32acba
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/doc/CCAPI-Windows-Design.html
@@ -0,0 +1,148 @@
+
+
+
+
+Windows CCAPI RPC design
+
+
+
+
+Proposed RPC design for Windows CCAPI clients and server
+The proposal is for a single user; the solution is replicated for each user logged onto the PC.
+Conventions & clarifications
+"Client" and "server" refer to the CCAPI client and server.
+The CCAPI client acts as both an RPC client and RPC server and the CCAPI server acts as both an RPC client and RPC server.
+
+ - The RPC call from the CCAPI client to the CCAPI server is called the "request." In this mode, the CCAPI client is the RPC client and the CCAPI server is the RPC server.
+ - The RPC call from the CCAPI server to the CCAPI client is called the "reply." In this mode, the CCAPI client is the RPC server and the CCAPI server is the RPC client.
+
+The Windows username is referred to below as "<USER>."
+The Windows Logon Security Identifier is referred to as "<LSID>."
+<UUID> means a thread-specific UUID.
+<SST> means server start time, a time_t.
+A description of client and server authentication has not been added yet.
+Design Requirements
+
+ - The server's OS-independent code is single threaded, because it must operate on platforms that do not allow multiple threads.
+ - The client and server must be able to maintain connections, where state is maintained between individual messages.
+ - Individual messages must be handled in a single threaded server.
+ - The server must be able to detect when a client dies, so that any connection state can be cleaned up.
+
+Design
+The server and each client create an RPC endpoint. The server's endpoint is CCS_<LSID> and the client's endpoint is CCAPI_<UUID>, where each client geta a UUID.
+On Windows, the server's ccs_pipe_t type is a char* and is set to the client UUID.
+How is the request handled in the server and the reply sent to the client?
+One straightforward way is for the reply to be the returned data in the request RPC call (an [out] parameter). That is, data passed from the RPC server to the RPC client. The request handler calls ccs_server_handle_request. Eventually, the server code calls ccs_os_server_send_reply, which saves the reply somewhere. When the server eventually returns to the request handler, the handler returns the saved reply to the client.
+But this doesn't work. If two clients A and B ask for the same lock, A will acquire the lock and B will have to wait. But if the single threaded server waits for B's lock, it will never handle A's unlock message. Therefore the server must return to B's request handler and not send a reply to B. So this method will not work.
+Instead, there are listener and worker threads in Windows-specific code.
+The client's cci_os_ipc function waits for ccs_reply. The client sends the request, including its UUID, from which the server can construct the endpoint on which to call ccs_reply.
+The server's listener thread listens for RPC requests. The request handler puts each request/reply endpoint in a queue and returns to the client.
+The server's worker thread removes items from the queue, calls ccs_server_handle_request. ccs_server_handle_request takes both the request data and the client UUID . Eventually ccs_os_server_send_reply is called, with the reply data and client UUID in the reply_pipe. ccs_os_server_send_reply calls ccs_reply on the client's endpoint, which sends the reply to the client.
+Is there any security issue with the client listening for RPC calls from the server?
+Connections
+If the client wants state to be maintained on the server, the client creates a connection. When the connection is closed, the server cleans up any state associated with the connection.
+Any given thread in an application process could want to create a connection. When cci_ipc_thread_init is called, the connection thread-local variables are initialized. New connections are created when cci_os_ipc() (via _cci_ipc_send) is called and no connection was previously established. Basically we lazily establish connections so the client doesn't talk to the server until it has to.
+Detecting client exit
+The server must be able to detect when clients disappear, so the server can free any resources that had been held for the client.
+The Windows RPC API does not appear to provide a notification for an endpoint disappearing. It does provide a way to ask if an endpoint is listening. This is useful for polling, but we want a better performing solution than that.
+The client has an isAlive function on its endpoint.
+To detect the client disappearing without using polling, the server makes an asynchronous call to the isAlive function on the client's endpoint. The isAlive function never returns. When the client exits for any reason, its endpoint will be closed and the server's function call will return an error. The asynchronous call on the server means no additional threads are used.
+Windows provides a number of notification methods to signal I/O completion. Among them are I/O completion ports and callback functions. I chose callback functions because they appear to consume fewer resources.
+RPC Endpoint / Function summary
+
+ - The server creates one CCS_<LSID> endpoint to listen for connection requests and client requests.
+ It has the functions
+
+ - ccs_rpc_connect(msgtype, UUIDlen, <UUID>, status)
+ - ccs_rpc_request(msgtype, UUIDlen, <UUID>, msglen, msg, SST, status) called by client. NB: The windows server sets the in_client_pipe to the in_reply_pipe.
+
+
+
+ - Each client thread creates a CCAPI_<UUID> endpoint. It has the functions
+
+ - isAlive [function never returns.]
+ - ccs_rpc_request_reply(msgtype, SST, replylen, reply, status)
+ - ccs_rpc_connect_reply(msgtype, SST, status
+
+
+
+Windows-specific implementation details
+Client CCAPI library initialization:
+This code runs when the CCAPI DLL is loaded.
+
+Client initialization:
+This code runs when cci_os_ipc_thread_init is called:
+
+ - Generate <UUID> and save in thread-specific storage. This serves as the client ID / ccs_pipe_t.
+ - Create client endpoint.
+ - Listen on client endpoint.
+ - Create canonical server connection endpoint from the <LSID>, which the client and server should have in common.
+ - Test if server is listening to the CCS_<LSID> endpoint.
+
+ - If not, quit. (! Start it?)
+
+
+ - Call ccs_connect(<UUID>) on the CCS_<LSID> endpoint.
+ - Save SST in thread-specific storage.
+
+Server initialization:
+[old]
+
+ - Server is initialized by client starting a new process. There should be only one server process per Windows username.
+
+[new]
+
+ - Server is started by kfwlogon (as is done currently).
+ - Capture server start time (SST).
+ - Start listener thread, create listener endpoint, listen on CCS_<LSID> endpoint.
+
+Establishing a connection:
+
+ - Client calls ccs_connect(<UUID>) on server's CCS_<LSID> endpoint.
+ - Client gets back and stores SST in thread-specific storage.
+ - If new connection, server ...
+
+ - adds connection to connection table
+ - calls isAlive on CCAPI_<UUID>.
+
+ - NB: isAlive never returns.
+
+
+
+
+
+Client request:
+The server's reply to the client's request is not synchronous.
+
+ - Client calls ccs_rpc_request(msglen, msg, msgtype, UUIDlen, <UUID>, SST, status) on server's endpoint.
+ - Server listen thread receives message, queues request.
+ - Server worker thread dequeues request, processes, calls ccs_rpc_reply(replylen, reply, msgtype, status) on CCAPI_<UUID>.
+ - Server checks SST. If server's SST is different, it means server has restarted since client created connection.
+ - Client receives reply.
+
+Detecting client exit
+
+ - When connection created, client created an endpoint.
+ - Server calls isAlive on client's endpoint.
+ - When isAlive returns, the server's notification callback will be called. Call back routine queues a DISCONNECT pseudo-message. When the server's worker thread handles the DISCONNECT, it will release connection resources.
+
+Detecting server exit
+
+ - Client's call to ccs_rpc_request will return an error if the server has gone away.
+
+
+------
+ Stop:
+Start:
+
+
diff --git a/krb5-1.21.3/src/ccapi/lib/Makefile.in b/krb5-1.21.3/src/ccapi/lib/Makefile.in
new file mode 100644
index 00000000..241e28b0
--- /dev/null
+++ b/krb5-1.21.3/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=$(COM_ERR_LIB) $(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/krb5-1.21.3/src/ccapi/lib/ccapi.exports b/krb5-1.21.3/src/ccapi/lib/ccapi.exports
new file mode 100644
index 00000000..92c859bd
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/ccapi.exports
@@ -0,0 +1 @@
+cc_initialize
diff --git a/krb5-1.21.3/src/ccapi/lib/ccapi_ccache.c b/krb5-1.21.3/src/ccapi/lib/ccapi_ccache.c
new file mode 100644
index 00000000..9e8ba36c
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_ccache.h b/krb5-1.21.3/src/ccapi/lib/ccapi_ccache.h
new file mode 100644
index 00000000..e6fc129a
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_ccache_iterator.c b/krb5-1.21.3/src/ccapi/lib/ccapi_ccache_iterator.c
new file mode 100644
index 00000000..795610d9
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_ccache_iterator.h b/krb5-1.21.3/src/ccapi/lib/ccapi_ccache_iterator.h
new file mode 100644
index 00000000..88947eaf
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_context.c b/krb5-1.21.3/src/ccapi/lib/ccapi_context.c
new file mode 100644
index 00000000..cf677fc5
--- /dev/null
+++ b/krb5-1.21.3/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
+
+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/krb5-1.21.3/src/ccapi/lib/ccapi_context.h b/krb5-1.21.3/src/ccapi/lib/ccapi_context.h
new file mode 100644
index 00000000..51b8982e
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_context_change_time.c b/krb5-1.21.3/src/ccapi/lib/ccapi_context_change_time.c
new file mode 100644
index 00000000..ec6b955e
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_context_change_time.h b/krb5-1.21.3/src/ccapi/lib/ccapi_context_change_time.h
new file mode 100644
index 00000000..b1fa110e
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_credentials.c b/krb5-1.21.3/src/ccapi/lib/ccapi_credentials.c
new file mode 100644
index 00000000..cb175a31
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_credentials.h b/krb5-1.21.3/src/ccapi/lib/ccapi_credentials.h
new file mode 100644
index 00000000..aea6a412
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_credentials_iterator.c b/krb5-1.21.3/src/ccapi/lib/ccapi_credentials_iterator.c
new file mode 100644
index 00000000..f1efc7f8
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_credentials_iterator.h b/krb5-1.21.3/src/ccapi/lib/ccapi_credentials_iterator.h
new file mode 100644
index 00000000..56c4505d
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_err.et b/krb5-1.21.3/src/ccapi/lib/ccapi_err.et
new file mode 100644
index 00000000..44cd2d0b
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_ipc.c b/krb5-1.21.3/src/ccapi/lib/ccapi_ipc.c
new file mode 100644
index 00000000..2c1fcba6
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_ipc.h b/krb5-1.21.3/src/ccapi/lib/ccapi_ipc.h
new file mode 100644
index 00000000..a23772b2
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_os_ipc.h b/krb5-1.21.3/src/ccapi/lib/ccapi_os_ipc.h
new file mode 100644
index 00000000..fe7c87a0
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_string.c b/krb5-1.21.3/src/ccapi/lib/ccapi_string.c
new file mode 100644
index 00000000..ab84dfe3
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_string.h b/krb5-1.21.3/src/ccapi/lib/ccapi_string.h
new file mode 100644
index 00000000..02debde9
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/ccapi_v2.c b/krb5-1.21.3/src/ccapi/lib/ccapi_v2.c
new file mode 100644
index 00000000..ae9b790b
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/ccapi_v2.c
@@ -0,0 +1,889 @@
+/* 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
+
+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_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_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); }
+
+ 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) {
+ 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/krb5-1.21.3/src/ccapi/lib/ccapi_v2.exports b/krb5-1.21.3/src/ccapi/lib/ccapi_v2.exports
new file mode 100644
index 00000000..efa9fcec
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/deps b/krb5-1.21.3/src/ccapi/lib/deps
new file mode 100644
index 00000000..ad996d9f
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/libkrb5-ccapi.exports b/krb5-1.21.3/src/ccapi/lib/libkrb5-ccapi.exports
new file mode 100644
index 00000000..1a8560f0
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/libkrb5-ccapi.exports
@@ -0,0 +1 @@
+cc_close
diff --git a/krb5-1.21.3/src/ccapi/lib/unix/Makefile.in b/krb5-1.21.3/src/ccapi/lib/unix/Makefile.in
new file mode 100644
index 00000000..ce47d65d
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/unix/deps b/krb5-1.21.3/src/ccapi/lib/unix/deps
new file mode 100644
index 00000000..2feac3c9
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/unix/deps
@@ -0,0 +1 @@
+# No dependencies here.
diff --git a/krb5-1.21.3/src/ccapi/lib/unix/stubs.c b/krb5-1.21.3/src/ccapi/lib/unix/stubs.c
new file mode 100644
index 00000000..3afd8f10
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/unix/stubs.c
@@ -0,0 +1,10 @@
+#include
+#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/krb5-1.21.3/src/ccapi/lib/win/Makefile.in b/krb5-1.21.3/src/ccapi/lib/win/Makefile.in
new file mode 100644
index 00000000..ef6c1cc2
--- /dev/null
+++ b/krb5-1.21.3/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) $(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/krb5-1.21.3/src/ccapi/lib/win/OldCC/ccapi.h b/krb5-1.21.3/src/ccapi/lib/win/OldCC/ccapi.h
new file mode 100644
index 00000000..4d6f3faa
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/OldCC/ccapi.h
@@ -0,0 +1,260 @@
+/* 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 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,
+ } ;
+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 _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()] */ 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/krb5-1.21.3/src/ccapi/lib/win/OldCC/client.cxx b/krb5-1.21.3/src/ccapi/lib/win/OldCC/client.cxx
new file mode 100644
index 00000000..0f95dfce
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/OldCC/client.cxx
@@ -0,0 +1,388 @@
+/*
+ * $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;
+
+ 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) {
+ alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline);
+ bRes = CreateProcess( szExe, // app name
+ NULL, //cmdline, // cmd line is
+ 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 (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/krb5-1.21.3/src/ccapi/lib/win/OldCC/client.h b/krb5-1.21.3/src/ccapi/lib/win/OldCC/client.h
new file mode 100644
index 00000000..1c67acd1
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/win/WINCCAPI.sln b/krb5-1.21.3/src/ccapi/lib/win/WINCCAPI.sln
new file mode 100644
index 00000000..cee98915
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/win/WINCCAPI.vcproj b/krb5-1.21.3/src/ccapi/lib/win/WINCCAPI.vcproj
new file mode 100644
index 00000000..9af0e21a
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/WINCCAPI.vcproj
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/krb5-1.21.3/src/ccapi/lib/win/ccapi_os_ipc.cxx b/krb5-1.21.3/src/ccapi/lib/win/ccapi_os_ipc.cxx
new file mode 100644
index 00000000..1b1f874e
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/ccapi_os_ipc.cxx
@@ -0,0 +1,365 @@
+/*
+ * $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);
+ }
+
+ // 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 _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. */
+ /* 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 (!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) {
+ 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/krb5-1.21.3/src/ccapi/lib/win/ccs_reply_proc.c b/krb5-1.21.3/src/ccapi/lib/win/ccs_reply_proc.c
new file mode 100644
index 00000000..b4dbc0d1
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/ccs_reply_proc.c
@@ -0,0 +1,91 @@
+/* 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
+#include
+#include
+
+#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;
+
+ 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);
+
+ 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/krb5-1.21.3/src/ccapi/lib/win/debug.exports b/krb5-1.21.3/src/ccapi/lib/win/debug.exports
new file mode 100644
index 00000000..6dc1fc08
--- /dev/null
+++ b/krb5-1.21.3/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/krb5-1.21.3/src/ccapi/lib/win/dllmain.cxx b/krb5-1.21.3/src/ccapi/lib/win/dllmain.cxx
new file mode 100644
index 00000000..18aa0055
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/lib/win/dllmain.cxx
@@ -0,0 +1,212 @@
+/*
+ * $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
+#include
+
+#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 process.
+ //
+ // A good potential workaround 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 );
+
+ // 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/krb5-1.21.3/src/ccapi/lib/win/dllmain.h b/krb5-1.21.3/src/ccapi/lib/win/dllmain.h
new file mode 100644
index 00000000..8238566e
--- /dev/null
+++ b/krb5-1.21.3/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
diff --git a/krb5-1.21.3/src/ccapi/server/Makefile.in b/krb5-1.21.3/src/ccapi/server/Makefile.in
new file mode 100644
index 00000000..2c01307f
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/Makefile.in
@@ -0,0 +1,59 @@
+mydir=ccapi$(S)server
+BUILDTOP=$(REL)..$(S)..
+SUBDIRS=unix
+
+LOCALINCLUDES= -I$(srcdir)/../common
+
+STLIBOBJS= \
+ ccs_array.o \
+ ccs_cache_collection.o \
+ ccs_callback.o \
+ ccs_ccache.o \
+ ccs_ccache_iterator.o \
+ ccs_client.o \
+ ccs_credentials.o \
+ ccs_credentials_iterator.o \
+ ccs_list.o \
+ ccs_list_internal.o \
+ ccs_lock.o \
+ ccs_lock_state.o \
+ ccs_pipe.o \
+ ccs_server.o
+
+OBJS= \
+ $(OUTPRE)ccs_array.$(OBJEXT) \
+ $(OUTPRE)ccs_cache_collection.$(OBJEXT) \
+ $(OUTPRE)ccs_callback.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_client.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_list.$(OBJEXT) \
+ $(OUTPRE)ccs_list_internal.$(OBJEXT) \
+ $(OUTPRE)ccs_lock.$(OBJEXT) \
+ $(OUTPRE)ccs_lock_state.$(OBJEXT) \
+ $(OUTPRE)ccs_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_server.$(OBJEXT)
+
+SRCS= \
+ ccs_array.c \
+ ccs_cache_collection.c \
+ ccs_callback.c \
+ ccs_ccache.c \
+ ccs_ccache_iterator.c \
+ ccs_client.c \
+ ccs_credentials.c \
+ ccs_credentials_iterator.c \
+ ccs_list.c \
+ ccs_list_internal.c \
+ ccs_lock.c \
+ ccs_lock_state.c \
+ ccs_pipe.c \
+ ccs_server.c
+
+all-unix: all-libobjs
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_array.c b/krb5-1.21.3/src/ccapi/server/ccs_array.c
new file mode 100644
index 00000000..7e0874a8
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_array.c
@@ -0,0 +1,309 @@
+/* ccapi/server/ccs_array.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 "ccs_common.h"
+#include "cci_array_internal.h"
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_client_object_release (cci_array_object_t io_client)
+{
+ return cci_check_error (ccs_client_release ((ccs_client_t) io_client));
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_array_new (ccs_client_array_t *out_array)
+{
+ return cci_array_new (out_array, ccs_client_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_array_release (ccs_client_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_client_array_count (ccs_client_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_client_t) cci_array_object_at_index (io_array, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_array_insert (ccs_client_array_t io_array,
+ ccs_client_t in_client,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array, (cci_array_object_t) in_client, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_array_remove (ccs_client_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_object_release (cci_array_object_t io_lock)
+{
+ return cci_check_error (ccs_lock_release ((ccs_lock_t) io_lock));
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array)
+{
+ return cci_array_new (out_array, ccs_lock_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_lock_t) cci_array_object_at_index (io_array, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array,
+ ccs_lock_t in_lock,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array, (cci_array_object_t) in_lock, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array,
+ cc_uint64 in_position,
+ cc_uint64 in_new_position,
+ cc_uint64 *out_real_new_position)
+{
+ return cci_array_move (io_array, in_position, in_new_position, out_real_new_position);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_callback_object_release (cci_array_object_t io_callback)
+{
+ return cci_check_error (ccs_callback_release ((ccs_callback_t) io_callback));
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array)
+{
+ return cci_array_new (out_array, ccs_callback_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_callback_t) cci_array_object_at_index (io_array, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array,
+ ccs_callback_t in_callback,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array)
+{
+ /* Ref arrays do not own their contents; pass NULL for release function */
+ return cci_array_new (out_array, NULL);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_callback_t) cci_array_object_at_index (io_array, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array,
+ ccs_callback_t in_callback,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array)
+{
+ /* Ref arrays do not own their contents; pass NULL for release function */
+ return cci_array_new (out_array, NULL);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_generic_list_iterator_t) cci_array_object_at_index (io_array,
+ in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array,
+ ccs_generic_list_iterator_t in_iterator,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array,
+ (cci_array_object_t) in_iterator,
+ in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_array.h b/krb5-1.21.3/src/ccapi/server/ccs_array.h
new file mode 100644
index 00000000..470812b3
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_array.h
@@ -0,0 +1,132 @@
+/* ccapi/server/ccs_array.h */
+/*
+ * 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.
+ */
+
+#ifndef CCS_ARRAY_H
+#define CCS_ARRAY_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_client_array_new (ccs_client_array_t *out_array);
+
+cc_int32 ccs_client_array_release (ccs_client_array_t io_array);
+
+cc_uint64 ccs_client_array_count (ccs_client_array_t in_array);
+
+ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_client_array_insert (ccs_client_array_t io_array,
+ ccs_client_t in_client,
+ cc_uint64 in_position);
+
+cc_int32 ccs_client_array_remove (ccs_client_array_t io_array,
+ cc_uint64 in_position);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array);
+
+cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array);
+
+cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array);
+
+ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array,
+ ccs_lock_t in_lock,
+ cc_uint64 in_position);
+
+cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array,
+ cc_uint64 in_position,
+ cc_uint64 in_new_position,
+ cc_uint64 *out_real_new_position);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array);
+
+cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array);
+
+cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array);
+
+ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array,
+ ccs_callback_t in_callback,
+ cc_uint64 in_position);
+
+cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array,
+ cc_uint64 in_position);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array);
+
+cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array);
+
+cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array);
+
+ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array,
+ ccs_callback_t in_callback,
+ cc_uint64 in_position);
+
+cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array,
+ cc_uint64 in_position);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array);
+
+cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array);
+
+cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array);
+
+ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array,
+ ccs_generic_list_iterator_t in_iterator,
+ cc_uint64 in_position);
+
+cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position);
+
+#endif /* CCS_ARRAY_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.c b/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.c
new file mode 100644
index 00000000..33300735
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.c
@@ -0,0 +1,1109 @@
+/* ccapi/server/ccs_cache_collection.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 "k5-platform.h" /* pull in asprintf decl/defn */
+#include "ccs_common.h"
+#include "ccs_os_notify.h"
+
+struct ccs_cache_collection_d {
+ cc_time_t last_changed_time;
+ cc_uint64 next_unique_name;
+ cci_identifier_t identifier;
+ ccs_lock_state_t lock_state;
+ ccs_ccache_list_t ccaches;
+ ccs_callback_array_t change_callbacks;
+};
+
+struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection)
+{
+ cc_int32 err = ccNoError;
+ ccs_cache_collection_t cache_collection = NULL;
+
+ if (!out_cache_collection) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cache_collection = malloc (sizeof (*cache_collection));
+ if (cache_collection) {
+ *cache_collection = ccs_cache_collection_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_server_new_identifier (&cache_collection->identifier);
+ }
+
+ if (!err) {
+ err = ccs_lock_state_new (&cache_collection->lock_state,
+ ccErrInvalidContext,
+ ccErrContextLocked,
+ ccErrContextUnlocked);
+ }
+
+ if (!err) {
+ err = ccs_ccache_list_new (&cache_collection->ccaches);
+ }
+
+ if (!err) {
+ err = ccs_callback_array_new (&cache_collection->change_callbacks);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (cache_collection);
+ }
+
+ if (!err) {
+ *out_cache_collection = cache_collection;
+ cache_collection = NULL;
+ }
+
+ ccs_cache_collection_release (cache_collection);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_cache_collection) {
+ cci_identifier_release (io_cache_collection->identifier);
+ ccs_lock_state_release (io_cache_collection->lock_state);
+ ccs_ccache_list_release (io_cache_collection->ccaches);
+ ccs_callback_array_release (io_cache_collection->change_callbacks);
+ free (io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_compare (in_cache_collection->identifier,
+ in_identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_time_t now = time (NULL);
+
+ if (io_cache_collection->last_changed_time < now) {
+ io_cache_collection->last_changed_time = now;
+ } else {
+ io_cache_collection->last_changed_time++;
+ }
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (reply_data, io_cache_collection->last_changed_time);
+ }
+
+ if (!err) {
+ /* Loop over callbacks sending messages to them */
+ cc_uint64 i;
+ cc_uint64 count = ccs_callback_array_count (io_cache_collection->change_callbacks);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_callback_t callback = ccs_callback_array_object_at_index (io_cache_collection->change_callbacks, i);
+
+ err = ccs_callback_reply_to_client (callback, reply_data);
+
+ if (!err) {
+ cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+ err = ccs_callback_array_remove (io_cache_collection->change_callbacks, i);
+ break;
+ }
+ }
+ }
+
+ if (!err) {
+ err = ccs_os_notify_cache_collection_changed (io_cache_collection);
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_invalidate_change_callback (ccs_callback_owner_t io_cache_collection,
+ ccs_callback_t in_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_callback ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* Remove callback */
+ ccs_cache_collection_t cache_collection = (ccs_cache_collection_t) io_cache_collection;
+ cc_uint64 i;
+ cc_uint64 count = ccs_callback_array_count (cache_collection->change_callbacks);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_callback_t callback = ccs_callback_array_object_at_index (cache_collection->change_callbacks, i);
+
+ if (callback == in_callback) {
+ cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+ err = ccs_callback_array_remove (cache_collection->change_callbacks, i);
+ break;
+ }
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t in_cache_collection,
+ const char *in_name,
+ ccs_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_list_iterator_t iterator = NULL;
+
+ if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_name ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
+ &iterator);
+ }
+
+ while (!err) {
+ ccs_ccache_t ccache = NULL;
+
+ err = ccs_ccache_list_iterator_next (iterator, &ccache);
+
+ if (!err) {
+ cc_uint32 equal = 0;
+
+ err = ccs_ccache_compare_name (ccache, in_name, &equal);
+
+ if (!err && equal) {
+ *out_ccache = ccache;
+ break;
+ }
+ }
+ }
+ if (err == ccIteratorEnd) { err = ccErrCCacheNotFound; }
+
+ if (iterator) { ccs_ccache_list_iterator_release (iterator); }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_find (in_cache_collection->ccaches,
+ in_identifier, out_ccache);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection,
+ cci_identifier_t in_source_identifier,
+ ccs_ccache_t io_destination_ccache)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t source_ccache = NULL;
+
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_source_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_find_ccache (io_cache_collection,
+ in_source_identifier,
+ &source_ccache);
+ }
+
+ if (!err) {
+ err = ccs_ccache_swap_contents (source_ccache,
+ io_destination_ccache,
+ io_cache_collection);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_destroy_ccache (io_cache_collection,
+ in_source_identifier);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t io_cache_collection,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_find_ccache (io_cache_collection,
+ in_identifier,
+ &ccache);
+ }
+
+ if (!err) {
+ /* Notify before deletion because after deletion the ccache
+ * will no longer exist (and won't know about its clients) */
+ err = ccs_ccache_changed (ccache, io_cache_collection);
+ }
+
+ if (!err) {
+ err = ccs_ccache_list_remove (io_cache_collection->ccaches,
+ in_identifier);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_iterator_t *out_ccache_iterator)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_find_iterator (in_cache_collection->ccaches,
+ in_identifier,
+ out_ccache_iterator);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache,
+ ccs_credentials_iterator_t *out_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_list_iterator_t iterator = NULL;
+
+ if (!in_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
+ &iterator);
+ }
+
+ while (!err) {
+ ccs_ccache_t ccache = NULL;
+
+ err = ccs_ccache_list_iterator_next (iterator, &ccache);
+
+ if (!err) {
+ cc_int32 terr = ccs_ccache_find_credentials_iterator (ccache,
+ in_identifier,
+ out_credentials_iterator);
+ if (!terr) {
+ *out_ccache = ccache;
+ break;
+ }
+ }
+ }
+ if (err == ccIteratorEnd) { err = cci_check_error (ccErrInvalidCredentialsIterator); }
+
+ if (iterator) { ccs_ccache_list_iterator_release (iterator); }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_get_next_unique_ccache_name (ccs_cache_collection_t io_cache_collection,
+ char **out_name)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 count = 0;
+ char *name = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!out_name ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count);
+ }
+
+ if (!err) {
+ if (count > 0) {
+ while (!err) {
+ int ret = asprintf (&name, "%lld", io_cache_collection->next_unique_name++);
+ if (ret < 0 || !name) { err = cci_check_error (ccErrNoMem); }
+
+ if (!err) {
+ ccs_ccache_t ccache = NULL; /* temporary to hold ccache pointer */
+ err = ccs_cache_collection_find_ccache_by_name (io_cache_collection,
+ name, &ccache);
+ }
+
+ if (err == ccErrCCacheNotFound) {
+ err = ccNoError;
+ break; /* found a unique one */
+ }
+ }
+ } else {
+ name = strdup (k_cci_context_initial_ccache_name);
+ if (!name) { err = cci_check_error (ccErrNoMem); }
+ }
+ }
+
+ if (!err) {
+ *out_name = name;
+ name = NULL;
+ }
+
+ free (name);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t in_cache_collection,
+ ccs_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 count = 0;
+
+ if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_count (in_cache_collection->ccaches, &count);
+ }
+
+ if (!err) {
+ if (count > 0) {
+ /* First ccache is the default */
+ ccs_ccache_list_iterator_t iterator = NULL;
+
+ err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
+ &iterator);
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_next (iterator, out_ccache);
+ }
+
+ ccs_ccache_list_iterator_release (iterator);
+
+ } else {
+ err = cci_check_error (ccErrCCacheNotFound);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t io_cache_collection,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t old_default = NULL;
+ ccs_ccache_t new_default = NULL;
+ cc_uint32 equal = 0;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_get_default_ccache (io_cache_collection,
+ &old_default);
+ }
+
+ if (!err) {
+ err = ccs_ccache_compare_identifier (old_default, in_identifier, &equal);
+ }
+
+
+ if (!err && !equal) {
+ err = ccs_ccache_list_push_front (io_cache_collection->ccaches,
+ in_identifier);
+
+ if (!err) {
+ err = ccs_ccache_notify_default_state_changed (old_default,
+ io_cache_collection,
+ 0 /* no longer default */);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_get_default_ccache (io_cache_collection,
+ &new_default);
+ }
+
+ if (!err) {
+ err = ccs_ccache_notify_default_state_changed (new_default,
+ io_cache_collection,
+ 1 /* now default */);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#pragma mark -- IPC Messages --
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_sync (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (io_cache_collection->identifier, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_get_change_time (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_cache_collection->last_changed_time);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data,
+ cc_uint32 *out_will_block)
+{
+ cc_int32 err = ccNoError;
+ cc_time_t last_wait_for_change_time = 0;
+ cc_uint32 will_block = 0;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time);
+ }
+
+ if (!err) {
+ if (last_wait_for_change_time < io_cache_collection->last_changed_time) {
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_cache_collection->last_changed_time);
+
+ } else {
+ ccs_callback_t callback = NULL;
+
+ err = ccs_callback_new (&callback,
+ ccErrInvalidContext,
+ in_client_pipe,
+ in_reply_pipe,
+ (ccs_callback_owner_t) io_cache_collection,
+ ccs_cache_collection_invalidate_change_callback);
+
+ if (!err) {
+ err = ccs_callback_array_insert (io_cache_collection->change_callbacks, callback,
+ ccs_callback_array_count (io_cache_collection->change_callbacks));
+ if (!err) { callback = NULL; /* take ownership */ }
+
+ will_block = 1;
+ }
+
+ ccs_callback_release (callback);
+ }
+ }
+
+ if (!err) {
+ *out_will_block = will_block;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_get_default_ccache_name (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 count = 0;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count);
+ }
+
+ if (!err) {
+ if (count > 0) {
+ ccs_ccache_t ccache = NULL;
+
+ err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache);
+
+ if (!err) {
+ err = ccs_ccache_write_name (ccache, io_reply_data);
+ }
+ } else {
+ err = krb5int_ipc_stream_write_string (io_reply_data,
+ k_cci_context_initial_ccache_name);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_open_ccache (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ char *name = NULL;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &name);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_find_ccache_by_name (io_cache_collection,
+ name, &ccache);
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ krb5int_ipc_stream_free_string (name);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_open_default_ccache (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_get_default_ccache (io_cache_collection,
+ &ccache);
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_create_ccache (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ char *name = NULL;
+ cc_uint32 cred_vers;
+ char *principal = NULL;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &name);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &principal);
+ }
+
+ if (!err) {
+ cc_int32 terr = ccs_cache_collection_find_ccache_by_name (io_cache_collection,
+ name,
+ &ccache);
+
+ if (!terr) {
+ err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal);
+
+ } else {
+ err = ccs_ccache_new (&ccache, cred_vers, name, principal,
+ io_cache_collection->ccaches);
+ }
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+
+ krb5int_ipc_stream_free_string (name);
+ krb5int_ipc_stream_free_string (principal);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_create_default_ccache (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 cred_vers;
+ char *principal = NULL;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &principal);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_get_default_ccache (io_cache_collection,
+ &ccache);
+
+ if (!err) {
+ err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal);
+
+ } else if (err == ccErrCCacheNotFound) {
+ char *name = NULL;
+
+ err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection,
+ &name);
+
+ if (!err) {
+ err = ccs_ccache_new (&ccache, cred_vers, name, principal,
+ io_cache_collection->ccaches);
+ }
+
+ free (name);
+ }
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+
+ krb5int_ipc_stream_free_string (principal);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 cred_vers;
+ char *principal = NULL;
+ char *name = NULL;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &principal);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection,
+ &name);
+ }
+
+ if (!err) {
+ err = ccs_ccache_new (&ccache, cred_vers, name, principal,
+ io_cache_collection->ccaches);
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+
+ free (name);
+ krb5int_ipc_stream_free_string (principal);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection,
+ ccs_pipe_t in_client_pipe,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_iterator_t ccache_iterator = NULL;
+
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches,
+ in_client_pipe,
+ &ccache_iterator);
+ }
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_lock (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 lock_type;
+ cc_uint32 block;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &lock_type);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &block);
+ }
+
+ if (!err) {
+ err = ccs_lock_state_add (io_cache_collection->lock_state,
+ in_client_pipe, in_reply_pipe,
+ lock_type, block, out_will_block);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pipe,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_lock_state_remove (io_cache_collection->lock_state,
+ in_client_pipe);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+ cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 will_block = 0;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ if (in_request_name == cci_context_unused_release_msg_id) {
+ /* Old release message. Do nothing. */
+
+ } else if (in_request_name == cci_context_sync_msg_id) {
+ err = ccs_cache_collection_sync (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_get_change_time_msg_id) {
+ err = ccs_cache_collection_get_change_time (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_wait_for_change_msg_id) {
+ err = ccs_cache_collection_wait_for_change (in_client_pipe, in_reply_pipe,
+ io_cache_collection,
+ in_request_data, reply_data,
+ &will_block);
+
+ } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) {
+ err = ccs_cache_collection_get_default_ccache_name (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_open_ccache_msg_id) {
+ err = ccs_cache_collection_open_ccache (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_open_default_ccache_msg_id) {
+ err = ccs_cache_collection_open_default_ccache (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_create_ccache_msg_id) {
+ err = ccs_cache_collection_create_ccache (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_create_default_ccache_msg_id) {
+ err = ccs_cache_collection_create_default_ccache (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_create_new_ccache_msg_id) {
+ err = ccs_cache_collection_create_new_ccache (io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_context_new_ccache_iterator_msg_id) {
+ err = ccs_cache_collection_new_ccache_iterator (io_cache_collection,
+ in_client_pipe,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_context_lock_msg_id) {
+ err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe,
+ io_cache_collection,
+ in_request_data,
+ &will_block, reply_data);
+
+ } else if (in_request_name == cci_context_unlock_msg_id) {
+ err = ccs_cache_collection_unlock (in_client_pipe, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else {
+ err = ccErrBadInternalMessage;
+ }
+ }
+
+ if (!err) {
+ *out_will_block = will_block;
+ if (!will_block) {
+ *out_reply_data = reply_data;
+ reply_data = NULL; /* take ownership */
+ } else {
+ *out_reply_data = NULL;
+ }
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.h b/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.h
new file mode 100644
index 00000000..37f7633a
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_cache_collection.h
@@ -0,0 +1,72 @@
+/* ccapi/server/ccs_cache_collection.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 CCS_CACHE_COLLECTION_H
+#define CCS_CACHE_COLLECTION_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection);
+
+cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection);
+
+cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection);
+
+cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache);
+
+cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection,
+ cci_identifier_t in_source_identifier,
+ ccs_ccache_t io_destination_ccache);
+
+cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_iterator_t *out_ccache_iterator);
+
+cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache,
+ ccs_credentials_iterator_t *out_credentials_iterator);
+
+cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream *out_reply_data);
+
+#endif /* CCS_CACHE_COLLECTION_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_callback.c b/krb5-1.21.3/src/ccapi/server/ccs_callback.c
new file mode 100644
index 00000000..d758acb1
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_callback.c
@@ -0,0 +1,238 @@
+/* ccapi/server/ccs_callback.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 "ccs_common.h"
+
+struct ccs_callback_d {
+ cc_int32 pending;
+ cc_int32 invalid_object_err;
+ ccs_pipe_t client_pipe;
+ ccs_pipe_t reply_pipe;
+ ccs_callback_owner_t owner; /* pointer to owner */
+ ccs_callback_owner_invalidate_t owner_invalidate;
+};
+
+struct ccs_callback_d ccs_callback_initializer = { 1, 1, CCS_PIPE_NULL, CCS_PIPE_NULL, NULL, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_new (ccs_callback_t *out_callback,
+ cc_int32 in_invalid_object_err,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_callback_owner_t in_owner,
+ ccs_callback_owner_invalidate_t in_owner_invalidate_function)
+{
+ cc_int32 err = ccNoError;
+ ccs_callback_t callback = NULL;
+ ccs_client_t client = NULL;
+
+ if (!out_callback ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_owner ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_owner_invalidate_function ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ callback = malloc (sizeof (*callback));
+ if (callback) {
+ *callback = ccs_callback_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_server_client_for_pipe (in_client_pipe, &client);
+ }
+
+ if (!err) {
+ err = ccs_pipe_copy (&callback->client_pipe, in_client_pipe);
+ }
+
+ if (!err) {
+ err = ccs_pipe_copy (&callback->reply_pipe, in_reply_pipe);
+ }
+
+ if (!err) {
+ callback->client_pipe = in_client_pipe;
+ callback->reply_pipe = in_reply_pipe;
+ callback->invalid_object_err = in_invalid_object_err;
+ callback->owner = in_owner;
+ callback->owner_invalidate = in_owner_invalidate_function;
+
+ err = ccs_client_add_callback (client, callback);
+ }
+
+ if (!err) {
+ *out_callback = callback;
+ callback = NULL;
+ }
+
+ ccs_callback_release (callback);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_release (ccs_callback_t io_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_callback) {
+ ccs_client_t client = NULL;
+
+ if (io_callback->pending) {
+ err = ccs_server_send_reply (io_callback->reply_pipe,
+ io_callback->invalid_object_err, NULL);
+
+ io_callback->pending = 0;
+ }
+
+ if (!err) {
+ err = ccs_server_client_for_pipe (io_callback->client_pipe, &client);
+ }
+
+ if (!err && client) {
+ /* if client object still has a reference to us, remove it */
+ err = ccs_client_remove_callback (client, io_callback);
+ }
+
+ if (!err) {
+ ccs_pipe_release (io_callback->client_pipe);
+ ccs_pipe_release (io_callback->reply_pipe);
+ free (io_callback);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_callback) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ io_callback->pending = 0; /* client is dead, don't try to talk to it */
+ if (io_callback->owner_invalidate) {
+ err = io_callback->owner_invalidate (io_callback->owner, io_callback);
+ } else {
+ cci_debug_printf ("WARNING %s() unable to notify callback owner!",
+ __FUNCTION__);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback,
+ k5_ipc_stream in_stream)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_callback) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ if (io_callback->pending) {
+ cci_debug_printf ("%s: callback %p replying to client.", __FUNCTION__, io_callback);
+
+ err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream);
+
+ if (err) {
+ cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!",
+ __FUNCTION__);
+ }
+
+ io_callback->pending = 0;
+ } else {
+ cci_debug_printf ("WARNING %s() called on non-pending callback!",
+ __FUNCTION__);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback,
+ cc_uint32 *out_pending)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_callback) { err = cci_check_error (ccErrBadParam); }
+ if (!out_pending) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_pending = in_callback->pending;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback,
+ ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_is_for_client_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_callback ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_pipe_compare (in_callback->client_pipe, in_client_pipe,
+ out_is_for_client_pipe);
+ }
+
+ return cci_check_error (err);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback,
+ ccs_pipe_t *out_client_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_callback ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_client_pipe = in_callback->client_pipe;
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_callback.h b/krb5-1.21.3/src/ccapi/server/ccs_callback.h
new file mode 100644
index 00000000..30c22280
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_callback.h
@@ -0,0 +1,61 @@
+/* ccapi/server/ccs_callback.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 CCS_CALLBACK_H
+#define CCS_CALLBACK_H
+
+#include "ccs_types.h"
+
+struct ccs_callback_owner_d;
+typedef struct ccs_callback_owner_d *ccs_callback_owner_t;
+
+typedef cc_int32 (*ccs_callback_owner_invalidate_t) (ccs_callback_owner_t, ccs_callback_t);
+
+
+cc_int32 ccs_callback_new (ccs_callback_t *out_callback,
+ cc_int32 in_invalid_object_err,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_callback_owner_t in_owner,
+ ccs_callback_owner_invalidate_t in_owner_invalidate_function);
+
+cc_int32 ccs_callback_release (ccs_callback_t io_callback);
+
+cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback);
+
+cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback,
+ k5_ipc_stream in_stream);
+
+cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback,
+ cc_uint32 *out_pending);
+
+cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback,
+ ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_is_for_client_pipe);
+
+cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback,
+ ccs_pipe_t *out_client_pipe);
+
+#endif /* CCS_CALLBACK_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_ccache.c b/krb5-1.21.3/src/ccapi/server/ccs_ccache.c
new file mode 100644
index 00000000..645380a7
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_ccache.c
@@ -0,0 +1,1183 @@
+/* ccapi/server/ccs_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 "ccs_common.h"
+#include "ccs_os_notify.h"
+
+struct ccs_ccache_d {
+ cci_identifier_t identifier;
+ ccs_lock_state_t lock_state;
+ cc_uint32 creds_version;
+ char *name;
+ char *v5_principal;
+ cc_time_t last_default_time;
+ cc_time_t last_changed_time;
+ cc_uint32 kdc_time_offset_v5_valid;
+ cc_time_t kdc_time_offset_v5;
+ ccs_credentials_list_t credentials;
+ ccs_callback_array_t change_callbacks;
+};
+
+struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache,
+ cc_uint32 in_creds_version,
+ const char *in_name,
+ const char *in_principal,
+ ccs_ccache_list_t io_ccache_list)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t ccache = NULL;
+
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_name ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccache = malloc (sizeof (*ccache));
+ if (ccache) {
+ *ccache = ccs_ccache_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_server_new_identifier (&ccache->identifier);
+ }
+
+ if (!err) {
+ err = ccs_lock_state_new (&ccache->lock_state,
+ ccErrInvalidCCache,
+ ccErrCCacheLocked,
+ ccErrCCacheUnlocked);
+ }
+
+ if (!err) {
+ ccache->name = strdup (in_name);
+ if (!ccache->name) { err = cci_check_error (ccErrNoMem); }
+ }
+
+ if (!err) {
+ ccache->creds_version = in_creds_version;
+
+ if (ccache->creds_version == cc_credentials_v5) {
+ ccache->v5_principal = strdup (in_principal);
+ if (!ccache->v5_principal) { err = cci_check_error (ccErrNoMem); }
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_new (&ccache->credentials);
+ }
+
+ if (!err) {
+ err = ccs_callback_array_new (&ccache->change_callbacks);
+ }
+
+ if (!err) {
+ cc_uint64 now = time (NULL);
+ cc_uint64 count = 0;
+
+ err = ccs_ccache_list_count (io_ccache_list, &count);
+
+ if (!err) {
+ /* first cache is default */
+ ccache->last_default_time = (count == 0) ? now : 0;
+ cci_debug_printf ("%s ccache->last_default_time is %d.",
+ __FUNCTION__, ccache->last_default_time);
+ ccache->last_changed_time = now;
+ }
+ }
+
+ if (!err) {
+ /* Add self to the list of ccaches */
+ err = ccs_ccache_list_add (io_ccache_list, ccache);
+ }
+
+ if (!err) {
+ *out_ccache = ccache;
+ ccache = NULL;
+ }
+
+ ccs_ccache_release (ccache);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ cc_uint32 in_creds_version,
+ const char *in_principal)
+{
+ cc_int32 err = ccNoError;
+ char *v5_principal = NULL;
+ ccs_credentials_list_t credentials = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ io_ccache->creds_version = in_creds_version;
+
+ if (io_ccache->creds_version == cc_credentials_v5) {
+ v5_principal = strdup (in_principal);
+ if (!v5_principal) { err = cci_check_error (ccErrNoMem); }
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_new (&credentials);
+ }
+
+ if (!err) {
+ io_ccache->kdc_time_offset_v5 = 0;
+ io_ccache->kdc_time_offset_v5_valid = 0;
+
+ if (io_ccache->v5_principal) { free (io_ccache->v5_principal); }
+ io_ccache->v5_principal = v5_principal;
+ v5_principal = NULL; /* take ownership */
+
+ ccs_credentials_list_release (io_ccache->credentials);
+ io_ccache->credentials = credentials;
+ credentials = NULL; /* take ownership */
+
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ free (v5_principal);
+ ccs_credentials_list_release (credentials);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache,
+ ccs_ccache_t io_destination_ccache,
+ ccs_cache_collection_t io_cache_collection)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ struct ccs_ccache_d temp_ccache = *io_destination_ccache;
+
+ /* swap everything */
+ *io_destination_ccache = *io_source_ccache;
+ *io_source_ccache = temp_ccache;
+
+ /* swap back the name and identifier */
+ io_source_ccache->identifier = io_destination_ccache->identifier;
+ io_destination_ccache->identifier = temp_ccache.identifier;
+
+ io_source_ccache->name = io_destination_ccache->name;
+ io_destination_ccache->name = temp_ccache.name;
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_source_ccache, io_cache_collection);
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_destination_ccache, io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_ccache) {
+ cci_identifier_release (io_ccache->identifier);
+ ccs_lock_state_release (io_ccache->lock_state);
+ free (io_ccache->name);
+ free (io_ccache->v5_principal);
+ ccs_credentials_list_release (io_ccache->credentials);
+ ccs_callback_array_release (io_ccache->change_callbacks);
+ free (io_ccache);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_compare (in_ccache->identifier,
+ in_identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache,
+ const char *in_name,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!in_name ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_equal = (strcmp (in_ccache->name, in_name) == 0);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_time_t now = time (NULL);
+
+ if (io_ccache->last_changed_time < now) {
+ io_ccache->last_changed_time = now;
+ } else {
+ io_ccache->last_changed_time++;
+ }
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (reply_data, io_ccache->last_changed_time);
+ }
+
+ if (!err) {
+ /* Loop over callbacks sending messages to them */
+ cc_uint64 i;
+ cc_uint64 count = ccs_callback_array_count (io_ccache->change_callbacks);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_callback_t callback = ccs_callback_array_object_at_index (io_ccache->change_callbacks, i);
+
+ err = ccs_callback_reply_to_client (callback, reply_data);
+
+ if (!err) {
+ cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+ err = ccs_callback_array_remove (io_ccache->change_callbacks, i);
+ break;
+ }
+ }
+ }
+
+ if (!err) {
+ err = ccs_os_notify_ccache_changed (io_cache_collection,
+ io_ccache->name);
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_invalidate_change_callback (ccs_callback_owner_t io_ccache,
+ ccs_callback_t in_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_callback) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* Remove callback */
+ ccs_ccache_t ccache = (ccs_ccache_t) io_ccache;
+ cc_uint64 i;
+ cc_uint64 count = ccs_callback_array_count (ccache->change_callbacks);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_callback_t callback = ccs_callback_array_object_at_index (ccache->change_callbacks, i);
+
+ if (callback == in_callback) {
+ cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+ err = ccs_callback_array_remove (ccache->change_callbacks, i);
+ break;
+ }
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ cc_uint32 in_new_default_state)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && in_new_default_state) {
+ cc_time_t now = time (NULL);
+
+ if (io_ccache->last_default_time < now) {
+ io_ccache->last_default_time = now;
+ } else {
+ io_ccache->last_default_time++;
+ }
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache,
+ cci_identifier_t in_identifier,
+ ccs_credentials_iterator_t *out_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_list_find_iterator (in_ccache->credentials,
+ in_identifier,
+ out_credentials_iterator);
+ }
+
+ // Don't report ccErrInvalidCredentials to the log file. Non-fatal.
+ return (err == ccErrInvalidCredentials) ? err : cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache,
+ k5_ipc_stream io_stream)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!io_stream) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (in_ccache->identifier, io_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache,
+ k5_ipc_stream io_stream)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!io_stream) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_string (io_stream, in_ccache->name);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#pragma mark -- IPC Messages --
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_destroy (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_destroy_ccache (io_cache_collection,
+ io_ccache->identifier);
+ }
+
+ if (!err) {
+ /* ccache has been destroyed so just mark the cache collection */
+ err = ccs_cache_collection_changed (io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_set_default (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_cache_collection_set_default_ccache (io_cache_collection,
+ io_ccache->identifier);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_credentials_version (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (io_reply_data, io_ccache->creds_version);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_name (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->name);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_principal (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 version = 0;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &version);
+ }
+
+ if (!err) {
+ if (version == cc_credentials_v5) {
+ err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->v5_principal);
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_set_principal (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 version = 0;
+ char *principal = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &version);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (in_request_data, &principal);
+ }
+
+ if (!err) {
+ /* reset KDC time offsets because they are per-KDC */
+ if (version == cc_credentials_v5) {
+ io_ccache->kdc_time_offset_v5 = 0;
+ io_ccache->kdc_time_offset_v5_valid = 0;
+
+ if (io_ccache->v5_principal) { free (io_ccache->v5_principal); }
+ io_ccache->v5_principal = principal;
+ principal = NULL; /* take ownership */
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ if (!err) {
+ io_ccache->creds_version |= version;
+
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ krb5int_ipc_stream_free_string (principal);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_store_credentials (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_credentials_t credentials = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_new (&credentials, in_request_data,
+ io_ccache->creds_version,
+ io_ccache->credentials);
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cci_identifier_t credentials_identifier = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_read (&credentials_identifier, in_request_data);
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_remove (io_ccache->credentials, credentials_identifier);
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ cci_identifier_release (credentials_identifier);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ ccs_pipe_t in_client_pipe,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_credentials_iterator_t credentials_iterator = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_list_new_iterator (io_ccache->credentials,
+ in_client_pipe,
+ &credentials_iterator);
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_move (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cci_identifier_t source_identifier = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* Note: message is sent as the destination ccache to avoid */
+ /* extra work on the server when deleting it the source ccache. */
+ err = cci_identifier_read (&source_identifier, in_request_data);
+ }
+
+ if (!err) {
+ err = ccs_ccache_collection_move_ccache (io_cache_collection,
+ source_identifier,
+ io_ccache);
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ cci_identifier_release (source_identifier);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_lock (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 lock_type;
+ cc_uint32 block;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &lock_type);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &block);
+ }
+
+ if (!err) {
+ err = ccs_lock_state_add (io_ccache->lock_state,
+ in_client_pipe, in_reply_pipe,
+ lock_type, block, out_will_block);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_unlock (ccs_pipe_t in_client_pipe,
+ ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_lock_state_remove (io_ccache->lock_state, in_client_pipe);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_last_default_time (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && io_ccache->last_default_time == 0) {
+ err = cci_check_error (ccErrNeverDefault);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_default_time);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data,
+ cc_uint32 *out_will_block)
+{
+ cc_int32 err = ccNoError;
+ cc_time_t last_wait_for_change_time = 0;
+ cc_uint32 will_block = 0;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time);
+ }
+
+ if (!err) {
+ if (last_wait_for_change_time < io_ccache->last_changed_time) {
+ cci_debug_printf ("%s returning immediately", __FUNCTION__);
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time);
+
+ } else {
+ ccs_callback_t callback = NULL;
+
+ err = ccs_callback_new (&callback,
+ ccErrInvalidCCache,
+ in_client_pipe,
+ in_reply_pipe,
+ (ccs_callback_owner_t) io_ccache,
+ ccs_ccache_invalidate_change_callback);
+
+ if (!err) {
+ err = ccs_callback_array_insert (io_ccache->change_callbacks, callback,
+ ccs_callback_array_count (io_ccache->change_callbacks));
+ if (!err) { callback = NULL; /* take ownership */ }
+
+ cci_debug_printf ("%s blocking", __FUNCTION__);
+ will_block = 1;
+ }
+
+ ccs_callback_release (callback);
+ }
+ }
+
+ if (!err) {
+ *out_will_block = will_block;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 cred_vers = 0;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ if (cred_vers == cc_credentials_v5) {
+ if (io_ccache->kdc_time_offset_v5_valid) {
+ err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v5);
+ } else {
+ err = cci_check_error (ccErrTimeOffsetNotSet);
+ }
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_set_kdc_time_offset (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 cred_vers = 0;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ if (cred_vers == cc_credentials_v5) {
+ err = krb5int_ipc_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v5);
+
+ if (!err) {
+ io_ccache->kdc_time_offset_v5_valid = 1;
+ }
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_clear_kdc_time_offset (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 cred_vers = 0;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
+ }
+
+ if (!err) {
+ if (cred_vers == cc_credentials_v5) {
+ io_ccache->kdc_time_offset_v5 = 0;
+ io_ccache->kdc_time_offset_v5_valid = 0;
+
+ } else {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+ }
+
+ if (!err) {
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 will_block = 0;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ if (in_request_name == cci_ccache_destroy_msg_id) {
+ err = ccs_ccache_destroy (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_set_default_msg_id) {
+ err = ccs_ccache_set_default (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_get_credentials_version_msg_id) {
+ err = ccs_ccache_get_credentials_version (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_get_name_msg_id) {
+ err = ccs_ccache_get_name (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_get_principal_msg_id) {
+ err = ccs_ccache_get_principal (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_set_principal_msg_id) {
+ err = ccs_ccache_set_principal (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_store_credentials_msg_id) {
+ err = ccs_ccache_store_credentials (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_remove_credentials_msg_id) {
+ err = ccs_ccache_remove_credentials (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) {
+ err = ccs_ccache_new_credentials_iterator (io_ccache,
+ io_cache_collection,
+ in_client_pipe,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_ccache_move_msg_id) {
+ err = ccs_ccache_move (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_lock_msg_id) {
+ err = ccs_ccache_lock (in_client_pipe, in_reply_pipe,
+ io_ccache, io_cache_collection,
+ in_request_data,
+ &will_block, reply_data);
+
+ } else if (in_request_name == cci_ccache_unlock_msg_id) {
+ err = ccs_ccache_unlock (in_client_pipe,
+ io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_get_last_default_time_msg_id) {
+ err = ccs_ccache_get_last_default_time (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_get_change_time_msg_id) {
+ err = ccs_ccache_get_change_time (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_wait_for_change_msg_id) {
+ err = ccs_ccache_wait_for_change (in_client_pipe, in_reply_pipe,
+ io_ccache, io_cache_collection,
+ in_request_data, reply_data,
+ &will_block);
+
+ } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) {
+ err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_set_kdc_time_offset_msg_id) {
+ err = ccs_ccache_set_kdc_time_offset (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else if (in_request_name == cci_ccache_clear_kdc_time_offset_msg_id) {
+ err = ccs_ccache_clear_kdc_time_offset (io_ccache, io_cache_collection,
+ in_request_data, reply_data);
+
+ } else {
+ err = ccErrBadInternalMessage;
+ }
+ }
+
+ if (!err) {
+ *out_will_block = will_block;
+ if (!will_block) {
+ *out_reply_data = reply_data;
+ reply_data = NULL; /* take ownership */
+ } else {
+ *out_reply_data = NULL;
+ }
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_ccache.h b/krb5-1.21.3/src/ccapi/server/ccs_ccache.h
new file mode 100644
index 00000000..8dab0651
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_ccache.h
@@ -0,0 +1,82 @@
+/* ccapi/server/ccs_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 CCS_CCACHE_H
+#define CCS_CCACHE_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache,
+ cc_uint32 in_cred_vers,
+ const char *in_name,
+ const char *in_principal,
+ ccs_ccache_list_t io_ccache_list);
+
+cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ cc_uint32 in_cred_vers,
+ const char *in_principal);
+
+cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache,
+ ccs_ccache_t io_destination_ccache,
+ ccs_cache_collection_t io_cache_collection);
+
+cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache);
+
+cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection);
+
+cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache,
+ const char *in_name,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ cc_uint32 in_new_default_state);
+
+cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache,
+ cci_identifier_t in_identifier,
+ ccs_credentials_iterator_t *out_credentials_iterator);
+
+cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache,
+ k5_ipc_stream io_stream);
+
+cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache,
+ k5_ipc_stream io_stream);
+
+cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_ccache_t io_ccache,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream *out_reply_data);
+
+#endif /* CCS_CCACHE_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.c b/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.c
new file mode 100644
index 00000000..172e68a8
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.c
@@ -0,0 +1,156 @@
+/* ccapi/server/ccs_ccache_iterator.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 "ccs_common.h"
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_iterator_release (ccs_ccache_iterator_t io_ccache_iterator,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_release (io_ccache_iterator);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_iterator_next (ccs_ccache_iterator_t io_ccache_iterator,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_t ccache = NULL;
+
+ if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_next (io_ccache_iterator, &ccache);
+ }
+
+ if (!err) {
+ err = ccs_ccache_write (ccache, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_iterator_clone (ccs_ccache_iterator_t io_ccache_iterator,
+ ccs_cache_collection_t io_cache_collection,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_ccache_iterator_t ccache_iterator = NULL;
+
+ if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_clone (io_ccache_iterator,
+ &ccache_iterator);
+ }
+
+ if (!err) {
+ err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+ cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!in_request_data) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ if (in_request_name == cci_ccache_iterator_release_msg_id) {
+ err = ccs_ccache_iterator_release (io_ccache_iterator,
+ io_cache_collection,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_ccache_iterator_next_msg_id) {
+ err = ccs_ccache_iterator_next (io_ccache_iterator,
+ io_cache_collection,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_ccache_iterator_clone_msg_id) {
+ err = ccs_ccache_iterator_clone (io_ccache_iterator,
+ io_cache_collection,
+ in_request_data,
+ reply_data);
+
+ } else {
+ err = ccErrBadInternalMessage;
+ }
+ }
+
+ if (!err) {
+ *out_reply_data = reply_data;
+ reply_data = NULL; /* take ownership */
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.h b/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.h
new file mode 100644
index 00000000..96bf929d
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_ccache_iterator.h
@@ -0,0 +1,37 @@
+/* ccapi/server/ccs_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 CCS_CCACHE_ITERATOR_H
+#define CCS_CCACHE_ITERATOR_H
+
+#include "ccs_types.h"
+
+ cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator,
+ ccs_cache_collection_t io_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data);
+
+#endif /* CCS_CCACHE_ITERATOR_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_client.c b/krb5-1.21.3/src/ccapi/server/ccs_client.c
new file mode 100644
index 00000000..a7b0ad0b
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_client.c
@@ -0,0 +1,236 @@
+/* ccapi/server/ccs_client.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 "ccs_common.h"
+
+struct ccs_client_d {
+ ccs_pipe_t client_pipe;
+
+ /* The following arrays do not own their contents */
+ ccs_callbackref_array_t callbacks;
+ ccs_iteratorref_array_t iterators;
+};
+
+struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_new (ccs_client_t *out_client,
+ ccs_pipe_t in_client_pipe)
+{
+ cc_int32 err = ccNoError;
+ ccs_client_t client = NULL;
+
+ if (!out_client ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ client = malloc (sizeof (*client));
+ if (client) {
+ *client = ccs_client_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_callbackref_array_new (&client->callbacks);
+ }
+
+ if (!err) {
+ err = ccs_iteratorref_array_new (&client->iterators);
+ }
+
+ if (!err) {
+ err = ccs_pipe_copy (&client->client_pipe, in_client_pipe);
+ }
+
+ if (!err) {
+ *out_client = client;
+ client = NULL;
+ }
+
+ ccs_client_release (client);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_release (ccs_client_t io_client)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_client) {
+ cc_uint64 i;
+ cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks);
+ cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators);
+
+ for (i = 0; !err && i < callback_count; i++) {
+ ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
+
+ cci_debug_printf ("%s: Invalidating callback reference %p.",
+ __FUNCTION__, callback);
+ ccs_callback_invalidate (callback);
+ }
+
+ for (i = 0; !err && i < iterator_count; i++) {
+ ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
+
+ cci_debug_printf ("%s: Invalidating iterator reference %p.",
+ __FUNCTION__, iterator);
+ ccs_generic_list_iterator_invalidate (iterator);
+ }
+
+ ccs_callbackref_array_release (io_client->callbacks);
+ ccs_iteratorref_array_release (io_client->iterators);
+ ccs_pipe_release (io_client->client_pipe);
+ free (io_client);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_add_callback (ccs_client_t io_client,
+ ccs_callback_t in_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_client ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_callback) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_callbackref_array_insert (io_client->callbacks, in_callback,
+ ccs_callbackref_array_count (io_client->callbacks));
+ }
+
+ return cci_check_error (err);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_remove_callback (ccs_client_t io_client,
+ ccs_callback_t in_callback)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 found_callback = 0;
+
+ if (!io_client) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks);
+
+ for (i = 0; !err && i < lock_count; i++) {
+ ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
+
+ if (callback == in_callback) {
+ cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+ found_callback = 1;
+ err = ccs_callbackref_array_remove (io_client->callbacks, i);
+ break;
+ }
+ }
+ }
+
+ if (!err && !found_callback) {
+ cci_debug_printf ("%s: WARNING! callback not found.", __FUNCTION__);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_add_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_client ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator,
+ ccs_iteratorref_array_count (io_client->iterators));
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_remove_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 found_iterator = 0;
+
+ if (!io_client) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators);
+
+ for (i = 0; !err && i < lock_count; i++) {
+ ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
+
+ if (iterator == in_iterator) {
+ cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator);
+ found_iterator = 1;
+ err = ccs_iteratorref_array_remove (io_client->iterators, i);
+ break;
+ }
+ }
+ }
+
+ if (!err && !found_iterator) {
+ cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_uses_pipe (ccs_client_t in_client,
+ ccs_pipe_t in_pipe,
+ cc_uint32 *out_uses_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_client ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_pipe ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_pipe_compare (in_client->client_pipe, in_pipe, out_uses_pipe);
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_client.h b/krb5-1.21.3/src/ccapi/server/ccs_client.h
new file mode 100644
index 00000000..b6070daa
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_client.h
@@ -0,0 +1,52 @@
+/* ccapi/server/ccs_client.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 CCS_CLIENT_H
+#define CCS_CLIENT_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_client_new (ccs_client_t *out_client,
+ ccs_pipe_t in_client_pipe);
+
+cc_int32 ccs_client_release (ccs_client_t io_client);
+
+cc_int32 ccs_client_add_callback (ccs_client_t io_client,
+ ccs_callback_t in_lock);
+
+cc_int32 ccs_client_remove_callback (ccs_client_t io_client,
+ ccs_callback_t in_lock);
+
+cc_int32 ccs_client_add_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator);
+
+cc_int32 ccs_client_remove_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator);
+
+cc_int32 ccs_client_uses_pipe (ccs_client_t in_client,
+ ccs_pipe_t in_pipe,
+ cc_uint32 *out_uses_pipe);
+
+#endif /* CCS_CLIENT_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_common.h b/krb5-1.21.3/src/ccapi/server/ccs_common.h
new file mode 100644
index 00000000..eafecd83
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_common.h
@@ -0,0 +1,47 @@
+/* ccapi/server/ccs_common.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 CCS_COMMON_H
+#define CCS_COMMON_H
+
+#include "cci_common.h"
+
+#include
+
+#include "ccs_array.h"
+#include "ccs_list.h"
+#include "ccs_cache_collection.h"
+#include "ccs_ccache_iterator.h"
+#include "ccs_ccache.h"
+#include "ccs_credentials_iterator.h"
+#include "ccs_credentials.h"
+#include "ccs_lock.h"
+#include "ccs_lock_state.h"
+#include "ccs_pipe.h"
+#include "ccs_client.h"
+#include "ccs_callback.h"
+#include "ccs_server.h"
+
+#endif /* CCS_COMMON_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_credentials.c b/krb5-1.21.3/src/ccapi/server/ccs_credentials.c
new file mode 100644
index 00000000..2c68e0f9
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_credentials.c
@@ -0,0 +1,139 @@
+/* ccapi/server/ccs_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 "ccs_common.h"
+
+struct ccs_credentials_d {
+ cc_credentials_union *cred_union;
+ cci_identifier_t identifier;
+};
+
+struct ccs_credentials_d ccs_credentials_initializer = { NULL, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials,
+ k5_ipc_stream in_stream,
+ cc_uint32 in_ccache_version,
+ ccs_credentials_list_t io_credentials_list)
+{
+ cc_int32 err = ccNoError;
+ ccs_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 = ccs_credentials_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_credentials_union_read (&credentials->cred_union, in_stream);
+ }
+
+ if (!err && !(credentials->cred_union->version & in_ccache_version)) {
+ /* ccache does not have a principal set for this credentials version */
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+
+ if (!err) {
+ err = ccs_server_new_identifier (&credentials->identifier);
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_add (io_credentials_list, credentials);
+ }
+
+ if (!err) {
+ *out_credentials = credentials;
+ credentials = NULL;
+ }
+
+ ccs_credentials_release (credentials);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_credentials) {
+ cci_credentials_union_release (io_credentials->cred_union);
+ cci_identifier_release (io_credentials->identifier);
+ free (io_credentials);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials,
+ k5_ipc_stream io_stream)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
+ if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (in_credentials->identifier, io_stream);
+ }
+
+ if (!err) {
+ err = cci_credentials_union_write (in_credentials->cred_union, io_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_compare (in_credentials->identifier,
+ in_identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_credentials.h b/krb5-1.21.3/src/ccapi/server/ccs_credentials.h
new file mode 100644
index 00000000..5f096b86
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_credentials.h
@@ -0,0 +1,46 @@
+/* ccapi/server/ccs_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 CCS_CREDENTIALS_H
+#define CCS_CREDENTIALS_H
+
+#include "ccs_types.h"
+
+
+cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials,
+ k5_ipc_stream in_stream,
+ cc_uint32 in_ccache_version,
+ ccs_credentials_list_t io_credentials_list);
+
+cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials);
+
+cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials,
+ k5_ipc_stream io_stream);
+
+cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal);
+
+#endif /* CCS_CREDENTIALS_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.c b/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.c
new file mode 100644
index 00000000..df18041c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.c
@@ -0,0 +1,158 @@
+/* ccapi/server/ccs_credentials_iterator.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 "ccs_common.h"
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator,
+ ccs_ccache_t io_ccache,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_list_iterator_release (io_credentials_iterator);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator,
+ ccs_ccache_t io_ccache,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_credentials_t credentials = NULL;
+
+ if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_list_iterator_next (io_credentials_iterator,
+ &credentials);
+ }
+
+ if (!err) {
+ err = ccs_credentials_write (credentials, io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_credentials_iterator_clone (ccs_credentials_iterator_t io_credentials_iterator,
+ ccs_ccache_t io_ccache,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream io_reply_data)
+{
+ cc_int32 err = ccNoError;
+ ccs_credentials_iterator_t credentials_iterator = NULL;
+
+ if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_credentials_list_iterator_clone (io_credentials_iterator,
+ &credentials_iterator);
+ }
+
+ if (!err) {
+ err = ccs_credentials_list_iterator_write (credentials_iterator,
+ io_reply_data);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+ cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator,
+ ccs_ccache_t io_ccache,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!in_request_data) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&reply_data);
+ }
+
+ if (!err) {
+ if (in_request_name == cci_credentials_iterator_release_msg_id) {
+ err = ccs_credentials_iterator_release (io_credentials_iterator,
+ io_ccache,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_credentials_iterator_next_msg_id) {
+ err = ccs_credentials_iterator_next (io_credentials_iterator,
+ io_ccache,
+ in_request_data,
+ reply_data);
+
+ } else if (in_request_name == cci_credentials_iterator_clone_msg_id) {
+ err = ccs_credentials_iterator_clone (io_credentials_iterator,
+ io_ccache,
+ in_request_data,
+ reply_data);
+
+ } else {
+ err = ccErrBadInternalMessage;
+ }
+ }
+
+ if (!err) {
+ *out_reply_data = reply_data;
+ reply_data = NULL; /* take ownership */
+ }
+
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.h b/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.h
new file mode 100644
index 00000000..fc81a82b
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_credentials_iterator.h
@@ -0,0 +1,37 @@
+/* ccapi/server/ccs_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 CCS_CREDENTIALS_ITERATOR_H
+#define CCS_CREDENTIALS_ITERATOR_H
+
+#include "ccs_types.h"
+
+ cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator,
+ ccs_ccache_t io_ccache,
+ enum cci_msg_id_t in_request_name,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data);
+
+#endif /* CCS_CREDENTIALS_ITERATOR_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_list.c b/krb5-1.21.3/src/ccapi/server/ccs_list.c
new file mode 100644
index 00000000..ef9a1906
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_list.c
@@ -0,0 +1,361 @@
+/* ccapi/server/ccs_list.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 "ccs_common.h"
+#include "ccs_list_internal.h"
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_list_object_release (ccs_list_object_t io_object)
+{
+ return cci_check_error (ccs_cache_collection_release ((ccs_cache_collection_t) io_object));
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_cache_collection_list_object_compare_identifier (ccs_list_object_t in_cache_collection,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ return ccs_cache_collection_compare_identifier ((ccs_cache_collection_t) in_cache_collection,
+ in_identifier,
+ out_equal);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list)
+{
+ return ccs_list_new (out_list,
+ ccErrInvalidContext,
+ ccErrInvalidContext,
+ ccs_cache_collection_list_object_compare_identifier,
+ ccs_cache_collection_list_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list,
+ cc_uint64 *out_count)
+{
+ return ccs_list_count (in_list, out_count);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_cache_collection_t *out_cache_collection)
+{
+ return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_cache_collection);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list,
+ ccs_cache_collection_t in_cache_collection)
+{
+ return ccs_list_add (io_list, (ccs_list_object_t) in_cache_collection);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ return ccs_list_remove (io_list, in_identifier);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list)
+{
+ return ccs_list_release (io_list);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_list_object_release (ccs_list_object_t io_ccache)
+{
+ return cci_check_error (ccs_ccache_release ((ccs_ccache_t) io_ccache));
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_ccache_list_object_compare_identifier (ccs_list_object_t in_ccache,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ return ccs_ccache_compare_identifier ((ccs_ccache_t) in_ccache,
+ in_identifier,
+ out_equal);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list)
+{
+ return ccs_list_new (out_list,
+ ccErrInvalidCCache,
+ ccErrInvalidCCacheIterator,
+ ccs_ccache_list_object_compare_identifier,
+ ccs_ccache_list_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_ccache_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list,
+ cc_uint64 *out_count)
+{
+ return ccs_list_count (in_list, out_count);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache)
+{
+ return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_ccache);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_ccache_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_find_iterator (in_list, in_identifier,
+ (ccs_list_iterator_t *) out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list,
+ ccs_ccache_t in_ccache)
+{
+ return ccs_list_add (io_list, (ccs_list_object_t) in_ccache);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ return ccs_list_remove (io_list, in_identifier);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ return ccs_list_push_front (io_list, in_identifier);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list)
+{
+ return ccs_list_release (io_list);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream)
+{
+ return ccs_list_iterator_write (in_list_iterator, in_stream);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator,
+ ccs_ccache_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_iterator_clone (in_list_iterator, out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator,
+ ccs_ccache_t *out_ccache)
+{
+ return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_ccache);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator)
+{
+ return ccs_list_iterator_release (io_list_iterator);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark-
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_credentials_list_object_release (ccs_list_object_t io_object)
+{
+ return cci_check_error (ccs_credentials_release ((ccs_credentials_t) io_object));
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_credentials_list_object_compare_identifier (ccs_list_object_t in_credentials,
+ cci_identifier_t in_identifier,
+ cc_uint32 *out_equal)
+{
+ return ccs_credentials_compare_identifier ((ccs_credentials_t) in_credentials,
+ in_identifier,
+ out_equal);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list)
+{
+ return ccs_list_new (out_list,
+ ccErrInvalidCredentials,
+ ccErrInvalidCredentialsIterator,
+ ccs_credentials_list_object_compare_identifier,
+ ccs_credentials_list_object_release);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_credentials_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list,
+ cc_uint64 *out_count)
+{
+ return ccs_list_count (in_list, out_count);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_credentials_t *out_credentials)
+{
+ return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_credentials);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_credentials_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_find_iterator (in_list, in_identifier,
+ (ccs_list_iterator_t *) out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list,
+ ccs_credentials_t in_credential)
+{
+ return ccs_list_add (io_list, (ccs_list_object_t) in_credential);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ return ccs_list_remove (io_list, in_identifier);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list)
+{
+ return ccs_list_release (io_list);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream)
+{
+ return ccs_list_iterator_write (in_list_iterator, in_stream);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator,
+ ccs_credentials_list_iterator_t *out_list_iterator)
+{
+ return ccs_list_iterator_clone (in_list_iterator, out_list_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator,
+ ccs_credentials_t *out_credential)
+{
+ return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_credential);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator)
+{
+ return ccs_list_iterator_release (io_list_iterator);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark-
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator)
+{
+ return ccs_list_iterator_invalidate (io_list_iterator);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_list.h b/krb5-1.21.3/src/ccapi/server/ccs_list.h
new file mode 100644
index 00000000..7b818f92
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_list.h
@@ -0,0 +1,140 @@
+/* ccapi/server/ccs_list.h */
+/*
+ * 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.
+ */
+
+#ifndef CCS_LIST_H
+#define CCS_LIST_H
+
+
+#include "ccs_types.h"
+
+cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list);
+
+cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list,
+ cc_uint64 *out_count);
+
+cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_cache_collection_t *out_cache_collection);
+
+cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list,
+ ccs_cache_collection_t in_cache_collection);
+
+cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list);
+
+cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_ccache_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list,
+ cc_uint64 *out_count);
+
+cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_ccache_t *out_ccache);
+
+cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_ccache_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list,
+ ccs_ccache_t in_ccache);
+
+cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list);
+
+
+cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream);
+
+cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator,
+ ccs_ccache_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator,
+ ccs_ccache_t *out_ccache);
+
+cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list);
+
+cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_credentials_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list,
+ cc_uint64 *out_count);
+
+cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_credentials_t *out_credentials);
+
+cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_credentials_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list,
+ ccs_credentials_t in_credential);
+
+cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list);
+
+
+cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream);
+
+cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator,
+ ccs_credentials_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator,
+ ccs_credentials_t *out_credential);
+
+cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator);
+
+#endif /* CCS_LIST_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_list_internal.c b/krb5-1.21.3/src/ccapi/server/ccs_list_internal.c
new file mode 100644
index 00000000..82d64652
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_list_internal.c
@@ -0,0 +1,675 @@
+/* ccapi/server/ccs_list_internal.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 "ccs_list_internal.h"
+#include "cci_array_internal.h"
+#include "cci_identifier.h"
+#include "ccs_server.h"
+
+typedef enum {
+ ccs_list_action_insert,
+ ccs_list_action_remove,
+ ccs_list_action_push_front
+} ccs_list_action_enum;
+
+/* ------------------------------------------------------------------------ */
+
+struct ccs_list_d {
+ cci_array_t objects;
+ cci_array_t iterators;
+
+ cc_int32 object_not_found_err;
+ cc_int32 iterator_not_found_err;
+
+ ccs_object_compare_identifier_t object_compare_identifier;
+};
+
+struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL };
+
+/* ------------------------------------------------------------------------ */
+
+struct ccs_list_iterator_d {
+ cci_identifier_t identifier;
+ ccs_pipe_t client_pipe;
+ ccs_list_t list;
+ cc_uint64 current;
+};
+
+struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, CCS_PIPE_NULL, NULL, 0 };
+
+static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
+ ccs_list_t in_list,
+ ccs_pipe_t in_client_pipe);
+
+static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator);
+
+static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator,
+ ccs_list_action_enum in_action,
+ cc_uint64 in_object_index);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_new (ccs_list_t *out_list,
+ cc_int32 in_object_not_found_err,
+ cc_int32 in_iterator_not_found_err,
+ ccs_object_compare_identifier_t in_object_compare_identifier,
+ ccs_object_release_t in_object_release)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_t list = NULL;
+
+ if (!out_list) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ list = malloc (sizeof (*list));
+ if (list) {
+ *list = ccs_list_initializer;
+ list->object_not_found_err = in_object_not_found_err;
+ list->iterator_not_found_err = in_iterator_not_found_err;
+ list->object_compare_identifier = in_object_compare_identifier;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_array_new (&list->objects, in_object_release);
+ }
+
+ if (!err) {
+ err = cci_array_new (&list->iterators, ccs_list_iterator_object_release);
+ }
+
+ if (!err) {
+ *out_list = list;
+ list = NULL;
+ }
+
+ ccs_list_release (list);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_release (ccs_list_t io_list)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_list) {
+ cci_array_release (io_list->iterators);
+ cci_array_release (io_list->objects);
+ free (io_list);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_new_iterator (ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_list_iterator_t *out_list_iterator)
+{
+ return cci_check_error (ccs_list_iterator_new (out_list_iterator,
+ io_list,
+ in_client_pipe));
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_release_iterator (ccs_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t iterator = NULL;
+
+ if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_find_iterator (io_list, in_identifier, &iterator);
+ }
+
+ if (!err) {
+ err = ccs_list_iterator_release (iterator);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_count (ccs_list_t in_list,
+ cc_uint64 *out_count)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_count) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_count = cci_array_count (in_list->objects);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static ccs_list_iterator_t ccs_list_iterator_at_index (ccs_list_t in_list,
+ cc_uint64 in_index)
+{
+ return (ccs_list_iterator_t) cci_array_object_at_index (in_list->iterators, in_index);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_list_find_index (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ cc_uint64 *out_object_index)
+{
+ cc_int32 err = ccNoError;
+ cc_int32 found = 0;
+
+ if (!in_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_object_index) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && !found) {
+ cc_uint64 i;
+
+ for (i = 0; !err && i < cci_array_count (in_list->objects); i++) {
+ cc_uint32 equal = 0;
+ cci_array_object_t object = cci_array_object_at_index (in_list->objects, i);
+
+ err = in_list->object_compare_identifier (object, in_identifier, &equal);
+
+ if (!err && equal) {
+ found = 1;
+ *out_object_index = i;
+ break;
+ }
+ }
+ }
+
+ if (!err && !found) {
+ err = cci_check_error (in_list->object_not_found_err);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+cc_int32 ccs_list_find (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_list_object_t *out_object)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 i;
+
+ if (!in_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+ if (!out_object ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_find_index (in_list, in_identifier, &i);
+ }
+
+ if (!err) {
+ *out_object = cci_array_object_at_index (in_list->objects, i);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_list_find_iterator_index (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ cc_uint64 *out_object_index)
+{
+ cc_int32 err = ccNoError;
+ cc_int32 found = 0;
+
+ if (!in_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_object_index) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && !found) {
+ cc_uint64 i;
+
+ for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) {
+ cc_uint32 equal = 0;
+ ccs_list_iterator_t iterator = ccs_list_iterator_at_index (in_list, i);
+
+ err = cci_identifier_compare (iterator->identifier, in_identifier, &equal);
+
+ if (!err && equal) {
+ found = 1;
+ *out_object_index = i;
+ break;
+ }
+ }
+ }
+
+ if (!err && !found) {
+ // Don't report this error to the log file. Non-fatal.
+ return in_list->object_not_found_err;
+ } else {
+ return cci_check_error (err);
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_find_iterator (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_list_iterator_t *out_list_iterator)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 i;
+
+ if (!in_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_find_iterator_index (in_list, in_identifier, &i);
+ }
+
+ if (!err) {
+ *out_list_iterator = ccs_list_iterator_at_index (in_list, i);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_add (ccs_list_t io_list,
+ ccs_list_object_t in_object)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 add_index;
+
+ if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_object) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ add_index = cci_array_count (io_list->objects);
+
+ err = cci_array_insert (io_list->objects, in_object, add_index);
+ }
+
+ if (!err) {
+ /* Fixup iterator indexes */
+ cc_uint64 i;
+
+ for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
+ ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
+
+ err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_remove (ccs_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 remove_index;
+
+ if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_find_index (io_list, in_identifier, &remove_index);
+ }
+
+ if (!err) {
+ err = cci_array_remove (io_list->objects, remove_index);
+ }
+
+ if (!err) {
+ /* Fixup iterator indexes */
+ cc_uint64 i;
+
+ for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
+ ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
+
+ err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_push_front (ccs_list_t io_list,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ cc_uint64 push_front_index;
+
+ if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_find_index (io_list, in_identifier, &push_front_index);
+ }
+
+ if (!err) {
+ err = cci_array_push_front (io_list->objects, push_front_index);
+ }
+
+ if (!err) {
+ /* Fixup iterator indexes */
+ cc_uint64 i;
+
+ for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
+ ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
+
+ err = ccs_list_iterator_update (iterator,
+ ccs_list_action_push_front,
+ push_front_index);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
+ ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t list_iterator = NULL;
+
+ if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ /* client_pipe may be NULL if the iterator exists for internal server use */
+
+ if (!err) {
+ list_iterator = malloc (sizeof (*list_iterator));
+ if (list_iterator) {
+ *list_iterator = ccs_list_iterator_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_server_new_identifier (&list_iterator->identifier);
+ }
+
+ if (!err) {
+ list_iterator->list = io_list;
+ list_iterator->current = 0;
+
+ err = cci_array_insert (io_list->iterators,
+ (cci_array_object_t) list_iterator,
+ cci_array_count (io_list->iterators));
+ }
+
+ if (!err && ccs_pipe_valid (in_client_pipe)) {
+ ccs_client_t client = NULL;
+
+ err = ccs_pipe_copy (&list_iterator->client_pipe, in_client_pipe);
+
+ if (!err) {
+ err = ccs_server_client_for_pipe (in_client_pipe, &client);
+ }
+
+ if (!err) {
+ err = ccs_client_add_iterator (client, list_iterator);
+ }
+ }
+
+ if (!err) {
+ *out_list_iterator = list_iterator;
+ list_iterator = NULL;
+ }
+
+ ccs_list_iterator_release (list_iterator);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_list_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (in_list_iterator->identifier,
+ in_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator,
+ ccs_list_iterator_t *out_list_iterator)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t list_iterator = NULL;
+
+ if (!in_list_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_list_iterator_new (&list_iterator,
+ in_list_iterator->list,
+ in_list_iterator->client_pipe);
+ }
+
+ if (!err) {
+ list_iterator->current = in_list_iterator->current;
+
+ *out_list_iterator = list_iterator;
+ list_iterator = NULL;
+ }
+
+ ccs_list_iterator_release (list_iterator);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator;
+
+ if (!io_list_iterator) { err = ccErrBadParam; }
+
+ if (!err && ccs_pipe_valid (list_iterator->client_pipe)) {
+ ccs_client_t client = NULL;
+
+ err = ccs_server_client_for_pipe (list_iterator->client_pipe, &client);
+
+ if (!err && client) {
+ /* if client object still has a reference to us, remove it */
+ err = ccs_client_remove_iterator (client, list_iterator);
+ }
+ }
+
+ if (!err) {
+ ccs_pipe_release (list_iterator->client_pipe);
+ cci_identifier_release (list_iterator->identifier);
+ free (io_list_iterator);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_list_iterator) {
+ cc_uint64 i = 0;
+
+ if (ccs_list_find_iterator_index (io_list_iterator->list,
+ io_list_iterator->identifier,
+ &i) == ccNoError) {
+ /* cci_array_remove will call ccs_list_iterator_object_release */
+ err = cci_array_remove (io_list_iterator->list->iterators, i);
+ } else {
+ cci_debug_printf ("Warning: iterator not in iterator list!");
+ }
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator;
+
+ if (!io_list_iterator) { err = ccErrBadParam; }
+
+ if (!err) {
+ /* Client owner died. Remove client reference and then the iterator. */
+ if (ccs_pipe_valid (list_iterator->client_pipe)) {
+ ccs_pipe_release (list_iterator->client_pipe);
+ list_iterator->client_pipe = CCS_PIPE_NULL;
+ }
+
+ err = ccs_list_iterator_release (io_list_iterator);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator,
+ ccs_list_object_t *out_object)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!out_object ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) {
+ *out_object = cci_array_object_at_index (io_list_iterator->list->objects,
+ io_list_iterator->current);
+ } else {
+ err = ccIteratorEnd;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator,
+ ccs_list_object_t *out_object)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!out_object ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) {
+ *out_object = cci_array_object_at_index (io_list_iterator->list->objects,
+ io_list_iterator->current);
+ io_list_iterator->current++;
+ } else {
+ err = ccIteratorEnd;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator,
+ ccs_list_action_enum in_action,
+ cc_uint64 in_object_index)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* When the list changes adjust the current index so that */
+ /* we don't unnecessarily skip or double count items */
+ if (in_action == ccs_list_action_insert) {
+ if (io_list_iterator->current > in_object_index) {
+ io_list_iterator->current++;
+ }
+
+ } else if (in_action == ccs_list_action_remove) {
+ if (io_list_iterator->current >= in_object_index) {
+ io_list_iterator->current--;
+ }
+
+ } else if (in_action == ccs_list_action_push_front) {
+ if (io_list_iterator->current < in_object_index) {
+ io_list_iterator->current++;
+ }
+
+ } else {
+ err = cci_check_error (ccErrBadParam);
+ }
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_list_internal.h b/krb5-1.21.3/src/ccapi/server/ccs_list_internal.h
new file mode 100644
index 00000000..08cfa201
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_list_internal.h
@@ -0,0 +1,94 @@
+/* ccapi/server/ccs_list_internal.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 CCS_LIST_INTERNAL_H
+#define CCS_LIST_INTERNAL_H
+
+#include "ccs_common.h"
+#include "cci_array_internal.h"
+
+struct ccs_list_d;
+typedef struct ccs_list_d *ccs_list_t;
+
+struct ccs_list_iterator_d;
+typedef struct ccs_list_iterator_d *ccs_list_iterator_t;
+
+typedef cci_array_object_t ccs_list_object_t;
+typedef cc_int32 (*ccs_object_release_t) (ccs_list_object_t);
+typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_list_object_t, cci_identifier_t, cc_uint32 *);
+
+cc_int32 ccs_list_new (ccs_list_t *out_list,
+ cc_int32 in_object_not_found_err,
+ cc_int32 in_iterator_not_found_err,
+ ccs_object_compare_identifier_t in_object_compare_identifier,
+ ccs_object_release_t in_object_release);
+
+cc_int32 ccs_list_release (ccs_list_t io_list);
+
+cc_int32 ccs_list_new_iterator (ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe,
+ ccs_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_list_release_iterator (ccs_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_list_count (ccs_list_t in_list,
+ cc_uint64 *out_count);
+
+cc_int32 ccs_list_find (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_list_object_t *out_object);
+
+cc_int32 ccs_list_find_iterator (ccs_list_t in_list,
+ cci_identifier_t in_identifier,
+ ccs_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_list_add (ccs_list_t io_list,
+ ccs_list_object_t in_object);
+
+cc_int32 ccs_list_remove (ccs_list_t io_list,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccs_list_push_front (ccs_list_t io_list,
+ cci_identifier_t in_identifier);
+
+
+cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator,
+ k5_ipc_stream in_stream);
+
+cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator,
+ ccs_list_iterator_t *out_list_iterator);
+
+cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator,
+ ccs_list_object_t *out_object);
+
+cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator,
+ ccs_list_object_t *out_object);
+
+cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator);
+
+cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator);
+
+#endif /* CCS_LIST_INTERNAL_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_lock.c b/krb5-1.21.3/src/ccapi/server/ccs_lock.c
new file mode 100644
index 00000000..06886f8c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_lock.c
@@ -0,0 +1,248 @@
+/* ccapi/server/ccs_lock.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 "ccs_common.h"
+
+struct ccs_lock_d {
+ cc_uint32 type;
+ ccs_lock_state_t lock_state_owner;
+ ccs_callback_t callback;
+};
+
+struct ccs_lock_d ccs_lock_initializer = { 0, NULL, NULL };
+
+static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock,
+ ccs_callback_t in_callback);
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_new (ccs_lock_t *out_lock,
+ cc_uint32 in_type,
+ cc_int32 in_invalid_object_err,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_lock_state_t in_lock_state_owner)
+{
+ cc_int32 err = ccNoError;
+ ccs_lock_t lock = NULL;
+
+ if (!out_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_lock_state_owner ) { err = cci_check_error (ccErrBadParam); }
+
+ if (in_type != cc_lock_read &&
+ in_type != cc_lock_write &&
+ in_type != cc_lock_upgrade &&
+ in_type != cc_lock_downgrade) {
+ err = cci_check_error (ccErrBadLockType);
+ }
+
+ if (!err) {
+ lock = malloc (sizeof (*lock));
+ if (lock) {
+ *lock = ccs_lock_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ lock->type = in_type;
+ lock->lock_state_owner = in_lock_state_owner;
+
+ err = ccs_callback_new (&lock->callback,
+ in_invalid_object_err,
+ in_client_pipe,
+ in_reply_pipe,
+ (ccs_callback_owner_t) lock,
+ ccs_lock_invalidate_callback);
+ }
+
+ if (!err) {
+ *out_lock = lock;
+ lock = NULL;
+ }
+
+ ccs_lock_release (lock);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_release (ccs_lock_t io_lock)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_lock) {
+ ccs_callback_release (io_lock->callback);
+ free (io_lock);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock,
+ ccs_callback_t in_callback)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_callback) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccs_lock_t lock = (ccs_lock_t) io_lock;
+
+ err = ccs_lock_state_invalidate_lock (lock->lock_state_owner, lock);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_lock) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_callback_reply_to_client (io_lock->callback, NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock,
+ cc_uint32 *out_pending)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_pending) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_callback_is_pending (in_lock->callback, out_pending);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_type (ccs_lock_t in_lock,
+ cc_uint32 *out_lock_type)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_lock_type) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_lock_type = in_lock->type;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock,
+ cc_uint32 *out_is_read_lock)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_is_read_lock) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_is_read_lock = (in_lock->type == cc_lock_read ||
+ in_lock->type == cc_lock_downgrade);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock,
+ cc_uint32 *out_is_write_lock)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_is_write_lock) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_is_write_lock = (in_lock->type == cc_lock_write ||
+ in_lock->type == cc_lock_upgrade);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock,
+ ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_is_for_client_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_callback_is_for_client_pipe (in_lock->callback, in_client_pipe,
+ out_is_for_client_pipe);
+ }
+
+ return cci_check_error (err);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock,
+ ccs_pipe_t *out_client_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_lock ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_callback_client_pipe (in_lock->callback, out_client_pipe);
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_lock.h b/krb5-1.21.3/src/ccapi/server/ccs_lock.h
new file mode 100644
index 00000000..71863ab1
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_lock.h
@@ -0,0 +1,61 @@
+/* ccapi/server/ccs_lock.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 CCS_LOCK_H
+#define CCS_LOCK_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_lock_new (ccs_lock_t *out_lock,
+ cc_uint32 in_type,
+ cc_int32 in_invalid_object_err,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_lock_state_t in_lock_state_owner);
+
+cc_int32 ccs_lock_release (ccs_lock_t io_lock);
+
+cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock);
+
+cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock,
+ cc_uint32 *out_pending);
+
+cc_int32 ccs_lock_type (ccs_lock_t in_lock,
+ cc_uint32 *out_lock_type);
+
+cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock,
+ cc_uint32 *out_is_read_lock);
+
+cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock,
+ cc_uint32 *out_is_write_lock);
+
+cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock,
+ ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_is_for_client_pipe);
+
+cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock,
+ ccs_pipe_t *out_client_pipe);
+
+#endif /* CCS_LOCK_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_lock_state.c b/krb5-1.21.3/src/ccapi/server/ccs_lock_state.c
new file mode 100644
index 00000000..681661ea
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_lock_state.c
@@ -0,0 +1,525 @@
+/* ccapi/server/ccs_lock_state.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 "ccs_common.h"
+
+struct ccs_lock_state_d {
+ cc_int32 invalid_object_err;
+ cc_int32 pending_lock_err;
+ cc_int32 no_lock_err;
+ ccs_lock_array_t locks;
+ cc_uint64 first_pending_lock_index;
+};
+
+struct ccs_lock_state_d ccs_lock_state_initializer = { 1, 1, 1, NULL, 0 };
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state,
+ cc_int32 in_invalid_object_err,
+ cc_int32 in_pending_lock_err,
+ cc_int32 in_no_lock_err)
+{
+ cc_int32 err = ccNoError;
+ ccs_lock_state_t lock_state = NULL;
+
+ if (!out_lock_state) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ lock_state = malloc (sizeof (*lock_state));
+ if (lock_state) {
+ *lock_state = ccs_lock_state_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = ccs_lock_array_new (&lock_state->locks);
+ }
+
+ if (!err) {
+ lock_state->invalid_object_err = in_invalid_object_err;
+ lock_state->pending_lock_err = in_pending_lock_err;
+ lock_state->no_lock_err = in_no_lock_err;
+
+ *out_lock_state = lock_state;
+ lock_state = NULL;
+ }
+
+ ccs_lock_state_release (lock_state);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err && io_lock_state) {
+ ccs_lock_array_release (io_lock_state->locks);
+ free (io_lock_state);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_status_add_pending_lock (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ cc_uint32 in_lock_type,
+ cc_uint64 *out_lock_index)
+{
+ cc_int32 err = ccNoError;
+ ccs_lock_t lock = NULL;
+
+ if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_lock_new (&lock, in_lock_type,
+ io_lock_state->invalid_object_err,
+ in_client_pipe, in_reply_pipe,
+ io_lock_state);
+ }
+
+ if (!err) {
+ err = ccs_lock_array_insert (io_lock_state->locks, lock,
+ ccs_lock_array_count (io_lock_state->locks));
+ if (!err) { lock = NULL; /* take ownership */ }
+ }
+
+ if (!err) {
+ *out_lock_index = ccs_lock_array_count (io_lock_state->locks) - 1;
+ }
+
+ ccs_lock_release (lock);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_status_remove_lock (ccs_lock_state_t io_lock_state,
+ cc_uint64 in_lock_index)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_lock_state) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_lock_array_remove (io_lock_state->locks, in_lock_index);
+
+ if (!err && in_lock_index < io_lock_state->first_pending_lock_index) {
+ io_lock_state->first_pending_lock_index--;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_status_grant_lock (ccs_lock_state_t io_lock_state,
+ cc_uint64 in_pending_lock_index)
+{
+ cc_int32 err = ccNoError;
+ ccs_lock_t pending_lock = NULL;
+ cc_uint32 type = 0;
+
+ if (!io_lock_state) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ pending_lock = ccs_lock_array_object_at_index (io_lock_state->locks,
+ in_pending_lock_index);
+ if (!pending_lock || in_pending_lock_index < io_lock_state->first_pending_lock_index) {
+ err = cci_check_error (ccErrBadParam);
+ }
+ }
+
+ if (!err) {
+ err = ccs_lock_type (pending_lock, &type);
+ }
+
+ if (!err && (type == cc_lock_upgrade || type == cc_lock_downgrade)) {
+ /* lock upgrades or downgrades. Find the old lock and remove it. */
+ ccs_pipe_t pending_client_pipe = CCS_PIPE_NULL;
+
+ err = ccs_lock_client_pipe (pending_lock, &pending_client_pipe);
+
+ if (!err) {
+ cc_uint64 i;
+
+ for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+ cc_uint32 is_lock_for_client = 0;
+
+ err = ccs_lock_is_for_client_pipe (lock, pending_client_pipe, &is_lock_for_client);
+
+ if (!err && is_lock_for_client) {
+ cci_debug_printf ("%s: Removing old lock %p at index %d to replace with pending lock %p.",
+ __FUNCTION__, lock, (int) i, pending_lock);
+ err = ccs_lock_status_remove_lock (io_lock_state, i);
+ if (!err) { i--; in_pending_lock_index--; /* We removed one so back up an index */ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (!err) {
+ cc_uint64 new_lock_index = 0;
+
+ err = ccs_lock_array_move (io_lock_state->locks,
+ in_pending_lock_index,
+ io_lock_state->first_pending_lock_index,
+ &new_lock_index);
+ if (!err) { io_lock_state->first_pending_lock_index++; }
+ }
+
+ if (!err) {
+ err = ccs_lock_grant_lock (pending_lock);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_pending_lock_client_pipe,
+ cc_uint32 in_pending_lock_type,
+ cc_uint32 *out_grant_lock)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 is_write_locked = 0;
+ cc_uint32 client_has_lock = 0;
+ cc_uint32 other_clients_have_locks = 0;
+ cc_uint32 client_lock_type = 0;
+ cc_uint64 client_lock_index = 0;
+ cc_uint32 grant_lock = 0;
+
+ if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_pending_lock_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!out_grant_lock ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 lock_count = io_lock_state->first_pending_lock_index;
+
+ for (i = 0; !err && i < lock_count; i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+ cc_uint32 lock_type = 0;
+ cc_uint32 lock_is_for_client = 0;
+
+ err = ccs_lock_type (lock, &lock_type);
+
+ if (!err) {
+ err = ccs_lock_is_for_client_pipe (lock, in_pending_lock_client_pipe,
+ &lock_is_for_client);
+ }
+
+ if (!err) {
+ if (lock_type == cc_lock_write || lock_type == cc_lock_upgrade) {
+ is_write_locked = 1;
+ }
+
+ if (!lock_is_for_client) {
+ other_clients_have_locks = 1;
+
+ } else if (!client_has_lock) { /* only record type of 1st lock */
+ client_has_lock = 1;
+ client_lock_type = lock_type;
+ client_lock_index = i;
+ }
+ }
+ }
+ }
+
+ if (!err) {
+ cc_uint64 lock_count = io_lock_state->first_pending_lock_index;
+
+ if (in_pending_lock_type == cc_lock_write) {
+ if (client_has_lock) {
+ err = cci_check_error (ccErrBadLockType);
+ } else {
+ grant_lock = (lock_count == 0);
+ }
+
+ } else if (in_pending_lock_type == cc_lock_read) {
+ if (client_has_lock) {
+ err = cci_check_error (ccErrBadLockType);
+ } else {
+ grant_lock = !is_write_locked;
+ }
+
+ } else if (in_pending_lock_type == cc_lock_upgrade) {
+ if (!client_has_lock || (client_lock_type != cc_lock_read &&
+ client_lock_type != cc_lock_downgrade)) {
+ err = cci_check_error (ccErrBadLockType);
+ } else {
+ /* don't grant if other clients have read locks */
+ grant_lock = !other_clients_have_locks;
+ }
+
+ } else if (in_pending_lock_type == cc_lock_downgrade) {
+ if (!client_has_lock || (client_lock_type != cc_lock_write &&
+ client_lock_type != cc_lock_upgrade)) {
+ err = cci_check_error (ccErrBadLockType);
+ } else {
+ /* downgrades can never block */
+ grant_lock = 1;
+ }
+ } else {
+ err = cci_check_error (ccErrBadLockType);
+ }
+ }
+
+ if (!err) {
+ *out_grant_lock = grant_lock;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_lock_state)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 done = 0;
+
+ if (!io_lock_state) { err = cci_check_error (ccErrBadParam); }
+
+ /* Look at the pending locks and see if we can grant them.
+ * Note that downgrade locks mean we must check all pending locks each pass
+ * since a downgrade lock might be last in the list. */
+
+ while (!err && !done) {
+ cc_uint64 i;
+ cc_uint64 count = ccs_lock_array_count (io_lock_state->locks);
+ cc_uint32 granted_lock = 0;
+
+ for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+ cc_uint32 lock_type = 0;
+ ccs_pipe_t client_pipe = CCS_PIPE_NULL;
+ cc_uint32 can_grant_lock_now = 0;
+
+ err = ccs_lock_client_pipe (lock, &client_pipe);
+
+ if (!err) {
+ err = ccs_lock_type (lock, &lock_type);
+ }
+
+ if (!err) {
+ err = ccs_lock_state_check_pending_lock (io_lock_state, client_pipe,
+ lock_type, &can_grant_lock_now);
+ }
+
+ if (!err && can_grant_lock_now) {
+ err = ccs_lock_status_grant_lock (io_lock_state, i);
+ if (!err) { granted_lock = 1; }
+ }
+ }
+
+ if (!err && !granted_lock) {
+ /* we walked over all the locks and couldn't grant any of them */
+ done = 1;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block,
+ cc_uint32 *out_will_send_reply)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 can_grant_lock_now = 0;
+
+ if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_send_reply ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* Sanity check: if there are any pending locks for this client
+ * the client must have timed out waiting for our reply. Remove any
+ * existing pending locks for the client. */
+ cc_uint64 i;
+
+ for (i = io_lock_state->first_pending_lock_index; !err && i < ccs_lock_array_count (io_lock_state->locks); i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+ cc_uint32 has_pending_lock_for_client = 0;
+
+ err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &has_pending_lock_for_client);
+
+ if (!err && has_pending_lock_for_client) {
+ cci_debug_printf ("WARNING %s: Removing unexpected pending lock %p at index %d.",
+ __FUNCTION__, lock, (int) i);
+ err = ccs_lock_status_remove_lock (io_lock_state, i);
+ if (!err) { i--; /* We removed one so back up an index */ }
+ }
+ }
+ }
+
+ if (!err) {
+ err = ccs_lock_state_check_pending_lock (io_lock_state, in_client_pipe,
+ in_lock_type, &can_grant_lock_now);
+ }
+
+ if (!err) {
+ if (!can_grant_lock_now && (in_block == cc_lock_noblock)) {
+ err = cci_check_error (io_lock_state->pending_lock_err);
+
+ } else {
+ cc_uint64 new_lock_index = 0;
+
+ err = ccs_lock_status_add_pending_lock (io_lock_state,
+ in_client_pipe,
+ in_reply_pipe,
+ in_lock_type,
+ &new_lock_index);
+
+ if (!err && can_grant_lock_now) {
+ err = ccs_lock_status_grant_lock (io_lock_state, new_lock_index);
+
+ if (!err && (in_lock_type == cc_lock_downgrade)) {
+ /* downgrades can allow us to grant other locks */
+ err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state);
+ }
+ }
+ }
+ }
+
+ if (!err) {
+ /* ccs_lock_state_add sends its replies via callback so caller shouldn't */
+ *out_will_send_reply = 1;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_client_pipe)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 found_lock = 0;
+
+ if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+
+ /* Remove all locks for this client.
+ * There should only be one so warn if there are multiple */
+ for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+ cc_uint32 is_for_client = 0;
+
+ err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &is_for_client);
+
+ if (!err && is_for_client) {
+ if (found_lock) {
+ cci_debug_printf ("WARNING %s: Found multiple locks for client.",
+ __FUNCTION__);
+ }
+
+ found_lock = 1;
+
+ cci_debug_printf ("%s: Removing lock %p at index %d.", __FUNCTION__, lock, (int) i);
+ err = ccs_lock_status_remove_lock (io_lock_state, i);
+ if (!err) { i--; /* We removed one so back up an index */ }
+ }
+ }
+ }
+
+ if (!err && !found_lock) {
+ err = cci_check_error (io_lock_state->no_lock_err);
+ }
+
+ if (!err) {
+ err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state,
+ ccs_lock_t in_lock)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_lock_state) { err = ccErrBadParam; }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 count = ccs_lock_array_count (io_lock_state->locks);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
+
+ if (lock == in_lock) {
+ err = ccs_lock_status_remove_lock (io_lock_state, i);
+
+ if (!err) {
+ err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state);
+ break;
+ }
+ }
+ }
+ }
+
+ return cci_check_error (err);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_lock_state.h b/krb5-1.21.3/src/ccapi/server/ccs_lock_state.h
new file mode 100644
index 00000000..de91fca4
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_lock_state.h
@@ -0,0 +1,51 @@
+/* ccapi/server/ccs_lock_state.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 CCS_LOCK_STATE_H
+#define CCS_LOCK_STATE_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state,
+ cc_int32 in_invalid_object_err,
+ cc_int32 in_pending_lock_err,
+ cc_int32 in_no_lock_err);
+
+cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state);
+
+cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block,
+ cc_uint32 *out_will_send_reply);
+
+cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state,
+ ccs_pipe_t in_client_pipe);
+
+cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state,
+ ccs_lock_t in_lock);
+
+#endif /* CCS_LOCK_STATE_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_os_notify.h b/krb5-1.21.3/src/ccapi/server/ccs_os_notify.h
new file mode 100644
index 00000000..4021568f
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_os_notify.h
@@ -0,0 +1,37 @@
+/* ccapi/server/ccs_os_notify.h */
+/*
+ * Copyright 2006-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 CCS_OS_NOTIFY_H
+#define CCS_OS_NOTIFY_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_os_notify_cache_collection_changed (ccs_cache_collection_t io_cache_collection);
+
+cc_int32 ccs_os_notify_ccache_changed (ccs_cache_collection_t io_cache_collection,
+ const char *in_ccache_name);
+
+
+#endif /* CCS_OS_NOTIFY_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_os_pipe.h b/krb5-1.21.3/src/ccapi/server/ccs_os_pipe.h
new file mode 100644
index 00000000..4f6a379c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_os_pipe.h
@@ -0,0 +1,42 @@
+/* ccapi/server/ccs_os_pipe.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 CCS_OS_PIPE_H
+#define CCS_OS_PIPE_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe);
+
+cc_int32 ccs_os_pipe_compare (ccs_pipe_t in_pipe,
+ ccs_pipe_t in_compare_to_pipe,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_os_pipe_copy (ccs_pipe_t *out_pipe,
+ ccs_pipe_t in_pipe);
+
+cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe);
+
+#endif /* CCS_OS_PIPE_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_os_server.h b/krb5-1.21.3/src/ccapi/server/ccs_os_server.h
new file mode 100644
index 00000000..dc89f1d6
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_os_server.h
@@ -0,0 +1,40 @@
+/* ccapi/server/ccs_os_server.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 CCS_OS_SERVER_H
+#define CCS_OS_SERVER_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_os_server_initialize (int argc, const char *argv[]);
+
+cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]);
+
+cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]);
+
+cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe,
+ k5_ipc_stream in_reply_stream);
+
+#endif /* CCS_OS_SERVER_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_pipe.c b/krb5-1.21.3/src/ccapi/server/ccs_pipe.c
new file mode 100644
index 00000000..37744f61
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_pipe.c
@@ -0,0 +1,58 @@
+/* ccapi/server/ccs_pipe.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 "ccs_common.h"
+#include "ccs_os_pipe.h"
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe)
+{
+ return ccs_os_pipe_valid (in_pipe);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe,
+ ccs_pipe_t in_compare_to_pipe,
+ cc_uint32 *out_equal)
+{
+ return ccs_os_pipe_compare (in_pipe, in_compare_to_pipe, out_equal);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe,
+ ccs_pipe_t in_pipe)
+{
+ return ccs_os_pipe_copy (out_pipe, in_pipe);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe)
+{
+ return ccs_os_pipe_release (io_pipe);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_pipe.h b/krb5-1.21.3/src/ccapi/server/ccs_pipe.h
new file mode 100644
index 00000000..6e4f9efa
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_pipe.h
@@ -0,0 +1,42 @@
+/* ccapi/server/ccs_pipe.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 CCS_PIPE_H
+#define CCS_PIPE_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe);
+
+cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe,
+ ccs_pipe_t in_compare_to_pipe,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe,
+ ccs_pipe_t in_pipe);
+
+cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe);
+
+#endif /* CCS_PIPE_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_server.c b/krb5-1.21.3/src/ccapi/server/ccs_server.c
new file mode 100644
index 00000000..1fc8d2c5
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_server.c
@@ -0,0 +1,408 @@
+/* ccapi/server/ccs_server.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 "ccs_common.h"
+#include "ccs_os_server.h"
+
+/* Server Globals: */
+
+cci_uuid_string_t g_server_id = NULL;
+ccs_cache_collection_t g_cache_collection = NULL;
+ccs_client_array_t g_client_array = NULL;
+
+/* ------------------------------------------------------------------------ */
+
+int main (int argc, const char *argv[])
+{
+ cc_int32 err = 0;
+
+ if (!err) {
+ err = ccs_os_server_initialize (argc, argv);
+ }
+
+ if (!err) {
+ err = cci_identifier_new_uuid (&g_server_id);
+ }
+
+ if (!err) {
+ err = ccs_cache_collection_new (&g_cache_collection);
+ }
+
+ if (!err) {
+ err = ccs_client_array_new (&g_client_array);
+ }
+
+ if (!err) {
+ err = ccs_os_server_listen_loop (argc, argv);
+ }
+
+ if (!err) {
+ free (g_server_id);
+ cci_check_error (ccs_cache_collection_release (g_cache_collection));
+ cci_check_error (ccs_client_array_release (g_client_array));
+
+ err = ccs_os_server_cleanup (argc, argv);
+ }
+
+ return cci_check_error (err) ? 1 : 0;
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier)
+{
+ return cci_check_error (cci_identifier_new (out_identifier,
+ g_server_id));
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe)
+{
+ cc_int32 err = ccNoError;
+ ccs_client_t client = NULL;
+
+ if (!err) {
+ err = ccs_client_new (&client, in_connection_pipe);
+ }
+
+ if (!err) {
+ cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, client);
+ err = ccs_client_array_insert (g_client_array,
+ client,
+ ccs_client_array_count (g_client_array));
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 count = ccs_client_array_count (g_client_array);
+ cc_uint32 found = 0;
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i);
+
+ err = ccs_client_uses_pipe (client, in_connection_pipe, &found);
+
+ if (!err && found) {
+ cci_debug_printf ("%s: Removing client %p.", __FUNCTION__, client);
+ err = ccs_client_array_remove (g_client_array, i);
+ break;
+ }
+ }
+
+ if (!err && !found) {
+ cci_debug_printf ("WARNING %s() didn't find client in client list.",
+ __FUNCTION__);
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe,
+ ccs_client_t *out_client)
+{
+ cc_int32 err = ccNoError;
+ ccs_client_t client_for_pipe = NULL;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!out_client ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 count = ccs_client_array_count (g_client_array);
+
+ for (i = 0; !err && i < count; i++) {
+ ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i);
+ cc_uint32 uses_pipe = 0;
+
+ err = ccs_client_uses_pipe (client, in_client_pipe, &uses_pipe);
+
+ if (!err && uses_pipe) {
+ client_for_pipe = client;
+ break;
+ }
+ }
+ }
+
+ if (!err) {
+ *out_client = client_for_pipe; /* may be NULL if not found */
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_client_is_valid)
+{
+ cc_int32 err = ccNoError;
+ ccs_client_t client = NULL;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!out_client_is_valid ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_server_client_for_pipe (in_client_pipe, &client);
+ }
+
+ if (!err) {
+ *out_client_is_valid = (client != NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 ccs_server_request_demux (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ ccs_cache_collection_t in_cache_collection,
+ enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_request_identifier,
+ k5_ipc_stream in_request_data,
+ cc_uint32 *out_will_block,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+
+ if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ if (in_request_name > cci_context_first_msg_id &&
+ in_request_name < cci_context_last_msg_id) {
+ /* Note: context identifier doesn't need to match.
+ * Client just uses the identifier to detect server relaunch. */
+
+ if (!err) {
+ err = ccs_cache_collection_handle_message (in_client_pipe,
+ in_reply_pipe,
+ in_cache_collection,
+ in_request_name,
+ in_request_data,
+ out_will_block,
+ out_reply_data);
+ }
+
+ } else if (in_request_name > cci_ccache_first_msg_id &&
+ in_request_name < cci_ccache_last_msg_id) {
+ ccs_ccache_t ccache = NULL;
+
+ err = ccs_cache_collection_find_ccache (in_cache_collection,
+ in_request_identifier,
+ &ccache);
+
+ if (!err) {
+ err = ccs_ccache_handle_message (in_client_pipe,
+ in_reply_pipe,
+ ccache,
+ in_cache_collection,
+ in_request_name,
+ in_request_data,
+ out_will_block,
+ out_reply_data);
+ }
+
+ } else if (in_request_name > cci_ccache_iterator_first_msg_id &&
+ in_request_name < cci_ccache_iterator_last_msg_id) {
+ ccs_ccache_iterator_t ccache_iterator = NULL;
+
+ err = ccs_cache_collection_find_ccache_iterator (in_cache_collection,
+ in_request_identifier,
+ &ccache_iterator);
+
+ if (!err) {
+ err = ccs_ccache_iterator_handle_message (ccache_iterator,
+ in_cache_collection,
+ in_request_name,
+ in_request_data,
+ out_reply_data);
+ }
+
+ if (!err) {
+ *out_will_block = 0; /* can't block */
+ }
+
+ } else if (in_request_name > cci_credentials_iterator_first_msg_id &&
+ in_request_name < cci_credentials_iterator_last_msg_id) {
+ ccs_credentials_iterator_t credentials_iterator = NULL;
+ ccs_ccache_t ccache = NULL;
+
+ err = ccs_cache_collection_find_credentials_iterator (in_cache_collection,
+ in_request_identifier,
+ &ccache,
+ &credentials_iterator);
+
+ if (!err) {
+ err = ccs_credentials_iterator_handle_message (credentials_iterator,
+ ccache,
+ in_request_name,
+ in_request_data,
+ out_reply_data);
+ }
+
+ if (!err) {
+ *out_will_block = 0; /* can't block */
+ }
+
+ } else {
+ err = ccErrBadInternalMessage;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ k5_ipc_stream in_request)
+{
+ cc_int32 err = ccNoError;
+ enum cci_msg_id_t request_name = 0;
+ cci_identifier_t request_identifier = NULL;
+ cc_uint32 will_block = 0;
+ k5_ipc_stream reply_data = NULL;
+
+ if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_request ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_message_read_request_header (in_request,
+ &request_name,
+ &request_identifier);
+ }
+
+ if (!err) {
+ cc_uint32 server_err = 0;
+ cc_uint32 valid = 0;
+ ccs_cache_collection_t cache_collection = g_cache_collection;
+
+ server_err = cci_identifier_is_for_server (request_identifier,
+ g_server_id,
+ &valid);
+
+ if (!server_err && !valid) {
+ server_err = cci_message_invalid_object_err (request_name);
+ }
+
+ if (!server_err) {
+
+ /* Monolithic server implementation would need to select
+ * cache collection here. Currently we only support per-user
+ * servers so we always use the same cache collection. */
+
+ server_err = ccs_server_request_demux (in_client_pipe,
+ in_reply_pipe,
+ cache_collection,
+ request_name,
+ request_identifier,
+ in_request,
+ &will_block,
+ &reply_data);
+ }
+
+ if (server_err || !will_block) {
+
+ /* send a reply now if the server isn't blocked on something */
+ err = ccs_server_send_reply (in_reply_pipe, server_err, reply_data);
+ }
+ }
+
+ cci_identifier_release (request_identifier);
+ krb5int_ipc_stream_release (reply_data);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe,
+ cc_int32 in_reply_err,
+ k5_ipc_stream in_reply_data)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream reply = NULL;
+
+ if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_message_new_reply_header (&reply, in_reply_err);
+ }
+
+ if (!err && in_reply_data && krb5int_ipc_stream_size (in_reply_data) > 0) {
+ err = krb5int_ipc_stream_write (reply,
+ krb5int_ipc_stream_data (in_reply_data),
+ krb5int_ipc_stream_size (in_reply_data));
+ }
+
+ if (!err) {
+ err = ccs_os_server_send_reply (in_reply_pipe, reply);
+ }
+
+ krb5int_ipc_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_server_client_count ()
+{
+ return ccs_client_array_count (g_client_array);
+}
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_server.h b/krb5-1.21.3/src/ccapi/server/ccs_server.h
new file mode 100644
index 00000000..e920ad93
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_server.h
@@ -0,0 +1,53 @@
+/* ccapi/server/ccs_server.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 CCS_SERVER_H
+#define CCS_SERVER_H
+
+#include "ccs_types.h"
+
+cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier);
+
+cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe);
+
+cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe);
+
+cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe,
+ ccs_client_t *out_client);
+
+cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe,
+ cc_uint32 *out_client_is_valid);
+
+cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe,
+ ccs_pipe_t in_reply_pipe,
+ k5_ipc_stream in_request);
+
+cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe,
+ cc_int32 in_reply_err,
+ k5_ipc_stream in_reply_data);
+
+cc_uint64 ccs_server_client_count ();
+
+#endif /* CCS_SERVER_H */
diff --git a/krb5-1.21.3/src/ccapi/server/ccs_types.h b/krb5-1.21.3/src/ccapi/server/ccs_types.h
new file mode 100644
index 00000000..773b3166
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/ccs_types.h
@@ -0,0 +1,120 @@
+/* ccapi/server/ccs_types.h */
+/*
+ * 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.
+ */
+
+#ifndef CCS_TYPES_H
+#define CCS_TYPES_H
+
+#ifdef WIN32
+#pragma warning ( disable : 4068)
+#endif
+
+#include "cci_types.h"
+
+struct cci_array_d;
+
+typedef struct cci_array_d *ccs_client_array_t;
+
+typedef struct cci_array_d *ccs_callback_array_t;
+
+typedef struct cci_array_d *ccs_callbackref_array_t;
+
+typedef struct cci_array_d *ccs_iteratorref_array_t;
+
+typedef struct cci_array_d *ccs_lock_array_t;
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ccs_os_pipe_t is IPC-specific so it's special cased here */
+
+#if TARGET_OS_MAC
+#include
+typedef mach_port_t ccs_pipe_t; /* Mach IPC port */
+#define CCS_PIPE_NULL MACH_PORT_NULL
+
+#else
+
+#ifdef WIN32
+/* On Windows, a pipe is s struct: */
+#include "ccs_win_pipe.h"
+typedef struct ccs_win_pipe_t* ccs_pipe_t;
+#define CCS_PIPE_NULL (ccs_pipe_t)NULL
+
+#else
+typedef int ccs_pipe_t; /* Unix domain socket */
+#define CCS_PIPE_NULL -1
+
+#endif
+#endif
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+struct ccs_callback_d;
+typedef struct ccs_callback_d *ccs_callback_t;
+
+struct ccs_list_d;
+struct ccs_list_iterator_d;
+
+/* Used for iterator array invalidate function */
+typedef struct ccs_list_iterator_d *ccs_generic_list_iterator_t;
+
+typedef struct ccs_list_d *ccs_cache_collection_list_t;
+
+typedef struct ccs_list_d *ccs_ccache_list_t;
+typedef struct ccs_list_iterator_d *ccs_ccache_list_iterator_t;
+
+typedef struct ccs_list_d *ccs_credentials_list_t;
+typedef struct ccs_list_iterator_d *ccs_credentials_list_iterator_t;
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+struct ccs_client_d;
+typedef struct ccs_client_d *ccs_client_t;
+
+struct ccs_lock_d;
+typedef struct ccs_lock_d *ccs_lock_t;
+
+struct ccs_lock_state_d;
+typedef struct ccs_lock_state_d *ccs_lock_state_t;
+
+struct ccs_credentials_d;
+typedef struct ccs_credentials_d *ccs_credentials_t;
+
+typedef ccs_credentials_list_iterator_t ccs_credentials_iterator_t;
+
+struct ccs_ccache_d;
+typedef struct ccs_ccache_d *ccs_ccache_t;
+
+typedef ccs_ccache_list_iterator_t ccs_ccache_iterator_t;
+
+struct ccs_cache_collection_d;
+typedef struct ccs_cache_collection_d *ccs_cache_collection_t;
+
+#endif /* CCS_TYPES_H */
diff --git a/krb5-1.21.3/src/ccapi/server/deps b/krb5-1.21.3/src/ccapi/server/deps
new file mode 100644
index 00000000..31582f58
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/deps
@@ -0,0 +1,170 @@
+#
+# Generated makefile dependencies follow.
+#
+ccs_array.so ccs_array.po $(OUTPRE)ccs_array.$(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_array_internal.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 ccs_array.c ccs_array.h \
+ ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \
+ ccs_pipe.h ccs_server.h ccs_types.h
+ccs_cache_collection.so ccs_cache_collection.po $(OUTPRE)ccs_cache_collection.$(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 \
+ ccs_array.h ccs_cache_collection.c ccs_cache_collection.h \
+ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \
+ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \
+ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_os_notify.h \
+ ccs_pipe.h ccs_server.h ccs_types.h
+ccs_callback.so ccs_callback.po $(OUTPRE)ccs_callback.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.c ccs_callback.h \
+ ccs_ccache.h ccs_ccache_iterator.h ccs_client.h ccs_common.h \
+ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \
+ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_ccache.so ccs_ccache.po $(OUTPRE)ccs_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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.c \
+ ccs_ccache.h ccs_ccache_iterator.h ccs_client.h ccs_common.h \
+ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \
+ ccs_lock.h ccs_lock_state.h ccs_os_notify.h ccs_pipe.h \
+ ccs_server.h ccs_types.h
+ccs_ccache_iterator.so ccs_ccache_iterator.po $(OUTPRE)ccs_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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.c ccs_ccache_iterator.h ccs_client.h \
+ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \
+ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_client.so ccs_client.po $(OUTPRE)ccs_client.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.c ccs_client.h ccs_common.h \
+ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \
+ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_credentials.so ccs_credentials.po $(OUTPRE)ccs_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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.c \
+ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \
+ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_credentials_iterator.so ccs_credentials_iterator.po \
+ $(OUTPRE)ccs_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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.c ccs_credentials_iterator.h \
+ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_list.so ccs_list.po $(OUTPRE)ccs_list.$(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_array_internal.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 ccs_array.h ccs_cache_collection.h \
+ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \
+ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \
+ ccs_list.c ccs_list.h ccs_list_internal.h ccs_lock.h \
+ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h
+ccs_list_internal.so ccs_list_internal.po $(OUTPRE)ccs_list_internal.$(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_array_internal.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 ccs_array.h ccs_cache_collection.h \
+ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \
+ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \
+ ccs_list.h ccs_list_internal.c ccs_list_internal.h \
+ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \
+ ccs_types.h
+ccs_lock.so ccs_lock.po $(OUTPRE)ccs_lock.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.h ccs_list.h ccs_lock.c ccs_lock.h \
+ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h
+ccs_lock_state.so ccs_lock_state.po $(OUTPRE)ccs_lock_state.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.c \
+ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h
+ccs_pipe.so ccs_pipe.po $(OUTPRE)ccs_pipe.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \
+ ccs_os_pipe.h ccs_pipe.c ccs_pipe.h ccs_server.h ccs_types.h
+ccs_server.so ccs_server.po $(OUTPRE)ccs_server.$(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 \
+ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \
+ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \
+ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \
+ ccs_os_server.h ccs_pipe.h ccs_server.c ccs_server.h \
+ ccs_types.h
diff --git a/krb5-1.21.3/src/ccapi/server/unix/Makefile.in b/krb5-1.21.3/src/ccapi/server/unix/Makefile.in
new file mode 100644
index 00000000..b3743f06
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/unix/Makefile.in
@@ -0,0 +1,12 @@
+mydir=ccapi$(S)server$(S)unix
+BUILDTOP=$(REL)..$(S)..$(S)..
+
+STLIBOBJS=
+OBJS=
+SRCS=
+
+all-unix: all-libobjs
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/krb5-1.21.3/src/ccapi/server/unix/deps b/krb5-1.21.3/src/ccapi/server/unix/deps
new file mode 100644
index 00000000..2feac3c9
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/unix/deps
@@ -0,0 +1 @@
+# No dependencies here.
diff --git a/krb5-1.21.3/src/ccapi/server/win/Makefile.in b/krb5-1.21.3/src/ccapi/server/win/Makefile.in
new file mode 100644
index 00000000..1c925a28
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/Makefile.in
@@ -0,0 +1,114 @@
+# makefile: Constructs the Kerberos for Windows CCAPI server.
+
+#BUILDTOP is krb5/src and is relative to krb5/src/ccapi/server/win, for making Makefile.
+BUILDTOP=..\..\..
+CCAPI = $(BUILDTOP)\CCAPI
+CO = $(CCAPI)\common
+COWIN = $(CCAPI)\common\win
+CCUTIL = $(CCAPI)\common\win\OldCC
+SRVDIR = $(CCAPI)\server
+SRVWIN = $(SRVDIR)\win
+POSIX = $(BUILDTOP)\lib\krb5\posix
+SRCTMP = $(SRVWIN)\srctmp
+
+!if defined(KRB5_KFW_COMPILE)
+KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
+!endif
+
+OBJS = $(OUTPRE)cci_array_internal.$(OBJEXT) \
+ $(OUTPRE)cci_cred_union.$(OBJEXT) \
+ $(OUTPRE)cci_debugging.$(OBJEXT) \
+ $(OUTPRE)cci_identifier.$(OBJEXT) \
+ $(OUTPRE)cci_message.$(OBJEXT) \
+ $(OUTPRE)cci_os_debugging.$(OBJEXT) \
+ $(OUTPRE)cci_os_identifier.$(OBJEXT) \
+ $(OUTPRE)ccs_array.$(OBJEXT) \
+ $(OUTPRE)ccs_cache_collection.$(OBJEXT) \
+ $(OUTPRE)ccs_callback.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_client.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_list.$(OBJEXT) \
+ $(OUTPRE)ccs_list_internal.$(OBJEXT) \
+ $(OUTPRE)ccs_lock.$(OBJEXT) \
+ $(OUTPRE)ccs_lock_state.$(OBJEXT) \
+ $(OUTPRE)ccs_os_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_os_server.$(OBJEXT) \
+ $(OUTPRE)ccs_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_reply_c.$(OBJEXT) \
+ $(OUTPRE)ccs_request_proc.$(OBJEXT) \
+ $(OUTPRE)ccs_server.$(OBJEXT) \
+ $(OUTPRE)ccs_win_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_request_s.$(OBJEXT) \
+ $(OUTPRE)ccutils.$(OBJEXT) \
+ $(OUTPRE)init.$(OBJEXT) \
+ $(OUTPRE)opts.$(OBJEXT) \
+ $(OUTPRE)secure.$(OBJEXT) \
+ $(OUTPRE)tls.$(OBJEXT) \
+ $(OUTPRE)util.$(OBJEXT) \
+ $(OUTPRE)win-utils.$(OBJEXT) \
+ $(OUTPRE)WorkItem.$(OBJEXT) \
+ $(OUTPRE)WorkQueue.$(OBJEXT)
+
+##### Options
+
+# 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 /I.
+MIDLI = /I..\$(BUILDTOP)\include
+
+CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \
+-D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS
+
+##### Linker
+LINK = link
+LIBS = ..\$(SLIB) rpcrt4.lib advapi32.lib ws2_32.lib user32.lib
+LFLAGS = /nologo $(LOPTS)
+
+
+all: Makefile copysrc midl $(OUTPRE)ccapiserver.exe 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 ccapiserver.exe 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 $(SRVDIR)\*.* $(SRCTMP)
+ xcopy /D/Y $(SRVWIN)\*.* $(SRCTMP)
+ cd $(SRCTMP)
+ if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE)
+
+midl : ccs_request.h ccs_reply.h
+
+VERSIONRC = $(BUILDTOP)\..\windows\version.rc
+CCAPISERVERRES = $(OUTPRE)ccapiserver.res
+$(CCAPISERVERRES): $(VERSIONRC)
+ $(RC) $(RCFLAGS) -DCCAPISERVER_APP -fo $@ -r $**
+
+$(OUTPRE)ccapiserver.exe: $(OBJS) $(CCAPISERVERRES)
+ $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(LIBS) $(CCAPISERVERRES) $(conlibsdll) $(conflags)
+
+finish :
+ @echo "Finished building ccapiserver.exe"
+ cd
+
+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/krb5-1.21.3/src/ccapi/server/win/Server.sln b/krb5-1.21.3/src/ccapi/server/win/Server.sln
new file mode 100644
index 00000000..ea1bd455
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/Server.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/krb5-1.21.3/src/ccapi/server/win/Server.vcproj b/krb5-1.21.3/src/ccapi/server/win/Server.vcproj
new file mode 100644
index 00000000..626c7a3c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/Server.vcproj
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/krb5-1.21.3/src/ccapi/server/win/WorkItem.cpp b/krb5-1.21.3/src/ccapi/server/win/WorkItem.cpp
new file mode 100644
index 00000000..79a34873
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/WorkItem.cpp
@@ -0,0 +1,142 @@
+/*
+ * $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
+#include "assert.h"
+
+#pragma warning (disable : 4996)
+
+#include "win-utils.h"
+#include "WorkItem.h"
+
+extern "C" {
+#include "cci_debugging.h"
+ }
+
+// CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted.
+
+void deleteBuffer(char** buf) {
+ if (*buf) {
+ delete [](*buf);
+ *buf = NULL;
+ }
+ }
+
+// WorkItem contains a CountedBuffer which must be deleted,
+// so each WorkItem must be deleted.
+WorkItem::WorkItem(k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long sst)
+: _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }
+
+WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {
+
+ k5_ipc_stream _buf = NULL;
+ krb5int_ipc_stream_new(&_buf);
+ krb5int_ipc_stream_write(_buf,
+ krb5int_ipc_stream_data(item.payload()),
+ krb5int_ipc_stream_size(item.payload()) );
+ WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);
+ }
+
+WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }
+
+WorkItem::~WorkItem() {
+ if (_buf) krb5int_ipc_stream_release(_buf);
+ if (_pipe) ccs_win_pipe_release(_pipe);
+ }
+
+const k5_ipc_stream WorkItem::take_payload() {
+ k5_ipc_stream temp = payload();
+ _buf = NULL;
+ return temp;
+ }
+
+WIN_PIPE* WorkItem::take_pipe() {
+ WIN_PIPE* temp = pipe();
+ _pipe = NULL;
+ return temp;
+ }
+
+WorkList::WorkList() {
+ assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));
+ }
+
+WorkList::~WorkList() {
+ // Delete any WorkItems in the queue:
+ WorkItem* item;
+ cci_debug_printf("%s", __FUNCTION__);
+ char buf[2048];
+ char* pbuf = (char*)buf;
+ while (remove(&item)) {
+ cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));
+ delete item;
+ }
+
+ DeleteCriticalSection(&cs);
+ }
+
+char* WorkItem::print(char* buf) {
+ sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst,
+ ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));
+ return buf;
+ }
+
+int WorkList::initialize() {
+ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ return 0;
+ }
+
+int WorkList::cleanup() {
+ CloseHandle(hEvent);
+ hEvent = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+
+void WorkList::wait() {
+ WaitForSingleObject(hEvent, INFINITE);
+ }
+
+int WorkList::add(WorkItem* item) {
+ EnterCriticalSection(&cs);
+ wl.push_front(item);
+ LeaveCriticalSection(&cs);
+ SetEvent(hEvent);
+ return 1;
+ }
+
+int WorkList::remove(WorkItem** item) {
+ bool bEmpty;
+
+ bEmpty = wl.empty() & 1;
+
+ if (!bEmpty) {
+ EnterCriticalSection(&cs);
+ *item = wl.back();
+ wl.pop_back();
+ LeaveCriticalSection(&cs);
+ }
+
+ return !bEmpty;
+ }
diff --git a/krb5-1.21.3/src/ccapi/server/win/WorkQueue.cpp b/krb5-1.21.3/src/ccapi/server/win/WorkQueue.cpp
new file mode 100644
index 00000000..fc5fa7e1
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/WorkQueue.cpp
@@ -0,0 +1,74 @@
+/*
+ * $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 "WorkQueue.h"
+extern "C" {
+ #include "cci_debugging.h"
+ }
+
+#include "WorkItem.h"
+
+WorkList worklist;
+
+EXTERN_C int worklist_initialize() {
+ return worklist.initialize();
+ }
+
+EXTERN_C int worklist_cleanup() {
+ return worklist.cleanup();
+ }
+
+EXTERN_C void worklist_wait() {
+ worklist.wait();
+ }
+
+/* C interfaces: */
+EXTERN_C BOOL worklist_isEmpty() {
+ return worklist.isEmpty() ? TRUE : FALSE;
+ }
+
+EXTERN_C int worklist_add( const long rpcmsg,
+ const ccs_pipe_t pipe,
+ const k5_ipc_stream stream,
+ const time_t serverStartTime) {
+ return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) );
+ }
+
+EXTERN_C int worklist_remove(long* rpcmsg,
+ ccs_pipe_t* pipe,
+ k5_ipc_stream* stream,
+ time_t* sst) {
+ WorkItem* item = NULL;
+ cc_int32 err = worklist.remove(&item);
+
+ *rpcmsg = item->type();
+ *pipe = item->take_pipe();
+ *stream = item->take_payload();
+ *sst = item->sst();
+ delete item;
+ return err;
+ }
+
diff --git a/krb5-1.21.3/src/ccapi/server/win/WorkQueue.h b/krb5-1.21.3/src/ccapi/server/win/WorkQueue.h
new file mode 100644
index 00000000..68aa8b1c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/WorkQueue.h
@@ -0,0 +1,51 @@
+/* ccapi/server/win/WorkQueue.h */
+/*
+ * Copyright 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.
+ */
+
+#ifndef _work_queue_h
+#define _work_queue_h
+
+#include "windows.h"
+#include "ccs_pipe.h"
+
+EXTERN_C int worklist_initialize();
+
+EXTERN_C int worklist_cleanup();
+
+/* Wait for work to be added to the list (via worklist_add) from another thread */
+EXTERN_C void worklist_wait();
+
+EXTERN_C BOOL worklist_isEmpty();
+
+EXTERN_C int worklist_add( const long rpcmsg,
+ const ccs_pipe_t pipe,
+ const k5_ipc_stream stream,
+ const time_t serverStartTime);
+
+EXTERN_C int worklist_remove(long* rpcmsg,
+ ccs_pipe_t* pipe,
+ k5_ipc_stream* stream,
+ time_t* serverStartTime);
+
+#endif // _work_queue_h
diff --git a/krb5-1.21.3/src/ccapi/server/win/ccs_os_pipe.c b/krb5-1.21.3/src/ccapi/server/win/ccs_os_pipe.c
new file mode 100644
index 00000000..7e190cee
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/ccs_os_pipe.c
@@ -0,0 +1,62 @@
+/* ccapi/server/win/ccs_os_pipe.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 "ccs_common.h"
+#include "ccs_os_pipe.h"
+#include "ccs_win_pipe.h"
+
+/* ------------------------------------------------------------------------ */
+
+/* On Windows, a pipe is a struct. See ccs_win_pipe.h for details. */
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) {
+ return ccs_win_pipe_valid(in_pipe);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_pipe_copy (ccs_pipe_t* out_pipe, ccs_pipe_t in_pipe) {
+ return ccs_win_pipe_copy(
+ out_pipe,
+ in_pipe);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe) {
+ return ccs_win_pipe_release(io_pipe);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_pipe_compare (ccs_pipe_t pipe_1,
+ ccs_pipe_t pipe_2,
+ cc_uint32 *out_equal) {
+
+ return ccs_win_pipe_compare(pipe_1, pipe_2, out_equal);
+ }
diff --git a/krb5-1.21.3/src/ccapi/server/win/ccs_os_server.cpp b/krb5-1.21.3/src/ccapi/server/win/ccs_os_server.cpp
new file mode 100644
index 00000000..1b54718a
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/ccs_os_server.cpp
@@ -0,0 +1,950 @@
+/*
+ * $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 "process.h"
+#include "windows.h"
+
+extern "C" {
+#include "ccs_common.h"
+#include "ccs_os_notify.h"
+#include "ccs_os_server.h"
+#include "ccs_reply.h"
+#include "ccs_request.h"
+#include "win-utils.h"
+#include "ccutils.h"
+ }
+
+#include "WorkQueue.h"
+#include "util.h"
+#include "opts.hxx"
+#include "init.hxx"
+
+#pragma warning (disable : 4996)
+
+BOOL bListen = TRUE; /* Why aren't bool and true defined? */
+const char* sessID = NULL; /* The logon session we are running on behalf of. */
+time_t _sst = 0;
+unsigned char* pszNetworkAddress = NULL;
+unsigned char* pszStringBinding = NULL;
+BOOL bRpcHandleInited = FALSE;
+_RPC_ASYNC_STATE* rpcState = NULL;
+
+/* Thread procedures can take only one void* argument. We put all the args we want
+ to pass into this struct and then pass a pointer to the struct: */
+struct RpcRcvArgs {
+ char* networkAddress;
+ unsigned char* protocolSequence;
+ unsigned char* sessID; /* Used for this server's endpoint */
+ unsigned char* uuid; /* Used for client's UUID */
+ ParseOpts::Opts* opts;
+ RPC_STATUS status;
+ } rpcargs = { NULL, /* pszNetworkAddress */
+ (unsigned char*)"ncalrpc", /* pszProtocolSequence */
+ NULL, /* sessID placeholder */
+ NULL, /* uuid placeholder */
+ NULL }; /* Opts placeholder */
+
+/* Command line format:
+ argv[0] Program name
+ argv[1] session ID to use
+ argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process
+ can be attached in debugger.
+ Any other value: continue
+ */
+#define N_FIXED_ARGS 3
+#define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle
+
+/* Forward declarations: */
+void receiveLoop(void* rpcargs);
+void connectionListener(void* rpcargs);
+void Usage(const char* argv0);
+void printError(TCHAR* msg);
+void setMySST() {_sst = time(&_sst);}
+time_t getMySST() {return _sst;}
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe);
+void RPC_ENTRY clientListener( _RPC_ASYNC_STATE*,
+ void* Context,
+ RPC_ASYNC_EVENT Event);
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
+ IN void *Context);
+RPC_STATUS send_init(char* clientUUID);
+//DWORD alloc_name(LPSTR* pname, LPSTR postfix);
+
+
+/* The layout of the rest of this module:
+
+ The four entrypoints defined in ccs_os_server.h:
+ ccs_os_server_initialize
+ cc_int32 ccs_os_server_cleanup
+ cc_int32 ccs_os_server_listen_loop
+ cc_int32 ccs_os_server_send_reply
+
+ Other routines needed by those four.
+ */
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+ ParseOpts::Opts opts = { 0 };
+ ParseOpts PO;
+ BOOL bAdjustedShutdown = FALSE;
+ HMODULE hKernel32 = GetModuleHandle("kernel32");
+
+ if (!err) {
+ sessID = argv[1];
+ setMySST();
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+#ifdef CCAPI_TEST_OPTIONS
+ PO.SetValidOpts("kemnfubc");
+#else
+ PO.SetValidOpts("kc");
+#endif
+
+ PO.Parse(opts, argc, (char**)argv);
+
+// while(*argv[2] == 'D') {} /* Hang here to attach process with debugger. */
+
+ if (hKernel32) {
+ typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD);
+ FP_SetProcessShutdownParameters pSetProcessShutdownParameters =
+ (FP_SetProcessShutdownParameters)
+ GetProcAddress(hKernel32, "SetProcessShutdownParameters");
+ if (pSetProcessShutdownParameters) {
+ bAdjustedShutdown = pSetProcessShutdownParameters(100, 0);
+ }
+ }
+ cci_debug_printf("%s Shutdown Parameters",
+ bAdjustedShutdown ? "Adjusted" : "Did not adjust");
+
+ err = Init::Initialize();
+ }
+
+// if (!err) {
+// if (opts.bShutdown) {
+// status = shutdown_server(opts.pszEndpoint);
+// }
+// }
+// else {
+// status = startup_server(opts);
+// }
+
+ if (!err) {
+ err = worklist_initialize();
+ }
+
+ if (err) {
+ Init::Cleanup();
+ fprintf( stderr, "An error occurred while %s the server (%u)\n",
+ opts.bShutdown ? "shutting down" : "starting/running",
+ err);
+ exit(cci_check_error (err));
+ }
+
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+
+ cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]);
+
+ worklist_cleanup();
+
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+/* This function takes work items off the work queue and executes them.
+ * This is the one and only place where the multi-threaded Windows code
+ * calls into the single-threaded common code.
+ *
+ * The actual 'listening' for requests from clients happens after receiveloop
+ * establishes the RPC endpoint the clients will connect to and the RPC procedures
+ * put the work items into the work queue.
+ */
+cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+ uintptr_t threadStatus;
+
+ ParseOpts::Opts opts = { 0 };
+ ParseOpts PO;
+ BOOL bQuitIfNoClients = FALSE;
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+#ifdef CCAPI_TEST_OPTIONS
+ PO.SetValidOpts("kemnfubc");
+#else
+ PO.SetValidOpts("kc");
+#endif
+ PO.Parse(opts, argc, (char**)argv);
+
+
+ //++ debug stuff
+ #define INFO_BUFFER_SIZE 32767
+ TCHAR infoBuf[INFO_BUFFER_SIZE];
+ DWORD bufCharCount = INFO_BUFFER_SIZE;
+ // Get and display the user name.
+ bufCharCount = INFO_BUFFER_SIZE;
+ if( !GetUserName( infoBuf, &bufCharCount ) ) printError( TEXT("GetUserName") );
+ //--
+
+ /* Sending the reply from within the request RPC handler doesn't seem to work.
+ So we listen for requests in a separate thread and put the requests in a
+ queue. */
+ rpcargs.sessID = (unsigned char*)sessID;
+ rpcargs.opts = &opts;
+ /// TODO: check for NULL handle, error, etc. probably move to initialize func...
+ threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs);
+
+ /* We handle the queue entries here. Work loop: */
+ while (ccs_server_client_count() > 0 || !bQuitIfNoClients) {
+ worklist_wait();
+ while (!worklist_isEmpty()) {
+ k5_ipc_stream buf = NULL;
+ long rpcmsg = CCMSG_INVALID;
+ time_t serverStartTime = 0xDEADDEAD;
+ RPC_STATUS status = 0;
+ char* uuid = NULL;
+ k5_ipc_stream stream = NULL;
+ ccs_pipe_t pipe = NULL;
+ ccs_pipe_t pipe2 = NULL;
+
+ if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) {
+ uuid = ccs_win_pipe_getUuid(pipe);
+
+ if (serverStartTime <= getMySST()) {
+ switch (rpcmsg) {
+ case CCMSG_CONNECT: {
+ cci_debug_printf(" Processing CONNECT");
+ rpcargs.uuid = (unsigned char*)uuid;
+
+ // Even if a disconnect message is received before this code finishes,
+ // it won't be dequeued and processed until after this code finishes.
+ // So we can add the client after starting the connection listener.
+ connectionListener((void*)&rpcargs);
+ status = rpcargs.status;
+
+ if (!status) {
+ status = ccs_server_add_client(pipe);
+ }
+ if (!status) {status = send_connection_reply(pipe);}
+ break;
+ }
+ case CCMSG_DISCONNECT: {
+ cci_debug_printf(" Processing DISCONNECT");
+ if (!status) {
+ status = ccs_server_remove_client(pipe);
+ }
+ break;
+ }
+ case CCMSG_REQUEST:
+ cci_debug_printf(" Processing REQUEST");
+ ccs_pipe_copy(&pipe2, pipe);
+ // Dispatch message here, setting both pipes to the client UUID:
+ err = ccs_server_handle_request (pipe, pipe2, buf);
+ break;
+ case CCMSG_PING:
+ cci_debug_printf(" Processing PING");
+ err = krb5int_ipc_stream_new (&stream);
+ err = krb5int_ipc_stream_write(stream, "This is a test of the emergency broadcasting system", 52);
+ err = ccs_os_server_send_reply(pipe, stream);
+ break;
+ case CCMSG_QUIT:
+ bQuitIfNoClients = TRUE;
+ break;
+ default:
+ cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>",
+ rpcmsg, uuid);
+ break;
+ }
+ if (buf) krb5int_ipc_stream_release(buf);
+ /* Don't free uuid, which was allocated here. A pointer to it is in the
+ rpcargs struct which was passed to connectionListener which will be
+ received by ccapi_listen when the client exits. ccapi_listen needs
+ the uuid to know which client to disconnect.
+ */
+ }
+ // Server's start time is different from what the client thinks.
+ // That means the server has rebooted since the client connected.
+ else {
+ cci_debug_printf("Whoops! Server has rebooted since client established connection.");
+ }
+ }
+ else {cci_debug_printf("Huh? Queue not empty but no item to remove.");}
+ }
+ }
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_pipe,
+ k5_ipc_stream in_reply_stream) {
+
+ /* ccs_pipe_t in_reply_pipe is a char* reply endpoint.
+ k5_ipc_stream in_reply_stream is the data to be sent.
+ */
+
+ cc_int32 err = 0;
+ char* uuid = ccs_win_pipe_getUuid(in_pipe);
+ UINT64 h = ccs_win_pipe_getHandle(in_pipe);
+
+ if (!err) {
+ err = send_init(uuid); // Sets RPC handle to be used.
+ }
+
+ if (!err) {
+ RpcTryExcept {
+ long status;
+ ccs_rpc_request_reply( // make call with user message
+ CCMSG_REQUEST_REPLY, /* Message type */
+ (unsigned char*)&h, /* client's tspdata* */
+ (unsigned char*)uuid,
+ getMySST(),
+ krb5int_ipc_stream_size(in_reply_stream), /* Length of buffer */
+ (const unsigned char*)krb5int_ipc_stream_data(in_reply_stream), /* Data buffer */
+ &status ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+ }
+
+ /* The calls to the remote procedures are complete. */
+ /* Free whatever we allocated: */
+ err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
+
+ return cci_check_error (err);
+ }
+
+
+/* Windows-specific routines: */
+
+void Usage(const char* argv0) {
+ printf("Usage:\n");
+ printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0);
+ printf(" CCAPI server process.\n");
+ printf(" h|? whow usage message. <\n");
+ }
+
+/* ------------------------------------------------------------------------ */
+/* The receive thread repeatedly issues RpcServerListen.
+ When a message arrives, it is handled in the RPC procedure.
+ */
+void receiveLoop(void* rpcargs) {
+
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
+ RPC_STATUS status = FALSE;
+ unsigned char* pszSecurity = NULL;
+ LPSTR endpoint = NULL;
+ LPSTR event_name = NULL;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ HANDLE hEvent = 0;
+ Init::InitInfo info;
+
+ cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__);
+
+ status = Init::Info(info);
+
+ /* Build complete RPC endpoint using previous CCAPI implementation: */
+ if (!status) {
+ if (!rcvargs->opts->pszEndpoint) {
+ if (!status) {
+ status = alloc_name(&endpoint, "ep", isNT());
+ }
+
+ if (!status) {
+ status = alloc_name(&event_name, "startup", isNT());
+ }
+
+ if (!status) {
+ hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
+ // We ignore any error opening the event because we do not know who started us.
+ // [Comment paraphrased from previous implementation, whence it was copied.]
+ }
+ }
+ else {
+ endpoint = rcvargs->opts->pszEndpoint;
+ }
+ }
+
+ cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);
+
+ if (!status && isNT()) {
+ status = alloc_own_security_descriptor_NT(&psd);
+ }
+
+ if (!status) {
+ status = RpcServerUseProtseqEp(rcvargs->protocolSequence,
+ rcvargs->opts->cMaxCalls,
+ (RPC_CSTR)endpoint,
+ rcvargs->opts->bDontProtect ? 0 : psd); // SD
+ }
+
+ if (!status) {
+ status = RpcServerRegisterAuthInfo(0, // server principal
+ RPC_C_AUTHN_WINNT,
+ 0,
+ 0);
+ }
+
+ while (bListen && !status) {
+ cci_debug_printf("%s is listening ...", __FUNCTION__);
+
+ if (!info.isNT) {
+ status = RpcServerRegisterIf(ccs_request_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL); // MgrEpv; null means use default
+ }
+ else {
+ status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL, // MgrEpv; 0 means default
+ RPC_IF_ALLOW_SECURE_ONLY,
+ rcvargs->opts->cMaxCalls,
+ rcvargs->opts->bSecCallback ?
+ (RPC_IF_CALLBACK_FN*)sec_callback : 0 );
+ }
+
+ if (!status) {
+ status = RpcServerListen(rcvargs->opts->cMinCalls,
+ rcvargs->opts->cMaxCalls,
+ rcvargs->opts->fDontWait);
+ }
+
+ if (!status) {
+ if (rcvargs->opts->fDontWait) {
+ if (hEvent) SetEvent(hEvent); // Ignore any error -- SetEvent is an optimization.
+ status = RpcMgmtWaitServerListen();
+ }
+ }
+ }
+
+ if (status) { // Cleanup in case of errors:
+ if (hEvent) CloseHandle(hEvent);
+ free_alloc_p(&event_name);
+ free_alloc_p(&psd);
+ if (endpoint && (endpoint != rcvargs->opts->pszEndpoint))
+ free_alloc_p(&endpoint);
+ }
+
+ // tell main thread to shutdown since it won't receive any more messages
+ worklist_add(CCMSG_QUIT, NULL, NULL, 0);
+ _endthread();
+ } // End receiveLoop
+
+
+
+/* ------------------------------------------------------------------------ */
+/* The connection listener thread waits forever for a call to the CCAPI_CLIENT_
+ endpoint, ccapi_listen function to complete. If the call completes or gets an
+ RPC exception, it means the client has disappeared.
+
+ A separate connectionListener is started for each client that has connected to the server.
+ */
+
+void connectionListener(void* rpcargs) {
+
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
+ RPC_STATUS status = FALSE;
+ char* endpoint;
+ unsigned char* pszOptions = NULL;
+ unsigned char * pszUuid = NULL;
+
+ endpoint = clientEndpoint((char*)rcvargs->uuid);
+ rpcState = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE));
+ status = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE));
+ cci_debug_printf("");
+ cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint);
+
+ rpcState->UserInfo = rcvargs->uuid;
+ rpcState->NotificationType = RpcNotificationTypeApc;
+ rpcState->u.APC.NotificationRoutine = clientListener;
+ rpcState->u.APC.hThread = 0;
+
+ /* [If in use] Free previous binding: */
+ if (bRpcHandleInited) {
+ // Free previous binding (could have been used to call ccapi_listen
+ // in a different client thread).
+ // Don't check result or update status.
+ RpcStringFree(&pszStringBinding);
+ RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
+ bRpcHandleInited = FALSE;
+ }
+
+ /* Set up binding to the client's endpoint: */
+ if (!status) {
+ status = RpcStringBindingCompose(
+ pszUuid,
+ pszProtocolSequence,
+ pszNetworkAddress,
+ (RPC_CSTR)endpoint,
+ pszOptions,
+ &pszStringBinding);
+ }
+
+ /* Set the binding handle that will be used to bind to the server. */
+ if (!status) {
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
+ }
+ if (!status) {bRpcHandleInited = TRUE;}
+
+ RpcTryExcept {
+ cci_debug_printf(" Calling remote procedure ccapi_listen");
+ ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status);
+ /* Asynchronous call will return immediately. */
+ }
+ RpcExcept(1) {
+ status = cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ rcvargs->status = status;
+ } // End connectionListener
+
+
+void RPC_ENTRY clientListener(
+ _RPC_ASYNC_STATE* pAsync,
+ void* Context,
+ RPC_ASYNC_EVENT Event
+ ) {
+
+ ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL);
+
+ cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!",
+ __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo);
+
+ worklist_add( CCMSG_DISCONNECT,
+ pipe,
+ NULL, /* No payload with connect request */
+ (const time_t)0 ); /* No server session number with connect request */
+ }
+
+
+void printError( TCHAR* msg ) {
+ DWORD eNum;
+ TCHAR sysMsg[256];
+ TCHAR* p;
+
+ eNum = GetLastError( );
+ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, eNum,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ sysMsg, 256, NULL );
+
+ // Trim the end of the line and terminate it with a null
+ p = sysMsg;
+ while( ( *p > 31 ) || ( *p == 9 ) )
+ ++p;
+ do { *p-- = 0; } while( ( p >= sysMsg ) &&
+ ( ( *p == '.' ) || ( *p < 33 ) ) );
+
+ // Display the message
+ cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg);
+ }
+
+
+RPC_STATUS send_init(char* clientUUID) {
+ RPC_STATUS status;
+ unsigned char * pszUuid = NULL;
+ unsigned char * pszOptions = NULL;
+
+ /* Use a convenience function to concatenate the elements of */
+ /* the string binding into the proper sequence. */
+ status = RpcStringBindingCompose(pszUuid,
+ pszProtocolSequence,
+ pszNetworkAddress,
+ (unsigned char*)clientEndpoint(clientUUID),
+ pszOptions,
+ &pszStringBinding);
+ if (status) {return (status);}
+
+ /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
+ return (status);
+ }
+
+RPC_STATUS send_finish() {
+ RPC_STATUS status;
+ /* Can't shut down client -- it runs listen function which */
+ /* server uses to detect the client going away. */
+
+ /* The calls to the remote procedures are complete. */
+ /* Free the string and the binding handle */
+ status = RpcStringFree(&pszStringBinding); // remote calls done; unbind
+ if (status) {return (status);}
+
+ status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); // remote calls done; unbind
+
+ return (status);
+ }
+
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) {
+ char* uuid = ccs_win_pipe_getUuid (in_pipe);
+ UINT64 h = ccs_win_pipe_getHandle(in_pipe);
+ RPC_STATUS status = send_init(uuid);
+
+ RpcTryExcept {
+ ccs_rpc_connect_reply( // make call with user message
+ CCMSG_CONNECT_REPLY, /* Message type */
+ (unsigned char*)&h, /* client's tspdata* */
+ (unsigned char*)uuid,
+ getMySST(), /* Server's session number = its start time */
+ &status ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ status = send_finish();
+ return (status);
+ }
+
+RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient,
+ LPTSTR pszClientName,
+ int iMaxLen) {
+ RPC_STATUS Status = RPC_S_OK;
+ RPC_BINDING_HANDLE hServer = NULL;
+ PTBYTE pszStringBinding = NULL;
+ PTBYTE pszClientNetAddr = NULL;
+ PTBYTE pszProtSequence = NULL;
+
+ memset(pszClientName, 0, iMaxLen * sizeof(TCHAR));
+
+ __try {
+ // Create a partially bound server handle from the client handle.
+ Status = RpcBindingServerFromClient (hClient, &hServer);
+ if (Status != RPC_S_OK) __leave;
+
+ // Get the partially bound server string binding and parse it.
+ Status = RpcBindingToStringBinding (hServer,
+ &pszStringBinding);
+ if (Status != RPC_S_OK) __leave;
+
+ // String binding only contains protocol sequence and client
+ // address, and is not currently implemented for named pipes.
+ Status = RpcStringBindingParse (pszStringBinding, NULL,
+ &pszProtSequence, &pszClientNetAddr,
+ NULL, NULL);
+ if (Status != RPC_S_OK)
+ __leave;
+ int iLen = lstrlen(pszClientName) + 1;
+ if (iMaxLen < iLen)
+ Status = RPC_S_BUFFER_TOO_SMALL;
+ lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen);
+ }
+ __finally {
+ if (pszProtSequence)
+ RpcStringFree (&pszProtSequence);
+
+ if (pszClientNetAddr)
+ RpcStringFree (&pszClientNetAddr);
+
+ if (pszStringBinding)
+ RpcStringFree (&pszStringBinding);
+
+ if (hServer)
+ RpcBindingFree (&hServer);
+ }
+ return Status;
+}
+
+struct client_auth_info {
+ RPC_AUTHZ_HANDLE authz_handle;
+ unsigned char* server_principal; // need to RpcFreeString this
+ ULONG authn_level;
+ ULONG authn_svc;
+ ULONG authz_svc;
+};
+
+RPC_STATUS
+GetClientId(
+ RPC_BINDING_HANDLE hClient,
+ char* client_id,
+ int max_len,
+ client_auth_info* info
+ )
+{
+ RPC_AUTHZ_HANDLE authz_handle = 0;
+ unsigned char* server_principal = 0;
+ ULONG authn_level = 0;
+ ULONG authn_svc = 0;
+ ULONG authz_svc = 0;
+ RPC_STATUS status = 0;
+
+ memset(client_id, 0, max_len);
+
+ if (info) {
+ memset(info, 0, sizeof(client_auth_info));
+ }
+
+ status = RpcBindingInqAuthClient(hClient, &authz_handle,
+ info ? &server_principal : 0,
+ &authn_level, &authn_svc, &authz_svc);
+ if (status == RPC_S_OK)
+ {
+ if (info) {
+ info->server_principal = server_principal;
+ info->authz_handle = authz_handle;
+ info->authn_level = authn_level;
+ info->authn_svc = authn_svc;
+ info->authz_svc = authz_svc;
+ }
+
+ if (authn_svc == RPC_C_AUTHN_WINNT) {
+ WCHAR* username = (WCHAR*)authz_handle;
+ int len = lstrlenW(username) + 1;
+ if (max_len < len)
+ status = RPC_S_BUFFER_TOO_SMALL;
+ _snprintf(client_id, max_len, "%S", username);
+ } else {
+ status = RPC_S_UNKNOWN_AUTHN_SERVICE;
+ }
+ }
+ return status;
+}
+
+char*
+rpc_error_to_string(
+ RPC_STATUS status
+ )
+{
+ switch(status) {
+ case RPC_S_OK:
+ return "OK";
+ case RPC_S_INVALID_BINDING:
+ return "Invalid binding";
+ case RPC_S_WRONG_KIND_OF_BINDING:
+ return "Wrong binding";
+ case RPC_S_BINDING_HAS_NO_AUTH:
+ RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH);
+ return "Binding has no auth";
+ default:
+ return "BUG: I am confused";
+ }
+}
+
+void
+print_client_info(
+ RPC_STATUS peer_status,
+ const char* peer_name,
+ RPC_STATUS client_status,
+ const char* client_id,
+ client_auth_info* info
+ )
+{
+ if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) {
+ cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name);
+ } else {
+ cci_debug_printf("%s Error %u getting Peer Name (%s)",
+ __FUNCTION__, peer_status, rpc_error_to_string(peer_status));
+ }
+
+ if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) {
+ if (info) {
+ cci_debug_printf("%s Client Auth Info"
+ "\tServer Principal: %s\n"
+ "\tAuthentication Level: %d\n"
+ "\tAuthentication Service: %d\n"
+ "\tAuthorization Service: %d\n",
+ __FUNCTION__,
+ info->server_principal,
+ info->authn_level,
+ info->authn_svc,
+ info->authz_svc);
+ }
+ cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id);
+ } else {
+ cci_debug_printf("%s Error getting Client Info (%u = %s)",
+ __FUNCTION__, client_status, rpc_error_to_string(client_status));
+ }
+}
+
+DWORD sid_check() {
+ DWORD status = 0;
+ HANDLE hToken_c = 0;
+ HANDLE hToken_s = 0;
+ PTOKEN_USER ptu_c = 0;
+ PTOKEN_USER ptu_s = 0;
+ DWORD len = 0;
+ BOOL bImpersonate = FALSE;
+
+ // Note GetUserName will fail while impersonating at identify
+ // level. The workaround is to impersonate, OpenThreadToken,
+ // revert, call GetTokenInformation, and finally, call
+ // LookupAccountSid.
+
+ // XXX - Note: This workaround does not appear to work.
+ // OpenThreadToken fails with error 1346: "Either a requid
+ // impersonation level was not provided or the provided
+ // impersonation level is invalid".
+
+ status = RpcImpersonateClient(0);
+
+ if (!status) {
+ bImpersonate = TRUE;
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ status = RpcRevertToSelf();
+ }
+
+ if (!status) {
+ bImpersonate = FALSE;
+
+ len = 0;
+ GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len);
+ if (len == 0) status = 1;
+ }
+
+ if (!status) {
+ if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len)))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ len = 0;
+ GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len);
+ if (len == 0) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len)))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len))
+ status = GetLastError();
+ }
+
+ if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid))
+ status = RPC_S_ACCESS_DENIED;
+
+/* Cleanup: */
+ if (!hToken_c && !bImpersonate)
+ cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status);
+ else if (!hToken_c)
+ cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status);
+ else if (bImpersonate)
+ cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status);
+ else if (!ptu_c)
+ cci_debug_printf("%s Failed to get client token user info (%u)",
+ __FUNCTION__, status);
+ else if (!hToken_s)
+ cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status);
+ else if (!ptu_s)
+ cci_debug_printf("%s Failed to get server token user info (%u)",
+ __FUNCTION__, status);
+ else if (status == RPC_S_ACCESS_DENIED)
+ cci_debug_printf("%s SID **does not** match!", __FUNCTION__);
+ else if (status == RPC_S_OK)
+ cci_debug_printf("%s SID matches!", __FUNCTION__);
+ else
+ if (status) {
+ cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status);
+ abort();
+ }
+
+ if (bImpersonate) RpcRevertToSelf();
+ if (hToken_c && hToken_c != INVALID_HANDLE_VALUE)
+ CloseHandle(hToken_c);
+ if (ptu_c) LocalFree(ptu_c);
+ if (hToken_s && hToken_s != INVALID_HANDLE_VALUE)
+ CloseHandle(hToken_s);
+ if (ptu_s) LocalFree(ptu_s);
+ if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status);
+ return status;
+ }
+
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
+ IN void *Context) {
+ char peer_name[1024];
+ char client_name[1024];
+ RPC_STATUS peer_status;
+ RPC_STATUS client_status;
+
+ cci_debug_printf("%s", __FUNCTION__);
+ peer_status = GetPeerName(Context, peer_name, sizeof(peer_name));
+ client_status = GetClientId(Context, client_name, sizeof(client_name), 0);
+ print_client_info(peer_status, peer_name, client_status, client_name, 0);
+ DWORD sid_status = sid_check();
+ cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status);
+ return sid_status;
+ }
+
+
+
+/*********************************************************************/
+/* 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);
+ }
+
+/* stubs */
+extern "C" cc_int32
+ccs_os_notify_cache_collection_changed (ccs_cache_collection_t cc)
+{
+ return 0;
+}
+
+extern "C" cc_int32
+ccs_os_notify_ccache_changed (ccs_cache_collection_t cc, const char *name)
+{
+ return 0;
+}
diff --git a/krb5-1.21.3/src/ccapi/server/win/ccs_request_proc.c b/krb5-1.21.3/src/ccapi/server/win/ccs_request_proc.c
new file mode 100644
index 00000000..c0328ea7
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/ccs_request_proc.c
@@ -0,0 +1,108 @@
+/* ccapi/server/win/ccs_request_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
+#include
+
+#include "ccs_request.h" // header file generated by MIDL compiler
+#include "cci_debugging.h"
+#include "WorkQueue.h"
+#include "win-utils.h"
+#include "ccs_win_pipe.h"
+
+void ccs_rpc_request(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* pszUUID, /* Where client will listen for the reply */
+ const long lenRequest, /* Length of buffer */
+ const char pbRequest[], /* Data buffer */
+ const long serverStartTime, /* Which server session we're talking to */
+ long* return_status ) { /* Return code */
+
+ cc_int32 status = 0;
+ k5_ipc_stream stream;
+ UINT64* p = (UINT64*)(tspHandle);
+ WIN_PIPE* pipe = NULL;
+
+ status = (rpcmsg != CCMSG_REQUEST) && (rpcmsg != CCMSG_PING);
+
+ 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, pbRequest, lenRequest);
+ }
+
+ pipe = ccs_win_pipe_new(pszUUID, *p);
+ worklist_add(rpcmsg, pipe, stream, serverStartTime);
+ *return_status = status;
+ }
+
+
+void ccs_rpc_connect(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* pszUUID, /* Data buffer */
+ long* return_status ) { /* Return code */
+
+ UINT64* p = (UINT64*)(tspHandle);
+ WIN_PIPE* pipe = ccs_win_pipe_new(pszUUID, *p);
+
+ worklist_add( rpcmsg,
+ pipe,
+ NULL, /* No payload with connect request */
+ (const time_t)0 ); /* No server session number with connect request */
+ }
+
+
+// 'Authentication' is client setting a value in a file and the server
+// returning that value plus one.
+CC_UINT32 ccs_authenticate(const CC_CHAR* name) {
+ HANDLE hMap = 0;
+ PDWORD pvalue = 0;
+ CC_UINT32 result = 0;
+ DWORD status = 0;
+
+ hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, (LPSTR)name);
+ status = !hMap;
+
+ if (!status) {
+ pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
+ status = !pvalue;
+ }
+
+ if (!status) {
+ *pvalue += 1;
+ result = *pvalue;
+ }
+
+ if (pvalue) {
+ UnmapViewOfFile(pvalue);
+ }
+
+ if (hMap) CloseHandle(hMap);
+ return result;
+ }
diff --git a/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.c b/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.c
new file mode 100644
index 00000000..99c66701
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.c
@@ -0,0 +1,162 @@
+/* ccapi/server/win/ccs_win_pipe.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 "assert.h"
+#include
+#include
+
+#include "ccs_win_pipe.h"
+#include "cci_debugging.h"
+
+/* Ref:
+struct ccs_win_pipe_t {
+ char* uuid;
+ UINT64 clientHandle;
+ }
+ */
+
+/* ------------------------------------------------------------------------ */
+
+struct ccs_win_pipe_t* ccs_win_pipe_new (const char* uuid, const UINT64 h) {
+
+ cc_int32 err = ccNoError;
+ struct ccs_win_pipe_t* out_pipe = NULL;
+ char* uuidCopy = NULL;
+
+ if (!err) {
+ if (!uuid) {err = cci_check_error(ccErrBadParam);}
+ }
+
+ if (!err) {
+ uuidCopy = (char*)malloc(1+strlen(uuid));
+ if (!uuidCopy) {err = cci_check_error(ccErrBadParam);}
+ strcpy(uuidCopy, uuid);
+ }
+
+ if (!err) {
+ out_pipe = (struct ccs_win_pipe_t*)malloc(sizeof(struct ccs_win_pipe_t));
+ if (!out_pipe) {err = cci_check_error(ccErrBadParam);}
+ out_pipe->uuid = uuidCopy;
+ out_pipe->clientHandle = h;
+ }
+
+ return out_pipe;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe,
+ const WIN_PIPE* in_pipe) {
+
+ *out_pipe =
+ ccs_win_pipe_new(
+ ccs_win_pipe_getUuid (in_pipe),
+ ccs_win_pipe_getHandle(in_pipe) );
+
+ return (*out_pipe) ? ccNoError : ccErrBadParam;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_win_pipe_release(const WIN_PIPE* in_pipe) {
+
+ cc_int32 err = ccNoError;
+
+ if (!ccs_win_pipe_valid(in_pipe)) {err = cci_check_error(ccErrBadParam);}
+
+ if (!err) {
+ if (!in_pipe->uuid) free(in_pipe->uuid);
+ if (!in_pipe) free(in_pipe);
+ }
+
+ return err;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe) {
+
+ if (!in_pipe) {
+ cci_check_error(ccErrBadParam);
+ return FALSE;
+ }
+
+ if (!in_pipe->uuid) {
+ cci_check_error(ccErrBadParam);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_win_pipe_compare (const WIN_PIPE* in_pipe_1,
+ const WIN_PIPE* in_pipe_2,
+ cc_uint32 *out_equal) {
+
+ cc_int32 err = ccNoError;
+ int seq = 0;
+ *out_equal = FALSE;
+
+ if (!ccs_win_pipe_valid(in_pipe_1)) {err = cci_check_error(ccErrBadParam);}
+ if (!ccs_win_pipe_valid(in_pipe_2)) {err = cci_check_error(ccErrBadParam);}
+ if (!out_equal) {err = cci_check_error(ccErrBadParam);}
+
+ /* A disconnect doesn't have a tls* with it -- only the uuid. SO only
+ compare the uuids.
+ */
+ if (!err) {
+ seq = strcmp( ccs_win_pipe_getUuid(in_pipe_1),
+ ccs_win_pipe_getUuid(in_pipe_2) );
+ *out_equal = (seq == 0);
+ }
+
+ return err;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe) {
+
+ char* result = NULL;
+
+ if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}
+ else {result = in_pipe->uuid;}
+
+ return result;
+ }
+
+/* ------------------------------------------------------------------------ */
+
+UINT64 ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe) {
+
+ UINT64 result = 0;
+
+ if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}
+ else {result = in_pipe->clientHandle;}
+
+ return result;
+ }
diff --git a/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.h b/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.h
new file mode 100644
index 00000000..fef99953
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/ccs_win_pipe.h
@@ -0,0 +1,68 @@
+/* ccapi/server/win/ccs_win_pipe.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 _ccs_win_pipe_h_
+#define _ccs_win_pipe_h_
+
+#include "windows.h"
+
+#include "CredentialsCache.h"
+
+/* ------------------------------------------------------------------------ */
+
+/* On Windows, a pipe is a struct containing a UUID and a handle. Both the
+ UUID and handle are supplied by the client.
+
+ The UUID is used to build the client's reply endpoint.
+
+ The handle is to the requesting client thread's thread local storage struct,
+ so that the client's one and only reply handler can put reply data where
+ the requesting thread will be able to see it.
+ */
+
+struct ccs_win_pipe_t {
+ char* uuid;
+ UINT64 clientHandle;
+ };
+
+typedef struct ccs_win_pipe_t WIN_PIPE;
+
+struct ccs_win_pipe_t* ccs_win_pipe_new(const char* uuid, const UINT64 h);
+
+cc_int32 ccs_win_pipe_release (const WIN_PIPE* io_pipe);
+
+cc_int32 ccs_win_pipe_compare (const WIN_PIPE* win_pipe_1,
+ const WIN_PIPE* win_pipe_2,
+ cc_uint32 *out_equal);
+
+cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe,
+ const WIN_PIPE* in_pipe);
+
+cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe);
+
+char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe);
+UINT64 ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe);
+
+#endif // _ccs_win_pipe_h_
diff --git a/krb5-1.21.3/src/ccapi/server/win/workitem.h b/krb5-1.21.3/src/ccapi/server/win/workitem.h
new file mode 100644
index 00000000..fff56f32
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/server/win/workitem.h
@@ -0,0 +1,51 @@
+#ifndef __WorkItem
+#define __WorkItem
+
+#include
+#include "windows.h"
+
+extern "C" {
+ #include "ccs_pipe.h"
+ }
+
+class WorkItem {
+private:
+ k5_ipc_stream _buf;
+ WIN_PIPE* _pipe;
+ const long _rpcmsg;
+ const long _sst;
+public:
+ WorkItem( k5_ipc_stream buf,
+ WIN_PIPE* pipe,
+ const long type,
+ const long serverStartTime);
+ WorkItem( const WorkItem&);
+ WorkItem();
+ ~WorkItem();
+
+ const k5_ipc_stream payload() const {return _buf;}
+ const k5_ipc_stream take_payload();
+ WIN_PIPE* take_pipe();
+ WIN_PIPE* pipe() const {return _pipe;}
+ const long type() const {return _rpcmsg;}
+ const long sst() const {return _sst;}
+ char* print(char* buf);
+ };
+
+class WorkList {
+private:
+ std::list wl;
+ CRITICAL_SECTION cs;
+ HANDLE hEvent;
+public:
+ WorkList();
+ ~WorkList();
+ int initialize();
+ int cleanup();
+ void wait();
+ int add(WorkItem*);
+ int remove(WorkItem**);
+ bool isEmpty() {return wl.empty();}
+ };
+
+#endif // __WorkItem
diff --git a/krb5-1.21.3/src/ccapi/test/Makefile.in b/krb5-1.21.3/src/ccapi/test/Makefile.in
new file mode 100644
index 00000000..23befe8e
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/Makefile.in
@@ -0,0 +1,225 @@
+mydir=ccapi$(S)test
+BUILDTOP=..$(S)..
+CCAPI=$(BUILDTOP)$(S)CCAPI
+
+!if defined(KRB5_KFW_COMPILE)
+KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
+!endif
+
+# Because all the sources are in .,
+# the only includes we need are to directories outside of ccapi.
+LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$(S)krb5 $(KFWINC) \
+ -I$(BUILDTOP)$(S)util$(S)et /I. -I$(CCAPI)$(S)COMMON -I$(CCAPI)$(S)LIB
+
+# run with "make all" to create CCAPI tests in "/tmp/ccapi_test"
+# run resulting tests with "sh test_ccapi.sh"
+
+##DOS##CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \
+##DOS## -D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS
+
+##DOS##WINH = cci_debugging.h \
+##DOS## ccs_reply.h \
+##DOS## ccs_request.h \
+##DOS## ccs_request_c.c \
+##DOS## cci_types.h \
+##DOS## win-utils.h
+
+##DOS##LIBSRC=ccapi_ccache.c \
+##DOS## ccapi_ccache_iterator.c \
+##DOS## ccapi_context.c \
+##DOS## ccapi_context_change_time.c \
+##DOS## ccapi_err.c \
+##DOS## ccapi_ipc.c \
+##DOS## ccapi_credentials.c \
+##DOS## ccapi_credentials_iterator.c \
+##DOS## ccapi_string.c \
+##DOS## ccapi_v2.c
+
+##DOS##COMSRC=cci_cred_union.c \
+##DOS## cci_identifier.c \
+##DOS## cci_message.c
+
+##DOS##COWSRC=cci_os_identifier.c
+
+SRCDIR = .
+DSTROOT = $(SRCDIR)
+OBJDIR = $(DSTROOT)$(S)ccapi_intermediates
+DSTDIR = $(DSTROOT)$(S)ccapi_test
+TESTDIR = $(DSTDIR)$(S)tests
+SRCTMP = $(SRCDIR)\srctmp
+
+SCRIPT_NAME = test_ccapi.sh
+
+OBJECTS = $(OUTPRE)test_ccapi_ccache.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_check.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_constants.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_context.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_v2.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_globals.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_iterators.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_log.$(OBJEXT) \
+ $(OUTPRE)test_ccapi_util.$(OBJEXT)
+
+PINGOBJS = $(OUTPRE)ccapi_ccache.$(OBJEXT) \
+ $(OUTPRE)ccapi_ccache_iterator.$(OBJEXT) \
+ $(OUTPRE)ccapi_context.$(OBJEXT) \
+ $(OUTPRE)ccapi_context_change_time.$(OBJEXT) \
+ $(OUTPRE)ccapi_err.$(OBJEXT) \
+ $(OUTPRE)ccapi_ipc.$(OBJEXT) \
+ $(OUTPRE)ccapi_credentials.$(OBJEXT) \
+ $(OUTPRE)ccapi_credentials_iterator.$(OBJEXT) \
+ $(OUTPRE)ccapi_string.$(OBJEXT) \
+ $(OUTPRE)ccapi_v2.$(OBJEXT) \
+ $(OUTPRE)cci_cred_union.$(OBJEXT) \
+ $(OUTPRE)cci_identifier.$(OBJEXT) \
+ $(OUTPRE)cci_os_identifier.$(OBJEXT) \
+ $(OUTPRE)cci_message.$(OBJEXT) \
+ $(OUTPRE)ccs_request_c.$(OBJEXT) \
+ $(OUTPRE)pingtest.$(OBJEXT) \
+ $(OBJECTS)
+
+TESTALLOBJS=$(OUTPRE)main.$(OBJEXT) \
+ $(OBJECTS)
+
+TEST_NAMES = test_cc_ccache_iterator_next \
+ test_constants \
+ test_cc_initialize \
+ test_cc_credentials_iterator_next
+
+MORE_TESTS = test_cc_context_release \
+ test_cc_context_get_change_time \
+ test_cc_context_get_default_ccache_name \
+ test_cc_context_open_ccache \
+ test_cc_context_open_default_ccache \
+ test_cc_context_create_ccache \
+ test_cc_context_create_default_ccache \
+ test_cc_context_create_new_ccache \
+ test_cc_context_new_ccache_iterator \
+ test_cc_context_compare \
+ test_cc_ccache_release \
+ test_cc_ccache_destroy \
+ test_cc_ccache_set_default \
+ test_cc_ccache_get_credentials_version \
+ test_cc_ccache_get_name \
+ test_cc_ccache_get_principal \
+ test_cc_ccache_set_principal \
+ test_cc_ccache_store_credentials \
+ test_cc_ccache_remove_credentials \
+ test_cc_ccache_new_credentials_iterator \
+ test_cc_ccache_get_change_time \
+ test_cc_ccache_get_last_default_time \
+ test_cc_ccache_move \
+ test_cc_ccache_compare \
+ test_cc_ccache_get_kdc_time_offset \
+ test_cc_ccache_set_kdc_time_offset \
+ test_cc_ccache_clear_kdc_time_offset \
+ test_cc_shutdown \
+ test_cc_get_change_time \
+ test_cc_open \
+ test_cc_create \
+ test_cc_close \
+ test_cc_destroy \
+ test_cc_get_cred_version \
+ test_cc_get_name \
+ test_cc_get_principal \
+ test_cc_set_principal \
+ test_cc_store \
+ test_cc_remove_cred \
+ test_cc_seq_fetch_NCs_begin \
+ test_cc_seq_fetch_NCs_next \
+ test_cc_seq_fetch_creds_begin \
+ test_cc_seq_fetch_creds_next \
+ test_cc_get_NC_info
+
+
+##### Linker
+LINK = link
+LIBS = -lkrb5
+##DOS##LIBS = $(CLIB) $(SLIB) advapi32.lib rpcrt4.lib user32.lib ws2_32.lib $(CCLIB).lib
+LFLAGS = /nologo $(LOPTS)
+
+all-mac: setup-test-dir pingtest simple_lock_test build-base build-tests link-tests copy-script success-message
+all-windows: setup-windows build-base $(OUTPRE)pingtest.exe build-tests build-testall copy-script success-message
+
+# compile base files used by all tests
+build-base: $(PINGOBJS)
+
+##++ These two rules build each element of the list:
+# compile each test
+build-tests: $(TEST_NAMES)
+ @echo build-tests complete.
+
+$(TEST_NAMES):
+ @echo DBG: $@
+ $(CC) $(ALL_CFLAGS) -Fe$(TESTDIR)$(S)$@.exe -Fd$(OBJDIR)$(S)$@.pdb $@.c $(OBJECTS) $(LIBS)
+# Clean .obj from .:
+ $(RM) $@.$(OBJEXT)
+##-- These two rules build each element of the list.
+
+# Make a build directory
+setup-test-dir:
+ @echo "Removing old destination directory... $(DSTDIR)"
+ if [ -d "$(DSTDIR)" ]; then chmod -R u+w "$(DSTDIR)" && rm -rf "$(DSTDIR)"; fi
+ mkdir -p "$(TESTDIR)"
+ if [ -d "$(OBJDIR)" ]; then chmod -R u+w "$(OBJDIR)" && rm -rf "$(OBJDIR)"; fi
+ mkdir -p "$(OBJDIR)"
+
+## The same trick as used in TEST_NAMES to run an action on each element ofthe list WINH:
+setup-windows: $(WINH) $(LIBSRC) $(COMSRC) $(COWSRC)
+ if NOT exist $(TESTDIR) mkdir $(TESTDIR)
+ if NOT exist $(OBJDIR) mkdir $(OBJDIR)
+ set LINK = link
+
+# This rule assumes that nmake in ..\lib\win has already run.
+# That is how ..\Makefile.in is set up.
+$(WINH):
+ copy ..\lib\win\srctmp\$@ .
+
+$(LIBSRC):
+ copy ..\lib\$@ .
+
+$(COMSRC):
+ copy ..\common\$@ .
+
+$(COWSRC):
+ copy ..\common\win\$@ .
+
+# This rule assumes that nmake in ..\lib\win\ has already run.
+$(OUTPRE)pingtest.exe: $(OBJECTS) $(PINGOBJS)
+# There doesn't appear to be any way to examine a variable and return a value
+# indicating whether a string is present in it. We use a perl script to
+# check the LIB variable. If the path to $(CCLIB).lib isn't present, the script
+# deletes a.tmp and the following nmake actions correct LIB.
+ echo %%PATH%% > a.tmp
+ perl setlib.pl
+ if not exist a.tmp (
+ @echo Adding ..\lib\win\srctmp to LIB
+ set LIB=%%LIB%%;..\lib\win\srctmp
+ )
+ $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(PINGOBJS) $(LIBS)
+ $(LINK) $(LFLAGS) /map:$(@B)2.map /out:$(*B)2.exe $(conflags) $(PINGOBJS) $(LIBS) $(conlibsdll)
+
+link-tests: $(TEST_NAMES)
+
+build-testall: $(TEST_NAMES) $(OBJECTS) $(TESTALLOBJS) testall.exe
+
+testall.exe:
+ $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(TESTALLOBJS) $(LIBS) $(conslibdll)
+
+
+simple_lock_test:
+ $(CC) -o $(TESTDIR)/simple_lock_test simple_lock_test.c $(LIBS)
+
+copy-script:
+ $(CP) $(SCRIPT_NAME) $(DSTDIR)$(S)$(SCRIPT_NAME)
+
+success-message:
+ @echo
+ @echo "CCAPI tests created in $(DSTDIR)"
+
+.PHONY: clean
+
+clean:
+ -rm -rf "$(OBJDIR)"
+ -rm -rf $(LIBSRC)
+ -rm -rf $(WINH)
diff --git a/krb5-1.21.3/src/ccapi/test/Makefile.w32 b/krb5-1.21.3/src/ccapi/test/Makefile.w32
new file mode 100644
index 00000000..8c3da951
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/Makefile.w32
@@ -0,0 +1,75 @@
+# . is ccapi/test.
+CO = ..\common
+COWIN = $(CO)\win
+LIBDIR = ..\lib
+LIBWIN = $(LIBDIR)\win
+SRV = ..\server
+SRVWIN = ..\server\win
+
+!include
+
+INC = -I..\..\include -I..\..\util\et -I$(CO) -I$(COWIN) -I$(LIBDIR) -I$(LIBWIN)
+
+!if "$(CPU)" == "i386"
+cflags = $(cflags) /EHsc /MTd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \
+$(INC)
+!else
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)
+!endif
+LIBS = $(LIBWIN)\ccapi.lib
+
+DSTROOT = .
+SRC = $(DSTROOT)
+#OBJDIR = $(DSTROOT)\obj
+OBJDIR = .
+OBJEXT = obj
+TESTDIR = $(DSTROOT)\tests
+TESTEXT = exe
+DSTDIR = $(DSTROOT)\ccapi_tests
+
+PINGOBJS = pingtest.obj
+SIMPLEOBJS = simple_lock_test.obj
+
+comobjs = cci_debugging.obj cci_stream.obj
+cowobjs = cci_os_debugging.obj
+libobjs = ccs_request_c.obj
+
+#all: build-base simple_lock_test pingtest
+all: build-base pingtest
+
+# compile base files used by all tests
+build-base: $(comobjs) $(libobjs) $(srvobjs)
+ @echo "Base objects built."
+
+# rule to compile src files
+.c.obj:
+ $(cc) $(cdebug) $(cflags) /Fo$(OBJDIR)\$(*B).$(OBJEXT) $(SRC)\$(*B).c
+
+$(comobjs) : $(CO)\$(*B).c
+ $(cc) $(cdebug) $(cflags) $(CO)\$(*B).c
+
+$(cowobjs) : $(COWIN)\$(*B).c
+ $(cc) $(cdebug) $(cflags) $(COWIN)\$(*B).c
+
+$(libobjs) : $(LIBWIN)\$(*B).c
+ $(cc) $(cdebug) $(cflags) $(LIBWIN)\$(*B).c
+
+#$(srvobjs) : $(SRVWIN)\$*.c
+# $(cc) $(cdebug) $(cflags) $(SRVWIN)\$*.c
+
+simple_lock_test: simple_lock_test.obj $(OBJS)
+ @echo R3+ Build $(*B) in $(TESTDIR)
+ $(cc) $(cdebug) $(cflags) $(*B).c
+ $(link) $(linkdebug) $(conflags) -out:$(TESTDIR)\$(*B).exe $(*B).obj \
+ $(LIBS) rpcrt4.lib
+ @echo R3- Built $(*B) in $(TESTDIR)
+
+pingtest: pingtest.obj
+ @echo R4+ Build $(*B) in $(TESTDIR)
+ $(cc) $(cdebug) $(cflags) $(*B).c
+ $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(PINGOBJS) $(libobjs) $(srvobjs) \
+ $(LIBS) rpcrt4.lib
+ @echo R4- Built $(*B) in $(TESTDIR)
+
+clean:
+ DEL *.$(OBJEXT)
\ No newline at end of file
diff --git a/krb5-1.21.3/src/ccapi/test/Pingtest.sln b/krb5-1.21.3/src/ccapi/test/Pingtest.sln
new file mode 100644
index 00000000..cf43a1e4
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/Pingtest.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pingtest", "Pingtest.vcproj", "{04017001-3222-43C4-A03C-8423B5349276}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {04017001-3222-43C4-A03C-8423B5349276}.Debug|Win32.ActiveCfg = Debug|Win32
+ {04017001-3222-43C4-A03C-8423B5349276}.Debug|Win32.Build.0 = Debug|Win32
+ {04017001-3222-43C4-A03C-8423B5349276}.Release|Win32.ActiveCfg = Release|Win32
+ {04017001-3222-43C4-A03C-8423B5349276}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/krb5-1.21.3/src/ccapi/test/deps b/krb5-1.21.3/src/ccapi/test/deps
new file mode 100644
index 00000000..e69de29b
diff --git a/krb5-1.21.3/src/ccapi/test/main.c b/krb5-1.21.3/src/ccapi/test/main.c
new file mode 100644
index 00000000..2ace9678
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/main.c
@@ -0,0 +1,90 @@
+#include
+#include
+
+// #include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+#include "test_ccapi_iterators.h"
+#include "test_ccapi_v2.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+// cc_ccache_iterator_t cache_iterator = NULL;
+// cc_credentials_iterator_t cred_iterator = NULL;
+
+ fprintf(stdout, "Testing CCAPI against CCAPI v3 rev 8 documentation...\n");
+ fprintf(stdout, "Warning: this test suite is woefully incomplete and unpolished.\n");
+
+ T_CCAPI_INIT;
+
+ // *** ccapi v2 compat ***
+ err = check_cc_shutdown();
+ err = check_cc_get_change_time();
+ err = check_cc_open();
+ err = check_cc_create();
+ err = check_cc_close();
+ err = check_cc_destroy();
+ err = check_cc_get_cred_version();
+ err = check_cc_get_name();
+ err = check_cc_get_principal();
+ err = check_cc_set_principal();
+ err = check_cc_store();
+ err = check_cc_remove_cred();
+ err = check_cc_seq_fetch_NCs_begin();
+ err = check_cc_seq_fetch_NCs_next();
+ err = check_cc_seq_fetch_creds_begin();
+ err = check_cc_seq_fetch_creds_next();
+ err = check_cc_get_NC_info();
+
+ err = check_constants();
+
+ // *** cc_context ***
+ err = check_cc_initialize();
+ err = check_cc_context_release();
+ err = check_cc_context_get_change_time();
+ err = check_cc_context_get_default_ccache_name();
+ err = check_cc_context_open_ccache();
+ err = check_cc_context_open_default_ccache();
+ err = check_cc_context_create_ccache();
+ err = check_cc_context_create_default_ccache();
+ err = check_cc_context_create_new_ccache();
+ err = check_cc_context_new_ccache_iterator();
+ // err = check_cc_context_lock();
+ // err = check_cc_context_unlock();
+ err = check_cc_context_compare();
+
+ // *** cc_ccache ***
+ err = check_cc_ccache_release();
+ err = check_cc_ccache_destroy();
+ err = check_cc_ccache_set_default();
+ err = check_cc_ccache_get_credentials_version();
+ err = check_cc_ccache_get_name();
+ err = check_cc_ccache_get_principal();
+ err = check_cc_ccache_set_principal();
+ err = check_cc_ccache_store_credentials();
+ err = check_cc_ccache_remove_credentials();
+ err = check_cc_ccache_new_credentials_iterator();
+ // err = check_cc_ccache_lock();
+ // err = check_cc_ccache_unlock();
+ err = check_cc_ccache_get_change_time();
+ err = check_cc_ccache_get_last_default_time();
+ err = check_cc_ccache_move();
+ err = check_cc_ccache_compare();
+ err = check_cc_ccache_get_kdc_time_offset();
+ err = check_cc_ccache_set_kdc_time_offset();
+ err = check_cc_ccache_clear_kdc_time_offset();
+
+ // *** cc_ccache_iterator ***
+ err = check_cc_ccache_iterator_next();
+
+ // *** cc_credentials_iterator ***
+ err = check_cc_credentials_iterator_next();
+
+ fprintf(stdout, "\nFinished testing CCAPI. %d failure%s in total.\n", total_failure_count, (total_failure_count == 1) ? "" : "s");
+
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/pingtest.c b/krb5-1.21.3/src/ccapi/test/pingtest.c
new file mode 100644
index 00000000..0ffc15e7
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/pingtest.c
@@ -0,0 +1,110 @@
+// pingtest.c
+//
+// Test RPC to server, with PING message, which exists for no other purpose than this test.
+
+#include
+#include
+#include
+#include
+
+#include "cci_debugging.h"
+#include "CredentialsCache.h"
+#include "win-utils.h"
+
+#include "ccs_request.h"
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle
+
+
+extern cc_int32 cci_os_ipc_thread_init (void);
+extern 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);
+
+static DWORD dwTlsIndex;
+
+DWORD GetTlsIndex() {return dwTlsIndex;}
+
+RPC_STATUS send_test(char* endpoint) {
+ unsigned char* pszNetworkAddress = NULL;
+ unsigned char* pszOptions = NULL;
+ unsigned char* pszStringBinding = NULL;
+ unsigned char* pszUuid = NULL;
+ RPC_STATUS status;
+
+ status = RpcStringBindingCompose(pszUuid,
+ (RPC_CSTR)"ncalrpc",
+ pszNetworkAddress,
+ (unsigned char*)endpoint,
+ pszOptions,
+ &pszStringBinding);
+ cci_debug_printf("%s pszStringBinding = %s", __FUNCTION__, pszStringBinding);
+ if (status) {return cci_check_error(status);}
+
+ /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */
+ status = RpcBindingFromStringBinding(pszStringBinding, &CLIENT_REQUEST_RPC_HANDLE);
+ if (status) {return cci_check_error(status);}
+
+ status = RpcStringFree(&pszStringBinding); // Temp var no longer needed.
+
+ if (!status) {
+ RpcTryExcept {
+ cci_debug_printf("%s calling remote procedure 'ccs_authenticate'", __FUNCTION__);
+ status = ccs_authenticate((CC_CHAR*)"DLLMAIN TEST!");
+ cci_debug_printf(" ccs_authenticate returned %d", status);
+ }
+ RpcExcept(1) {
+ status = cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+ }
+
+ cci_check_error(RpcBindingFree(&CLIENT_REQUEST_RPC_HANDLE));
+
+ return (status);
+ }
+
+int main( int argc, char *argv[]) {
+ cc_int32 err = 0;
+ cc_context_t context = NULL;
+ k5_ipc_stream send_stream = NULL;
+ k5_ipc_stream reply_stream = NULL;
+ char* message = "Hello, RPC!";
+
+
+ if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
+
+ if (!err) {
+ err = cci_os_ipc_thread_init();
+ }
+ if (!err) {
+ err = krb5int_ipc_stream_new (&send_stream);
+ err = krb5int_ipc_stream_write(send_stream, message,
+ 1+strlen(message));
+ }
+
+ if (!err) {
+ err = cci_os_ipc_msg(TRUE, send_stream, CCMSG_PING, &reply_stream);
+ }
+ Sleep(10*1000);
+ cci_debug_printf("Try finishing async call.");
+
+ Sleep(INFINITE);
+ cci_debug_printf("main: return. err == %d", err);
+
+ return 0;
+ }
+
+
+
+/*********************************************************************/
+/* MIDL allocate and free */
+/*********************************************************************/
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {
+ return(malloc(len));
+ }
+
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {
+ free(ptr);
+ }
diff --git a/krb5-1.21.3/src/ccapi/test/setlib.pl b/krb5-1.21.3/src/ccapi/test/setlib.pl
new file mode 100644
index 00000000..bba22506
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/setlib.pl
@@ -0,0 +1,10 @@
+#!perl -w
+
+$b = "lib\\win\\srctmp";
+$a = $ENV{LIB};
+if (! ($a =~ /$b/) ) {
+ print "$b Not in LIB!\n";
+ system("del a.tmp");
+ }
+else {print "$b in LIB.\n";}
+exit(0);
\ No newline at end of file
diff --git a/krb5-1.21.3/src/ccapi/test/simple_lock_test.c b/krb5-1.21.3/src/ccapi/test/simple_lock_test.c
new file mode 100644
index 00000000..8961d999
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/simple_lock_test.c
@@ -0,0 +1,91 @@
+/*
+ simple_lock_test.c
+
+ Initializes two contexts in two different threads and tries to get read locks on both at the same time.
+ Hangs at line 24.
+*/
+#include
+#include
+
+#include "test_ccapi_log.h"
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include
+#endif
+
+#ifdef TARGET_OS_MAC
+#include
+#include
+#include
+#else
+#include "CredentialsCache.h"
+#endif
+
+
+void *other_thread (void) {
+ cc_int32 err;
+ cc_context_t context = NULL;
+
+ err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
+
+ log_error("thread: attempting lock. may hang. err == %d", err);
+
+ if (!err) {
+ // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately
+ err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
+ }
+
+ if (context) {
+ cc_context_unlock(context);
+ cc_context_release(context);
+ context = NULL;
+ }
+ log_error("thread: return. err == %d", err);
+}
+
+
+int main (int argc, char *argv[]) {
+ cc_int32 err;
+ int status;
+ cc_context_t context = NULL;
+
+#ifdef TARGET_OS_MAC
+ pthread_t thread_id;
+#endif
+
+ err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
+ if (!err) {
+ err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
+ }
+
+ log_error("main: initialized and read locked context. err == %d", err);
+
+#ifdef TARGET_OS_MAC
+ status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);
+ if (status != 0) {
+ log_error("pthread_create() returned %d", status);
+ exit(-1);
+ }
+
+ pthread_join(thread_id, NULL);
+#else
+
+#endif
+
+ log_error("main: unlocking and releasing context. err == %d", err);
+
+ if (context) {
+ log_error("main: calling cc_context_unlock");
+ cc_context_unlock(context);
+ log_error("main: calling cc_context_release");
+ cc_context_release(context);
+ context = NULL;
+ }
+
+ log_error("main: return. err == %d", err);
+
+#if defined(_WIN32)
+ UNREFERENCED_PARAMETER(status); // no whining!
+#endif
+ return 0;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c
new file mode 100644
index 00000000..1698535f
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_clear_kdc_time_offset();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_compare.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_compare.c
new file mode 100644
index 00000000..96aaa56c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_compare.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_compare();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_destroy.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_destroy.c
new file mode 100644
index 00000000..95c417ca
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_destroy.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_destroy();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_change_time.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_change_time.c
new file mode 100644
index 00000000..a515d5bd
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_change_time.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_change_time();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_credentials_version.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_credentials_version.c
new file mode 100644
index 00000000..f5df7c07
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_credentials_version.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_credentials_version();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c
new file mode 100644
index 00000000..13e61165
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_kdc_time_offset();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_last_default_time.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_last_default_time.c
new file mode 100644
index 00000000..4de22e4a
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_last_default_time.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_last_default_time();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_name.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_name.c
new file mode 100644
index 00000000..f6649974
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_name.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_name();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_principal.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_principal.c
new file mode 100644
index 00000000..05d7c434
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_get_principal.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_get_principal();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_iterator_next.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_iterator_next.c
new file mode 100644
index 00000000..945a98d2
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_iterator_next.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_iterator_next();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_move.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_move.c
new file mode 100644
index 00000000..880198c8
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_move.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_move();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c
new file mode 100644
index 00000000..1338e832
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_new_credentials_iterator();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_release.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_release.c
new file mode 100644
index 00000000..75d604c9
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_release.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_release();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_remove_credentials.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_remove_credentials.c
new file mode 100644
index 00000000..679da85c
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_remove_credentials.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_remove_credentials();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_default.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_default.c
new file mode 100644
index 00000000..71bba2a4
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_default.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_set_default();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c
new file mode 100644
index 00000000..b8b21e98
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_set_kdc_time_offset();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_principal.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_principal.c
new file mode 100644
index 00000000..ec55acd7
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_set_principal.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_set_principal();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_ccache_store_credentials.c b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_store_credentials.c
new file mode 100644
index 00000000..c52125bd
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_ccache_store_credentials.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_ccache_store_credentials();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_close.c b/krb5-1.21.3/src/ccapi/test/test_cc_close.c
new file mode 100644
index 00000000..b6bc3afa
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_close.c
@@ -0,0 +1,14 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_v2.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_close();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_context_compare.c b/krb5-1.21.3/src/ccapi/test/test_cc_context_compare.c
new file mode 100644
index 00000000..f4965af3
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_context_compare.c
@@ -0,0 +1,15 @@
+#include
+#include
+
+#include "test_ccapi_check.h"
+#include "test_ccapi_constants.h"
+#include "test_ccapi_context.h"
+#include "test_ccapi_ccache.h"
+
+int main (int argc, const char * argv[]) {
+
+ cc_int32 err = ccNoError;
+ T_CCAPI_INIT;
+ err = check_cc_context_compare();
+ return err;
+}
diff --git a/krb5-1.21.3/src/ccapi/test/test_cc_context_create_ccache.c b/krb5-1.21.3/src/ccapi/test/test_cc_context_create_ccache.c
new file mode 100644
index 00000000..c9429451
--- /dev/null
+++ b/krb5-1.21.3/src/ccapi/test/test_cc_context_create_ccache.c
@@ -0,0 +1,15 @@
+#include