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