From: Alexandra Ellwood Date: Thu, 31 May 2007 21:06:54 +0000 (+0000) Subject: Move CCAPI sources to krb5 repository X-Git-Tag: krb5-1.7-alpha1~1100 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d45eeb7f708d5be2e9fbdbc54a04655776074f6c;p=krb5.git Move CCAPI sources to krb5 repository ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19564 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/ccapi/common/cci_array_internal.c b/src/ccapi/common/cci_array_internal.c new file mode 100644 index 000000000..8e6bcd7e2 --- /dev/null +++ b/src/ccapi/common/cci_array_internal.c @@ -0,0 +1,306 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" +#include "cci_array_internal.h" + +/* ------------------------------------------------------------------------ */ + +struct cci_array_d { + cci_array_object_t *objects; + cc_uint64 count; + cc_uint64 max_count; + + cci_array_object_release_t object_release; +}; + +struct cci_array_d cci_array_initializer = { NULL, 0, 0, NULL }; + +#define CCI_ARRAY_COUNT_INCREMENT 16 + +/* ------------------------------------------------------------------------ */ + +static cc_int32 cci_array_resize (cci_array_t io_array, + cc_uint64 in_new_count) +{ + cc_int32 err = ccNoError; + cc_uint64 new_max_count = 0; + cci_array_object_t *objects = NULL; + + if (!io_array) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 old_max_count = io_array->max_count; + new_max_count = io_array->max_count; + + if (in_new_count > old_max_count) { + /* Expand the array */ + while (in_new_count > new_max_count) { + new_max_count += CCI_ARRAY_COUNT_INCREMENT; + } + + } else if ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < old_max_count) { + /* Shrink the array, but never drop below CC_ARRAY_COUNT_INCREMENT */ + while ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < new_max_count && + (new_max_count > CCI_ARRAY_COUNT_INCREMENT)) { + new_max_count -= CCI_ARRAY_COUNT_INCREMENT; + } + } + } + + if (!err) { + objects = io_array->objects; + + if (!objects) { + objects = malloc (new_max_count * sizeof (*objects)); + } else { + objects = realloc (objects, new_max_count * sizeof (*objects)); + } + if (!objects) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + io_array->objects = objects; + io_array->max_count = new_max_count; + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_new (cci_array_t *out_array, + cci_array_object_release_t in_array_object_release) +{ + cc_int32 err = ccNoError; + cci_array_t array = NULL; + + if (!out_array) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + array = malloc (sizeof (*array)); + if (array) { + *array = cci_array_initializer; + array->object_release = in_array_object_release; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + *out_array = array; + array = NULL; + } + + cci_array_release (array); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_release (cci_array_t io_array) +{ + cc_int32 err = ccNoError; + + if (!io_array) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i; + + for (i = 0; i < io_array->count; i++) { + io_array->object_release (io_array->objects[i]); + } + free (io_array->objects); + free (io_array); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_uint64 cci_array_count (cci_array_t in_array) +{ + return in_array ? in_array->count : 0; +} + +/* ------------------------------------------------------------------------ */ + +cci_array_object_t cci_array_object_at_index (cci_array_t io_array, + cc_uint64 in_position) +{ + if (io_array && in_position < io_array->count) { + return io_array->objects[in_position]; + } else { + if (!io_array) { + cci_debug_printf ("%s() got NULL array", __FUNCTION__); + } else { + cci_debug_printf ("%s() got bad index %lld (count = %lld)", __FUNCTION__, + in_position, io_array->count); + } + return NULL; + } +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_insert (cci_array_t io_array, + cci_array_object_t in_object, + cc_uint64 in_position) +{ + cc_int32 err = ccNoError; + + if (!io_array ) { err = cci_check_error (ccErrBadParam); } + if (!in_object) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Don't try to insert past the end and don't overflow the array */ + if (in_position > io_array->count || io_array->count == UINT64_MAX) { + err = cci_check_error (ccErrBadParam); + } + } + + if (!err) { + err = cci_array_resize (io_array, io_array->count + 1); + } + + if (!err) { + unsigned char **objects = (unsigned char **)io_array->objects; + cc_uint64 move_count = io_array->count - in_position; + + if (move_count > 0) { + memmove (&objects[in_position + 1], &objects[in_position], + move_count * sizeof (*objects)); + } + + objects[in_position] = in_object; + io_array->count++; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_remove (cci_array_t io_array, + cc_uint64 in_position) +{ + cc_int32 err = ccNoError; + + if (!io_array) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_position >= io_array->count) { + err = cci_check_error (ccErrBadParam); + } + + if (!err) { + unsigned char **objects = (unsigned char **)io_array->objects; + cc_uint64 move_count = io_array->count - in_position - 1; + cci_array_object_t object = objects[in_position]; + + if (move_count > 0) { + memmove (&objects[in_position], &objects[in_position + 1], + move_count * sizeof (*objects)); + } + + io_array->object_release (object); + io_array->count--; + + cci_array_resize (io_array, io_array->count); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_move (cci_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position) +{ + cc_int32 err = ccNoError; + + if (!io_array ) { err = cci_check_error (ccErrBadParam); } + if (!out_real_new_position) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_position >= io_array->count) { + err = cci_check_error (ccErrBadParam); + } + + if (!err && in_new_position > io_array->count) { + err = cci_check_error (ccErrBadParam); + } + if (!err) { + cc_uint64 move_from = 0; + cc_uint64 move_to = 0; + cc_uint64 move_count = 0; + cc_uint64 real_new_position = 0; + + if (in_position < in_new_position) { + /* shift right, making an empty space so the + * actual new position is one less in_new_position */ + move_from = in_position + 1; + move_to = in_position; + move_count = in_new_position - in_position - 1; + real_new_position = in_new_position - 1; + } else { + /* shift left */ + move_from = in_new_position; + move_to = in_new_position + 1; + move_count = in_position - in_new_position; + real_new_position = in_new_position; + } + + if (move_count > 0) { + unsigned char **objects = (unsigned char **)io_array->objects; + cci_array_object_t object = objects[in_position]; + + memmove (&objects[move_to], &objects[move_from], + move_count * sizeof (*objects)); + objects[real_new_position] = object; + } + + *out_real_new_position = real_new_position; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_array_push_front (cci_array_t io_array, + cc_uint64 in_position) +{ + cc_uint64 real_new_position = 0; + return cci_array_move (io_array, in_position, 0, &real_new_position); +} + diff --git a/src/ccapi/common/cci_array_internal.h b/src/ccapi/common/cci_array_internal.h new file mode 100644 index 000000000..a88e52951 --- /dev/null +++ b/src/ccapi/common/cci_array_internal.h @@ -0,0 +1,64 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_ARRAY_INTERNAL_H +#define CCI_ARRAY_INTERNAL_H + +#include "cci_types.h" + +typedef void *cci_array_object_t; +typedef cc_int32 (*cci_array_object_release_t) (cci_array_object_t); + +struct cci_array_d; +typedef struct cci_array_d *cci_array_t; + +cc_int32 cci_array_new (cci_array_t *out_array, + cci_array_object_release_t in_array_object_release); + +cc_int32 cci_array_release (cci_array_t io_array); + +cc_uint64 cci_array_count (cci_array_t in_array); + +cci_array_object_t cci_array_object_at_index (cci_array_t io_array, + cc_uint64 in_position); + +cc_int32 cci_array_insert (cci_array_t io_array, + cci_array_object_t in_object, + cc_uint64 in_position); + +cc_int32 cci_array_remove (cci_array_t io_array, + cc_uint64 in_position); + +cc_int32 cci_array_move (cci_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position); + +cc_int32 cci_array_push_front (cci_array_t io_array, + cc_uint64 in_position); + + +#endif /* CCI_ARRAY_INTERNAL_H */ diff --git a/src/ccapi/common/cci_common.h b/src/ccapi/common/cci_common.h new file mode 100644 index 000000000..a77b16c3e --- /dev/null +++ b/src/ccapi/common/cci_common.h @@ -0,0 +1,55 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_COMMON_H +#define CCI_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if TARGET_OS_MAC +#define VECTOR_FUNCTIONS_INITIALIZER ,NULL +#else +#define VECTOR_FUNCTIONS_INITIALIZER +#endif + +#define k_cci_context_initial_ccache_name "Initial default ccache" + +#include "cci_cred_union.h" +#include "cci_debugging.h" +#include "cci_identifier.h" +#include "cci_message.h" +#include "cci_stream.h" + +#endif /* CCI_COMMON_H */ diff --git a/src/ccapi/common/cci_cred_union.c b/src/ccapi/common/cci_cred_union.c new file mode 100644 index 000000000..74a87a686 --- /dev/null +++ b/src/ccapi/common/cci_cred_union.c @@ -0,0 +1,679 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v4_release (cc_credentials_v4_t *io_v4creds) +{ + cc_int32 err = ccNoError; + + if (!io_v4creds) { err = ccErrBadParam; } + + if (!err) { + memset (io_v4creds, 0, sizeof (*io_v4creds)); + free (io_v4creds); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v4_read (cc_credentials_v4_t **out_v4creds, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_credentials_v4_t *v4creds = NULL; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!out_v4creds) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + v4creds = malloc (sizeof (*v4creds)); + if (!v4creds) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &v4creds->version); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->principal, cc_v4_name_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->principal_instance, cc_v4_instance_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->service, cc_v4_name_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->service_instance, cc_v4_instance_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->realm, cc_v4_realm_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->session_key, cc_v4_key_size); + } + + if (!err) { + err = cci_stream_read_int32 (io_stream, &v4creds->kvno); + } + + if (!err) { + err = cci_stream_read_int32 (io_stream, &v4creds->string_to_key_type); + } + + if (!err) { + err = cci_stream_read_time (io_stream, &v4creds->issue_date); + } + + if (!err) { + err = cci_stream_read_int32 (io_stream, &v4creds->lifetime); + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &v4creds->address); + } + + if (!err) { + err = cci_stream_read_int32 (io_stream, &v4creds->ticket_size); + } + + if (!err) { + err = cci_stream_read (io_stream, v4creds->ticket, cc_v4_ticket_size); + } + + if (!err) { + *out_v4creds = v4creds; + v4creds = NULL; + } + + free (v4creds); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v4_write (cc_credentials_v4_t *in_v4creds, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!in_v4creds) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_v4creds->version); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->principal, cc_v4_name_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->principal_instance, cc_v4_instance_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->service, cc_v4_name_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->service_instance, cc_v4_instance_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->realm, cc_v4_realm_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->session_key, cc_v4_key_size); + } + + if (!err) { + err = cci_stream_write_int32 (io_stream, in_v4creds->kvno); + } + + if (!err) { + err = cci_stream_write_int32 (io_stream, in_v4creds->string_to_key_type); + } + + if (!err) { + err = cci_stream_write_time (io_stream, in_v4creds->issue_date); + } + + if (!err) { + err = cci_stream_write_int32 (io_stream, in_v4creds->lifetime); + } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_v4creds->address); + } + + if (!err) { + err = cci_stream_write_int32 (io_stream, in_v4creds->ticket_size); + } + + if (!err) { + err = cci_stream_write (io_stream, in_v4creds->ticket, cc_v4_ticket_size); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_contents_release (cc_data *io_ccdata) +{ + cc_int32 err = ccNoError; + + if (!io_ccdata && io_ccdata->data) { err = ccErrBadParam; } + + if (!err) { + if (io_ccdata->length) { + memset (io_ccdata->data, 0, io_ccdata->length); + } + free (io_ccdata->data); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_release (cc_data *io_ccdata) +{ + cc_int32 err = ccNoError; + + if (!io_ccdata) { err = ccErrBadParam; } + + if (!err) { + cci_cc_data_contents_release (io_ccdata); + free (io_ccdata); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_read (cc_data *io_ccdata, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_uint32 type = 0; + cc_uint32 length = 0; + char *data = NULL; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!io_ccdata) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &type); + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &length); + } + + if (!err && length > 0) { + data = malloc (length); + if (!data) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + err = cci_stream_read (io_stream, data, length); + } + } + + if (!err) { + io_ccdata->type = type; + io_ccdata->length = length; + io_ccdata->data = data; + data = NULL; + } + + free (data); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_write (cc_data *in_ccdata, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!in_ccdata) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_ccdata->type); + } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_ccdata->length); + } + + if (!err && in_ccdata->length > 0) { + err = cci_stream_write (io_stream, in_ccdata->data, in_ccdata->length); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_array_release (cc_data **io_ccdata_array) +{ + cc_int32 err = ccNoError; + + if (!io_ccdata_array) { err = ccErrBadParam; } + + if (!err) { + cc_uint32 i; + + for (i = 0; io_ccdata_array && io_ccdata_array[i]; i++) { + cci_cc_data_release (io_ccdata_array[i]); + } + free (io_ccdata_array); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_array_read (cc_data ***io_ccdata_array, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_uint32 count = 0; + cc_data **array = NULL; + cc_uint32 i; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &count); + } + + if (!err && count > 0) { + array = malloc ((count + 1) * sizeof (*array)); + if (array) { + for (i = 0; i <= count; i++) { array[i] = NULL; } + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + for (i = 0; !err && i < count; i++) { + array[i] = malloc (sizeof (cc_data)); + if (!array[i]) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + err = cci_cc_data_read (array[i], io_stream); + } + } + } + + if (!err) { + *io_ccdata_array = array; + array = NULL; + } + + cci_cc_data_array_release (array); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_array_write (cc_data **in_ccdata_array, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_uint32 count = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + /* in_ccdata_array may be NULL */ + + if (!err) { + for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++); + + err = cci_stream_write_uint32 (io_stream, count); + } + + if (!err) { + cc_uint32 i; + + for (i = 0; !err && i < count; i++) { + err = cci_cc_data_write (in_ccdata_array[i], io_stream); + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_credentials_v5_t cci_credentials_v5_initializer = { + NULL, + NULL, + { 0, 0, NULL }, + 0, 0, 0, 0, 0, 0, + NULL, + { 0, 0, NULL }, + { 0, 0, NULL }, + NULL +}; + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v5_release (cc_credentials_v5_t *io_v5creds) +{ + cc_int32 err = ccNoError; + + if (!io_v5creds) { err = ccErrBadParam; } + + if (!err) { + free (io_v5creds->client); + free (io_v5creds->server); + cci_cc_data_contents_release (&io_v5creds->keyblock); + cci_cc_data_array_release (io_v5creds->addresses); + cci_cc_data_contents_release (&io_v5creds->ticket); + cci_cc_data_contents_release (&io_v5creds->second_ticket); + cci_cc_data_array_release (io_v5creds->authdata); + free (io_v5creds); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v5_read (cc_credentials_v5_t **out_v5creds, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_credentials_v5_t *v5creds = NULL; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!out_v5creds) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + v5creds = malloc (sizeof (*v5creds)); + if (v5creds) { + *v5creds = cci_credentials_v5_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_stream_read_string (io_stream, &v5creds->client); + } + + if (!err) { + err = cci_stream_read_string (io_stream, &v5creds->server); + } + + if (!err) { + err = cci_cc_data_read (&v5creds->keyblock, io_stream); + } + + if (!err) { + err = cci_stream_read_time (io_stream, &v5creds->authtime); + } + + if (!err) { + err = cci_stream_read_time (io_stream, &v5creds->starttime); + } + + if (!err) { + err = cci_stream_read_time (io_stream, &v5creds->endtime); + } + + if (!err) { + err = cci_stream_read_time (io_stream, &v5creds->renew_till); + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &v5creds->is_skey); + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &v5creds->ticket_flags); + } + + if (!err) { + err = cci_cc_data_array_read (&v5creds->addresses, io_stream); + } + + if (!err) { + err = cci_cc_data_read (&v5creds->ticket, io_stream); + } + + if (!err) { + err = cci_cc_data_read (&v5creds->second_ticket, io_stream); + } + + if (!err) { + err = cci_cc_data_array_read (&v5creds->authdata, io_stream); + } + + if (!err) { + *out_v5creds = v5creds; + v5creds = NULL; + } + + cci_credentials_v5_release (v5creds); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!in_v5creds) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_stream, in_v5creds->client); + } + + if (!err) { + err = cci_stream_write_string (io_stream, in_v5creds->server); + } + + if (!err) { + err = cci_cc_data_write (&in_v5creds->keyblock, io_stream); + } + + if (!err) { + err = cci_stream_write_time (io_stream, in_v5creds->authtime); + } + + if (!err) { + err = cci_stream_write_time (io_stream, in_v5creds->starttime); + } + + if (!err) { + err = cci_stream_write_time (io_stream, in_v5creds->endtime); + } + + if (!err) { + err = cci_stream_write_time (io_stream, in_v5creds->renew_till); + } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_v5creds->is_skey); + } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_v5creds->ticket_flags); + } + + if (!err) { + err = cci_cc_data_array_write (in_v5creds->addresses, io_stream); + } + + if (!err) { + err = cci_cc_data_write (&in_v5creds->ticket, io_stream); + } + + if (!err) { + err = cci_cc_data_write (&in_v5creds->second_ticket, io_stream); + } + + if (!err) { + err = cci_cc_data_array_write (in_v5creds->authdata, io_stream); + } + + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_release (cc_credentials_union *io_cred_union) +{ + cc_int32 err = ccNoError; + + if (!io_cred_union) { err = ccErrBadParam; } + + if (!err) { + if (io_cred_union->version == cc_credentials_v4) { + cci_credentials_v4_release (io_cred_union->credentials.credentials_v4); + } else if (io_cred_union->version == cc_credentials_v5) { + cci_credentials_v5_release (io_cred_union->credentials.credentials_v5); + } + free (io_cred_union); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cc_credentials_union *cred_union = NULL; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cred_union = malloc (sizeof (*cred_union)); + if (!cred_union) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &cred_union->version); + } + + if (!err) { + if (cred_union->version == cc_credentials_v4) { + err = cci_credentials_v4_read (&cred_union->credentials.credentials_v4, + io_stream); + + } else if (cred_union->version == cc_credentials_v5) { + err = cci_credentials_v5_read (&cred_union->credentials.credentials_v5, + io_stream); + + + } else { + err = ccErrBadCredentialsVersion; + } + } + + if (!err) { + *out_credentials_union = cred_union; + cred_union = NULL; + } + + if (cred_union) { cci_cred_union_release (cred_union); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_uint32 (io_stream, in_credentials_union->version); + } + + if (!err) { + if (in_credentials_union->version == cc_credentials_v4) { + err = cci_credentials_v4_write (in_credentials_union->credentials.credentials_v4, + io_stream); + + } else if (in_credentials_union->version == cc_credentials_v5) { + err = cci_credentials_v5_write (in_credentials_union->credentials.credentials_v5, + io_stream); + + } else { + err = ccErrBadCredentialsVersion; + } + } + + return cci_check_error (err); +} diff --git a/src/ccapi/common/cci_cred_union.h b/src/ccapi/common/cci_cred_union.h new file mode 100644 index 000000000..f734d6a35 --- /dev/null +++ b/src/ccapi/common/cci_cred_union.h @@ -0,0 +1,41 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_CRED_UNION_H +#define CCI_CRED_UNION_H + +#include "cci_types.h" + +cc_uint32 cci_cred_union_release (cc_credentials_union *io_credentials); + +cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union, + cci_stream_t io_stream); + +cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union, + cci_stream_t io_stream); + + +#endif /* CCI_CRED_UNION_H */ diff --git a/src/ccapi/common/cci_debugging.c b/src/ccapi/common/cci_debugging.c new file mode 100644 index 000000000..4545b402e --- /dev/null +++ b/src/ccapi/common/cci_debugging.c @@ -0,0 +1,55 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" +#include "cci_os_debugging.h" + +/* ------------------------------------------------------------------------ */ + +cc_int32 _cci_check_error (cc_int32 in_error, + const char *in_function, + const char *in_file, + int in_line) +{ + /* Do not log for flow control errors or when there is no error at all */ + if (in_error != ccNoError && in_error != ccIteratorEnd) { + cci_debug_printf ("%s() got %d at %s: %d", in_function, + in_error, in_file, in_line); + } + + return in_error; +} + +/* ------------------------------------------------------------------------ */ + +void cci_debug_printf (const char *in_format, ...) +{ + va_list args; + + va_start (args, in_format); + cci_os_debug_vprintf (in_format, args); + va_end (args); +} diff --git a/src/ccapi/common/cci_debugging.h b/src/ccapi/common/cci_debugging.h new file mode 100644 index 000000000..169981f65 --- /dev/null +++ b/src/ccapi/common/cci_debugging.h @@ -0,0 +1,40 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_DEBUGGING_H +#define CCI_DEBUGGING_H + +#include "cci_types.h" + +cc_int32 _cci_check_error (cc_int32 in_err, + const char *in_function, + const char *in_file, + int in_line); +#define cci_check_error(err) _cci_check_error(err, __FUNCTION__, __FILE__, __LINE__) + +void cci_debug_printf (const char *in_format, ...) __attribute__ ((format (printf, 1, 2))); + +#endif /* CCI_DEBUGGING_H */ diff --git a/src/ccapi/common/cci_identifier.c b/src/ccapi/common/cci_identifier.c new file mode 100644 index 000000000..8695d2171 --- /dev/null +++ b/src/ccapi/common/cci_identifier.c @@ -0,0 +1,289 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" +#include "cci_os_identifier.h" + +struct cci_identifier_d { + cci_uuid_string_t server_id; + cci_uuid_string_t object_id; +}; + +struct cci_identifier_d cci_identifier_initializer = { NULL, NULL }; + +#define cci_uninitialized_server_id "NEEDS_SYNC" +#define cci_uninitialized_object_id "NEEDS_SYNC" + +struct cci_identifier_d cci_identifier_uninitialized_d = { + cci_uninitialized_server_id, + cci_uninitialized_object_id +}; +const cci_identifier_t cci_identifier_uninitialized = &cci_identifier_uninitialized_d; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) +{ + return cci_os_identifier_new_uuid (out_uuid_string); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 cci_identifier_alloc (cci_identifier_t *out_identifier, + cci_uuid_string_t in_server_id, + cci_uuid_string_t in_object_id) +{ + cc_int32 err = ccNoError; + cci_identifier_t identifier = NULL; + + if (!out_identifier) { err = cci_check_error (ccErrBadParam); } + if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } + if (!in_object_id ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + identifier = malloc (sizeof (*identifier)); + if (identifier) { + *identifier = cci_identifier_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + identifier->server_id = strdup (in_server_id); + if (!identifier->server_id) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + identifier->object_id = strdup (in_object_id); + if (!identifier->object_id) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + *out_identifier = identifier; + identifier = NULL; /* take ownership */ + } + + cci_identifier_release (identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_new (cci_identifier_t *out_identifier, + cci_uuid_string_t in_server_id) +{ + cc_int32 err = ccNoError; + cci_uuid_string_t object_id = NULL; + + if (!out_identifier) { err = cci_check_error (ccErrBadParam); } + if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_os_identifier_new_uuid (&object_id); + } + + if (!err) { + err = cci_identifier_alloc (out_identifier, in_server_id, object_id); + } + + if (object_id) { free (object_id); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_copy (cci_identifier_t *out_identifier, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + + if (!out_identifier) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_alloc (out_identifier, + in_identifier->server_id, + in_identifier->object_id); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_release (cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + + if (!in_identifier) { err = ccErrBadParam; } + + /* Do not free the static "uninitialized" identifier */ + if (!err && in_identifier != cci_identifier_uninitialized) { + free (in_identifier->server_id); + free (in_identifier->object_id); + free (in_identifier); + } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_compare (cci_identifier_t in_identifier, + cci_identifier_t in_compare_to_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal = (!strcmp (in_identifier->object_id, + in_compare_to_identifier->object_id) && + !strcmp (in_identifier->server_id, + in_compare_to_identifier->server_id)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_is_for_server (cci_identifier_t in_identifier, + cci_uuid_string_t in_server_id, + cc_uint32 *out_is_for_server) +{ + cc_int32 err = ccNoError; + + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_server) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_for_server = (!strcmp (in_identifier->server_id, in_server_id) || + !strcmp (in_identifier->server_id, cci_uninitialized_server_id)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_compare_server_id (cci_identifier_t in_identifier, + cci_identifier_t in_compare_to_identifier, + cc_uint32 *out_equal_server_id) +{ + cc_int32 err = ccNoError; + + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_equal_server_id ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal_server_id = (!strcmp (in_identifier->server_id, + in_compare_to_identifier->server_id)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_identifier_is_initialized (cci_identifier_t in_identifier, + cc_uint32 *out_is_initialized) +{ + cc_int32 err = ccNoError; + + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_initialized) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_initialized = (strcmp (in_identifier->server_id, + cci_uninitialized_server_id) != 0); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_identifier_read (cci_identifier_t *out_identifier, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + cci_uuid_string_t server_id = NULL; + cci_uuid_string_t object_id = NULL; + + if (!out_identifier) { err = cci_check_error (ccErrBadParam); } + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (io_stream, &server_id); + } + + if (!err) { + err = cci_stream_read_string (io_stream, &object_id); + } + + if (!err) { + err = cci_identifier_alloc (out_identifier, server_id, object_id); + } + + if (server_id) { free (server_id); } + if (object_id) { free (object_id); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_identifier_write (cci_identifier_t in_identifier, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_stream, in_identifier->server_id); + } + + if (!err) { + err = cci_stream_write_string (io_stream, in_identifier->object_id); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/common/cci_identifier.h b/src/ccapi/common/cci_identifier.h new file mode 100644 index 000000000..7d835de0a --- /dev/null +++ b/src/ccapi/common/cci_identifier.h @@ -0,0 +1,65 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_IDENTIFIER_H +#define CCI_IDENTIFIER_H + +#include "cci_types.h" + +extern const cci_identifier_t cci_identifier_uninitialized; + +cc_int32 cci_identifier_new_uuid (cci_uuid_string_t *out_uuid_string); + +cc_int32 cci_identifier_new (cci_identifier_t *out_identifier, + cci_uuid_string_t in_server_id); + +cc_int32 cci_identifier_copy (cci_identifier_t *out_identifier, + cci_identifier_t in_handle); + +cc_int32 cci_identifier_release (cci_identifier_t in_identifier); + +cc_int32 cci_identifier_compare (cci_identifier_t in_identifier, + cci_identifier_t in_compare_to_identifier, + cc_uint32 *out_equal); + +cc_int32 cci_identifier_is_for_server (cci_identifier_t in_identifier, + cci_uuid_string_t in_server_id, + cc_uint32 *out_is_for_server); + +cc_int32 cci_identifier_compare_server_id (cci_identifier_t in_identifier, + cci_identifier_t in_compare_to_identifier, + cc_uint32 *out_equal_server_id); + +cc_int32 cci_identifier_is_initialized (cci_identifier_t in_identifier, + cc_uint32 *out_is_initialized); + +cc_uint32 cci_identifier_read (cci_identifier_t *out_identifier, + cci_stream_t io_stream); + +cc_uint32 cci_identifier_write (cci_identifier_t in_identifier, + cci_stream_t io_stream); + +#endif /* CCI_IDENTIFIER_H */ diff --git a/src/ccapi/common/cci_message.c b/src/ccapi/common/cci_message.c new file mode 100644 index 000000000..4152e6c3c --- /dev/null +++ b/src/ccapi/common/cci_message.c @@ -0,0 +1,172 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_message_invalid_object_err (enum cci_msg_id_t in_request_name) +{ + cc_int32 err = ccNoError; + + if (in_request_name > cci_context_first_msg_id && + in_request_name < cci_context_last_msg_id) { + err = ccErrInvalidContext; + + } else if (in_request_name > cci_ccache_first_msg_id && + in_request_name < cci_ccache_last_msg_id) { + err = ccErrInvalidCCache; + + } else if (in_request_name > cci_ccache_iterator_first_msg_id && + in_request_name < cci_ccache_iterator_last_msg_id) { + err = ccErrInvalidCCacheIterator; + + } else if (in_request_name > cci_credentials_iterator_first_msg_id && + in_request_name < cci_credentials_iterator_last_msg_id) { + err = ccErrInvalidCredentialsIterator; + + } else { + err = ccErrBadInternalMessage; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_message_new_request_header (cci_stream_t *out_request, + enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cci_stream_t request = NULL; + + if (!out_request) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_request_name); + } + + if (!err) { + err = cci_identifier_write (in_identifier, request); + } + + if (!err) { + *out_request = request; + request = NULL; + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_message_read_request_header (cci_stream_t in_request, + enum cci_msg_id_t *out_request_name, + cci_identifier_t *out_identifier) +{ + cc_int32 err = ccNoError; + cc_uint32 request_name; + cci_identifier_t identifier = NULL; + + if (!in_request ) { err = cci_check_error (ccErrBadParam); } + if (!out_request_name) { err = cci_check_error (ccErrBadParam); } + if (!out_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request, &request_name); + } + + if (!err) { + err = cci_identifier_read (&identifier, in_request); + } + + if (!err) { + *out_request_name = request_name; + *out_identifier = identifier; + identifier = NULL; /* take ownership */ + } + + cci_identifier_release (identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_message_new_reply_header (cci_stream_t *out_reply, + cc_int32 in_error) +{ + cc_int32 err = ccNoError; + cci_stream_t reply = NULL; + + if (!out_reply) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply); + } + + if (!err) { + err = cci_stream_write_int32 (reply, in_error); + } + + if (!err) { + *out_reply = reply; + reply = NULL; + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_message_read_reply_header (cci_stream_t in_reply, + cc_int32 *out_reply_error) +{ + cc_int32 err = ccNoError; + cc_int32 reply_err = 0; + + if (!in_reply ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_error) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_int32 (in_reply, &reply_err); + } + + if (!err) { + *out_reply_error = reply_err; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/common/cci_message.h b/src/ccapi/common/cci_message.h new file mode 100644 index 000000000..7cab2dc76 --- /dev/null +++ b/src/ccapi/common/cci_message.h @@ -0,0 +1,48 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_MESSAGE_H +#define CCI_MESSAGE_H + +#include "cci_types.h" + +cc_int32 cci_message_invalid_object_err (enum cci_msg_id_t in_request_name); + +cc_int32 cci_message_new_request_header (cci_stream_t *out_request, + enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier); + +cc_int32 cci_message_read_request_header (cci_stream_t in_request, + enum cci_msg_id_t *out_request_name, + cci_identifier_t *out_identifier); + +cc_int32 cci_message_new_reply_header (cci_stream_t *out_reply, + cc_int32 in_error); + +cc_int32 cci_message_read_reply_header (cci_stream_t in_reply, + cc_int32 *out_reply_error); + +#endif /* CCI_MESSAGE_H */ diff --git a/src/ccapi/common/cci_os_debugging.h b/src/ccapi/common/cci_os_debugging.h new file mode 100644 index 000000000..b08ee002e --- /dev/null +++ b/src/ccapi/common/cci_os_debugging.h @@ -0,0 +1,35 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_OS_DEBUGGING_H +#define CCI_OS_DEBUGGING_H + +#include "cci_types.h" +#include + +inline void cci_os_debug_vprintf (const char *in_format, va_list in_args); + +#endif /* CCI_OS_DEBUGGING_H */ diff --git a/src/ccapi/common/cci_os_identifier.h b/src/ccapi/common/cci_os_identifier.h new file mode 100644 index 000000000..b60772095 --- /dev/null +++ b/src/ccapi/common/cci_os_identifier.h @@ -0,0 +1,34 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_OS_IDENTIFIER_H +#define CCI_OS_IDENTIFIER_H + +#include "cci_types.h" + +inline cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string); + +#endif /* CCI_OS_IDENTIFIER_H */ diff --git a/src/ccapi/common/cci_stream.c b/src/ccapi/common/cci_stream.c new file mode 100644 index 000000000..cac5431e7 --- /dev/null +++ b/src/ccapi/common/cci_stream.c @@ -0,0 +1,490 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" + +#if TARGET_OS_MAC +#include + +#if !defined(htonll) +#define htonll(x) OSSwapHostToBigInt64(x) +#endif + +#if !defined(ntohll) +#define ntohll(x) OSSwapBigToHostInt64(x) +#endif + +#endif /* TARGET_OS_MAC */ + +struct cci_stream_d { + char *data; + cc_uint64 size; + cc_uint64 max_size; +}; + +const struct cci_stream_d cci_stream_initializer = { NULL, 0, 0 }; + +#define CC_STREAM_SIZE_INCREMENT 128 + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_stream_reallocate (cci_stream_t io_stream, + cc_uint64 in_new_size) +{ + cc_int32 err = ccNoError; + cc_uint64 new_max_size = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 old_max_size = io_stream->max_size; + new_max_size = io_stream->max_size; + + if (in_new_size > old_max_size) { + /* Expand the stream */ + while (in_new_size > new_max_size) { + new_max_size += CC_STREAM_SIZE_INCREMENT; + } + + + } else if ((in_new_size + CC_STREAM_SIZE_INCREMENT) < old_max_size) { + /* Shrink the array, but never drop below CC_LIST_COUNT_INCREMENT */ + while ((in_new_size + CC_STREAM_SIZE_INCREMENT) < new_max_size && + (new_max_size > CC_STREAM_SIZE_INCREMENT)) { + new_max_size -= CC_STREAM_SIZE_INCREMENT; + } + } + } + + if (!err && new_max_size != io_stream->max_size) { + char *data = io_stream->data; + + if (!data) { + data = malloc (new_max_size * sizeof (*data)); + } else { + data = realloc (data, new_max_size * sizeof (*data)); + } + + if (data) { + io_stream->data = data; + io_stream->max_size = new_max_size; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_stream_new (cci_stream_t *out_stream) +{ + cc_int32 err = ccNoError; + cci_stream_t stream = NULL; + + if (!out_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + stream = malloc (sizeof (*stream)); + if (stream) { + *stream = cci_stream_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + *out_stream = stream; + stream = NULL; + } + + cci_stream_release (stream); + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_release (cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!io_stream) { err = ccErrBadParam; } + + if (!err) { + free (io_stream->data); + free (io_stream); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +inline cc_uint64 cci_stream_size (cci_stream_t in_stream) +{ + return in_stream ? in_stream->size : 0; +} + + +/* ------------------------------------------------------------------------ */ + +inline const char *cci_stream_data (cci_stream_t in_stream) +{ + return in_stream ? in_stream->data : NULL; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read (cci_stream_t io_stream, + void *io_data, + cc_uint64 in_size) +{ + cc_int32 err = ccNoError; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!io_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_size > io_stream->size) { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (!err) { + memcpy (io_data, io_stream->data, in_size); + memmove (io_stream->data, &io_stream->data[in_size], + io_stream->size - in_size); + + err = cci_stream_reallocate (io_stream, io_stream->size - in_size); + + if (!err) { + io_stream->size -= in_size; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write (cci_stream_t io_stream, + const void *in_data, + cc_uint64 in_size) +{ + cc_int32 err = ccNoError; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!in_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Security check: Do not let the caller overflow the length */ + if (in_size > (UINT64_MAX - io_stream->size)) { + err = cci_check_error (ccErrBadParam); + } + } + + if (!err) { + err = cci_stream_reallocate (io_stream, io_stream->size + in_size); + } + + if (!err) { + memcpy (&io_stream->data[io_stream->size], in_data, in_size); + io_stream->size += in_size; + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_string (cci_stream_t io_stream, + char **out_string) +{ + cc_int32 err = ccNoError; + cc_uint32 length = 0; + char *string = NULL; + + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + if (!out_string) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (io_stream, &length); + } + + if (!err) { + string = malloc (length); + if (!string) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = cci_stream_read (io_stream, string, length); + } + + if (!err) { + *out_string = string; + string = NULL; + } + + free (string); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_string (cci_stream_t io_stream, + const char *in_string) +{ + cc_int32 err = ccNoError; + cc_uint32 length = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!in_string) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + length = strlen (in_string) + 1; + + err = cci_stream_write_uint32 (io_stream, length); + } + + if (!err) { + err = cci_stream_write (io_stream, in_string, length); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_int32 (cci_stream_t io_stream, + cc_int32 *out_int32) +{ + cc_int32 err = ccNoError; + cc_int32 int32 = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_int32) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read (io_stream, &int32, sizeof (int32)); + } + + if (!err) { + *out_int32 = ntohl (int32); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_int32 (cci_stream_t io_stream, + cc_int32 in_int32) +{ + cc_int32 err = ccNoError; + cc_int32 int32 = htonl (in_int32); + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write (io_stream, &int32, sizeof (int32)); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_uint32 (cci_stream_t io_stream, + cc_uint32 *out_uint32) +{ + cc_int32 err = ccNoError; + cc_uint32 uint32 = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_uint32) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read (io_stream, &uint32, sizeof (uint32)); + } + + if (!err) { + *out_uint32 = ntohl (uint32); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_uint32 (cci_stream_t io_stream, + cc_uint32 in_uint32) +{ + cc_int32 err = ccNoError; + cc_int32 uint32 = htonl (in_uint32); + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write (io_stream, &uint32, sizeof (uint32)); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_int64 (cci_stream_t io_stream, + cc_int64 *out_int64) +{ + cc_int32 err = ccNoError; + cc_uint64 int64 = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_int64) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read (io_stream, &int64, sizeof (int64)); + } + + if (!err) { + *out_int64 = ntohll (int64); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_int64 (cci_stream_t io_stream, + cc_int64 in_int64) +{ + cc_int32 err = ccNoError; + cc_int64 int64 = htonll (in_int64); + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write (io_stream, &int64, sizeof (int64)); + } + + return cci_check_error (err); +} + + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_uint64 (cci_stream_t io_stream, + cc_uint64 *out_uint64) +{ + cc_int32 err = ccNoError; + cc_uint64 uint64 = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_uint64) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read (io_stream, &uint64, sizeof (uint64)); + } + + if (!err) { + *out_uint64 = ntohll (uint64); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_uint64 (cci_stream_t io_stream, + cc_uint64 in_uint64) +{ + cc_int32 err = ccNoError; + cc_int64 uint64 = htonll (in_uint64); + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write (io_stream, &uint64, sizeof (uint64)); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_read_time (cci_stream_t io_stream, + cc_time_t *out_time) +{ + cc_int32 err = ccNoError; + cc_int64 t = 0; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_time ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_int64 (io_stream, &t); + } + + if (!err) { + *out_time = t; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_stream_write_time (cci_stream_t io_stream, + cc_time_t in_time) +{ + cc_int32 err = ccNoError; + + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_int64 (io_stream, in_time); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/common/cci_stream.h b/src/ccapi/common/cci_stream.h new file mode 100644 index 000000000..9c37361cd --- /dev/null +++ b/src/ccapi/common/cci_stream.h @@ -0,0 +1,77 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_STREAM_H +#define CCI_STREAM_H + +#include "cci_types.h" + +cc_int32 cci_stream_new (cci_stream_t *out_stream); + +cc_uint32 cci_stream_release (cci_stream_t io_stream); + +inline cc_uint64 cci_stream_size (cci_stream_t in_stream); + +inline const char *cci_stream_data (cci_stream_t in_stream); + +cc_uint32 cci_stream_read (cci_stream_t in_stream, + void *io_data, + cc_uint64 in_size); +cc_uint32 cci_stream_write (cci_stream_t in_stream, + const void *in_data, + cc_uint64 in_size); + +cc_uint32 cci_stream_read_string (cci_stream_t io_stream, + char **out_string); +cc_uint32 cci_stream_write_string (cci_stream_t io_stream, + const char *in_string); + +cc_uint32 cci_stream_read_int32 (cci_stream_t io_stream, + cc_int32 *out_int32); +cc_uint32 cci_stream_write_int32 (cci_stream_t io_stream, + cc_int32 in_int32); + +cc_uint32 cci_stream_read_uint32 (cci_stream_t io_stream, + cc_uint32 *out_uint32); +cc_uint32 cci_stream_write_uint32 (cci_stream_t io_stream, + cc_uint32 in_uint32); + +cc_uint32 cci_stream_read_int64 (cci_stream_t io_stream, + cc_int64 *out_int64); +cc_uint32 cci_stream_write_int64 (cci_stream_t io_stream, + cc_int64 in_int64); + +cc_uint32 cci_stream_read_uint64 (cci_stream_t io_stream, + cc_uint64 *out_uint64); +cc_uint32 cci_stream_write_uint64 (cci_stream_t io_stream, + cc_uint64 in_uint64); + +cc_uint32 cci_stream_read_time (cci_stream_t io_stream, + cc_time_t *out_time); +cc_uint32 cci_stream_write_time (cci_stream_t io_stream, + cc_time_t in_time); + +#endif /* CCI_STREAM_H */ diff --git a/src/ccapi/common/cci_types.h b/src/ccapi/common/cci_types.h new file mode 100644 index 000000000..8ace67ce7 --- /dev/null +++ b/src/ccapi/common/cci_types.h @@ -0,0 +1,105 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCI_TYPES_H +#define CCI_TYPES_H + +#include + +struct cci_stream_d; +typedef struct cci_stream_d *cci_stream_t; + +typedef char *cci_uuid_string_t; + +struct cci_identifier_d; +typedef struct cci_identifier_d *cci_identifier_t; + +enum cci_msg_id_t { + /* cc_context_t */ + cci_context_first_msg_id, + + cci_context_release_msg_id, + cci_context_sync_msg_id, + cci_context_get_change_time_msg_id, + cci_context_wait_for_change_msg_id, + cci_context_get_default_ccache_name_msg_id, + cci_context_open_ccache_msg_id, + cci_context_open_default_ccache_msg_id, + cci_context_create_ccache_msg_id, + cci_context_create_default_ccache_msg_id, + cci_context_create_new_ccache_msg_id, + cci_context_new_ccache_iterator_msg_id, + cci_context_lock_msg_id, + cci_context_unlock_msg_id, + + cci_context_last_msg_id, + + /* cc_ccache_t */ + cci_ccache_first_msg_id, + + cci_ccache_destroy_msg_id, + cci_ccache_set_default_msg_id, + cci_ccache_get_credentials_version_msg_id, + cci_ccache_get_name_msg_id, + cci_ccache_get_principal_msg_id, + cci_ccache_set_principal_msg_id, + cci_ccache_store_credentials_msg_id, + cci_ccache_remove_credentials_msg_id, + cci_ccache_new_credentials_iterator_msg_id, + cci_ccache_move_msg_id, + cci_ccache_lock_msg_id, + cci_ccache_unlock_msg_id, + cci_ccache_get_last_default_time_msg_id, + cci_ccache_get_change_time_msg_id, + cci_ccache_wait_for_change_msg_id, + cci_ccache_get_kdc_time_offset_msg_id, + cci_ccache_set_kdc_time_offset_msg_id, + cci_ccache_clear_kdc_time_offset_msg_id, + + cci_ccache_last_msg_id, + + /* cc_ccache_iterator_t */ + cci_ccache_iterator_first_msg_id, + + cci_ccache_iterator_release_msg_id, + cci_ccache_iterator_next_msg_id, + cci_ccache_iterator_clone_msg_id, + + cci_ccache_iterator_last_msg_id, + + /* cc_credentials_iterator_t */ + cci_credentials_iterator_first_msg_id, + + cci_credentials_iterator_release_msg_id, + cci_credentials_iterator_next_msg_id, + cci_credentials_iterator_clone_msg_id, + + cci_credentials_iterator_last_msg_id, + + cci_max_msg_id /* must be last! */ +}; + +#endif /* CCI_TYPES_H */ diff --git a/src/ccapi/common/mac/cci_mig.defs b/src/ccapi/common/mac/cci_mig.defs new file mode 100644 index 000000000..3a573681a --- /dev/null +++ b/src/ccapi/common/mac/cci_mig.defs @@ -0,0 +1,54 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include +#include + +import "cci_mig_types.h"; + +/* Note the 1024 must be the same as kCCAPIMaxILMsgSize */ +type cci_mipc_inl_request_t = array [ * : 1024 ] of char; +type cci_mipc_ool_request_t = array [] of char; + +type cci_mipc_inl_reply_t = array [ * : 1024 ] of char; +type cci_mipc_ool_reply_t = array [] of char; diff --git a/src/ccapi/common/mac/cci_mig_reply.defs b/src/ccapi/common/mac/cci_mig_reply.defs new file mode 100644 index 000000000..f500ef9ac --- /dev/null +++ b/src/ccapi/common/mac/cci_mig_reply.defs @@ -0,0 +1,58 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "cci_mig.defs" + +subsystem cci 200; + +serverprefix cci_mipc_; +userprefix ccs_mipc_; + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * client side because we can't know when server has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine reply (in_reply_port : mach_port_move_send_once_t; + in_inl_reply : cci_mipc_inl_reply_t; + in_ool_reply : cci_mipc_ool_reply_t, dealloc); diff --git a/src/ccapi/common/mac/cci_mig_request.defs b/src/ccapi/common/mac/cci_mig_request.defs new file mode 100644 index 000000000..45887e1a1 --- /dev/null +++ b/src/ccapi/common/mac/cci_mig_request.defs @@ -0,0 +1,62 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "cci_mig.defs" + +subsystem ccs 100; + +serverprefix ccs_mipc_; +userprefix cci_mipc_; + +routine create_client_connection (in_server_port : mach_port_t; + out out_connection_port : mach_port_t = MACH_MSG_TYPE_MAKE_SEND); + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * server side because we can't know when client has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine request (in_connection_port : mach_port_t; + in_reply_port : mach_port_make_send_once_t; + in_inl_request : cci_mipc_inl_request_t; + in_ool_request : cci_mipc_ool_request_t, dealloc); diff --git a/src/ccapi/common/mac/cci_mig_types.h b/src/ccapi/common/mac/cci_mig_types.h new file mode 100644 index 000000000..d82d5ac59 --- /dev/null +++ b/src/ccapi/common/mac/cci_mig_types.h @@ -0,0 +1,56 @@ +/* $Copyright: +* +* Copyright 2004-2006 by the 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 MIT 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. +* +* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +* +* Individual source code files are copyright MIT, Cygnus Support, +* OpenVision, Oracle, Sun Soft, FundsXpress, and others. +* +* Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, +* and Zephyr are trademarks of the Massachusetts Institute of Technology +* (MIT). No commercial use of these trademarks may be made without prior +* written permission of MIT. +* +* "Commercial use" means use of a name in a product or other for-profit +* manner. It does NOT prevent a commercial firm from referring to the MIT +* trademarks in order to convey information (although in doing so, +* recognition of their trademark status should be given). +* $ +*/ + +#ifndef CCI_MIG_TYPES_H +#define CCI_MIG_TYPES_H + +#include "cci_common.h" + +#define kCCAPIMaxILMsgSize 1024 + +typedef const char cci_mipc_inl_request_t[kCCAPIMaxILMsgSize]; +typedef const char *cci_mipc_ool_request_t; +typedef char cci_mipc_inl_reply_t[kCCAPIMaxILMsgSize]; +typedef char *cci_mipc_ool_reply_t; + +#endif /* CCI_MIG_TYPES_H */ diff --git a/src/ccapi/common/mac/cci_os_debugging.c b/src/ccapi/common/mac/cci_os_debugging.c new file mode 100644 index 000000000..f64b83916 --- /dev/null +++ b/src/ccapi/common/mac/cci_os_debugging.c @@ -0,0 +1,36 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + + +#include "cci_os_debugging.h" +#include + +/* ------------------------------------------------------------------------ */ + +inline void cci_os_debug_vprintf (const char *in_format, va_list in_args) +{ + dvprintf (in_format, in_args); +} diff --git a/src/ccapi/common/mac/cci_os_identifier.c b/src/ccapi/common/mac/cci_os_identifier.c new file mode 100644 index 000000000..c01e727bb --- /dev/null +++ b/src/ccapi/common/mac/cci_os_identifier.c @@ -0,0 +1,80 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" +#include "cci_os_identifier.h" + +#include + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) +{ + cc_int32 err = ccNoError; + cci_uuid_string_t uuid_string = NULL; + CFUUIDRef uuid = NULL; + CFStringRef uuid_stringref = NULL; + CFStringEncoding encoding = kCFStringEncodingUTF8; + CFIndex length = 0; + + if (!out_uuid_string) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + uuid = CFUUIDCreate (kCFAllocatorDefault); + if (!uuid) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + uuid_stringref = CFUUIDCreateString (kCFAllocatorDefault, uuid); + if (!uuid_stringref) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + length = CFStringGetMaximumSizeForEncoding (CFStringGetLength (uuid_stringref), + encoding) + 1; + + uuid_string = malloc (length); + if (!uuid_string) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + if (!CFStringGetCString (uuid_stringref, uuid_string, length, encoding)) { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + *out_uuid_string = uuid_string; + uuid_string = NULL; /* take ownership */ + } + + if (uuid_string ) { free (uuid_string); } + if (uuid_stringref) { CFRelease (uuid_stringref); } + if (uuid ) { CFRelease (uuid); } + + return cci_check_error (err); +} + diff --git a/src/ccapi/lib/ccapi.exports b/src/ccapi/lib/ccapi.exports new file mode 100644 index 000000000..92c859bd7 --- /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 000000000..5a975810c --- /dev/null +++ b/src/ccapi/lib/ccapi_ccache.c @@ -0,0 +1,736 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_ccache.h" + +#include "ccapi_string.h" +#include "ccapi_credentials.h" +#include "ccapi_credentials_iterator.h" +#include "ccapi_ipc.h" + +#if TARGET_OS_MAC +#warning Workaround for AppleConnect crash causes leak +#include +#endif + +/* ------------------------------------------------------------------------ */ + +typedef struct cci_ccache_d { + cc_ccache_f *functions; +#if TARGET_OS_MAC + cc_ccache_f *vector_functions; +#endif + cci_identifier_t identifier; +} *cci_ccache_t; + +/* ------------------------------------------------------------------------ */ + +struct cci_ccache_d cci_ccache_initializer = { + NULL + VECTOR_FUNCTIONS_INITIALIZER, + NULL, +}; + +cc_ccache_f cci_ccache_f_initializer = { + ccapi_ccache_release, + ccapi_ccache_destroy, + ccapi_ccache_set_default, + ccapi_ccache_get_credentials_version, + ccapi_ccache_get_name, + ccapi_ccache_get_principal, + ccapi_ccache_set_principal, + ccapi_ccache_store_credentials, + ccapi_ccache_remove_credentials, + ccapi_ccache_new_credentials_iterator, + ccapi_ccache_move, + ccapi_ccache_lock, + ccapi_ccache_unlock, + ccapi_ccache_get_last_default_time, + ccapi_ccache_get_change_time, + ccapi_ccache_compare, + ccapi_ccache_get_kdc_time_offset, + ccapi_ccache_set_kdc_time_offset, + ccapi_ccache_clear_kdc_time_offset, + ccapi_ccache_wait_for_change +}; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_new (cc_ccache_t *out_ccache, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = NULL; + + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache = malloc (sizeof (*ccache)); + if (ccache) { + *ccache = cci_ccache_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + ccache->functions = malloc (sizeof (*ccache->functions)); + if (ccache->functions) { + *ccache->functions = cci_ccache_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_identifier_copy (&ccache->identifier, in_identifier); + } + + if (!err) { + *out_ccache = (cc_ccache_t) ccache; + ccache = NULL; /* take ownership */ + } + + ccapi_ccache_release ((cc_ccache_t) ccache); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_write (cc_ccache_t in_ccache, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!in_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (ccache->identifier, in_stream); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + + if (!io_ccache) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (ccache->identifier); + +#if TARGET_OS_MAC +#warning Workaround for AppleConnect crash causes leak + CFBundleRef main_bundle = CFBundleGetMainBundle (); + if (main_bundle) { + CFStringRef bundle_id = CFBundleGetIdentifier (main_bundle); + if (bundle_id) { + CFStringRef ac_id = CFSTR("com.apple.ist.ds.appleconnect"); + if (CFStringCompare (bundle_id, ac_id, 0) == kCFCompareEqualTo) { + return ccNoError; + } + } + } +#endif + free ((char *) ccache->functions); + free (ccache); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_destroy_msg_id, + ccache->identifier, + NULL, + NULL); + } + + if (!err) { + err = ccapi_ccache_release (io_ccache); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_set_default_msg_id, + ccache->identifier, + NULL, + NULL); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache, + cc_uint32 *out_credentials_version) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_version) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_credentials_version_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_stream_read_uint32 (reply, out_credentials_version); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache, + cc_string_t *out_name) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + char *name = NULL; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!out_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_name_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_stream_read_string (reply, &name); + } + + if (!err) { + err = cci_string_new (out_name, name); + } + + cci_stream_release (reply); + free (name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_string_t *out_principal) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + char *principal = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_principal_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_stream_read_string (reply, &principal); + } + + if (!err) { + err = cci_string_new (out_principal, principal); + } + + cci_stream_release (reply); + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + const char *in_principal) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_string (request, in_principal); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_set_principal_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache, + const cc_credentials_union *in_credentials_union) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_cred_union_write (in_credentials_union, request); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_store_credentials_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache, + cc_credentials_t in_credentials) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_credentials_write (in_credentials, request); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_remove_credentials_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache, + cc_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_new_credentials_iterator_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_credentials_iterator_new (out_credentials_iterator, identifier); + } + + cci_stream_release (reply); + cci_identifier_release (identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ +/* Note: message is sent as the destination to avoid extra work on the */ +/* server when deleting it the source ccache. */ + +cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache, + cc_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t source_ccache = (cci_ccache_t) io_source_ccache; + cci_ccache_t destination_ccache = (cci_ccache_t) io_destination_ccache; + cci_stream_t request = NULL; + + if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_identifier_write (source_ccache->identifier, request); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_move_msg_id, + destination_ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache, + cc_uint32 in_lock_type, + cc_uint32 in_block) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_lock_type); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_block); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_lock_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_unlock_msg_id, + ccache->identifier, + NULL, + NULL); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache, + cc_time_t *out_last_default_time) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_last_default_time) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_last_default_time_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_stream_read_time (reply, out_last_default_time); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache, + cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t reply = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_change_time) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_change_time_msg_id, + ccache->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_stream_read_time (reply, out_change_time); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_ccache_wait_for_change_msg_id, + ccache->identifier, + NULL, NULL); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache, + cc_ccache_t in_compare_to_ccache, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_ccache_t compare_to_ccache = (cci_ccache_t) in_compare_to_ccache; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_ccache) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (ccache->identifier, + compare_to_ccache->identifier, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_time_t *out_time_offset) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_time_offset) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_credentials_version); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_get_kdc_time_offset_msg_id, + ccache->identifier, + request, + &reply); + } + + if (!err) { + err = cci_stream_read_time (reply, out_time_offset); + } + + cci_stream_release (request); + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + cc_time_t in_time_offset) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_credentials_version); + } + + if (!err) { + err = cci_stream_write_time (request, in_time_offset); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_set_kdc_time_offset_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + cci_stream_t request = NULL; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_credentials_version); + } + + if (!err) { + err = cci_ipc_send (cci_ccache_clear_kdc_time_offset_msg_id, + ccache->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_ccache.h b/src/ccapi/lib/ccapi_ccache.h new file mode 100644 index 000000000..82a9f6c1c --- /dev/null +++ b/src/ccapi/lib/ccapi_ccache.h @@ -0,0 +1,99 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CCACHE_H +#define CCAPI_CCACHE_H + +#include "cci_common.h" + +cc_int32 cci_ccache_new (cc_ccache_t *out_ccache, + cci_identifier_t in_identifier); + +cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache); + +cc_int32 cci_ccache_write (cc_ccache_t in_ccache, + cci_stream_t in_stream); + +cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache); + +cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache); + +cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache, + cc_uint32 *out_credentials_version); + +cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache, + cc_string_t *out_name); + +cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_string_t *out_principal); + +cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + const char *in_principal); + +cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache, + const cc_credentials_union *in_credentials_union); + +cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache, + cc_credentials_t in_credentials); + +cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache, + cc_credentials_iterator_t *out_credentials_iterator); + +cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache, + cc_ccache_t io_destination_ccache); + +cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache, + cc_uint32 in_lock_type, + cc_uint32 in_block); + +cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache); + +cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache, + cc_time_t *out_last_default_time); + +cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache, + cc_time_t *out_change_time); + +cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache); + +cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache, + cc_ccache_t in_compare_to_ccache, + cc_uint32 *out_equal); + +cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_time_t *out_time_offset); + +cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + cc_time_t in_time_offset); + +cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version); + +#endif /* CCAPI_CCACHE_H */ diff --git a/src/ccapi/lib/ccapi_ccache_iterator.c b/src/ccapi/lib/ccapi_ccache_iterator.c new file mode 100644 index 000000000..815da36f1 --- /dev/null +++ b/src/ccapi/lib/ccapi_ccache_iterator.c @@ -0,0 +1,224 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_ccache_iterator.h" +#include "ccapi_ccache.h" +#include "ccapi_ipc.h" + +/* ------------------------------------------------------------------------ */ + +typedef struct cci_ccache_iterator_d { + cc_ccache_iterator_f *functions; +#if TARGET_OS_MAC + cc_ccache_iterator_f *vector_functions; +#endif + cci_identifier_t identifier; +} *cci_ccache_iterator_t; + +/* ------------------------------------------------------------------------ */ + +struct cci_ccache_iterator_d cci_ccache_iterator_initializer = { + NULL + VECTOR_FUNCTIONS_INITIALIZER, + NULL +}; + +cc_ccache_iterator_f cci_ccache_iterator_f_initializer = { + ccapi_ccache_iterator_release, + ccapi_ccache_iterator_next, + ccapi_ccache_iterator_clone +}; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = NULL; + + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache_iterator = malloc (sizeof (*ccache_iterator)); + if (ccache_iterator) { + *ccache_iterator = cci_ccache_iterator_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + ccache_iterator->functions = malloc (sizeof (*ccache_iterator->functions)); + if (ccache_iterator->functions) { + *ccache_iterator->functions = cci_ccache_iterator_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_identifier_copy (&ccache_iterator->identifier, in_identifier); + } + + if (!err) { + *out_ccache_iterator = (cc_ccache_iterator_t) ccache_iterator; + ccache_iterator = NULL; /* take ownership */ + } + + ccapi_ccache_iterator_release ((cc_ccache_iterator_t) ccache_iterator); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; + + if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (ccache_iterator->identifier, in_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator; + + if (!io_ccache_iterator) { err = ccErrBadParam; } + + if (!err) { + free ((char *) ccache_iterator->functions); + cci_identifier_release (ccache_iterator->identifier); + free (ccache_iterator); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint32 initialized = 0; + + err = cci_identifier_is_initialized (ccache_iterator->identifier, + &initialized); + + if (!err && !initialized) { + /* server doesn't actually exist. Pretend we're empty. */ + err = cci_check_error (ccIteratorEnd); + } + } + + if (!err) { + err = cci_ipc_send (cci_ccache_iterator_next_msg_id, + ccache_iterator->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_stream_release (reply); + cci_identifier_release (identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_iterator_t *out_ccache_iterator) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; + cci_stream_t reply = NULL; + cc_uint32 initialized = 0; + cci_identifier_t identifier = NULL; + + if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_is_initialized (ccache_iterator->identifier, + &initialized); + } + + if (!err) { + if (initialized) { + err = cci_ipc_send (cci_ccache_iterator_next_msg_id, + ccache_iterator->identifier, + NULL, + &reply); + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + } else { + /* server doesn't actually exist. Make another dummy one. */ + identifier = cci_identifier_uninitialized; + } + } + + if (!err) { + err = cci_ccache_iterator_new (out_ccache_iterator, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_ccache_iterator.h b/src/ccapi/lib/ccapi_ccache_iterator.h new file mode 100644 index 000000000..0a5a4f456 --- /dev/null +++ b/src/ccapi/lib/ccapi_ccache_iterator.h @@ -0,0 +1,46 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CCACHE_ITERATOR_H +#define CCAPI_CCACHE_ITERATOR_H + +#include "cci_common.h" + +cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator, + cci_identifier_t in_identifier); + +cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator, + cci_stream_t in_stream); + +cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator); + +cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_iterator_t *out_ccache_iterator); + +#endif /* CCAPI_CCACHE_ITERATOR_H */ diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c new file mode 100644 index 000000000..7a24f2248 --- /dev/null +++ b/src/ccapi/lib/ccapi_context.c @@ -0,0 +1,789 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_context.h" + +#include "k5-platform.h" + +#include "ccapi_ccache.h" +#include "ccapi_ccache_iterator.h" +#include "ccapi_string.h" +#include "ccapi_ipc.h" +#include "ccapi_context_change_time.h" + +#include + +typedef struct cci_context_d { + cc_context_f *functions; +#if TARGET_OS_MAC + cc_context_f *vector_functions; +#endif + cci_identifier_t identifier; + cc_uint32 synchronized; +} *cci_context_t; + +/* ------------------------------------------------------------------------ */ + +struct cci_context_d cci_context_initializer = { + NULL + VECTOR_FUNCTIONS_INITIALIZER, + NULL, + 0 +}; + +cc_context_f cci_context_f_initializer = { + ccapi_context_release, + ccapi_context_get_change_time, + ccapi_context_get_default_ccache_name, + ccapi_context_open_ccache, + ccapi_context_open_default_ccache, + ccapi_context_create_ccache, + ccapi_context_create_default_ccache, + ccapi_context_create_new_ccache, + ccapi_context_new_ccache_iterator, + ccapi_context_lock, + ccapi_context_unlock, + ccapi_context_compare, + ccapi_context_wait_for_change +}; + +static cc_int32 cci_context_sync (cci_context_t in_context, + cc_uint32 in_launch); + +#pragma mark - + +MAKE_INIT_FUNCTION(cci_thread_init); + +/* ------------------------------------------------------------------------ */ + +static int cci_thread_init (void) +{ + cc_int32 err = ccNoError; + + if (!err) { + err = cci_context_change_time_thread_init (); + } + + if (!err) { + err = cci_ipc_thread_init (); + } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cc_initialize (cc_context_t *out_context, + cc_int32 in_version, + cc_int32 *out_supported_version, + char const **out_vendor) +{ + cc_int32 err = ccNoError; + cci_context_t context = NULL; + static char *vendor_string = "MIT Kerberos CCAPI"; + + if (!out_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = CALL_INIT_FUNCTION (cci_thread_init); + } + + if (!err) { + switch (in_version) { + case ccapi_version_2: + err = CC_NOT_SUPP; + break; + + case ccapi_version_3: + case ccapi_version_4: + case ccapi_version_5: + case ccapi_version_6: + break; + + default: + err = ccErrBadAPIVersion; + break; + } + } + + if (!err) { + context = malloc (sizeof (*context)); + if (context) { + *context = cci_context_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + context->functions = malloc (sizeof (*context->functions)); + if (context->functions) { + *context->functions = cci_context_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + context->identifier = cci_identifier_uninitialized; + + *out_context = (cc_context_t) context; + context = NULL; /* take ownership */ + + if (out_supported_version) { + *out_supported_version = ccapi_version_max; + } + + if (out_vendor) { + *out_vendor = vendor_string; + } + } + + ccapi_context_release ((cc_context_t) context); + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_release (cc_context_t in_context) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + + if (!in_context) { err = ccErrBadParam; } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_release_msg_id, + context->identifier, + NULL, + NULL); + } + + if (!err) { + cci_identifier_release (context->identifier); + free (context->functions); + free (context); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_get_change_time (cc_context_t in_context, + cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t reply = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_change_time) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_get_change_time_msg_id, + context->identifier, + NULL, &reply); + } + + if (!err && cci_stream_size (reply) > 0) { + cc_time_t change_time = 0; + + /* got a response from the server */ + err = cci_stream_read_time (reply, &change_time); + + if (!err) { + err = cci_context_change_time_update (context->identifier, + change_time); + } + } + + if (!err) { + err = cci_context_change_time_get (out_change_time); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_wait_for_change (cc_context_t in_context) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_wait_for_change_msg_id, + context->identifier, + NULL, NULL); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context, + cc_string_t *out_name) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t reply = NULL; + char *reply_name = NULL; + char *name = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!out_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_get_default_ccache_name_msg_id, + context->identifier, + NULL, + &reply); + } + + if (!err) { + if (cci_stream_size (reply) > 0) { + /* got a response from the server */ + err = cci_stream_read_string (reply, &reply_name); + + if (!err) { + name = reply_name; + } + } else { + name = k_cci_context_initial_ccache_name; + } + } + + if (!err) { + err = cci_string_new (out_name, name); + } + + cci_stream_release (reply); + free (reply_name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_open_ccache (cc_context_t in_context, + const char *in_name, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_string (request, in_name); + } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_open_ccache_msg_id, + context->identifier, + request, + &reply); + } + + if (!err && !(cci_stream_size (reply) > 0)) { + err = ccErrCCacheNotFound; + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_open_default_ccache_msg_id, + context->identifier, + NULL, + &reply); + } + + if (!err && !(cci_stream_size (reply) > 0)) { + err = ccErrCCacheNotFound; + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_create_ccache (cc_context_t in_context, + const char *in_name, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_string (request, in_name); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_cred_vers); + } + + if (!err) { + err = cci_stream_write_string (request, in_principal); + } + + if (!err) { + err = cci_context_sync (context, 1); + } + + if (!err) { + err = cci_ipc_send (cci_context_create_ccache_msg_id, + context->identifier, + request, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_cred_vers); + } + + if (!err) { + err = cci_stream_write_string (request, in_principal); + } + + if (!err) { + err = cci_context_sync (context, 1); + } + + if (!err) { + err = cci_ipc_send (cci_context_create_default_ccache_msg_id, + context->identifier, + request, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_cred_vers); + } + + if (!err) { + err = cci_stream_write_string (request, in_principal); + } + + if (!err) { + err = cci_context_sync (context, 1); + } + + if (!err) { + err = cci_ipc_send (cci_context_create_new_ccache_msg_id, + context->identifier, + request, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_ccache_new (out_ccache, identifier); + } + + cci_identifier_release (identifier); + cci_stream_release (reply); + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context, + cc_ccache_iterator_t *out_iterator) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_ipc_send_no_launch (cci_context_new_ccache_iterator_msg_id, + context->identifier, + NULL, + &reply); + } + + if (!err) { + if (cci_stream_size (reply) > 0) { + err = cci_identifier_read (&identifier, reply); + } else { + identifier = cci_identifier_uninitialized; + } + } + + if (!err) { + err = cci_ccache_iterator_new (out_iterator, identifier); + } + + cci_stream_release (reply); + cci_identifier_release (identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_lock (cc_context_t in_context, + cc_uint32 in_lock_type, + cc_uint32 in_block) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_lock_type); + } + + if (!err) { + err = cci_stream_write_uint32 (request, in_block); + } + + if (!err) { + err = cci_context_sync (context, 1); + } + + if (!err) { + err = cci_ipc_send (cci_context_lock_msg_id, + context->identifier, + request, + NULL); + } + + cci_stream_release (request); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_unlock (cc_context_t in_context) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 1); + } + + if (!err) { + err = cci_ipc_send (cci_context_unlock_msg_id, + context->identifier, + NULL, + NULL); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_context_compare (cc_context_t in_context, + cc_context_t in_compare_to_context, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_context_t compare_to_context = (cci_context_t) in_compare_to_context; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_context) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_context_sync (context, 0); + } + + if (!err) { + err = cci_context_sync (compare_to_context, 0); + } + + if (!err) { + /* If both contexts can't talk to the server, then + * we assume they are equivalent */ + err = cci_identifier_compare (context->identifier, + compare_to_context->identifier, + out_equal); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 cci_context_sync (cci_context_t in_context, + cc_uint32 in_launch) +{ + cc_int32 err = ccNoError; + cci_context_t context = (cci_context_t) in_context; + cci_stream_t reply = NULL; + cci_identifier_t new_identifier = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Use the uninitialized identifier because we may be talking */ + /* to a different server which would reject our identifier and */ + /* the point of this message is to sync with the server's id */ + if (in_launch) { + err = cci_ipc_send (cci_context_sync_msg_id, + cci_identifier_uninitialized, + NULL, + &reply); + } else { + err = cci_ipc_send_no_launch (cci_context_sync_msg_id, + cci_identifier_uninitialized, + NULL, + &reply); + } + } + + if (!err) { + if (cci_stream_size (reply) > 0) { + err = cci_identifier_read (&new_identifier, reply); + } else { + new_identifier = cci_identifier_uninitialized; + } + } + + if (!err) { + cc_uint32 equal = 0; + + err = cci_identifier_compare (context->identifier, new_identifier, &equal); + + if (!err && !equal) { + if (context->identifier) { + cci_identifier_release (context->identifier); + } + context->identifier = new_identifier; + new_identifier = NULL; /* take ownership */ + } + } + + if (!err && context->synchronized) { + err = cci_context_change_time_sync (context->identifier); + } + + if (!err && !context->synchronized) { + /* Keep state about whether this is the first call to avoid always */ + /* modifying the global change time on the context's first ipc call. */ + context->synchronized = 1; + } + + cci_identifier_release (new_identifier); + cci_stream_release (reply); + + return cci_check_error (err); +} + diff --git a/src/ccapi/lib/ccapi_context.h b/src/ccapi/lib/ccapi_context.h new file mode 100644 index 000000000..4ac0b06c3 --- /dev/null +++ b/src/ccapi/lib/ccapi_context.h @@ -0,0 +1,78 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CONTEXT_H +#define CCAPI_CONTEXT_H + +#include "cci_common.h" + +cc_int32 ccapi_context_release (cc_context_t in_context); + +cc_int32 ccapi_context_get_change_time (cc_context_t in_context, + cc_time_t *out_time); + +cc_int32 ccapi_context_wait_for_change (cc_context_t in_context); + +cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context, + cc_string_t *out_name); + +cc_int32 ccapi_context_open_ccache (cc_context_t in_context, + const char *in_name, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_context_create_ccache (cc_context_t in_context, + const char *in_name, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache); + +cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context, + cc_ccache_iterator_t *out_iterator); + +cc_int32 ccapi_context_lock (cc_context_t in_context, + cc_uint32 in_lock_type, + cc_uint32 in_block); + +cc_int32 ccapi_context_unlock (cc_context_t in_context); + +cc_int32 ccapi_context_compare (cc_context_t in_context, + cc_context_t in_compare_to_context, + cc_uint32 *out_equal); + +#endif /* CCAPI_CONTEXT_H */ diff --git a/src/ccapi/lib/ccapi_context_change_time.c b/src/ccapi/lib/ccapi_context_change_time.c new file mode 100644 index 000000000..fb5b7ddae --- /dev/null +++ b/src/ccapi/lib/ccapi_context_change_time.c @@ -0,0 +1,200 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_context_change_time.h" +#include "cci_common.h" + +#include "k5-thread.h" + +static cci_identifier_t g_change_time_identifer = NULL; +static cc_time_t g_change_time = 0; +static cc_time_t g_change_time_offset = 0; +static k5_mutex_t g_change_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_context_change_time_thread_init (void) +{ + return k5_mutex_finish_init(&g_change_time_mutex); +} + +/* ------------------------------------------------------------------------ */ +/* WARNING! Mutex must be locked when calling this! */ + +static cc_int32 cci_context_change_time_update_identifier (cci_identifier_t in_new_identifier, + cc_uint32 *out_server_ids_match, + cc_uint32 *out_old_server_running, + cc_uint32 *out_new_server_running) +{ + cc_int32 err = ccNoError; + cc_uint32 server_ids_match = 0; + cc_uint32 old_server_running = 0; + cc_uint32 new_server_running = 0; + + if (!in_new_identifier) { err = cci_check_error (err); } + + if (!err && !g_change_time_identifer) { + g_change_time_identifer = cci_identifier_uninitialized; + } + + if (!err) { + err = cci_identifier_compare_server_id (g_change_time_identifer, + in_new_identifier, + &server_ids_match); + } + + if (!err && out_old_server_running) { + err = cci_identifier_is_initialized (g_change_time_identifer, &old_server_running); + } + + if (!err && out_new_server_running) { + err = cci_identifier_is_initialized (in_new_identifier, &new_server_running); + } + + if (!err && !server_ids_match) { + cci_identifier_t new_change_time_identifer = NULL; + + err = cci_identifier_copy (&new_change_time_identifer, in_new_identifier); + + if (!err) { + /* Save the new identifier */ + if (g_change_time_identifer) { + cci_identifier_release (g_change_time_identifer); + } + g_change_time_identifer = new_change_time_identifer; + } + } + + if (!err) { + if (out_server_ids_match ) { *out_server_ids_match = server_ids_match; } + if (out_old_server_running) { *out_old_server_running = old_server_running; } + if (out_new_server_running) { *out_new_server_running = new_server_running; } + } + + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_context_change_time_get (cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + + err = k5_mutex_lock (&g_change_time_mutex); + + if (!err) { + *out_change_time = g_change_time + g_change_time_offset; + k5_mutex_unlock (&g_change_time_mutex); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier, + cc_time_t in_new_change_time) +{ + cc_int32 err = ccNoError; + cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex); + + if (!err) { + if (!in_identifier) { err = cci_check_error (err); } + } + + if (!err) { + if (g_change_time < in_new_change_time) { + /* Only update if it increases the time. May be a different server. */ + g_change_time = in_new_change_time; + cci_debug_printf ("%s: setting change time to %d", + __FUNCTION__, in_new_change_time); + } + } + + if (!err) { + err = cci_context_change_time_update_identifier (in_identifier, + NULL, NULL, NULL); + } + + if (!lock_err) { + k5_mutex_unlock (&g_change_time_mutex); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier) +{ + cc_int32 err = ccNoError; + cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex); + cc_uint32 server_ids_match = 0; + cc_uint32 server_was_running = 0; + cc_uint32 server_is_running = 0; + + if (!err) { + if (!in_new_identifier) { err = cci_check_error (err); } + } + + if (!err) { + err = cci_context_change_time_update_identifier (in_new_identifier, + &server_ids_match, + &server_was_running, + &server_is_running); + } + + if (!err && !server_ids_match) { + /* Increment the change time so callers re-read */ + g_change_time_offset++; + + /* If the server died, absorb the offset */ + if (server_was_running && !server_is_running) { + cc_time_t now = time (NULL); + + g_change_time += g_change_time_offset; + g_change_time_offset = 0; + + /* Make sure the change time increases, ideally with the current time */ + g_change_time = (g_change_time < now) ? now : g_change_time; + } + + cci_debug_printf ("%s noticed server changed (" + "server_was_running = %d; server_is_running = %d; " + "g_change_time = %d; g_change_time_offset = %d", + __FUNCTION__, server_was_running, server_is_running, + g_change_time, g_change_time_offset); + } + + if (!lock_err) { + k5_mutex_unlock (&g_change_time_mutex); + } + + return err; +} diff --git a/src/ccapi/lib/ccapi_context_change_time.h b/src/ccapi/lib/ccapi_context_change_time.h new file mode 100644 index 000000000..536c492d8 --- /dev/null +++ b/src/ccapi/lib/ccapi_context_change_time.h @@ -0,0 +1,41 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CONTEXT_CHANGE_TIME_H +#define CCAPI_CONTEXT_CHANGE_TIME_H + +#include "cci_common.h" + +cc_int32 cci_context_change_time_thread_init (void); + +cc_int32 cci_context_change_time_get (cc_time_t *out_change_time); + +cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier, + cc_time_t in_new_change_time); + +cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier); + +#endif /* CCAPI_CONTEXT_CHANGE_TIME_H */ diff --git a/src/ccapi/lib/ccapi_credentials.c b/src/ccapi/lib/ccapi_credentials.c new file mode 100644 index 000000000..4e1f48e01 --- /dev/null +++ b/src/ccapi/lib/ccapi_credentials.c @@ -0,0 +1,166 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_credentials.h" + +#include "ccapi_string.h" + +/* ------------------------------------------------------------------------ */ + +typedef struct cci_credentials_d { + cc_credentials_union *data; + cc_credentials_f *functions; +#if TARGET_OS_MAC + cc_credentials_f *vector_functions; +#endif + cci_identifier_t identifier; +} *cci_credentials_t; + +/* ------------------------------------------------------------------------ */ + +struct cci_credentials_d cci_credentials_initializer = { + NULL, + NULL + VECTOR_FUNCTIONS_INITIALIZER, + NULL +}; + +cc_credentials_f cci_credentials_f_initializer = { + ccapi_credentials_release, + ccapi_credentials_compare +}; + +cc_credentials_union cci_cred_union_initializer = { + 0, + { NULL } +}; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_read (cc_credentials_t *out_credentials, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + cci_credentials_t credentials = NULL; + + if (!out_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + credentials = malloc (sizeof (*credentials)); + if (credentials) { + *credentials = cci_credentials_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + credentials->functions = malloc (sizeof (*credentials->functions)); + if (credentials->functions) { + *credentials->functions = cci_credentials_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_identifier_read (&credentials->identifier, in_stream); + } + + if (!err) { + err = cci_cred_union_read (&credentials->data, in_stream); + } + + if (!err) { + *out_credentials = (cc_credentials_t) credentials; + credentials = NULL; /* take ownership */ + } + + if (credentials) { ccapi_credentials_release ((cc_credentials_t) credentials); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_write (cc_credentials_t in_credentials, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + cci_credentials_t credentials = (cci_credentials_t) in_credentials; + + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (credentials->identifier, in_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials, + cc_credentials_t in_compare_to_credentials, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_credentials_t credentials = (cci_credentials_t) in_credentials; + cci_credentials_t compare_to_credentials = (cci_credentials_t) in_compare_to_credentials; + + if (!in_credentials ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_credentials) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (credentials->identifier, + compare_to_credentials->identifier, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials) +{ + cc_int32 err = ccNoError; + cci_credentials_t credentials = (cci_credentials_t) io_credentials; + + if (!io_credentials) { err = ccErrBadParam; } + + if (!err) { + cci_cred_union_release (credentials->data); + free ((char *) credentials->functions); + cci_identifier_release (credentials->identifier); + free (credentials); + } + + return err; +} diff --git a/src/ccapi/lib/ccapi_credentials.h b/src/ccapi/lib/ccapi_credentials.h new file mode 100644 index 000000000..bde0b2c03 --- /dev/null +++ b/src/ccapi/lib/ccapi_credentials.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CREDENTIALS_H +#define CCAPI_CREDENTIALS_H + +#include "cci_common.h" + +cc_int32 cci_credentials_read (cc_credentials_t *out_credentials, + cci_stream_t in_stream); + +cc_int32 cci_credentials_write (cc_credentials_t in_credentials, + cci_stream_t in_stream); + +cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials, + cc_credentials_t in_compare_to_credentials, + cc_uint32 *out_equal); + +cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials); + +#endif /* CCAPI_CREDENTIALS_H */ diff --git a/src/ccapi/lib/ccapi_credentials_iterator.c b/src/ccapi/lib/ccapi_credentials_iterator.c new file mode 100644 index 000000000..a99e52b49 --- /dev/null +++ b/src/ccapi/lib/ccapi_credentials_iterator.c @@ -0,0 +1,194 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_credentials_iterator.h" +#include "ccapi_credentials.h" +#include "ccapi_ipc.h" + +/* ------------------------------------------------------------------------ */ + +typedef struct cci_credentials_iterator_d { + cc_credentials_iterator_f *functions; +#if TARGET_OS_MAC + cc_credentials_iterator_f *vector_functions; +#endif + cci_identifier_t identifier; +} *cci_credentials_iterator_t; + +/* ------------------------------------------------------------------------ */ + +struct cci_credentials_iterator_d cci_credentials_iterator_initializer = { + NULL + VECTOR_FUNCTIONS_INITIALIZER, + NULL +}; + +cc_credentials_iterator_f cci_credentials_iterator_f_initializer = { + ccapi_credentials_iterator_release, + ccapi_credentials_iterator_next, + ccapi_credentials_iterator_clone +}; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = NULL; + + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + credentials_iterator = malloc (sizeof (*credentials_iterator)); + if (credentials_iterator) { + *credentials_iterator = cci_credentials_iterator_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + credentials_iterator->functions = malloc (sizeof (*credentials_iterator->functions)); + if (credentials_iterator->functions) { + *credentials_iterator->functions = cci_credentials_iterator_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_identifier_copy (&credentials_iterator->identifier, in_identifier); + } + + if (!err) { + *out_credentials_iterator = (cc_credentials_iterator_t) credentials_iterator; + credentials_iterator = NULL; /* take ownership */ + } + + if (credentials_iterator) { ccapi_credentials_iterator_release ((cc_credentials_iterator_t) credentials_iterator); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; + + if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (credentials_iterator->identifier, in_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator; + + if (!io_credentials_iterator) { err = ccErrBadParam; } + + if (!err) { + free ((char *) credentials_iterator->functions); + cci_identifier_release (credentials_iterator->identifier); + free (credentials_iterator); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_t *out_credentials) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; + cci_stream_t reply = NULL; + + if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_credentials_iterator_next_msg_id, + credentials_iterator->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_credentials_read (out_credentials, reply); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; + cci_stream_t reply = NULL; + cci_identifier_t identifier = NULL; + + if (!in_credentials_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ipc_send (cci_credentials_iterator_next_msg_id, + credentials_iterator->identifier, + NULL, + &reply); + } + + if (!err) { + err = cci_identifier_read (&identifier, reply); + } + + if (!err) { + err = cci_credentials_iterator_new (out_credentials_iterator, identifier); + } + + cci_stream_release (reply); + cci_identifier_release (identifier); + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_credentials_iterator.h b/src/ccapi/lib/ccapi_credentials_iterator.h new file mode 100644 index 000000000..7ffbd2301 --- /dev/null +++ b/src/ccapi/lib/ccapi_credentials_iterator.h @@ -0,0 +1,46 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_CREDENTIALS_ITERATOR_H +#define CCAPI_CREDENTIALS_ITERATOR_H + +#include "cci_common.h" + +cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator, + cci_identifier_t in_identifier); + +cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator, + cci_stream_t in_stream); + +cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator); + +cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_t *out_credentials); + +cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_iterator_t *out_credentials_iterator); + +#endif /* CCAPI_CREDENTIALS_ITERATOR_H */ diff --git a/src/ccapi/lib/ccapi_err.et b/src/ccapi/lib/ccapi_err.et new file mode 100644 index 000000000..44cd2d0b5 --- /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 000000000..4d2e4314d --- /dev/null +++ b/src/ccapi/lib/ccapi_ipc.c @@ -0,0 +1,113 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_ipc.h" +#include "ccapi_os_ipc.h" + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ipc_thread_init (void) +{ + return cci_os_ipc_thread_init (); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 _cci_ipc_send (enum cci_msg_id_t in_request_name, + cc_int32 in_launch_server, + cci_identifier_t in_identifier, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; + cc_int32 reply_error = 0; + + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + /* in_request_data may be NULL */ + /* out_reply_data may be NULL */ + + if (!err) { + err = cci_message_new_request_header (&request, + in_request_name, + in_identifier); + } + + if (!err && in_request_data) { + err = cci_stream_write (request, + cci_stream_data (in_request_data), + cci_stream_size (in_request_data)); + } + + if (!err) { + err = cci_os_ipc (in_launch_server, request, &reply); + + if (!err && cci_stream_size (reply) > 0) { + err = cci_message_read_reply_header (reply, &reply_error); + } + } + + if (!err && reply_error) { + err = reply_error; + } + + if (!err && out_reply_data) { + *out_reply_data = reply; + reply = NULL; /* take ownership */ + } + + cci_stream_release (request); + cci_stream_release (reply); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + return cci_check_error (_cci_ipc_send (in_request_name, 1, + in_identifier, + in_request_data, + out_reply_data)); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + return cci_check_error (_cci_ipc_send (in_request_name, 0, + in_identifier, + in_request_data, + out_reply_data)); +} diff --git a/src/ccapi/lib/ccapi_ipc.h b/src/ccapi/lib/ccapi_ipc.h new file mode 100644 index 000000000..73c5b2497 --- /dev/null +++ b/src/ccapi/lib/ccapi_ipc.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_IPC_H +#define CCAPI_IPC_H + +#include "cci_common.h" + +cc_int32 cci_ipc_thread_init (void); + +cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name, + cci_identifier_t in_identifier, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +#endif /* CCAPI_IPC_H */ diff --git a/src/ccapi/lib/ccapi_os_ipc.h b/src/ccapi/lib/ccapi_os_ipc.h new file mode 100644 index 000000000..8cce06c60 --- /dev/null +++ b/src/ccapi/lib/ccapi_os_ipc.h @@ -0,0 +1,38 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_OS_IPC_H +#define CCAPI_OS_IPC_H + +#include "cci_common.h" + +inline cc_int32 cci_os_ipc_thread_init (void); + +cc_int32 cci_os_ipc (cc_int32 in_launch_server, + cci_stream_t in_request_stream, + cci_stream_t *out_reply_stream); + +#endif /* CCAPI_OS_IPC_H */ diff --git a/src/ccapi/lib/ccapi_string.c b/src/ccapi/lib/ccapi_string.c new file mode 100644 index 000000000..4acd9a89d --- /dev/null +++ b/src/ccapi/lib/ccapi_string.c @@ -0,0 +1,104 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_string.h" + +/* ------------------------------------------------------------------------ */ + +cc_string_d cci_string_d_initializer = { + NULL, + NULL + VECTOR_FUNCTIONS_INITIALIZER }; + +cc_string_f cci_string_f_initializer = { + ccapi_string_release +}; + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_string_new (cc_string_t *out_string, + char *in_cstring) +{ + cc_int32 err = ccNoError; + cc_string_t string = NULL; + + if (!out_string) { err = cci_check_error (ccErrBadParam); } + if (!in_cstring) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + string = malloc (sizeof (*string)); + if (string) { + *string = cci_string_d_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + string->functions = malloc (sizeof (*string->functions)); + if (string->functions) { + *((cc_string_f *) string->functions) = cci_string_f_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + string->data = malloc (strlen (in_cstring) + 1); + if (string->data) { + strcpy ((char *)string->data, in_cstring); + } else { + err = cci_check_error (ccErrNoMem); + } + + } + + if (!err) { + *out_string = string; + string = NULL; /* take ownership */ + } + + if (string) { ccapi_string_release (string); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccapi_string_release (cc_string_t in_string) +{ + cc_int32 err = ccNoError; + + if (!in_string) { err = ccErrBadParam; } + + if (!err) { + free ((char *) in_string->data); + free ((char *) in_string->functions); + free (in_string); + } + + return err; +} diff --git a/src/ccapi/lib/ccapi_string.h b/src/ccapi/lib/ccapi_string.h new file mode 100644 index 000000000..dec7a7cc7 --- /dev/null +++ b/src/ccapi/lib/ccapi_string.h @@ -0,0 +1,37 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCAPI_STRING_H +#define CCAPI_STRING_H + +#include "cci_common.h" + +cc_int32 cci_string_new (cc_string_t *out_string, + char *in_cstring); + +cc_int32 ccapi_string_release (cc_string_t in_string); + +#endif /* CCAPI_STRING_H */ diff --git a/src/ccapi/lib/ccapi_v2.c b/src/ccapi/lib/ccapi_v2.c new file mode 100644 index 000000000..0036c70d3 --- /dev/null +++ b/src/ccapi/lib/ccapi_v2.c @@ -0,0 +1,232 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "cci_common.h" +#include + +/* ------------------------------------------------------------------------ */ + +cc_result cc_shutdown (apiCB **io_context) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_NC_info (apiCB *in_context, + infoNC ***out_info) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_change_time (apiCB *in_context, + cc_time_t *out_change_time) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cc_open (apiCB *in_context, + const char *in_name, + cc_int32 in_version, + cc_uint32 in_flags, + ccache_p **out_ccache) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_create (apiCB *in_context, + const char *in_name, + const char *in_principal, + cc_int32 in_version, + cc_uint32 in_flags, + ccache_p **out_ccache) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_close (apiCB *in_context, + ccache_p **io_ccache) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_destroy (apiCB *in_context, + ccache_p **io_ccache) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_NCs_begin (apiCB *in_context, + ccache_cit **out_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +// CCache iterators need to return some ccaches twice (when v3 ccache has +// two kinds of credentials). To do that, we use a single v3 iterator, but +// sometimes don't advance it. + +cc_result cc_seq_fetch_NCs_next (apiCB *in_context, + ccache_p **out_ccache, + ccache_cit *in_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_NCs_end (apiCB *in_context, + ccache_cit **io_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_name (apiCB *in_context, + ccache_p *in_ccache, + char **out_name) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_cred_version (apiCB *in_context, + ccache_p *in_ccache, + cc_int32 *out_version) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_set_principal (apiCB *in_context, + ccache_p *io_ccache, + cc_int32 in_version, + char *in_principal) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_principal (apiCB *in_context, + ccache_p *in_ccache, + char **out_principal) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_store (apiCB *in_context, + ccache_p *io_ccache, + cred_union in_credentials) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_remove_cred (apiCB *in_context, + ccache_p *in_ccache, + cred_union in_credentials) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_creds_begin (apiCB *in_context, + const ccache_p *in_ccache, + ccache_cit **out_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_creds_next (apiCB *in_context, + cred_union **out_creds, + ccache_cit *in_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_creds_end (apiCB *in_context, + ccache_cit **io_iterator) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_free_principal (apiCB *in_context, + char **io_principal) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_free_name (apiCB *in_context, + char **io_name) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_free_creds (apiCB *in_context, + cred_union **io_credentials) +{ + return CC_NOT_SUPP; +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_free_NC_info (apiCB *in_context, + infoNC ***io_info) +{ + return CC_NOT_SUPP; +} diff --git a/src/ccapi/lib/ccapi_v2.exports b/src/ccapi/lib/ccapi_v2.exports new file mode 100644 index 000000000..efa9fcec7 --- /dev/null +++ b/src/ccapi/lib/ccapi_v2.exports @@ -0,0 +1,23 @@ +cc_shutdown +cc_create +cc_close +cc_destroy +cc_get_change_time +cc_open +cc_store +cc_remove_cred +cc_set_principal +cc_get_principal +cc_get_cred_version +cc_get_name +cc_seq_fetch_NCs_begin +cc_seq_fetch_NCs_next +cc_seq_fetch_NCs_end +cc_seq_fetch_creds_begin +cc_seq_fetch_creds_next +cc_seq_fetch_creds_end +cc_get_NC_info +cc_free_principal +cc_free_name +cc_free_creds +cc_free_NC_info diff --git a/src/ccapi/lib/mac/ccapi_os_ipc.c b/src/ccapi/lib/mac/ccapi_os_ipc.c new file mode 100644 index 000000000..ea3b548f8 --- /dev/null +++ b/src/ccapi/lib/mac/ccapi_os_ipc.c @@ -0,0 +1,266 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_os_ipc.h" + +#include +#include "cci_mig_request.h" +#include "cci_mig_replyServer.h" +#include "k5-thread.h" + +#define cci_server_bundle_id "edu.mit.Kerberos.CCacheServer" +#define cci_server_path "/System/Library/CoreServices/CCacheServer.app/Contents/MacOS/CCacheServer" + +static pthread_key_t g_request_port_key = 0; +static pthread_key_t g_reply_stream_key = 0; +static pthread_key_t g_server_died_key = 0; + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 cci_os_ipc_thread_init (void) +{ + cc_int32 err = ccNoError; + + err = pthread_key_create (&g_request_port_key, free); + + if (!err) { + err = pthread_key_create (&g_reply_stream_key, NULL); + } + + if (!err) { + err = pthread_key_create (&g_server_died_key, NULL); + } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static boolean_t cci_server_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + cc_int32 *server_died = pthread_getspecific (g_server_died_key); + if (!server_died) { + *server_died = 1; + } + + handled = 1; /* server died */ + } + + if (!handled) { + handled = cci_server (request, reply); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t cci_mipc_reply (mach_port_t in_reply_port, + cci_mipc_inl_reply_t in_inl_reply, + mach_msg_type_number_t in_inl_replyCnt, + cci_mipc_ool_reply_t in_ool_reply, + mach_msg_type_number_t in_ool_replyCnt) +{ + kern_return_t err = KERN_SUCCESS; + cci_stream_t reply_stream = NULL; + + if (!err) { + reply_stream = pthread_getspecific (g_reply_stream_key); + if (!reply_stream) { err = cci_check_error (ccErrBadInternalMessage); } + } + + if (!err) { + if (in_inl_replyCnt) { + err = cci_stream_write (reply_stream, in_inl_reply, in_inl_replyCnt); + + } else if (in_ool_replyCnt) { + err = cci_stream_write (reply_stream, in_ool_reply, in_ool_replyCnt); + + } else { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_os_ipc (cc_int32 in_launch_server, + cci_stream_t in_request_stream, + cci_stream_t *out_reply_stream) +{ + cc_int32 err = ccNoError; + cc_int32 done = 0; + cc_int32 try_count = 0; + cc_int32 server_died = 0; + mach_port_t server_port = MACH_PORT_NULL; + mach_port_t *request_port = NULL; + mach_port_t reply_port = MACH_PORT_NULL; + const char *inl_request = NULL; /* char * so we can pass the buffer in directly */ + mach_msg_type_number_t inl_request_length = 0; + cci_mipc_ool_request_t ool_request = NULL; + mach_msg_type_number_t ool_request_length = 0; + cci_stream_t reply_stream = NULL; + + if (!in_request_stream) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = kipc_client_lookup_server (cci_server_bundle_id, cci_server_path, + in_launch_server, &server_port); + } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t request_length = cci_stream_size (in_request_stream); + + if (request_length > kCCAPIMaxILMsgSize) { + cci_debug_printf ("%s choosing out of line buffer (size is %d)", + __FUNCTION__, request_length); + + err = vm_read (mach_task_self (), + (vm_address_t) cci_stream_data (in_request_stream), request_length, + (vm_address_t *) &ool_request, &ool_request_length); + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, request_length); + + inl_request_length = request_length; + inl_request = cci_stream_data (in_request_stream); + } + } + + if (!err) { + request_port = pthread_getspecific (g_request_port_key); + + if (!request_port) { + request_port = malloc (sizeof (mach_port_t)); + if (!request_port) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + *request_port = MACH_PORT_NULL; + err = pthread_setspecific (g_request_port_key, request_port); + } + } + } + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port); + } + + while (!err && !done) { + if (!err && !MACH_PORT_VALID (*request_port)) { + err = cci_mipc_create_client_connection (server_port, request_port); + } + + if (!err) { + err = cci_mipc_request (*request_port, reply_port, + inl_request, inl_request_length, + ool_request, ool_request_length); + + } + + if (err == MACH_SEND_INVALID_DEST) { + if (request_port && MACH_PORT_VALID (*request_port)) { + mach_port_mod_refs (mach_task_self(), *request_port, MACH_PORT_RIGHT_SEND, -1 ); + *request_port = MACH_PORT_NULL; + } + + if (try_count < 2) { + try_count++; + err = ccNoError; + } + } else { + /* Talked to server, though we may have gotten an error */ + done = 1; + + /* Because we use ",dealloc" ool_request will be freed by mach. + * Don't double free it. */ + ool_request = NULL; + ool_request_length = 0; + } + } + + if (!err) { + err = cci_stream_new (&reply_stream); + } + + if (!err) { + err = pthread_setspecific (g_reply_stream_key, reply_stream); + } + + if (!err) { + err = pthread_setspecific (g_server_died_key, &server_died); + } + + if (!err) { + mach_port_t old_notification_target = MACH_PORT_NULL; + + /* request no-senders notification so we can get a message when server dies */ + err = mach_port_request_notification (mach_task_self (), reply_port, + MACH_NOTIFY_NO_SENDERS, 1, reply_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &old_notification_target ); + } + + if (!err) { + err = mach_msg_server_once (cci_server_demux, kkipc_max_message_size, + reply_port, MACH_MSG_TIMEOUT_NONE); + } + + if (!err && server_died) { + err = cci_check_error (ccErrServerUnavailable); + } + + if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { + err = ccNoError; /* If the server is not running just return an empty stream. */ + } + + if (!err) { + *out_reply_stream = reply_stream; + reply_stream = NULL; + } + + pthread_setspecific (g_reply_stream_key, NULL); + pthread_setspecific (g_server_died_key, NULL); + if (MACH_PORT_VALID (reply_port)) { mach_port_deallocate (mach_task_self (), reply_port); } + if (ool_request_length ) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); } + if (reply_stream ) { cci_stream_release (reply_stream); } + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/mac/ccapi_vector.c b/src/ccapi/lib/mac/ccapi_vector.c new file mode 100644 index 000000000..ea749c089 --- /dev/null +++ b/src/ccapi/lib/mac/ccapi_vector.c @@ -0,0 +1,839 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccapi_vector.h" + +#include "ccapi_context.h" +#include "ccapi_string.h" +#include "ccapi_ccache.h" +#include "ccapi_credentials.h" +#include "ccapi_ccache_iterator.h" +#include "ccapi_credentials_iterator.h" + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_string_functions (cc_string_t io_string) +{ + cc_string_f temp = *(io_string->functions); + *((cc_string_f *)io_string->functions) = *(io_string->vector_functions); + *((cc_string_f *)io_string->vector_functions) = temp; +} + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_context_functions (cc_context_t io_context) +{ + cc_context_f temp = *(io_context->functions); + *((cc_context_f *)io_context->functions) = *(io_context->vector_functions); + *((cc_context_f *)io_context->vector_functions) = temp; +} + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_ccache_functions (cc_ccache_t io_ccache) +{ + cc_ccache_f temp = *(io_ccache->functions); + *((cc_ccache_f *)io_ccache->functions) = *(io_ccache->vector_functions); + *((cc_ccache_f *)io_ccache->vector_functions) = temp; +} + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_credentials_functions (cc_credentials_t io_credentials) +{ + cc_credentials_f temp = *(io_credentials->functions); + *((cc_credentials_f *)io_credentials->functions) = *(io_credentials->otherFunctions); + *((cc_credentials_f *)io_credentials->otherFunctions) = temp; +} + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_ccache_iterator_functions (cc_ccache_iterator_t io_ccache_iterator) +{ + cc_ccache_iterator_f temp = *(io_ccache_iterator->functions); + *((cc_ccache_iterator_f *)io_ccache_iterator->functions) = *(io_ccache_iterator->vector_functions); + *((cc_ccache_iterator_f *)io_ccache_iterator->vector_functions) = temp; +} + +/* ------------------------------------------------------------------------ */ + +static void cci_swap_credentials_iterator_functions (cc_credentials_iterator_t io_credentials_iterator) +{ + cc_credentials_iterator_f temp = *(io_credentials_iterator->functions); + *((cc_credentials_iterator_f *)io_credentials_iterator->functions) = *(io_credentials_iterator->vector_functions); + *((cc_credentials_iterator_f *)io_credentials_iterator->vector_functions) = temp; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_initialize_vector (cc_context_t *out_context, + cc_int32 in_version, + cc_int32 *out_supported_version, + char const **out_vendor) +{ + return cc_initialize (out_context, in_version, out_supported_version, out_vendor); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_string_release_vector (cc_string_t in_string) +{ + cci_swap_string_functions (in_string); + return ccapi_string_release (in_string); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_release_vector (cc_context_t io_context) +{ + cci_swap_context_functions (io_context); + return ccapi_context_release (io_context); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_get_change_time_vector (cc_context_t in_context, + cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_get_change_time (in_context, out_change_time); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_get_default_ccache_name_vector (cc_context_t in_context, + cc_string_t *out_name) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_get_default_ccache_name (in_context, out_name); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_open_ccache_vector (cc_context_t in_context, + const char *in_name, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_open_ccache (in_context, in_name, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_open_default_ccache_vector (cc_context_t in_context, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_open_default_ccache (in_context, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_create_ccache_vector (cc_context_t in_context, + const char *in_name, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_create_ccache (in_context, in_name, in_cred_vers, in_principal, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_create_default_ccache_vector (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_create_default_ccache (in_context, in_cred_vers, in_principal, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_create_new_ccache_vector (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_create_new_ccache (in_context, in_cred_vers, in_principal, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_new_ccache_iterator_vector (cc_context_t in_context, + cc_ccache_iterator_t *out_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_new_ccache_iterator (in_context, out_iterator); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_lock_vector (cc_context_t in_context, + cc_uint32 in_lock_type, + cc_uint32 in_block) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_lock (in_context, in_lock_type, in_block); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_unlock_vector (cc_context_t in_context) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_unlock (in_context); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_context_compare_vector (cc_context_t in_context, + cc_context_t in_compare_to_context, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = ccapi_context_compare (in_context, in_compare_to_context, out_equal); + cci_swap_context_functions (in_context); + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_release_vector (cc_ccache_t io_ccache) +{ + cci_swap_ccache_functions (io_ccache); + return ccapi_ccache_release (io_ccache); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_destroy_vector (cc_ccache_t io_ccache) +{ + cci_swap_ccache_functions (io_ccache); + return ccapi_ccache_destroy (io_ccache); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_set_default_vector (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + err = ccapi_ccache_set_default (io_ccache); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 __cc_ccache_get_credentials_version_vector (cc_ccache_t in_ccache, + cc_uint32 *out_credentials_version) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_get_credentials_version (in_ccache, out_credentials_version); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_get_name_vector (cc_ccache_t in_ccache, + cc_string_t *out_name) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_get_name (in_ccache, out_name); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_get_principal_vector (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_string_t *out_principal) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_get_principal (in_ccache, in_credentials_version, out_principal); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_set_principal_vector (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + const char *in_principal) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + err = ccapi_ccache_set_principal (io_ccache, in_credentials_version, in_principal); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_store_credentials_vector (cc_ccache_t io_ccache, + const cc_credentials_union *in_credentials_union) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + err = ccapi_ccache_store_credentials (io_ccache, in_credentials_union); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_remove_credentials_vector (cc_ccache_t io_ccache, + cc_credentials_t in_credentials) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + cci_swap_credentials_functions (in_credentials); + err = ccapi_ccache_remove_credentials (io_ccache, in_credentials); + cci_swap_ccache_functions (io_ccache); + cci_swap_credentials_functions (in_credentials); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_new_credentials_iterator_vector (cc_ccache_t in_ccache, + cc_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_new_credentials_iterator (in_ccache, out_credentials_iterator); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_move_vector (cc_ccache_t io_source_ccache, + cc_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_source_ccache); + cci_swap_ccache_functions (io_destination_ccache); + err = ccapi_ccache_move (io_source_ccache, io_destination_ccache); + cci_swap_ccache_functions (io_source_ccache); + cci_swap_ccache_functions (io_destination_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_lock_vector (cc_ccache_t io_ccache, + cc_uint32 in_lock_type, + cc_uint32 in_block) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + err = ccapi_ccache_lock (io_ccache, in_lock_type, in_block); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_unlock_vector (cc_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (io_ccache); + err = ccapi_ccache_unlock (io_ccache); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_get_last_default_time_vector (cc_ccache_t in_ccache, + cc_time_t *out_last_default_time) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_get_last_default_time (in_ccache, out_last_default_time); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_get_change_time_vector (cc_ccache_t in_ccache, + cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + err = ccapi_ccache_get_change_time (in_ccache, out_change_time); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_compare_vector (cc_ccache_t in_ccache, + cc_ccache_t in_compare_to_ccache, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_functions (in_ccache); + cci_swap_ccache_functions (in_compare_to_ccache); + err = ccapi_ccache_compare (in_ccache, in_compare_to_ccache, out_equal); + cci_swap_ccache_functions (in_ccache); + cci_swap_ccache_functions (in_compare_to_ccache); + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_credentials_release_vector (cc_credentials_t io_credentials) +{ + cci_swap_credentials_functions (io_credentials); + return ccapi_credentials_release (io_credentials); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_credentials_compare_vector (cc_credentials_t in_credentials, + cc_credentials_t in_compare_to_credentials, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cci_swap_credentials_functions (in_credentials); + cci_swap_credentials_functions (in_compare_to_credentials); + err = ccapi_credentials_compare (in_credentials, in_compare_to_credentials, out_equal); + cci_swap_credentials_functions (in_credentials); + cci_swap_credentials_functions (in_compare_to_credentials); + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_iterator_release_vector (cc_ccache_iterator_t io_ccache_iterator) +{ + cci_swap_ccache_iterator_functions (io_ccache_iterator); + return ccapi_ccache_iterator_release (io_ccache_iterator); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_ccache_iterator_next_vector (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_ccache_iterator_functions (in_ccache_iterator); + err = ccapi_ccache_iterator_next (in_ccache_iterator, out_ccache); + cci_swap_ccache_iterator_functions (in_ccache_iterator); + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_credentials_iterator_release_vector (cc_credentials_iterator_t io_credentials_iterator) +{ + cci_swap_credentials_iterator_functions (io_credentials_iterator); + return ccapi_credentials_iterator_release (io_credentials_iterator); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_credentials_iterator_next_vector (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_t *out_credentials) +{ + cc_int32 err = ccNoError; + cci_swap_credentials_iterator_functions (in_credentials_iterator); + err = ccapi_credentials_iterator_next (in_credentials_iterator, out_credentials); + cci_swap_credentials_iterator_functions (in_credentials_iterator); + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_shutdown_vector (apiCB **io_context) +{ + cci_swap_context_functions (*io_context); + return cc_shutdown (io_context); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_get_NC_info_vector (apiCB *in_context, + infoNC ***out_info) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_get_NC_info (in_context, out_info); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_get_change_time_vector (apiCB *in_context, + cc_time_t *out_change_time) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_get_change_time (in_context, out_change_time); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_open_vector (apiCB *in_context, + const char *in_name, + cc_int32 in_version, + cc_uint32 in_flags, + ccache_p **out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_open (in_context, in_name, in_version, in_flags, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_create_vector (apiCB *in_context, + const char *in_name, + const char *in_principal, + cc_int32 in_version, + cc_uint32 in_flags, + ccache_p **out_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_create (in_context, in_name, in_principal, in_version, in_flags, out_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_close_vector (apiCB *in_context, + ccache_p **io_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (*io_ccache); + err = cc_close (in_context, io_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_destroy_vector (apiCB *in_context, + ccache_p **io_ccache) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (*io_ccache); + err = cc_destroy (in_context, io_ccache); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_NCs_begin_vector (apiCB *in_context, + ccache_cit **out_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_seq_fetch_NCs_begin (in_context, out_iterator); + cci_swap_context_functions (in_context); + return err; +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_NCs_next_vector (apiCB *in_context, + ccache_p **out_ccache, + ccache_cit *in_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator); + err = cc_seq_fetch_NCs_next (in_context, out_ccache, in_iterator); + cci_swap_context_functions (in_context); + cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_NCs_end_vector (apiCB *in_context, + ccache_cit **io_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_iterator_functions ((ccache_cit_ccache *) *io_iterator); + err = cc_seq_fetch_NCs_end (in_context, io_iterator); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_get_name_vector (apiCB *in_context, + ccache_p *in_ccache, + char **out_name) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + err = cc_get_name (in_context, in_ccache, out_name); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_get_cred_version_vector (apiCB *in_context, + ccache_p *in_ccache, + cc_int32 *out_version) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + err = cc_get_cred_version (in_context, in_ccache, out_version); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_set_principal_vector (apiCB *in_context, + ccache_p *io_ccache, + cc_int32 in_version, + char *in_principal) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (io_ccache); + err = cc_set_principal (in_context, io_ccache, in_version, in_principal); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_get_principal_vector (apiCB *in_context, + ccache_p *in_ccache, + char **out_principal) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + err = cc_get_principal (in_context, in_ccache, out_principal); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_store_vector (apiCB *in_context, + ccache_p *io_ccache, + cred_union in_credentials) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (io_ccache); + err = cc_store (in_context, io_ccache, in_credentials); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (io_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_remove_cred_vector (apiCB *in_context, + ccache_p *in_ccache, + cred_union in_credentials) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + err = cc_remove_cred (in_context, in_ccache, in_credentials); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions (in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_creds_begin_vector (apiCB *in_context, + const ccache_p *in_ccache, + ccache_cit **out_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_ccache_functions ((ccache_p *)in_ccache); + err = cc_seq_fetch_creds_begin (in_context, in_ccache, out_iterator); + cci_swap_context_functions (in_context); + cci_swap_ccache_functions ((ccache_p *)in_ccache); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_creds_next_vector (apiCB *in_context, + cred_union **out_creds, + ccache_cit *in_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator); + err = cc_seq_fetch_creds_next (in_context, out_creds, in_iterator); + cci_swap_context_functions (in_context); + cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_seq_fetch_creds_end_vector (apiCB *in_context, + ccache_cit **io_iterator) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + cci_swap_credentials_iterator_functions ((ccache_cit_creds *) *io_iterator); + err = cc_seq_fetch_creds_end (in_context, io_iterator); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_free_principal_vector (apiCB *in_context, + char **io_principal) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_free_principal (in_context, io_principal); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_free_name_vector (apiCB *in_context, + char **io_name) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_free_name (in_context, io_name); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_free_creds_vector (apiCB *in_context, + cred_union **io_credentials) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_free_creds (in_context, io_credentials); + cci_swap_context_functions (in_context); + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 __cc_free_NC_info_vector (apiCB *in_context, + infoNC ***io_info) +{ + cc_int32 err = ccNoError; + cci_swap_context_functions (in_context); + err = cc_free_NC_info (in_context, io_info); + cci_swap_context_functions (in_context); + return err; +} diff --git a/src/ccapi/lib/mac/ccapi_vector.exports b/src/ccapi/lib/mac/ccapi_vector.exports new file mode 100644 index 000000000..0f02e4148 --- /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 000000000..80840f111 --- /dev/null +++ b/src/ccapi/lib/mac/ccapi_vector.h @@ -0,0 +1,228 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include + + +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/server/ccs_array.c b/src/ccapi/server/ccs_array.c new file mode 100644 index 000000000..c798c7a3a --- /dev/null +++ b/src/ccapi/server/ccs_array.c @@ -0,0 +1,145 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "cci_array_internal.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_pipe_object_release (void *io_pipe) +{ + return cci_check_error (ccs_pipe_release ((ccs_pipe_t) io_pipe)); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array) +{ + return cci_array_new (out_array, ccs_pipe_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +inline ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, + ccs_pipe_t in_pipe, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, in_pipe, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_object_release (void *io_lock) +{ + return cci_check_error (ccs_lock_release ((ccs_lock_t) io_lock)); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array) +{ + return cci_array_new (out_array, ccs_lock_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +inline ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, + ccs_lock_t in_lock, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, in_lock, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ +inline cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position) +{ + return cci_array_move (io_array, in_position, in_new_position, out_real_new_position); +} diff --git a/src/ccapi/server/ccs_array.h b/src/ccapi/server/ccs_array.h new file mode 100644 index 000000000..865647c1c --- /dev/null +++ b/src/ccapi/server/ccs_array.h @@ -0,0 +1,71 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_ARRAY_H +#define CCS_ARRAY_H + +#include "ccs_types.h" + +inline cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array); + +inline cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array); + +inline cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array); + +inline ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, + ccs_pipe_t in_pipe, + cc_uint64 in_position); + +inline cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, + cc_uint64 in_position); + +#pragma mark - + +inline cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array); + +inline cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array); + +inline cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array); + +inline ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, + ccs_lock_t in_lock, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position); + +#endif /* CCS_ARRAY_H */ diff --git a/src/ccapi/server/ccs_cache_collection.c b/src/ccapi/server/ccs_cache_collection.c new file mode 100644 index 000000000..4927aaacb --- /dev/null +++ b/src/ccapi/server/ccs_cache_collection.c @@ -0,0 +1,949 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_cache_collection_d { + cc_time_t last_changed_time; + cc_uint64 next_unique_name; + cci_identifier_t identifier; + ccs_lock_state_t lock_state; + ccs_ccache_list_t ccaches; +}; + +struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection) +{ + cc_int32 err = ccNoError; + ccs_cache_collection_t cache_collection = NULL; + + if (!out_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cache_collection = malloc (sizeof (*cache_collection)); + if (cache_collection) { + *cache_collection = ccs_cache_collection_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&cache_collection->identifier); + } + + if (!err) { + err = ccs_lock_state_new (&cache_collection->lock_state, + ccErrInvalidContext, + ccErrContextLocked, + ccErrContextUnlocked); + } + + if (!err) { + err = ccs_ccache_list_new (&cache_collection->ccaches); + } + + if (!err) { + err = ccs_cache_collection_changed (cache_collection); + } + + if (!err) { + *out_cache_collection = cache_collection; + cache_collection = NULL; + } + + ccs_cache_collection_release (cache_collection); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (io_cache_collection->identifier); + ccs_lock_state_release (io_cache_collection->lock_state); + ccs_ccache_list_release (io_cache_collection->ccaches); + free (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_cache_collection->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_time_t now = time (NULL); + + if (io_cache_collection->last_changed_time < now) { + io_cache_collection->last_changed_time = now; + } else { + io_cache_collection->last_changed_time++; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t in_cache_collection, + const char *in_name, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + ccs_ccache_list_iterator_t iterator = NULL; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + } + + while (!err) { + ccs_ccache_t ccache = NULL; + + err = ccs_ccache_list_iterator_next (iterator, &ccache); + + if (!err) { + cc_uint32 equal = 0; + + err = ccs_ccache_compare_name (ccache, in_name, &equal); + + if (!err && equal) { + *out_ccache = ccache; + break; + } + } + } + if (err == ccIteratorEnd) { err = ccErrCCacheNotFound; } + + if (iterator) { ccs_ccache_list_iterator_release (iterator); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_find (in_cache_collection->ccaches, + in_identifier, out_ccache); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_source_identifier, + ccs_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + ccs_ccache_t source_ccache = NULL; + + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_source_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_find_ccache (io_cache_collection, + in_source_identifier, + &source_ccache); + } + + if (!err) { + err = ccs_ccache_swap_contents (source_ccache, io_destination_ccache); + } + + if (!err) { + err = ccs_cache_collection_destroy_ccache (io_cache_collection, + in_source_identifier); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_remove (io_cache_collection->ccaches, + in_identifier); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_iterator_t *out_ccache_iterator) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_find_iterator (in_cache_collection->ccaches, + in_identifier, + out_ccache_iterator); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache, + ccs_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + ccs_ccache_list_iterator_t iterator = NULL; + + if (!in_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + } + + while (!err) { + ccs_ccache_t ccache = NULL; + + err = ccs_ccache_list_iterator_next (iterator, &ccache); + + if (!err) { + cc_int32 terr = ccs_ccache_find_credentials_iterator (ccache, + in_identifier, + out_credentials_iterator); + if (!terr) { + *out_ccache = ccache; + break; + } + } + } + if (err == ccIteratorEnd) { err = cci_check_error (ccErrInvalidCredentialsIterator); } + + if (iterator) { ccs_ccache_list_iterator_release (iterator); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_next_unique_ccache_name (ccs_cache_collection_t io_cache_collection, + char **out_name) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + char *name = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!out_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + while (!err) { + int ret = asprintf (&name, "%lld", io_cache_collection->next_unique_name++); + if (ret < 0 || !name) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + ccs_ccache_t ccache = NULL; /* temporary to hold ccache pointer */ + err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, &ccache); + } + + if (err == ccErrCCacheNotFound) { + err = ccNoError; + break; /* found a unique one */ + } + } + } else { + name = strdup (k_cci_context_initial_ccache_name); + if (!name) { err = cci_check_error (ccErrNoMem); } + } + } + + if (!err) { + *out_name = name; + name = NULL; + } + + free (name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t in_cache_collection, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_count (in_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + /* First ccache is the default */ + ccs_ccache_list_iterator_t iterator = NULL; + + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, + &iterator); + + if (!err) { + err = ccs_ccache_list_iterator_next (iterator, out_ccache); + } + + ccs_ccache_list_iterator_release (iterator); + + } else { + err = cci_check_error (ccErrCCacheNotFound); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + ccs_ccache_t old_default = NULL; + ccs_ccache_t new_default = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &old_default); + } + + if (!err) { + err = ccs_ccache_list_push_front (io_cache_collection->ccaches, + in_identifier); + } + + if (!err) { + err = ccs_ccache_notify_default_state_changed (old_default, + io_cache_collection, + FALSE /* no longer default */); + } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &new_default); + } + + if (!err) { + err = ccs_ccache_notify_default_state_changed (new_default, + io_cache_collection, + TRUE /* now default */); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - +#pragma mark -- IPC Messages -- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_context_release (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Currently does nothing */ + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_sync (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (io_cache_collection->identifier, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_change_time (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_cache_collection->last_changed_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_default_ccache_name (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache); + + if (!err) { + err = ccs_ccache_write_name (ccache, io_reply_data); + } + } else { + err = cci_stream_write_string (io_reply_data, + k_cci_context_initial_ccache_name); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_open_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *name = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (in_request_data, &name); + } + + if (!err) { + err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + free (name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_open_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *name = NULL; + cc_uint32 cred_vers; + char *principal = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (in_request_data, &name); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + cc_int32 terr = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, + &ccache); + + if (!terr) { + err = ccs_ccache_reset (ccache, cred_vers, principal); + + } else { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (name); + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers; + char *principal = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &ccache); + + if (!err) { + err = ccs_ccache_reset (ccache, cred_vers, principal); + + } else if (err == ccErrCCacheNotFound) { + char *name = NULL; + + err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, + &name); + + if (!err) { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + + free (name); + } + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers; + char *principal = NULL; + char *name = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, + &name); + } + + if (!err) { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (name); + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_iterator_t ccache_iterator = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches, + &ccache_iterator); + } + + if (!err) { + err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_lock (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 lock_type; + cc_uint32 block; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &lock_type); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &block); + } + + if (!err) { + err = ccs_lock_state_add (io_cache_collection->lock_state, + in_client_pipe, in_reply_pipe, + lock_type, block, out_will_block); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pipe, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_state_remove (io_cache_collection->lock_state, + in_client_pipe); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 will_block = 0; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_context_release_msg_id) { + err = ccs_cache_collection_context_release (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_sync_msg_id) { + err = ccs_cache_collection_sync (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_get_change_time_msg_id) { + err = ccs_cache_collection_get_change_time (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) { + err = ccs_cache_collection_get_default_ccache_name (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_open_ccache_msg_id) { + err = ccs_cache_collection_open_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_open_default_ccache_msg_id) { + err = ccs_cache_collection_open_default_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_ccache_msg_id) { + err = ccs_cache_collection_create_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_default_ccache_msg_id) { + err = ccs_cache_collection_create_default_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_new_ccache_msg_id) { + err = ccs_cache_collection_create_new_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_new_ccache_iterator_msg_id) { + err = ccs_cache_collection_new_ccache_iterator (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_lock_msg_id) { + err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe, + io_cache_collection, + in_request_data, + &will_block, reply_data); + + } else if (in_request_name == cci_context_unlock_msg_id) { + err = ccs_cache_collection_unlock (in_client_pipe, io_cache_collection, + in_request_data, reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_will_block = will_block; + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_cache_collection.h b/src/ccapi/server/ccs_cache_collection.h new file mode 100644 index 000000000..4d663f992 --- /dev/null +++ b/src/ccapi/server/ccs_cache_collection.h @@ -0,0 +1,73 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CACHE_COLLECTION_H +#define CCS_CACHE_COLLECTION_H + +#include "ccs_types.h" + +cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection); + +inline cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection); + +inline cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection); + +cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_source_identifier, + ccs_ccache_t io_destination_ccache); + +cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_iterator_t *out_ccache_iterator); + +cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache, + ccs_credentials_iterator_t *out_credentials_iterator); + +cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data); + +#endif /* CCS_CACHE_COLLECTION_H */ diff --git a/src/ccapi/server/ccs_ccache.c b/src/ccapi/server/ccs_ccache.c new file mode 100644 index 000000000..aaeed9796 --- /dev/null +++ b/src/ccapi/server/ccs_ccache.c @@ -0,0 +1,1002 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_ccache_d { + cci_identifier_t identifier; + ccs_lock_state_t lock_state; + cc_uint32 cred_vers; + char *name; + char *principal; + cc_time_t last_default_time; + cc_time_t last_changed_time; + cc_uint32 kdc_time_offset_v4_valid; + cc_time_t kdc_time_offset_v4; + cc_uint32 kdc_time_offset_v5_valid; + cc_time_t kdc_time_offset_v5; + ccs_credentials_list_t credentials; +}; + +struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, + cc_uint32 in_cred_vers, + const char *in_name, + const char *in_principal, + ccs_ccache_list_t io_ccache_list) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache = malloc (sizeof (*ccache)); + if (ccache) { + *ccache = ccs_ccache_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&ccache->identifier); + } + + if (!err) { + err = ccs_lock_state_new (&ccache->lock_state, + ccErrInvalidCCache, + ccErrCCacheLocked, + ccErrCCacheUnlocked); + } + + if (!err) { + ccache->cred_vers = in_cred_vers; + + if (in_cred_vers != cc_credentials_v4 && + in_cred_vers != cc_credentials_v5) { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + ccache->name = strdup (in_name); + if (!ccache->name) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + ccache->principal = strdup (in_principal); + if (!ccache->principal) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = ccs_credentials_list_new (&ccache->credentials); + } + + if (!err) { + cc_uint64 now = time (NULL); + cc_uint64 count = 0; + + err = ccs_ccache_list_count (io_ccache_list, &count); + + if (!err) { + /* first cache is default */ + ccache->last_default_time = (count == 0) ? now : 0; + ccache->last_changed_time = now; + } + } + + if (!err) { + /* Add self to the list of ccaches */ + err = ccs_ccache_list_add (io_ccache_list, ccache); + } + + if (!err) { + *out_ccache = ccache; + ccache = NULL; + } + + ccs_ccache_release (ccache); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + cc_uint32 in_cred_vers, + const char *in_principal) +{ + cc_int32 err = ccNoError; + char *principal = NULL; + ccs_credentials_list_t credentials = NULL; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_cred_vers != cc_credentials_v4 && + in_cred_vers != cc_credentials_v5) { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + principal = strdup (in_principal); + if (!io_ccache->principal) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = ccs_credentials_list_new (&credentials); + } + + if (!err) { + io_ccache->cred_vers = in_cred_vers; + + free (io_ccache->principal); + io_ccache->principal = principal; + principal = NULL; /* take ownership */ + + ccs_credentials_list_release (io_ccache->credentials); + io_ccache->credentials = credentials; + credentials = NULL; /* take ownership */ + + } + + free (principal); + ccs_credentials_list_release (credentials); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + + if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + struct ccs_ccache_d temp_ccache = *io_destination_ccache; + + /* swap everything */ + *io_destination_ccache = *io_source_ccache; + *io_source_ccache = temp_ccache; + + /* swap back the name and identifier */ + io_source_ccache->identifier = io_destination_ccache->identifier; + io_destination_ccache->identifier = temp_ccache.identifier; + + io_source_ccache->name = io_destination_ccache->name; + io_destination_ccache->name = temp_ccache.name; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + + if (!io_ccache) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (io_ccache->identifier); + ccs_lock_state_release (io_ccache->lock_state); + free (io_ccache->name); + free (io_ccache->principal); + ccs_credentials_list_release (io_ccache->credentials); + free (io_ccache); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_ccache->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, + const char *in_name, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal = (strcmp (in_ccache->name, in_name) == 0); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_time_t now = time (NULL); + + if (io_ccache->last_changed_time < now) { + io_ccache->last_changed_time = now; + } else { + io_ccache->last_changed_time++; + } + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_new_default_state) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_new_default_state) { + cc_time_t now = time (NULL); + + if (io_ccache->last_default_time < now) { + io_ccache->last_default_time = now; + } else { + io_ccache->last_default_time++; + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + ccs_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_find_iterator (in_ccache->credentials, + in_identifier, + out_credentials_iterator); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_ccache->identifier, io_stream); + } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_stream, in_ccache->name); + } + + return cci_check_error (err); +} + +#pragma mark - +#pragma mark -- IPC Messages -- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_destroy (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_destroy_ccache (io_cache_collection, + io_ccache->identifier); + } + + if (!err) { + /* ccache has been destroyed so just mark the cache collection */ + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_default (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_set_default_ccache (io_cache_collection, + io_ccache->identifier); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_credentials_version (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_uint32 (io_reply_data, io_ccache->cred_vers); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_name (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_reply_data, io_ccache->name); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_principal (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_reply_data, io_ccache->principal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_principal (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *principal = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (io_reply_data, &principal); + } + + if (!err) { + free (io_ccache->principal); + io_ccache->principal = principal; + principal = NULL; + + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_store_credentials (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_new (&credentials, in_request_data, + io_ccache->credentials); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cci_identifier_t credentials_identifier = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_read (&credentials_identifier, in_request_data); + } + + if (!err) { + err = ccs_credentials_list_remove (io_ccache->credentials, credentials_identifier); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + cci_identifier_release (credentials_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_iterator_t credentials_iterator = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_new_iterator (io_ccache->credentials, + &credentials_iterator); + } + + if (!err) { + err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_move (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cci_identifier_t source_identifier = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Note: message is sent as the destination ccache to avoid */ + /* extra work on the server when deleting it the source ccache. */ + err = cci_identifier_read (&source_identifier, in_request_data); + } + + if (!err) { + err = ccs_ccache_collection_move_ccache (io_cache_collection, + source_identifier, + io_ccache); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + cci_identifier_release (source_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_lock (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 lock_type; + cc_uint32 block; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &lock_type); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &block); + } + + if (!err) { + err = ccs_lock_state_add (io_ccache->lock_state, + in_client_pipe, in_reply_pipe, + lock_type, block, out_will_block); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_unlock (ccs_pipe_t in_client_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_state_remove (io_ccache->lock_state, in_client_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_last_default_time (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err && io_ccache->last_default_time == 0) { + err = cci_check_error (ccErrNeverDefault); + } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_ccache->last_default_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_ccache->last_changed_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + if (io_ccache->kdc_time_offset_v4_valid) { + err = cci_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v4); + } else { + err = cci_check_error (ccErrTimeOffsetNotSet); + } + + } else if (cred_vers == cc_credentials_v5) { + if (io_ccache->kdc_time_offset_v5_valid) { + err = cci_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v5); + } else { + err = cci_check_error (ccErrTimeOffsetNotSet); + } + + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + err = cci_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v4); + + if (!err) { + io_ccache->kdc_time_offset_v4_valid = 1; + } + } else if (cred_vers == cc_credentials_v5) { + err = cci_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v5); + + if (!err) { + io_ccache->kdc_time_offset_v5_valid = 1; + } + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_clear_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + io_ccache->kdc_time_offset_v4 = 0; + io_ccache->kdc_time_offset_v4_valid = 0; + + } else if (cred_vers == cc_credentials_v5) { + io_ccache->kdc_time_offset_v5 = 0; + io_ccache->kdc_time_offset_v5_valid = 0; + + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 will_block = 0; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_ccache_destroy_msg_id) { + err = ccs_ccache_destroy (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_default_msg_id) { + err = ccs_ccache_set_default (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_credentials_version_msg_id) { + err = ccs_ccache_get_credentials_version (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_name_msg_id) { + err = ccs_ccache_get_name (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_principal_msg_id) { + err = ccs_ccache_get_principal (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_principal_msg_id) { + err = ccs_ccache_set_principal (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_store_credentials_msg_id) { + err = ccs_ccache_store_credentials (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_remove_credentials_msg_id) { + err = ccs_ccache_remove_credentials (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) { + err = ccs_ccache_new_credentials_iterator (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_move_msg_id) { + err = ccs_ccache_move (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_lock_msg_id) { + err = ccs_ccache_lock (in_client_pipe, in_reply_pipe, + io_ccache, io_cache_collection, + in_request_data, + &will_block, reply_data); + + } else if (in_request_name == cci_ccache_unlock_msg_id) { + err = ccs_ccache_unlock (in_client_pipe, + io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_last_default_time_msg_id) { + err = ccs_ccache_get_last_default_time (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_change_time_msg_id) { + err = ccs_ccache_get_change_time (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) { + err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_kdc_time_offset_msg_id) { + err = ccs_ccache_set_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_clear_kdc_time_offset_msg_id) { + err = ccs_ccache_clear_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_will_block = will_block; + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_ccache.h b/src/ccapi/server/ccs_ccache.h new file mode 100644 index 000000000..837c6b457 --- /dev/null +++ b/src/ccapi/server/ccs_ccache.h @@ -0,0 +1,78 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CCACHE_H +#define CCS_CCACHE_H + +#include "ccs_types.h" + +cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, + cc_uint32 in_cred_vers, + const char *in_name, + const char *in_principal, + ccs_ccache_list_t io_ccache_list); + +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + cc_uint32 in_cred_vers, + const char *in_principal); + +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache); + +inline cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache); + +inline cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, + const char *in_name, + cc_uint32 *out_equal); + +cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_new_default_state); + +cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + ccs_credentials_iterator_t *out_credentials_iterator); + +cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, + cci_stream_t io_stream); + +cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, + cci_stream_t io_stream); + +cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data); + +#endif /* CCS_CCACHE_H */ diff --git a/src/ccapi/server/ccs_ccache_iterator.c b/src/ccapi/server/ccs_ccache_iterator.c new file mode 100644 index 000000000..77d83f1b0 --- /dev/null +++ b/src/ccapi/server/ccs_ccache_iterator.c @@ -0,0 +1,156 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_release (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_release (io_ccache_iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_next (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_next (io_ccache_iterator, &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_clone (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_iterator_t ccache_iterator = NULL; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_clone (io_ccache_iterator, + &ccache_iterator); + } + + if (!err) { + err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; + + if (!in_request_data) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_ccache_iterator_release_msg_id) { + err = ccs_ccache_iterator_release (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else if (in_request_name == cci_ccache_iterator_next_msg_id) { + err = ccs_ccache_iterator_next (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else if (in_request_name == cci_ccache_iterator_clone_msg_id) { + err = ccs_ccache_iterator_clone (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_ccache_iterator.h b/src/ccapi/server/ccs_ccache_iterator.h new file mode 100644 index 000000000..8ec361a67 --- /dev/null +++ b/src/ccapi/server/ccs_ccache_iterator.h @@ -0,0 +1,38 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CCACHE_ITERATOR_H +#define CCS_CCACHE_ITERATOR_H + +#include "ccs_types.h" + + cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +#endif /* CCS_CCACHE_ITERATOR_H */ diff --git a/src/ccapi/server/ccs_common.h b/src/ccapi/server/ccs_common.h new file mode 100644 index 000000000..f035780da --- /dev/null +++ b/src/ccapi/server/ccs_common.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_COMMON_H +#define CCS_COMMON_H + +#include "cci_common.h" + +#include "ccs_array.h" +#include "ccs_list.h" +#include "ccs_cache_collection.h" +#include "ccs_ccache_iterator.h" +#include "ccs_ccache.h" +#include "ccs_credentials_iterator.h" +#include "ccs_credentials.h" +#include "ccs_lock.h" +#include "ccs_lock_state.h" +#include "ccs_pipe.h" +#include "ccs_server.h" + +#endif /* CCS_COMMON_H */ diff --git a/src/ccapi/server/ccs_credentials.c b/src/ccapi/server/ccs_credentials.c new file mode 100644 index 000000000..7cb6483f0 --- /dev/null +++ b/src/ccapi/server/ccs_credentials.c @@ -0,0 +1,136 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_credentials_d { + cc_credentials_union *cred_union; + cci_identifier_t identifier; +}; + +struct ccs_credentials_d ccs_credentials_initializer = { NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, + cci_stream_t in_stream, + ccs_credentials_list_t io_credentials_list) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!out_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + credentials = malloc (sizeof (*credentials)); + if (credentials) { + *credentials = ccs_credentials_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_cred_union_read (&credentials->cred_union, in_stream); + } + + if (!err) { + err = ccs_server_new_identifier (&credentials->identifier); + } + + if (!err) { + err = ccs_credentials_list_add (io_credentials_list, credentials); + } + + if (!err) { + *out_credentials = credentials; + credentials = NULL; + } + + ccs_credentials_release (credentials); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials) +{ + cc_int32 err = ccNoError; + + if (!io_credentials) { err = ccErrBadParam; } + + if (!err) { + cci_cred_union_release (io_credentials->cred_union); + cci_identifier_release (io_credentials->identifier); + free (io_credentials); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_credentials->identifier, io_stream); + } + + if (!err) { + err = cci_cred_union_write (in_credentials->cred_union, io_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_credentials->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_credentials.h b/src/ccapi/server/ccs_credentials.h new file mode 100644 index 000000000..e4dbb69f5 --- /dev/null +++ b/src/ccapi/server/ccs_credentials.h @@ -0,0 +1,46 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CREDENTIALS_H +#define CCS_CREDENTIALS_H + +#include "ccs_types.h" + + +cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, + cci_stream_t in_stream, + ccs_credentials_list_t io_credentials_list); + +inline cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials); + +cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, + cci_stream_t io_stream); + +inline cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +#endif /* CCS_CREDENTIALS_H */ diff --git a/src/ccapi/server/ccs_credentials_iterator.c b/src/ccapi/server/ccs_credentials_iterator.c new file mode 100644 index 000000000..f95dc4842 --- /dev/null +++ b/src/ccapi/server/ccs_credentials_iterator.c @@ -0,0 +1,158 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_release (io_credentials_iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_next (io_credentials_iterator, + &credentials); + } + + if (!err) { + err = ccs_credentials_write (credentials, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_clone (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_iterator_t credentials_iterator = NULL; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_clone (io_credentials_iterator, + &credentials_iterator); + } + + if (!err) { + err = ccs_credentials_list_iterator_write (credentials_iterator, + io_reply_data); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; + + if (!in_request_data) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_credentials_iterator_release_msg_id) { + err = ccs_credentials_iterator_release (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else if (in_request_name == cci_credentials_iterator_next_msg_id) { + err = ccs_credentials_iterator_next (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else if (in_request_name == cci_credentials_iterator_clone_msg_id) { + err = ccs_credentials_iterator_clone (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_credentials_iterator.h b/src/ccapi/server/ccs_credentials_iterator.h new file mode 100644 index 000000000..af3cf1a18 --- /dev/null +++ b/src/ccapi/server/ccs_credentials_iterator.h @@ -0,0 +1,38 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CREDENTIALS_ITERATOR_H +#define CCS_CREDENTIALS_ITERATOR_H + +#include "ccs_types.h" + + cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +#endif /* CCS_CREDENTIALS_ITERATOR_H */ diff --git a/src/ccapi/server/ccs_list.c b/src/ccapi/server/ccs_list.c new file mode 100644 index 000000000..17355c08f --- /dev/null +++ b/src/ccapi/server/ccs_list.c @@ -0,0 +1,345 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_list_internal.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_list_object_release (void *io_object) +{ + return cci_check_error (ccs_cache_collection_release ((ccs_cache_collection_t) io_object)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_list_object_compare_identifier (void *in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_cache_collection_compare_identifier ((ccs_cache_collection_t) in_cache_collection, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidContext, + ccErrInvalidContext, + ccs_cache_collection_list_object_compare_identifier, + ccs_cache_collection_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, + cci_identifier_t in_identifier, + ccs_cache_collection_t *out_cache_collection) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_cache_collection); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, + ccs_cache_collection_t in_cache_collection) +{ + return ccs_list_add (io_list, in_cache_collection); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list) +{ + return ccs_list_release (io_list); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_list_object_release (void *io_ccache) +{ + return cci_check_error (ccs_ccache_release ((ccs_ccache_t) io_ccache)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_list_object_compare_identifier (void *in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_ccache_compare_identifier ((ccs_ccache_t) in_ccache, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidCCache, + ccErrInvalidCCacheIterator, + ccs_ccache_list_object_compare_identifier, + ccs_ccache_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_new_iterator (in_list, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_find_iterator (in_list, in_identifier, + (ccs_list_iterator_t *) out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, + ccs_ccache_t in_ccache) +{ + return ccs_list_add (io_list, in_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_push_front (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list) +{ + return ccs_list_release (io_list); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + return ccs_list_iterator_write (in_list_iterator, in_stream); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, + ccs_ccache_t *out_ccache) +{ + return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator) +{ + return ccs_list_iterator_release (io_list_iterator); +} + +#pragma mark- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_list_object_release (void *io_object) +{ + return cci_check_error (ccs_credentials_release ((ccs_credentials_t) io_object)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_list_object_compare_identifier (void *in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_credentials_compare_identifier ((ccs_credentials_t) in_credentials, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidCredentials, + ccErrInvalidCredentialsIterator, + ccs_credentials_list_object_compare_identifier, + ccs_credentials_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_new_iterator (in_list, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_t *out_credentials) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_credentials); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_find_iterator (in_list, in_identifier, + (ccs_list_iterator_t *) out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, + ccs_credentials_t in_credential) +{ + return ccs_list_add (io_list, in_credential); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list) +{ + return ccs_list_release (io_list); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + return ccs_list_iterator_write (in_list_iterator, in_stream); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, + ccs_credentials_t *out_credential) +{ + return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_credential); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator) +{ + return ccs_list_iterator_release (io_list_iterator); +} diff --git a/src/ccapi/server/ccs_list.h b/src/ccapi/server/ccs_list.h new file mode 100644 index 000000000..435821a5b --- /dev/null +++ b/src/ccapi/server/ccs_list.h @@ -0,0 +1,129 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LIST_H +#define CCS_LIST_H + + +#include "ccs_types.h" + +cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list); + +cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, + cci_identifier_t in_identifier, + ccs_cache_collection_t *out_cache_collection); + +cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, + ccs_cache_collection_t in_cache_collection); + +cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list); + +#pragma mark - + +cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list); + +cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, + ccs_ccache_t in_ccache); + +cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list); + + +cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator); + +#pragma mark - + +cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list); + +cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_t *out_credentials); + +cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, + ccs_credentials_t in_credential); + +cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list); + + +cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, + ccs_credentials_t *out_credential); + +cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator); + +#endif /* CCS_LIST_H */ diff --git a/src/ccapi/server/ccs_list_internal.c b/src/ccapi/server/ccs_list_internal.c new file mode 100644 index 000000000..a930fba33 --- /dev/null +++ b/src/ccapi/server/ccs_list_internal.c @@ -0,0 +1,612 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_list_internal.h" +#include "cci_array_internal.h" +#include "cci_identifier.h" +#include "ccs_server.h" + +typedef enum { + ccs_list_action_insert, + ccs_list_action_remove, + ccs_list_action_push_front +} ccs_list_action_enum; + +/* ------------------------------------------------------------------------ */ + +struct ccs_list_d { + cci_array_t objects; + cci_array_t iterators; + + cc_int32 object_not_found_err; + cc_int32 iterator_not_found_err; + + ccs_object_compare_identifier_t object_compare_identifier; +}; + +struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL }; + +/* ------------------------------------------------------------------------ */ + +struct ccs_list_iterator_d { + cci_identifier_t identifier; + ccs_list_t list; + cc_uint64 current; +}; + +struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, NULL, 0 }; + +static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, + ccs_list_t in_list); + +static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator); + +static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, + ccs_list_action_enum in_action, + cc_uint64 in_object_index); +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_new (ccs_list_t *out_list, + cc_int32 in_object_not_found_err, + cc_int32 in_iterator_not_found_err, + ccs_object_compare_identifier_t in_object_compare_identifier, + ccs_object_release_t in_object_release) +{ + cc_int32 err = ccNoError; + ccs_list_t list = NULL; + + if (!out_list) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + list = malloc (sizeof (*list)); + if (list) { + *list = ccs_list_initializer; + list->object_not_found_err = in_object_not_found_err; + list->iterator_not_found_err = in_iterator_not_found_err; + list->object_compare_identifier = in_object_compare_identifier; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_array_new (&list->objects, in_object_release); + } + + if (!err) { + err = cci_array_new (&list->iterators, ccs_list_iterator_object_release); + } + + if (!err) { + *out_list = list; + list = NULL; + } + + ccs_list_release (list); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_release (ccs_list_t io_list) +{ + cc_int32 err = ccNoError; + + if (!io_list) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i; + + for (i = 0; i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_release (cci_array_object_at_index (io_list->iterators, i)); + } + free (io_list->iterators); + cci_array_release (io_list->objects); + free (io_list); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_list_iterator_t *out_list_iterator) +{ + return cci_check_error (ccs_list_iterator_new (out_list_iterator, io_list)); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_release_iterator (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t iterator = NULL; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_iterator (io_list, in_identifier, &iterator); + } + + if (!err) { + err = ccs_list_iterator_release (iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_count (ccs_list_t in_list, + cc_uint64 *out_count) +{ + cc_int32 err = ccNoError; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!out_count) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_count = cci_array_count (in_list->objects); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_find_index (ccs_list_t in_list, + cci_identifier_t in_identifier, + cc_uint64 *out_object_index) +{ + cc_int32 err = ccNoError; + cc_int32 found = 0; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_object_index) { err = cci_check_error (ccErrBadParam); } + + if (!err && !found) { + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (in_list->objects); i++) { + cc_uint32 equal = 0; + cci_array_object_t object = cci_array_object_at_index (in_list->objects, i); + + err = in_list->object_compare_identifier (object, in_identifier, &equal); + + if (!err && equal) { + found = 1; + *out_object_index = i; + } + } + } + + if (!err && !found) { + err = cci_check_error (in_list->object_not_found_err); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + cc_uint64 i; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (in_list, in_identifier, &i); + } + + if (!err) { + *out_object = cci_array_object_at_index (in_list->objects, i); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_find_iterator_index (ccs_list_t in_list, + cci_identifier_t in_identifier, + cc_uint64 *out_object_index) +{ + cc_int32 err = ccNoError; + cc_int32 found = 0; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_object_index) { err = cci_check_error (ccErrBadParam); } + + if (!err && !found) { + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) { + cc_uint32 equal = 0; + ccs_list_iterator_t iterator = cci_array_object_at_index (in_list->iterators, i); + + err = cci_identifier_compare (iterator->identifier, in_identifier, &equal); + + if (!err && equal) { + found = 1; + *out_object_index = i; + } + } + } + + if (!err && !found) { + err = cci_check_error (in_list->object_not_found_err); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_find_iterator (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_iterator_t *out_list_iterator) +{ + cc_int32 err = ccNoError; + cc_uint64 i; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_iterator_index (in_list, in_identifier, &i); + } + + if (!err) { + *out_list_iterator = cci_array_object_at_index (in_list->iterators, i); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_object_t in_object) +{ + cc_int32 err = ccNoError; + cc_uint64 add_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_object) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + add_index = cci_array_count (io_list->objects); + + err = cci_array_insert (io_list->objects, in_object, add_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_remove (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cc_uint64 remove_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (io_list, in_identifier, &remove_index); + } + + if (!err) { + err = cci_array_remove (io_list->objects, remove_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_push_front (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cc_uint64 push_front_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (io_list, in_identifier, &push_front_index); + } + + if (!err) { + err = cci_array_push_front (io_list->objects, push_front_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, + ccs_list_action_push_front, + push_front_index); + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, + ccs_list_t io_list) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = NULL; + + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + list_iterator = malloc (sizeof (*list_iterator)); + if (list_iterator) { + *list_iterator = ccs_list_iterator_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&list_iterator->identifier); + } + + if (!err) { + list_iterator->list = io_list; + list_iterator->current = 0; + + err = cci_array_insert (io_list->iterators, + list_iterator, cci_array_count (io_list->iterators)); + } + + if (!err) { + *out_list_iterator = list_iterator; + list_iterator = NULL; + } + + ccs_list_iterator_release (list_iterator); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + + if (!in_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_list_iterator->identifier, + in_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, + ccs_list_iterator_t *out_list_iterator) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = NULL; + + if (!in_list_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_iterator_new (&list_iterator, in_list_iterator->list); + } + + if (!err) { + list_iterator->current = in_list_iterator->current; + + *out_list_iterator = list_iterator; + list_iterator = NULL; + } + + ccs_list_iterator_release (list_iterator); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator; + + if (!io_list_iterator) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (list_iterator->identifier); + free (io_list_iterator); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i = 0; + + if (ccs_list_find_iterator_index (io_list_iterator->list, + io_list_iterator->identifier, + &i) == ccNoError) { + /* cci_array_remove will call ccs_list_iterator_object_release */ + cci_array_remove (io_list_iterator->list->iterators, i); + } else { + cci_debug_printf ("Warning: iterator not in iterator list!"); + } + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { + *out_object = cci_array_object_at_index (io_list_iterator->list->objects, + io_list_iterator->current); + } else { + err = ccIteratorEnd; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { + *out_object = cci_array_object_at_index (io_list_iterator->list->objects, + io_list_iterator->current); + io_list_iterator->current++; + } else { + err = ccIteratorEnd; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, + ccs_list_action_enum in_action, + cc_uint64 in_object_index) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* When the list changes adjust the current index so that */ + /* we don't unnecessarily skip or double count items */ + if (in_action == ccs_list_action_insert) { + if (io_list_iterator->current > in_object_index) { + io_list_iterator->current++; + } + + } else if (in_action == ccs_list_action_remove) { + if (io_list_iterator->current >= in_object_index) { + io_list_iterator->current--; + } + + } else if (in_action == ccs_list_action_push_front) { + if (io_list_iterator->current < in_object_index) { + io_list_iterator->current++; + } + + } else { + err = cci_check_error (ccErrBadParam); + } + } + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_list_internal.h b/src/ccapi/server/ccs_list_internal.h new file mode 100644 index 000000000..83320a5eb --- /dev/null +++ b/src/ccapi/server/ccs_list_internal.h @@ -0,0 +1,92 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LIST_INTERNAL_H +#define CCS_LIST_INTERNAL_H + +#include "cci_common.h" + +struct ccs_list_d; +typedef struct ccs_list_d *ccs_list_t; + +struct ccs_list_iterator_d; +typedef struct ccs_list_iterator_d *ccs_list_iterator_t; + +typedef void *ccs_object_t; +typedef cc_int32 (*ccs_object_release_t) (ccs_object_t); +typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_object_t, cci_identifier_t, cc_uint32 *); + +cc_int32 ccs_list_new (ccs_list_t *out_list, + cc_int32 in_object_not_found_err, + cc_int32 in_iterator_not_found_err, + ccs_object_compare_identifier_t in_object_compare_identifier, + ccs_object_release_t in_object_release); + +cc_int32 ccs_list_release (ccs_list_t io_list); + +cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_release_iterator (ccs_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_list_count (ccs_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_object_t *out_object); + +cc_int32 ccs_list_find_iterator (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_object_t in_object); + +cc_int32 ccs_list_remove (ccs_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_list_push_front (ccs_list_t io_list, + cci_identifier_t in_identifier); + + +cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object); + +cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object); + +cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); + + +#endif /* CCS_LIST_INTERNAL_H */ diff --git a/src/ccapi/server/ccs_lock.c b/src/ccapi/server/ccs_lock.c new file mode 100644 index 000000000..939da5e12 --- /dev/null +++ b/src/ccapi/server/ccs_lock.c @@ -0,0 +1,245 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_lock_d { + cc_uint32 type; + cc_uint32 pending; + cc_int32 invalid_object_err; + ccs_pipe_t client_pipe; + ccs_pipe_t reply_pipe; +}; + +struct ccs_lock_d ccs_lock_initializer = { 0, 1, 1, NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe) +{ + cc_int32 err = ccNoError; + ccs_lock_t lock = NULL; + + if (!out_lock ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (in_type != cc_lock_read && + in_type != cc_lock_write && + in_type != cc_lock_upgrade && + in_type != cc_lock_downgrade) { + err = cci_check_error (ccErrBadLockType); + } + + if (!err) { + lock = malloc (sizeof (*lock)); + if (lock) { + *lock = ccs_lock_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_pipe_copy (&lock->client_pipe, in_client_pipe); + } + + if (!err) { + err = ccs_pipe_copy (&lock->reply_pipe, in_reply_pipe); + } + + if (!err) { + lock->type = in_type; + lock->invalid_object_err = in_invalid_object_err; + + *out_lock = lock; + lock = NULL; + } + + ccs_lock_release (lock); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_release (ccs_lock_t io_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err && io_lock->pending) { + err = ccs_server_send_reply (io_lock->reply_pipe, + io_lock->invalid_object_err, NULL); + } + + if (!err) { + ccs_pipe_release (io_lock->client_pipe); + ccs_pipe_release (io_lock->reply_pipe); + free (io_lock); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_lock->pending) { + err = ccs_server_send_reply (io_lock->reply_pipe, err, NULL); + + if (!err) { + ccs_pipe_release (io_lock->reply_pipe); + io_lock->pending = 0; + io_lock->reply_pipe = NULL; + } + } else { + cci_debug_printf ("WARNING %s() called on non-pending lock!", + __FUNCTION__); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, + cc_uint32 *out_pending) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_pending) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_pending = in_lock->pending; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_type (ccs_lock_t in_lock, + cc_uint32 *out_lock_type) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_lock_type) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_lock_type = in_lock->type; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_read_lock) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_read_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_read_lock = (in_lock->type == cc_lock_read || + in_lock->type == cc_lock_downgrade); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_write_lock) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_write_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_write_lock = (in_lock->type == cc_lock_write || + in_lock->type == cc_lock_upgrade); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_client ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_pipe_compare (in_lock->client_pipe, in_client_pipe, + out_is_for_client); + } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_client (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_client_pipe = in_lock->client_pipe; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_lock.h b/src/ccapi/server/ccs_lock.h new file mode 100644 index 000000000..197f5d50d --- /dev/null +++ b/src/ccapi/server/ccs_lock.h @@ -0,0 +1,61 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LOCK_H +#define CCS_LOCK_H + +#include "ccs_types.h" + +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe); + +cc_int32 ccs_lock_release (ccs_lock_t io_lock); + +cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock); + +cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, + cc_uint32 *out_pending); + +cc_int32 ccs_lock_type (ccs_lock_t in_lock, + cc_uint32 *out_lock_type); + +cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_read_lock); + +cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_write_lock); + +cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client); + +cc_int32 ccs_lock_client (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe); + +#endif /* CCS_LOCK_H */ diff --git a/src/ccapi/server/ccs_lock_state.c b/src/ccapi/server/ccs_lock_state.c new file mode 100644 index 000000000..f9bb614c2 --- /dev/null +++ b/src/ccapi/server/ccs_lock_state.c @@ -0,0 +1,543 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_lock_state_d { + cc_int32 invalid_object_err; + cc_int32 pending_lock_err; + cc_int32 no_lock_err; + ccs_lock_array_t locks; + cc_uint64 first_pending_lock_index; +}; + +struct ccs_lock_state_d ccs_lock_state_initializer = { 1, 1, 1, NULL, 0 }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, + cc_int32 in_invalid_object_err, + cc_int32 in_pending_lock_err, + cc_int32 in_no_lock_err) +{ + cc_int32 err = ccNoError; + ccs_lock_state_t lock_state = NULL; + + if (!out_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + lock_state = malloc (sizeof (*lock_state)); + if (lock_state) { + *lock_state = ccs_lock_state_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_lock_array_new (&lock_state->locks); + } + + if (!err) { + lock_state->invalid_object_err = in_invalid_object_err; + lock_state->pending_lock_err = in_pending_lock_err; + lock_state->no_lock_err = in_no_lock_err; + + *out_lock_state = lock_state; + lock_state = NULL; + } + + ccs_lock_state_release (lock_state); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state) +{ + cc_int32 err = ccNoError; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccs_lock_array_release (io_lock_state->locks); + free (io_lock_state); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_allow_read (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_read) +{ + cc_int32 err = ccNoError; + cc_uint32 allow_read = 0; + + if (!in_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_allow_read ) { err = cci_check_error (ccErrBadParam); } + + /* A client may read if no other clients have write locks */ + + if (!err) { + cc_uint64 lock_count = in_lock_state->first_pending_lock_index; + if (lock_count == 0) { + allow_read = 1; + } else { + ccs_lock_t lock = ccs_lock_array_object_at_index (in_lock_state->locks, 0); + cc_uint32 is_read_lock; + cc_uint32 is_for_client; + + err = ccs_lock_is_read_lock (lock, &is_read_lock); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_client_pipe, &is_for_client); + } + + if (!err) { + /* read locks or write lock we own */ + allow_read = (is_read_lock || is_for_client); + } + } + } + + if (!err) { + *out_allow_read = allow_read; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_allow_write (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_write) +{ + cc_int32 err = ccNoError; + cc_uint32 allow_write = 0; + + if (!in_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_allow_write ) { err = cci_check_error (ccErrBadParam); } + + /* A client may write if there are no locks or if it has a write lock */ + + if (!err) { + cc_uint64 lock_count = in_lock_state->first_pending_lock_index; + if (lock_count == 0) { + allow_write = 1; + } else { + ccs_lock_t lock = ccs_lock_array_object_at_index (in_lock_state->locks, 0); + cc_uint32 is_write_lock = 0; + cc_uint32 is_for_client = 0; + + err = ccs_lock_is_write_lock (lock, &is_write_lock); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_client_pipe, &is_for_client); + } + + if (!err) { + allow_write = (is_write_lock && is_for_client); + } + } + } + + if (!err) { + *out_allow_write = allow_write; + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_add_pending_lock (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint64 *out_lock_index) +{ + cc_int32 err = ccNoError; + ccs_lock_t lock = NULL; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_new (&lock, in_lock_type, + io_lock_state->invalid_object_err, + in_client_pipe, in_reply_pipe); + } + + if (!err) { + err = ccs_lock_array_insert (io_lock_state->locks, lock, + ccs_lock_array_count (io_lock_state->locks)); + if (!err) { lock = NULL; /* take ownership */ } + } + + if (!err) { + *out_lock_index = ccs_lock_array_count (io_lock_state->locks) - 1; + } + + ccs_lock_release (lock); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_remove_lock (ccs_lock_state_t io_lock_state, + cc_uint64 in_lock_index) +{ + cc_int32 err = ccNoError; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_array_remove (io_lock_state->locks, in_lock_index); + + if (!err && in_lock_index < io_lock_state->first_pending_lock_index) { + io_lock_state->first_pending_lock_index--; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_grant_lock (ccs_lock_state_t io_lock_state, + cc_uint64 in_pending_lock_index) +{ + cc_int32 err = ccNoError; + cc_uint64 new_lock_index = 0; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_pending_lock_index < io_lock_state->first_pending_lock_index) { + err = cci_check_error (ccErrBadParam); + } + + if (!err) { + err = ccs_lock_array_move (io_lock_state->locks, + in_pending_lock_index, + io_lock_state->first_pending_lock_index, + &new_lock_index); + if (!err) { io_lock_state->first_pending_lock_index++; } + } + + if (!err) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, + new_lock_index); + err = ccs_lock_grant_lock (lock); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_pending_lock_client_pipe, + cc_uint32 in_pending_lock_type, + cc_uint32 *out_grant_lock) +{ + cc_int32 err = ccNoError; + cc_uint32 is_write_locked = 0; + cc_uint32 client_has_lock = 0; + cc_uint32 client_lock_type = 0; + cc_uint32 grant_lock = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_pending_lock_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_grant_lock ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + for (i = 0; !err && i < lock_count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 lock_type = 0; + cc_uint32 lock_is_for_client = 0; + + err = ccs_lock_type (lock, &lock_type); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_pending_lock_client_pipe, + &lock_is_for_client); + } + + if (!err) { + if (lock_type == cc_lock_write || lock_type == cc_lock_upgrade) { + if (is_write_locked) { + cci_debug_printf ("WARNING %s() multiple write locks.", + __FUNCTION__); + } + is_write_locked = 1; + } + + if (lock_is_for_client) { + if (client_has_lock) { + cci_debug_printf ("WARNING %s() client has multiple locks.", + __FUNCTION__); + } + client_has_lock = 1; + client_lock_type = lock_type; + } + } + } + } + + if (!err) { + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + if (in_pending_lock_type == cc_lock_write) { + if (client_has_lock) { + err = cci_check_error (ccErrBadLockType); + } else { + grant_lock = (lock_count == 0); + } + + } else if (in_pending_lock_type == cc_lock_read) { + if (client_has_lock) { + err = cci_check_error (ccErrBadLockType); + } else { + grant_lock = !is_write_locked; + } + + } else if (in_pending_lock_type == cc_lock_upgrade) { + if (!client_has_lock || (client_lock_type != cc_lock_read && + client_lock_type != cc_lock_downgrade)) { + err = cci_check_error (ccErrBadLockType); + } else { + /* don't grant if other clients have read locks */ + grant_lock = (lock_count == 1); + } + + } else if (in_pending_lock_type == cc_lock_downgrade) { + if (!client_has_lock || (client_lock_type != cc_lock_write && + client_lock_type != cc_lock_upgrade)) { + err = cci_check_error (ccErrBadLockType); + } else { + /* downgrades can never block */ + grant_lock = 1; + } + } else { + err = cci_check_error (ccErrBadLockType); + } + } + + if (!err) { + *out_grant_lock = grant_lock; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_lock_state) +{ + cc_int32 err = ccNoError; + cc_uint32 done = 1; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + /* The lock array should now be in one of two states: empty or containing + * only read locks because if it contained a write lock we would have just + * deleted it. Look at the pending locks and see if we can grant them. + * Note that downgrade locks mean we must check all pending locks each pass + * since a downgrade lock might be last in the list. */ + + + while (!err && !done) { + cc_uint64 i; + cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); + cc_uint32 granted_lock = 0; + + for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 lock_type = 0; + ccs_pipe_t client_pipe = NULL; + cc_uint32 can_grant_lock_now = 0; + + err = ccs_lock_client (lock, &client_pipe); + + if (!err) { + err = ccs_lock_type (lock, &lock_type); + } + + if (!err) { + err = ccs_lock_state_check_pending_lock (io_lock_state, client_pipe, + lock_type, &can_grant_lock_now); + } + + if (!err && can_grant_lock_now) { + err = ccs_lock_status_grant_lock (io_lock_state, i); + if (!err) { granted_lock = 1; } + } + } + + if (!err && !granted_lock) { + done = 1; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint32 in_block, + cc_uint32 *out_will_block) +{ + cc_int32 err = ccNoError; + cc_uint32 can_grant_lock_now = 0; + cc_uint32 will_block = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Sanity check: if there are any pending locks for this client + * the client must have timed out waiting for our reply. Remove any + * existing pending locks for the client. */ + cc_uint64 i; + cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); + + for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 has_pending_lock_for_client = 0; + + err = ccs_lock_is_for_client (lock, in_client_pipe, &has_pending_lock_for_client); + + if (!err && has_pending_lock_for_client) { + cci_debug_printf ("WARNING %s() removing pending lock for client.", __FUNCTION__); + err = ccs_lock_status_remove_lock (io_lock_state, i); + } + } + } + + if (!err) { + err = ccs_lock_state_check_pending_lock (io_lock_state, in_client_pipe, + in_lock_type, &can_grant_lock_now); + } + + if (!err) { + if (!can_grant_lock_now && !in_block) { + err = cci_check_error (io_lock_state->pending_lock_err); + + } else { + cc_uint64 new_lock_index = 0; + + err = ccs_lock_status_add_pending_lock (io_lock_state, + in_client_pipe, + in_reply_pipe, + in_lock_type, + &new_lock_index); + + if (!err) { + if (can_grant_lock_now) { + err = ccs_lock_status_grant_lock (io_lock_state, + new_lock_index); + + if (!err && (in_lock_type == cc_lock_downgrade)) { + /* downgrades can allow us to grant other locks */ + err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); + } + } else { + will_block = 1; + } + } + } + } + + if (!err) { + *out_will_block = will_block; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe) +{ + cc_int32 err = ccNoError; + cc_uint32 found_lock = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + for (i = 0; !err && i < lock_count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + + err = ccs_lock_is_for_client (lock, in_client_pipe, &found_lock); + + if (!err && found_lock) { + cci_debug_printf ("%s: Removing lock %p.", __FUNCTION__, lock); + err = ccs_lock_status_remove_lock (io_lock_state, i); + break; + } + } + } + + if (!err && !found_lock) { + err = cci_check_error (io_lock_state->no_lock_err); + } + + if (!err) { + err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); + } + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_lock_state.h b/src/ccapi/server/ccs_lock_state.h new file mode 100644 index 000000000..1918452c6 --- /dev/null +++ b/src/ccapi/server/ccs_lock_state.h @@ -0,0 +1,57 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LOCK_STATE_H +#define CCS_LOCK_STATE_H + +#include "ccs_types.h" + +cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, + cc_int32 in_invalid_object_err, + cc_int32 in_pending_lock_err, + cc_int32 in_no_lock_err); + +cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state); + +cc_int32 ccs_lock_state_allow_read (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_read); + +cc_int32 ccs_lock_state_allow_write (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_write); + +cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint32 in_block, + cc_uint32 *out_will_block); + +cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe); + +#endif /* CCS_LOCK_STATE_H */ diff --git a/src/ccapi/server/ccs_os_pipe.h b/src/ccapi/server/ccs_os_pipe.h new file mode 100644 index 000000000..57fe64b99 --- /dev/null +++ b/src/ccapi/server/ccs_os_pipe.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_OS_PIPE_H +#define CCS_OS_PIPE_H + +#include "ccs_types.h" + +inline cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, + ccs_os_pipe_t in_pipe); + +inline cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe); + +inline cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe); + + +#endif /* CCS_OS_PIPE_H */ diff --git a/src/ccapi/server/ccs_os_server.h b/src/ccapi/server/ccs_os_server.h new file mode 100644 index 000000000..557ad5905 --- /dev/null +++ b/src/ccapi/server/ccs_os_server.h @@ -0,0 +1,35 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_OS_SERVER_H +#define CCS_OS_SERVER_H + +#include "ccs_types.h" + +cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, + cci_stream_t in_reply_stream); + +#endif /* CCS_OS_SERVER_H */ diff --git a/src/ccapi/server/ccs_pipe.c b/src/ccapi/server/ccs_pipe.c new file mode 100644 index 000000000..d7521b57f --- /dev/null +++ b/src/ccapi/server/ccs_pipe.c @@ -0,0 +1,163 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_pipe.h" + +struct ccs_pipe_d { + ccs_os_pipe_t os_pipe; +}; + +struct ccs_pipe_d ccs_pipe_initializer = { CCS_OS_PIPE_NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, + ccs_os_pipe_t in_os_pipe) +{ + cc_int32 err = ccNoError; + ccs_pipe_t new_pipe = NULL; + + if (!out_pipe ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_os_pipe_valid (in_os_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + new_pipe = malloc (sizeof (*new_pipe)); + if (new_pipe) { + *new_pipe = ccs_pipe_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_os_pipe_copy (&new_pipe->os_pipe, in_os_pipe); + } + + if (!err) { + *out_pipe = new_pipe; + new_pipe = NULL; + } + + ccs_pipe_release (new_pipe); + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe) +{ + cc_int32 err = ccNoError; + + if (!io_pipe) { err = ccErrBadParam; } + + if (!err) { + ccs_os_pipe_release (io_pipe->os_pipe); + free (io_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, + ccs_pipe_t in_pipe) +{ + cc_int32 err = ccNoError; + + if (!out_pipe) { err = cci_check_error (ccErrBadParam); } + if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_pipe_new (out_pipe, in_pipe->os_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, + ccs_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_pipe) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_os_pipe_compare (in_pipe->os_pipe, + in_compare_to_pipe->os_pipe, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_os_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (in_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_os_pipe_compare (in_pipe->os_pipe, + in_compare_to_os_pipe, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe) +{ + if (in_pipe) { + return ccs_os_pipe_valid (in_pipe->os_pipe); + } else { + return 0; + } +} + + +/* ------------------------------------------------------------------------ */ + +ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe) +{ + if (in_pipe) { + return in_pipe->os_pipe; + } else { + return CCS_OS_PIPE_NULL; + } +} diff --git a/src/ccapi/server/ccs_pipe.h b/src/ccapi/server/ccs_pipe.h new file mode 100644 index 000000000..7f3c0d40d --- /dev/null +++ b/src/ccapi/server/ccs_pipe.h @@ -0,0 +1,52 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_PIPE_H +#define CCS_PIPE_H + +#include "ccs_types.h" + +cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, + ccs_os_pipe_t in_os_pipe); + +cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, + ccs_pipe_t in_pipe); + +inline cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe); + +cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, + ccs_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_os_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe); + +ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe); + +#endif /* CCS_PIPE_H */ diff --git a/src/ccapi/server/ccs_server.c b/src/ccapi/server/ccs_server.c new file mode 100644 index 000000000..b7d3be4b1 --- /dev/null +++ b/src/ccapi/server/ccs_server.c @@ -0,0 +1,333 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_server.h" + +/* Server Globals: */ + +cci_uuid_string_t g_server_id = NULL; +ccs_cache_collection_t g_cache_collection = NULL; +ccs_pipe_array_t g_client_pipe_array = NULL; + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_server_initialize (void) +{ + cc_int32 err = ccNoError; + + if (!err) { + err = cci_identifier_new_uuid (&g_server_id); + } + + if (!err) { + err = ccs_cache_collection_new (&g_cache_collection); + } + + if (!err) { + err = ccs_pipe_array_new (&g_client_pipe_array); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_server_cleanup (void) +{ + cc_int32 err = ccNoError; + + if (!err) { + free (g_server_id); + cci_check_error (ccs_cache_collection_release (g_cache_collection)); + cci_check_error (ccs_pipe_array_release (g_client_pipe_array)); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier) +{ + return cci_check_error (cci_identifier_new (out_identifier, + g_server_id)); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe) +{ + cc_int32 err = ccNoError; + ccs_pipe_t connection_pipe = NULL; + + if (!err) { + err = ccs_pipe_new (&connection_pipe, in_connection_os_pipe); + } + + if (!err) { + cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, connection_pipe); + err = ccs_pipe_array_insert (g_client_pipe_array, + connection_pipe, + ccs_pipe_array_count (g_client_pipe_array)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe) +{ + cc_int32 err = ccNoError; + + if (!err) { + cc_uint64 i; + cc_uint64 count = ccs_pipe_array_count (g_client_pipe_array); + cc_uint32 found = 0; + + for (i = 0; !err && i < count; i++) { + ccs_pipe_t client = ccs_pipe_array_object_at_index (g_client_pipe_array, i); + + err = ccs_pipe_compare_to_os_pipe (client, in_connection_os_pipe, &found); + + if (!err && found) { + cci_debug_printf ("%s: Removing client %p.", __FUNCTION__, client); + err = ccs_pipe_array_remove (g_client_pipe_array, i); + break; + } + } + + if (!err && !found) { + cci_debug_printf ("WARNING %s() didn't find client in client list.", + __FUNCTION__); + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_server_request_demux (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t in_cache_collection, + enum cci_msg_id_t in_request_name, + cci_identifier_t in_request_identifier, + cci_stream_t in_request_data, + cc_uint32 *out_reply_immediately, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_immediately ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_request_name > cci_context_first_msg_id && + in_request_name < cci_context_last_msg_id) { + /* Note: context identifier doesn't need to match. + * Client just uses the identifier to detect server relaunch. */ + + if (!err) { + err = ccs_cache_collection_handle_message (in_client_pipe, + in_reply_pipe, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_immediately, + out_reply_data); + } + + } else if (in_request_name > cci_ccache_first_msg_id && + in_request_name < cci_ccache_last_msg_id) { + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_find_ccache (in_cache_collection, + in_request_identifier, + &ccache); + + if (!err) { + err = ccs_ccache_handle_message (in_client_pipe, + in_reply_pipe, + ccache, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_immediately, + out_reply_data); + } + + } else if (in_request_name > cci_ccache_iterator_first_msg_id && + in_request_name < cci_ccache_iterator_last_msg_id) { + ccs_ccache_iterator_t ccache_iterator = NULL; + + err = ccs_cache_collection_find_ccache_iterator (in_cache_collection, + in_request_identifier, + &ccache_iterator); + + if (!err) { + err = ccs_ccache_iterator_handle_message (ccache_iterator, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_data); + } + + if (!err) { + *out_reply_immediately = 1; /* can't block */ + } + + } else if (in_request_name > cci_credentials_iterator_first_msg_id && + in_request_name < cci_credentials_iterator_last_msg_id) { + ccs_credentials_iterator_t credentials_iterator = NULL; + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_find_credentials_iterator (in_cache_collection, + in_request_identifier, + &ccache, + &credentials_iterator); + + if (!err) { + err = ccs_credentials_iterator_handle_message (credentials_iterator, + ccache, + in_request_name, + in_request_data, + out_reply_data); + } + + if (!err) { + *out_reply_immediately = 1; /* can't block */ + } + + } else { + err = ccErrBadInternalMessage; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cci_stream_t in_request) +{ + cc_int32 err = ccNoError; + enum cci_msg_id_t request_name = 0; + cci_identifier_t request_identifier = NULL; + cc_uint32 reply_immediately = 1; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!in_request ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_message_read_request_header (in_request, + &request_name, + &request_identifier); + } + + if (!err) { + cc_uint32 server_err = 0; + cc_uint32 valid = 0; + ccs_cache_collection_t cache_collection = g_cache_collection; + + server_err = cci_identifier_is_for_server (request_identifier, + g_server_id, + &valid); + + if (!server_err && !valid) { + server_err = cci_message_invalid_object_err (request_name); + } + + if (!server_err) { + + /* Monolithic server implementation would need to select + * cache collection here. Currently we only support per-user + * servers so we always use the same cache collection. */ + + server_err = ccs_server_request_demux (in_client_pipe, + in_reply_pipe, + cache_collection, + request_name, + request_identifier, + in_request, + &reply_immediately, + &reply_data); + } + + if (server_err || reply_immediately) { + err = ccs_server_send_reply (in_reply_pipe, server_err, reply_data); + } + } + + cci_identifier_release (request_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + cc_int32 in_reply_err, + cci_stream_t in_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply = NULL; + + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_message_new_reply_header (&reply, in_reply_err); + } + + if (!err && in_reply_data && cci_stream_size (in_reply_data) > 0) { + err = cci_stream_write (in_reply_data, + cci_stream_data (in_reply_data), + cci_stream_size (in_reply_data)); + } + + if (!err) { + err = ccs_os_server_send_reply (in_reply_pipe, reply); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_server.h b/src/ccapi/server/ccs_server.h new file mode 100644 index 000000000..713271072 --- /dev/null +++ b/src/ccapi/server/ccs_server.h @@ -0,0 +1,50 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_SERVER_H +#define CCS_SERVER_H + +#include "ccs_types.h" + +cc_int32 ccs_server_initialize (void); + +cc_int32 ccs_server_cleanup (void); + +cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier); + +cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe); + +cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe); + +cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cci_stream_t in_request); + +cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + cc_int32 in_reply_err, + cci_stream_t in_reply_data); + +#endif /* CCS_SERVER_H */ diff --git a/src/ccapi/server/ccs_types.h b/src/ccapi/server/ccs_types.h new file mode 100644 index 000000000..f96e8d39d --- /dev/null +++ b/src/ccapi/server/ccs_types.h @@ -0,0 +1,93 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_TYPES_H +#define CCS_TYPES_H + +#include "cci_types.h" + +struct cci_array_d; + +typedef struct cci_array_d *ccs_pipe_array_t; + +typedef struct cci_array_d *ccs_lock_array_t; + +#pragma mark - + +/* ccs_os_pipe_t is IPC-specific so it's special cased here */ + +#if TARGET_OS_MAC +#include +typedef mach_port_t ccs_os_pipe_t; /* Mach IPC port */ +#define CCS_OS_PIPE_NULL MACH_PORT_NULL + +#else +typedef int ccs_os_pipe_t; /* Unix domain socket */ +#define CCS_OS_PIPE_NULL -1 + +#endif + +#pragma mark - + +struct ccs_pipe_d; +typedef struct ccs_pipe_d *ccs_pipe_t; + +struct ccs_list_d; +struct ccs_list_iterator_d; + +typedef struct ccs_list_d *ccs_cache_collection_list_t; + +typedef struct ccs_list_d *ccs_ccache_list_t; +typedef struct ccs_list_iterator_d *ccs_ccache_list_iterator_t; + +typedef struct ccs_list_d *ccs_credentials_list_t; +typedef struct ccs_list_iterator_d *ccs_credentials_list_iterator_t; + +#pragma mark - + +struct ccs_client_d; +typedef struct ccs_client_d *ccs_client_t; + +struct ccs_lock_d; +typedef struct ccs_lock_d *ccs_lock_t; + +struct ccs_lock_state_d; +typedef struct ccs_lock_state_d *ccs_lock_state_t; + +struct ccs_credentials_d; +typedef struct ccs_credentials_d *ccs_credentials_t; + +typedef ccs_credentials_list_iterator_t ccs_credentials_iterator_t; + +struct ccs_ccache_d; +typedef struct ccs_ccache_d *ccs_ccache_t; + +typedef ccs_ccache_list_iterator_t ccs_ccache_iterator_t; + +struct ccs_cache_collection_d; +typedef struct ccs_cache_collection_d *ccs_cache_collection_t; + +#endif /* CCS_TYPES_H */ diff --git a/src/ccapi/server/mac/CCacheServerInfo.plist b/src/ccapi/server/mac/CCacheServerInfo.plist new file mode 100644 index 000000000..e03d5f3ff --- /dev/null +++ b/src/ccapi/server/mac/CCacheServerInfo.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + CCacheServer + CFBundleGetInfoString + 4.1 + CFBundleIconFile + + CFBundleIdentifier + edu.mit.Kerberos.CCacheServer + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Kerberos Credentials Cache Server + CFBundlePackageType + APPL + CFBundleSignature + CCSa + CFBundleVersion + 0.0.1d1 + CFBundleShortVersionString + 5.5 + CFBundleGetInfoString + 5.5 Copyright MIT + KfMDisplayVersion + 5.5 Copyright MIT + KfMDisplayCopyright + Copyright MIT + NSHumanReadableCopyright + 5.5 Copyright MIT + LSBackgroundOnly + 1 + + diff --git a/src/ccapi/server/mac/ccs_os_pipe.c b/src/ccapi/server/mac/ccs_os_pipe.c new file mode 100644 index 000000000..c3e7542a6 --- /dev/null +++ b/src/ccapi/server/mac/ccs_os_pipe.c @@ -0,0 +1,79 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_pipe.h" +#include + +/* On Mac OS X ccs_os_pipe_t is a mach_port_t */ + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, + ccs_os_pipe_t in_pipe) +{ + cc_int32 err = ccNoError; + + if (!out_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_pipe = in_pipe; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe) +{ + return ccNoError; +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!out_equal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal = (in_pipe == in_compare_to_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe) +{ + return MACH_PORT_VALID (in_pipe); +} + diff --git a/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist b/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist new file mode 100644 index 000000000..42e7f2720 --- /dev/null +++ b/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist @@ -0,0 +1,17 @@ + + + + + Label + edu.mit.Kerberos.CCacheServer + Program + /System/Library/CoreServices/CCacheServer.app/Contents/MacOS/CCacheServer + MachServices + + edu.mit.Kerberos.CCacheServer.ipcService + + + OnDemand + + + diff --git a/src/ccapi/server/mac/main.c b/src/ccapi/server/mac/main.c new file mode 100644 index 000000000..0753a240b --- /dev/null +++ b/src/ccapi/server/mac/main.c @@ -0,0 +1,233 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +#include +#include +#include "cci_mig_requestServer.h" +#include "cci_mig_reply.h" +#include "ccs_os_server.h" + +/* ------------------------------------------------------------------------ */ + +static boolean_t ccs_server_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled) { + handled = ccs_server (request, reply); + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + kern_return_t err = KERN_SUCCESS; + + err = ccs_server_remove_client (request->msgh_local_port); + + if (!err) { + /* Check here for a client in our table and free rights associated with it */ + err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, + MACH_PORT_RIGHT_RECEIVE, -1); + } + + if (!err) { + handled = 1; /* was a port we are tracking */ + } + + cci_check_error (err); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +int main (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + if (!err) { + err = ccs_server_initialize (); + } + + if (!err) { + err = kipc_server_run_server (ccs_server_demux); + } + + /* cleanup ccs resources */ + ccs_server_cleanup (); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + /* exit */ + return err ? 1 : 0; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, + mach_port_t *out_connection_port) +{ + kern_return_t err = KERN_SUCCESS; + mach_port_t connection_port = MACH_PORT_NULL; + mach_port_t old_notification_target = MACH_PORT_NULL; + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); + } + + if (!err) { + err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); + } + + if (!err) { + /* request no-senders notification so we can tell when client quits/crashes */ + err = mach_port_request_notification (mach_task_self (), connection_port, + MACH_NOTIFY_NO_SENDERS, 1, connection_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); + } + + if (!err) { + err = ccs_server_add_client (connection_port); + } + + if (!err) { + *out_connection_port = connection_port; + connection_port = MACH_PORT_NULL; + } + + if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, + cci_stream_t in_reply_stream) +{ + kern_return_t err = KERN_SUCCESS; + cci_mipc_inl_reply_t inl_reply; + mach_msg_type_number_t inl_reply_length = 0; + cci_mipc_ool_reply_t ool_reply = NULL; + mach_msg_type_number_t ool_reply_length = 0; + + if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!in_reply_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t reply_length = cci_stream_size (in_reply_stream); + + if (reply_length > kCCAPIMaxILMsgSize) { + cci_debug_printf ("%s choosing out of line buffer (size is %d)", + __FUNCTION__, reply_length); + + err = vm_read (mach_task_self (), + (vm_address_t) cci_stream_data (in_reply_stream), reply_length, + (vm_address_t *) &ool_reply, &ool_reply_length); + + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, reply_length); + + inl_reply_length = reply_length; + memcpy (inl_reply, cci_stream_data (in_reply_stream), reply_length); + } + } + + if (!err) { + err = ccs_mipc_reply (ccs_pipe_os (in_reply_pipe), + inl_reply, inl_reply_length, + ool_reply, ool_reply_length); + } + + if (!err) { + /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ + ool_reply = NULL; + ool_reply_length = 0; + } + + if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + cci_mipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + cci_mipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + cci_stream_t request_stream = NULL; + ccs_pipe_t connection_pipe = NULL; + ccs_pipe_t reply_pipe = NULL; + + if (!err) { + err = cci_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (!err) { + err = ccs_pipe_new (&connection_pipe, in_connection_port); + } + + if (!err) { + err = ccs_pipe_new (&reply_pipe, in_reply_port); + } + + if (!err) { + err = ccs_server_handle_request (connection_pipe, reply_pipe, request_stream); + } + + ccs_pipe_release (connection_pipe); + ccs_pipe_release (reply_pipe); + cci_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return cci_check_error (err); +} diff --git a/src/ccapi/test/Makefile b/src/ccapi/test/Makefile new file mode 100644 index 000000000..28d487c01 --- /dev/null +++ b/src/ccapi/test/Makefile @@ -0,0 +1,60 @@ +# run with "make all" to create CCAPI tests in "/tmp/ccapi_test" +# run resulting tests with "sh test_ccapi.sh" + +CC = gcc +LIBS = -lkrb5 + +SRCDIR = src +DSTROOT = /tmp +OBJDIR = $(DSTROOT)/ccapi_intermediates +DSTDIR = $(DSTROOT)/ccapi_test +TESTDIR = $(DSTDIR)/tests + +SCRIPT_NAME = test_ccapi.sh + +_OBJECTS = test_ccapi_ccache test_ccapi_check test_ccapi_constants test_ccapi_context test_ccapi_globals test_ccapi_iterators test_ccapi_log test_ccapi_util + +OBJECTS = $(patsubst %,$(OBJDIR)/%.o,$(_OBJECTS)) + +TEST_NAMES = test_constants test_cc_initialize test_cc_context_get_version test_cc_context_release test_cc_context_get_change_time test_cc_context_get_default_ccache_name test_cc_context_open_ccache test_cc_context_open_default_ccache test_cc_context_create_ccache test_cc_context_create_default_ccache test_cc_context_create_new_ccache test_cc_context_new_ccache_iterator test_cc_context_compare test_cc_ccache_release test_cc_ccache_destroy test_cc_ccache_set_default test_cc_ccache_get_credentials_version test_cc_ccache_get_name test_cc_ccache_get_principal test_cc_ccache_set_principal test_cc_ccache_store_credentials test_cc_ccache_remove_credentials test_cc_ccache_new_credentials_iterator test_cc_ccache_get_change_time test_cc_ccache_get_last_default_time test_cc_ccache_move test_cc_ccache_compare test_cc_ccache_get_kdc_time_offset test_cc_ccache_set_kdc_time_offset test_cc_ccache_clear_kdc_time_offset test_cc_ccache_iterator_next test_cc_credentials_iterator_next + +TEST_OBJECTS = $(patsubst %,$(OBJDIR)/%.o,$(TEST_NAMES)) + +all: setup-test-dir build-base build-tests link-tests copy-script success-message + +# compile base files used by all tests +build-base: $(OBJECTS) + +# compile each test +build-tests: $(TEST_OBJECTS) + +# rule to compile files in src directory +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(CC) -c -o $@ $< + +# Make a build directory +setup-test-dir: + @echo "Removing old destination directory... $(DSTDIR)" + if [ -d "$(DSTDIR)" ]; then chmod -R u+w "$(DSTDIR)" && rm -rf "$(DSTDIR)"; fi + mkdir -p "$(TESTDIR)" + if [ -d "$(OBJDIR)" ]; then chmod -R u+w "$(OBJDIR)" && rm -rf "$(OBJDIR)"; fi + mkdir -p "$(OBJDIR)" + +link-tests: $(TEST_NAMES) + +$(TEST_NAMES): $(TEST_OBJECTS) + $(CC) -o $(TESTDIR)/$@ $(OBJDIR)/$@.o $(OBJECTS) $(LIBS) + +copy-script: + cp $(SRCDIR)/$(SCRIPT_NAME) $(DSTDIR)/$(SCRIPT_NAME) + +success-message: + @echo + @echo "CCAPI tests created in $(DSTDIR)" + +.PHONY: clean + +clean: + -rm -rf "$(OBJDIR)" + + diff --git a/src/ccapi/test/main.c b/src/ccapi/test/main.c new file mode 100644 index 000000000..94176f5e6 --- /dev/null +++ b/src/ccapi/test/main.c @@ -0,0 +1,69 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; +// cc_ccache_iterator_t cache_iterator = NULL; +// cc_credentials_iterator_t cred_iterator = NULL; + + fprintf(stdout, "Testing CCAPI against CCAPI v3 rev 8 documentation...\n"); + fprintf(stdout, "Warning: this test suite is woefully incomplete and unpolished.\n"); + + T_CCAPI_INIT; + + err = check_constants(); + + // *** cc_context *** + err = check_cc_initialize(); + err = check_cc_context_get_version(); + err = check_cc_context_release(); + err = check_cc_context_get_change_time(); + err = check_cc_context_get_default_ccache_name(); + err = check_cc_context_open_ccache(); + err = check_cc_context_open_default_ccache(); + err = check_cc_context_create_ccache(); + err = check_cc_context_create_default_ccache(); + err = check_cc_context_create_new_ccache(); + err = check_cc_context_new_ccache_iterator(); + // err = check_cc_context_lock(); + // err = check_cc_context_unlock(); + err = check_cc_context_compare(); + + // *** cc_ccache *** + err = check_cc_ccache_release(); + err = check_cc_ccache_destroy(); + err = check_cc_ccache_set_default(); + err = check_cc_ccache_get_credentials_version(); + err = check_cc_ccache_get_name(); + err = check_cc_ccache_get_principal(); + err = check_cc_ccache_set_principal(); + err = check_cc_ccache_store_credentials(); + err = check_cc_ccache_remove_credentials(); + err = check_cc_ccache_new_credentials_iterator(); + // err = check_cc_ccache_lock(); + // err = check_cc_ccache_unlock(); + err = check_cc_ccache_get_change_time(); + err = check_cc_ccache_get_last_default_time(); + err = check_cc_ccache_move(); + err = check_cc_ccache_compare(); + err = check_cc_ccache_get_kdc_time_offset(); + err = check_cc_ccache_set_kdc_time_offset(); + err = check_cc_ccache_clear_kdc_time_offset(); + + // *** cc_ccache_iterator *** + err = check_cc_ccache_iterator_next(); + + // *** cc_credentials_iterator *** + err = check_cc_credentials_iterator_next(); + + fprintf(stdout, "\nFinished testing CCAPI. %d failure%s in total.\n", total_failure_count, (total_failure_count == 1) ? "" : "s"); + + return err; +} diff --git a/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c b/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c new file mode 100644 index 000000000..ea6300785 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_clear_kdc_time_offset(); + return err; +} diff --git a/src/ccapi/test/test_cc_ccache_compare.c b/src/ccapi/test/test_cc_ccache_compare.c new file mode 100644 index 000000000..aec606bb5 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_compare.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_compare(); + return err; +} diff --git a/src/ccapi/test/test_cc_ccache_destroy.c b/src/ccapi/test/test_cc_ccache_destroy.c new file mode 100644 index 000000000..ee589e25b --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_destroy.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_destroy(); + return err; +} diff --git a/src/ccapi/test/test_cc_ccache_get_change_time.c b/src/ccapi/test/test_cc_ccache_get_change_time.c new file mode 100644 index 000000000..44d4c2c10 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_change_time.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_change_time(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_get_credentials_version.c b/src/ccapi/test/test_cc_ccache_get_credentials_version.c new file mode 100644 index 000000000..4f16c9de7 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_credentials_version.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_credentials_version(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c b/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c new file mode 100644 index 000000000..f3591a3f3 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_kdc_time_offset(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_get_last_default_time.c b/src/ccapi/test/test_cc_ccache_get_last_default_time.c new file mode 100644 index 000000000..a2c9e2557 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_last_default_time.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_last_default_time(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_get_name.c b/src/ccapi/test/test_cc_ccache_get_name.c new file mode 100644 index 000000000..749bd9381 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_name.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_name(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_get_principal.c b/src/ccapi/test/test_cc_ccache_get_principal.c new file mode 100644 index 000000000..8ab935cc9 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_get_principal.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_get_principal(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_iterator_next.c b/src/ccapi/test/test_cc_ccache_iterator_next.c new file mode 100644 index 000000000..8e124e511 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_iterator_next.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_iterator_next(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_move.c b/src/ccapi/test/test_cc_ccache_move.c new file mode 100644 index 000000000..49790e499 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_move.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_move(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c b/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c new file mode 100644 index 000000000..fc1acbfb3 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_new_credentials_iterator(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_release.c b/src/ccapi/test/test_cc_ccache_release.c new file mode 100644 index 000000000..1cd2d91f5 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_release.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_release(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_remove_credentials.c b/src/ccapi/test/test_cc_ccache_remove_credentials.c new file mode 100644 index 000000000..00fe8c1b1 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_remove_credentials.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_remove_credentials(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_set_default.c b/src/ccapi/test/test_cc_ccache_set_default.c new file mode 100644 index 000000000..40d9bbdc5 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_set_default.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_set_default(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c b/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c new file mode 100644 index 000000000..f8f9a86cc --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_set_kdc_time_offset(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_set_principal.c b/src/ccapi/test/test_cc_ccache_set_principal.c new file mode 100644 index 000000000..b9b52304b --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_set_principal.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_set_principal(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_ccache_store_credentials.c b/src/ccapi/test/test_cc_ccache_store_credentials.c new file mode 100644 index 000000000..0676d4d07 --- /dev/null +++ b/src/ccapi/test/test_cc_ccache_store_credentials.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_ccache_store_credentials(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_compare.c b/src/ccapi/test/test_cc_context_compare.c new file mode 100644 index 000000000..6155618fb --- /dev/null +++ b/src/ccapi/test/test_cc_context_compare.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_compare(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_create_ccache.c b/src/ccapi/test/test_cc_context_create_ccache.c new file mode 100644 index 000000000..dd65a538a --- /dev/null +++ b/src/ccapi/test/test_cc_context_create_ccache.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_create_ccache(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_create_default_ccache.c b/src/ccapi/test/test_cc_context_create_default_ccache.c new file mode 100644 index 000000000..b7ef872c9 --- /dev/null +++ b/src/ccapi/test/test_cc_context_create_default_ccache.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_create_default_ccache(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_create_new_ccache.c b/src/ccapi/test/test_cc_context_create_new_ccache.c new file mode 100644 index 000000000..b460f3a62 --- /dev/null +++ b/src/ccapi/test/test_cc_context_create_new_ccache.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_create_new_ccache(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_get_change_time.c b/src/ccapi/test/test_cc_context_get_change_time.c new file mode 100644 index 000000000..e6e601885 --- /dev/null +++ b/src/ccapi/test/test_cc_context_get_change_time.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_get_change_time(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_get_default_ccache_name.c b/src/ccapi/test/test_cc_context_get_default_ccache_name.c new file mode 100644 index 000000000..a0514af5b --- /dev/null +++ b/src/ccapi/test/test_cc_context_get_default_ccache_name.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_get_default_ccache_name(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_get_version.c b/src/ccapi/test/test_cc_context_get_version.c new file mode 100644 index 000000000..f3ea8b9f4 --- /dev/null +++ b/src/ccapi/test/test_cc_context_get_version.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_get_version(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_new_ccache_iterator.c b/src/ccapi/test/test_cc_context_new_ccache_iterator.c new file mode 100644 index 000000000..7f8937666 --- /dev/null +++ b/src/ccapi/test/test_cc_context_new_ccache_iterator.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_new_ccache_iterator(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_open_ccache.c b/src/ccapi/test/test_cc_context_open_ccache.c new file mode 100644 index 000000000..7212402c1 --- /dev/null +++ b/src/ccapi/test/test_cc_context_open_ccache.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_open_ccache(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_open_default_ccache.c b/src/ccapi/test/test_cc_context_open_default_ccache.c new file mode 100644 index 000000000..00e0afdef --- /dev/null +++ b/src/ccapi/test/test_cc_context_open_default_ccache.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_open_default_ccache(); + return err; +} + \ No newline at end of file diff --git a/src/ccapi/test/test_cc_context_release.c b/src/ccapi/test/test_cc_context_release.c new file mode 100644 index 000000000..5d7d49cb9 --- /dev/null +++ b/src/ccapi/test/test_cc_context_release.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_context_release(); + return err; +} diff --git a/src/ccapi/test/test_cc_credentials_iterator_next.c b/src/ccapi/test/test_cc_credentials_iterator_next.c new file mode 100644 index 000000000..f66a2f77f --- /dev/null +++ b/src/ccapi/test/test_cc_credentials_iterator_next.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_credentials_iterator_next(); + return err; +} diff --git a/src/ccapi/test/test_cc_initialize.c b/src/ccapi/test/test_cc_initialize.c new file mode 100644 index 000000000..47eeb3631 --- /dev/null +++ b/src/ccapi/test/test_cc_initialize.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_cc_initialize(); + return err; +} diff --git a/src/ccapi/test/test_ccapi_ccache.c b/src/ccapi/test/test_ccapi_ccache.c new file mode 100644 index 000000000..cba481c75 --- /dev/null +++ b/src/ccapi/test/test_ccapi_ccache.c @@ -0,0 +1,2025 @@ +#include "test_ccapi_ccache.h" + +#include +#include +#include +#include +#include "test_ccapi_check.h" +#include "test_ccapi_util.h" + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_release() { + BEGIN_TEST("cc_ccache_release"); + + #ifndef cc_ccache_release + log_error("cc_ccache_release is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + + + if (!err) { + check_once_cc_ccache_release(context, ccache, ccNoError, NULL); + ccache = NULL; + } + + if (context) { cc_context_release(context); } + + #endif /* cc_ccache_release */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_release(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_release + + cc_int32 possible_return_values[2] = { + ccNoError, + ccErrInvalidCCache, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_string_t name = NULL; + + err = cc_ccache_get_name(ccache, &name); + err = cc_ccache_release(ccache); + ccache = NULL; + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && name) { // try opening released ccache to make sure it still exists + err = cc_context_open_ccache(context, name->data, &ccache); + } + check_if(err == ccErrCCacheNotFound, "released ccache was actually destroyed instead"); + + if (ccache) { cc_ccache_destroy(ccache); } + if (name) { cc_string_release(name); } + + #endif /* cc_ccache_release */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_destroy() { + BEGIN_TEST("cc_ccache_destroy"); + + #ifndef cc_ccache_destroy + log_error("cc_ccache_destroy is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + + + if (!err) { + check_once_cc_ccache_destroy(context, ccache, ccNoError, NULL); + ccache = NULL; + } + + if (context) { cc_context_release(context); } + + #endif /* cc_ccache_destroy */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_destroy(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_destroy + + cc_int32 possible_return_values[2] = { + ccNoError, + ccErrInvalidCCache, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_string_t name = NULL; + + err = cc_ccache_get_name(ccache, &name); + err = cc_ccache_destroy(ccache); + ccache = NULL; + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && name) { // try opening released ccache to make sure it still exists + err = cc_context_open_ccache(context, name->data, &ccache); + } + check_if(err != ccErrCCacheNotFound, "destroyed ccache was actually released instead"); + + if (ccache) { cc_ccache_destroy(ccache); } + if (name) { cc_string_release(name); } + + #endif /* cc_ccache_destroy */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_set_default() { + BEGIN_TEST("cc_ccache_set_default"); + + #ifndef cc_ccache_set_default + log_error("cc_ccache_set_default is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + // try when it's the only ccache (already default) + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's the only ccache (already default)"); + } + if (ccache) { + err = cc_ccache_release(ccache); + ccache = NULL; + } + + // try when it's not the only ccache (and not default) + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and not default)"); + } + if (ccache) { + err = cc_ccache_release(ccache); + ccache = NULL; + } + + // try when it's not the only ccache (and already default) + if (!err) { + err = cc_context_open_default_ccache(context, &ccache); + } + if (!err) { + check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and already default)"); + } + if (ccache) { + err = cc_ccache_release(ccache); + ccache = NULL; + } + + if (!err) { + err = destroy_all_ccaches(context); + } + + if (context) { cc_context_release(context); } + + #endif /* cc_ccache_set_default */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_set_default(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_set_default + + cc_int32 possible_return_values[3] = { + ccNoError, + ccErrInvalidCCache, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_ccache_t default_ccache = NULL; + cc_string_t name = NULL; + cc_string_t default_name = NULL; + + err = cc_ccache_set_default(ccache); + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + err = cc_ccache_get_name(ccache, &name); + } + if (!err) { + err = cc_context_open_default_ccache(context, &default_ccache); + } + if (!err) { + err = cc_ccache_get_name(default_ccache, &default_name); + } + if (name && default_name) { + check_if(strcmp(name->data, default_name->data), NULL); + } + else { + check_if(1, "cc_ccache_get_name failed"); + } + + if (default_ccache) { cc_ccache_release(default_ccache); } + //if (ccache) { cc_ccache_destroy(ccache); } // ccache is released by the caller + if (default_name) { cc_string_release(default_name); } + if (name) { cc_string_release(name); } + + #endif /* cc_ccache_set_default */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_get_credentials_version() { + BEGIN_TEST("cc_ccache_get_credentials_version"); + + #ifndef cc_ccache_get_credentials_version + log_error("cc_ccache_get_credentials_version is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + // try one created with v5 creds + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v5, ccNoError, "v5 creds"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + + // try it with added v4 creds + if (!err) { + err = cc_ccache_set_principal(ccache, cc_credentials_v4, "foo@BAR.ORG"); + } + if (!err) { + check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v5 with v4 creds added"); + } + else { + log_error("cc_ccache_set_principal failed, can't complete test"); + failure_count++; + } + + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + err = ccNoError; + + // try one created with v4 creds + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4, ccNoError, "v4 creds"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + + // try it with added v5 creds + if (!err) { + err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); + } + if (!err) { + check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v4 with v5 creds added"); + } + else { + log_error("cc_ccache_set_principal failed, can't complete test"); + failure_count++; + } + + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + if (context) { cc_context_release(context); } + + #endif /* cc_ccache_get_credentials_version */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_credentials_version(cc_ccache_t ccache, cc_uint32 expected_cred_vers, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_credentials_version + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidCCache, + ccErrBadParam, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_uint32 stored_cred_vers = 0; + + err = cc_ccache_get_credentials_version(ccache, &stored_cred_vers); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(stored_cred_vers != expected_cred_vers, NULL); + } + + #endif /* cc_ccache_get_credentials_version */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_get_name() { + BEGIN_TEST("cc_ccache_get_name"); + + #ifndef cc_ccache_get_name + log_error("cc_ccache_get_name is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // try with unique ccache (which happens to be default) + if (!err) { + err = cc_context_create_ccache(context, "0", cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_name(ccache, "0", ccNoError, "unique ccache (which happens to be default)"); + } + else { + log_error("cc_context_create_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + // try with unique ccache (which is not default) + if (!err) { + err = cc_context_create_ccache(context, "1", cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_name(ccache, "1", ccNoError, "unique ccache (which is not default)"); + } + else { + log_error("cc_context_create_ccache failed, can't complete test"); + failure_count++; + } + + // try with bad param + if (!err) { + check_once_cc_ccache_get_name(ccache, NULL, ccErrBadParam, "NULL param"); + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_get_name */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_name(cc_ccache_t ccache, const char *expected_name, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_name + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidCCache, + ccErrBadParam, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_string_t stored_name = NULL; + + if (expected_name == NULL) { // we want to try with a NULL param + err = cc_ccache_get_name(ccache, NULL); + } + else { + err = cc_ccache_get_name(ccache, &stored_name); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(strcmp(stored_name->data, expected_name), NULL); + } + + if (stored_name) { cc_string_release(stored_name); } + + #endif /* cc_ccache_get_name */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_get_principal() { + BEGIN_TEST("cc_ccache_get_principal"); + + #ifndef cc_ccache_get_principal + log_error("cc_ccache_get_principal is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // try with krb5 principal + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo/BAR@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, "foo/BAR@BAZ.ORG", ccNoError); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + // try with krb4 principal + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo.BAR@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_get_principal(ccache, cc_credentials_v4, "foo.BAR@BAZ.ORG", ccNoError); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + + // try with bad param + if (!err) { + // cc_ccache_t doesn't have any concept of the difference between a v4 and v5 principal + check_once_cc_ccache_get_principal(ccache, cc_credentials_v4_v5, "foo.BAR@BAZ.ORG", + ccErrBadCredentialsVersion, + "passing cc_credentials_v4_v5 (shouldn't be allowed)"); + check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam); + } + + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_get_principal */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *expected_principal, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_principal + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrNoMem, + ccErrBadCredentialsVersion, + ccErrBadParam, + ccErrInvalidCCache, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_string_t stored_principal = NULL; + + if (expected_principal == NULL) { // we want to try with a NULL param + err = cc_ccache_get_principal(ccache, cred_vers, NULL); + } + else { + err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(strcmp(stored_principal->data, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal->data); + } + + if (stored_principal) { cc_string_release(stored_principal); } + + #endif /* cc_ccache_get_principal */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_set_principal() { + BEGIN_TEST("cc_ccache_set_principal"); + + #ifndef cc_ccache_set_principal + log_error("cc_ccache_set_principal is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // bad params + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_principal(ccache, cc_credentials_v4_v5, "foo/BAZ@BAR.ORG", ccErrBadCredentialsVersion, "cc_credentials_v4_v5 (not allowed)"); + check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL principal"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + + // empty ccache + + // replace v5 only ccache's principal + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "replace v5 only ccache's principal (empty ccache)"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + // add v4 principal to v5 only ccache + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "add v4 principal to v5 only ccache (empty ccache)"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + // replace v4 only ccache's principal + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "replace v4 only ccache's principal (empty ccache)"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + // add v5 principal to v4 only ccache + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache); + } + if (!err) { + check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "add v5 principal to v4 only ccache (empty ccache)"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; + } + + // with credentials + + // replace v5 only ccache's principal + + // add v4 principal to v5 only ccache + + // replace v4 only ccache's principal + + // add v5 principal to v4 only ccache + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_set_principal */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_set_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_set_principal + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrNoMem, + ccErrInvalidCCache, + ccErrBadCredentialsVersion, + ccErrBadParam, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_string_t stored_principal = NULL; + + err = cc_ccache_set_principal(ccache, cred_vers, in_principal); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal); + } + + // compare stored with input + if (!err) { + check_if(strcmp(stored_principal->data, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal->data); + } + + if (stored_principal) { cc_string_release(stored_principal); } + + #endif /* cc_ccache_set_principal */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_store_credentials() { + BEGIN_TEST("cc_ccache_store_credentials"); + + #ifndef cc_ccache_store_credentials + log_error("cc_ccache_store_credentials is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_ccache_t dup_ccache = NULL; + cc_credentials_union creds_union; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + // cred with matching version and realm + if (!err) { + err = new_v5_creds_union(&creds_union, "BAR.ORG"); + } + + if (!err) { + check_once_cc_ccache_store_credentials(ccache, &creds_union, ccNoError, "ok creds"); + } + + if (&creds_union) { release_v5_creds_union(&creds_union); } + + // try with bad params + check_once_cc_ccache_store_credentials(ccache, NULL, ccErrInvalidCredentials, "NULL creds param"); + + // invalid creds + if (!err) { + err = new_v5_creds_union(&creds_union, "BAR.ORG"); + } + + if (!err) { + if (creds_union.credentials.credentials_v5->client) { + free(creds_union.credentials.credentials_v5->client); + creds_union.credentials.credentials_v5->client = NULL; + } + check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrInvalidCredentials, "invalid creds (NULL client string)"); + } + + if (&creds_union) { release_v5_creds_union(&creds_union); } + + // bad creds version + if (!err) { + err = new_v5_creds_union(&creds_union, "BAR.ORG"); + } + + if (!err) { + creds_union.version = cc_credentials_v4_v5; + check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4_v5 creds (invalid) into a ccache with only v5 princ"); + creds_union.version = cc_credentials_v4; + check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4 creds into a ccache with only v5 princ"); + creds_union.version = cc_credentials_v5; + } + + if (&creds_union) { release_v5_creds_union(&creds_union); } + + // non-existent ccache + if (ccache) { + err = cc_ccache_get_name(ccache, &name); + if (!err) { + err = cc_context_open_ccache(context, name->data, &dup_ccache); + } + if (name) { cc_string_release(name); } + if (dup_ccache) { cc_ccache_destroy(dup_ccache); } + } + + if (!err) { + err = new_v5_creds_union(&creds_union, "BAR.ORG"); + } + + if (!err) { + check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrInvalidCCache, "invalid ccache"); + } + + if (&creds_union) { release_v5_creds_union(&creds_union); } + if (ccache) { cc_ccache_release(ccache); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_store_credentials */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_store_credentials(cc_ccache_t ccache, const cc_credentials_union *credentials, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_store_credentials + + cc_int32 possible_return_values[5] = { + ccNoError, + ccErrInvalidCCache, + ccErrInvalidCredentials, + ccErrBadCredentialsVersion, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_credentials_iterator_t creds_iterator = NULL; + cc_credentials_t creds = NULL; + + err = cc_ccache_store_credentials(ccache, credentials); + + // check returned error + check_err(err, expected_err, possible_return_values); + + // make sure credentials were truly stored + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); + } + while (!err) { + err = cc_credentials_iterator_next(creds_iterator, &creds); + if (creds) { + if (compare_v5_creds_unions(credentials, creds->data) == 0) { + break; + } + cc_credentials_release(creds); + creds = NULL; + } + } + + if (err == ccIteratorEnd) { + check_if((creds != NULL), "stored credentials not found in ccache"); + err = ccNoError; + } + if (creds) { cc_credentials_release(creds); } + + #endif /* cc_ccache_store_credentials */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_remove_credentials() { + BEGIN_TEST("cc_ccache_remove_credentials"); + + #ifndef cc_ccache_remove_credentials + log_error("cc_ccache_remove_credentials is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_ccache_t dup_ccache = NULL; + cc_credentials_t creds_array[10]; + cc_credentials_t creds = NULL; + cc_credentials_union creds_union; + cc_credentials_iterator_t creds_iterator = NULL; + cc_string_t name = NULL; + unsigned int i; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + // store 10 creds and retrieve their cc_credentials_t representations + for(i = 0; !err && (i < 10); i++) { + new_v5_creds_union(&creds_union, "BAR.ORG"); + err = cc_ccache_store_credentials(ccache, &creds_union); + if (&creds_union) { release_v5_creds_union(&creds_union); } + } + if (err) { + log_error("failure to store creds_union in remove_creds test"); + } + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); + } + i = 0; + while (!err && i < 10) { + err = cc_credentials_iterator_next(creds_iterator, &creds); + if (creds) { + creds_array[i++] = creds; + creds = NULL; + } + } + if (err == ccIteratorEnd) { err = ccNoError; } + + // remove 10 valid creds + for (i = 0; !err && (i < 8); i++) { + check_once_cc_ccache_remove_credentials(ccache, creds_array[i], ccNoError, "10 ok creds"); + } + + // NULL param + check_once_cc_ccache_remove_credentials(ccache, NULL, ccErrInvalidCredentials, "NULL creds in param"); + + // non-existent creds (remove same one twice) + check_once_cc_ccache_remove_credentials(ccache, creds_array[0], ccErrCredentialsNotFound, "removed same creds twice"); + + // non-existent ccache + if (ccache) { + err = cc_ccache_get_name(ccache, &name); + if (!err) { + err = cc_context_open_ccache(context, name->data, &dup_ccache); + } + if (name) { cc_string_release(name); } + if (dup_ccache) { cc_ccache_destroy(dup_ccache); } + } + + if (!err) { + err = new_v5_creds_union(&creds_union, "BAR.ORG"); + } + + if (!err) { + check_once_cc_ccache_remove_credentials(ccache, creds_array[8], ccErrInvalidCCache, "invalid ccache"); + } + + for(i = 0; i < 10; i++) { + if (creds_array[i]) { cc_credentials_release(creds_array[i]); } + } + + if (ccache) { cc_ccache_release(ccache); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_remove_credentials */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_remove_credentials(cc_ccache_t ccache, cc_credentials_t in_creds, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_remove_credentials + + cc_int32 possible_return_values[5] = { + ccNoError, + ccErrInvalidCCache, + ccErrInvalidCredentials, + ccErrCredentialsNotFound, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_credentials_iterator_t creds_iterator = NULL; + cc_credentials_t creds = NULL; + + err = cc_ccache_remove_credentials(ccache, in_creds); + + // check returned error + check_err(err, expected_err, possible_return_values); + + // make sure credentials were truly removed + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); + } + while (!err) { + err = cc_credentials_iterator_next(creds_iterator, &creds); + if (creds) { + if (compare_v5_creds_unions(in_creds->data, creds->data) == 0) { + break; + } + cc_credentials_release(creds); + creds = NULL; + } + } + + if (err == ccIteratorEnd) { + err = ccNoError; + } + else { + check_if((creds != NULL), "credentials not removed from ccache"); + } + if (creds) { cc_credentials_release(creds); } + + #endif /* cc_ccache_remove_credentials */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_new_credentials_iterator() { + BEGIN_TEST("cc_ccache_new_credentials_iterator"); + + #ifndef cc_ccache_new_credentials_iterator + log_error("cc_ccache_new_credentials_iterator is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_ccache_t dup_ccache = NULL; + cc_credentials_iterator_t creds_iterator = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + // valid params + if (!err) { + check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccNoError, "valid params"); + } + if (creds_iterator) { + cc_credentials_iterator_release(creds_iterator); + creds_iterator = NULL; + } + + // NULL out param + if (!err) { + check_once_cc_ccache_new_credentials_iterator(ccache, NULL, ccErrBadParam, "NULL out iterator param"); + } + if (creds_iterator) { + cc_credentials_iterator_release(creds_iterator); + creds_iterator = NULL; + } + + // non-existent ccache + if (ccache) { + err = cc_ccache_get_name(ccache, &name); + if (!err) { + err = cc_context_open_ccache(context, name->data, &dup_ccache); + } + if (name) { cc_string_release(name); } + if (dup_ccache) { cc_ccache_destroy(dup_ccache); } + } + + if (!err) { + check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccErrCCacheNotFound, "invalid ccache"); + } + + if (creds_iterator) { + cc_credentials_iterator_release(creds_iterator); + creds_iterator = NULL; + } + if (ccache) { cc_ccache_release(ccache); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_new_credentials_iterator */ + + END_TEST_AND_RETURN +} + + +cc_int32 check_once_cc_ccache_new_credentials_iterator(cc_ccache_t ccache, cc_credentials_iterator_t *iterator, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_new_credentials_iterator + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrBadParam, + ccErrNoMem, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_ccache_new_credentials_iterator(ccache, iterator); + + // check returned error + check_err(err, expected_err, possible_return_values); + + #endif /* cc_ccache_new_credentials_iterator */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_get_change_time() { + BEGIN_TEST("cc_ccache_get_change_time"); + + #ifndef cc_ccache_get_change_time + log_error("cc_ccache_get_change_time is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t dummy_ccache = NULL; + cc_ccache_t ccache = NULL; + cc_credentials_union creds_union; + cc_credentials_iterator_t creds_iterator = NULL; + cc_credentials_t credentials = NULL; + cc_time_t last_time = 0; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // create some ccaches (so that the one we keep around as 'ccache' is not default) + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (ccache) { + cc_ccache_release(ccache); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); + } + + // change it in all the ways it can change, checking after each + + // the ccache is created + if (!err) { + check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "new ccache (change time should be > 0)"); + } + + // the ccache is made default + if (!err) { + err = cc_ccache_set_default(ccache); + } + if (!err) { + check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "non-default ccache became default"); + } + + // the ccache is made not-default + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "something@ELSE.COM", &dummy_ccache); + } + if (!err) { + err = cc_ccache_set_default(dummy_ccache); + } + if (dummy_ccache) { + cc_ccache_release(dummy_ccache); + } + if (!err) { + check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "default ccache became non-default"); + } + + // try with bad params + + // NULL out param + if (!err) { + check_once_cc_ccache_get_change_time(ccache, NULL, ccErrBadParam, "NULL out param for time"); + } + + // store a credential + if (!err) { + new_v5_creds_union(&creds_union, "BAR.ORG"); + err = cc_ccache_store_credentials(ccache, &creds_union); + release_v5_creds_union(&creds_union); + } + check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "stored new credential"); + + if (!err) { + // change principal (fails with ccErrBadInternalMessage) + err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); + if (err) { + log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + err = ccNoError; + } + } + check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after changing a principle"); + + // remove a credential + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); + } + if (!err) { + err = cc_credentials_iterator_next(creds_iterator, &credentials); + } + if (err == ccIteratorEnd) { + err = ccNoError; + } + if (!err) { + err = cc_ccache_remove_credentials(ccache, credentials); + } + check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after removing a credential"); + + + // invalid ccache + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + check_once_cc_ccache_get_change_time(ccache, &last_time, ccErrInvalidCCache, "getting change time on destroyed ccache"); + } + + if (ccache) { cc_ccache_release(ccache); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_get_change_time */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_change_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_change_time + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidCCache, + ccErrBadParam, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t this_time = 0; + + if (last_time == NULL) { + err = cc_ccache_get_change_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead + } else { + err = cc_ccache_get_change_time(ccache, &this_time); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if ((!err) && last_time) { + check_if(this_time <= *last_time, "change time didn't increase when expected"); + *last_time = this_time; + } + + #endif /* cc_ccache_get_change_time */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_get_last_default_time() { + BEGIN_TEST("cc_ccache_get_last_default_time"); + + #ifndef cc_ccache_get_last_default_time + log_error("cc_ccache_get_last_default_time is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache_1 = NULL; + cc_ccache_t ccache_2 = NULL; + cc_time_t last_time_1 = 0; + cc_time_t last_time_2 = 0; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // create 2 ccaches + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &ccache_1); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &ccache_2); + } + + if (!err) { + err = cc_ccache_get_change_time(ccache_1, &last_time_1); + } + + // since we destroyed all ccaches before creating these two, + // ccache_1 should be default and ccache_2 should never have been default + if (!err) { + check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 default at creation"); + check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccErrNeverDefault, "ccache_2 never default"); + } + + // make ccache_2 default and check each of their times again + if (!err) { + err = cc_ccache_set_default(ccache_2); + } + if (!err) { + err = cc_ccache_get_change_time(ccache_2, &last_time_2); + } + if (!err) { + check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 no longer default"); + check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccNoError, "ccache_2 newly default"); + } + + // NULL param + if (!err) { + check_once_cc_ccache_get_last_default_time(ccache_1, NULL, ccErrBadParam, "NULL out param"); + } + + // non-existent ccache + if (ccache_2) { + cc_ccache_release(ccache_2); + ccache_2 = NULL; + } + if (!err) { + err = cc_ccache_get_name(ccache_1, &name); + } + if (!err) { + err = cc_context_open_ccache(context, name->data, &ccache_2); + } + if (!err) { + cc_ccache_destroy(ccache_2); + ccache_2 = NULL; + } + + if (!err) { + check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccErrCCacheNotFound, "destroyed ccache"); + } + + if (ccache_1) { cc_ccache_release(ccache_1); } + + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_get_last_default_time */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_last_default_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_last_default_time + + cc_int32 possible_return_values[5] = { + ccNoError, + ccErrInvalidCCache, + ccErrBadParam, + ccErrNeverDefault, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t this_time = 0; + + if (last_time == NULL) { + err = cc_ccache_get_last_default_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead + } else { + err = cc_ccache_get_last_default_time(ccache, &this_time); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && last_time) { + check_if(this_time > *last_time, "last default time isn't as expected"); + *last_time = this_time; + } + + #endif /* cc_ccache_get_last_default_time */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + + +int check_cc_ccache_move() { + BEGIN_TEST("cc_ccache_move"); + + #ifndef cc_ccache_move + log_error("cc_ccache_move is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t source = NULL; + cc_ccache_t destination = NULL; + + cc_credentials_union creds_union; + unsigned int i = 0; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // create 2 ccaches + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &source); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &destination); + } + + // store credentials in each + for (i = 0; !err && (i < 10); i++) { + new_v5_creds_union(&creds_union, "ONE.ORG"); + err = cc_ccache_store_credentials(source, &creds_union); + } + for (i = 0; !err && (i < 10); i++) { + new_v5_creds_union(&creds_union, "TWO.ORG"); + err = cc_ccache_store_credentials(destination, &creds_union); + } + + // move source into destination + if (!err) { + check_once_cc_ccache_move(source, destination, ccNoError, "valid params"); + } + + // NULL param + if (!err) { + check_once_cc_ccache_move(destination, NULL, ccErrInvalidCCache, "NULL destination param"); + } + + // non-existent ccache + if (!err) { + check_once_cc_ccache_move(destination, source, ccErrInvalidCCache, "recently moved source as destination param"); + } + + if (source) { cc_ccache_release(source); } + if (destination) { cc_ccache_release(destination); } + + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_move */ + + END_TEST_AND_RETURN + + +} + +cc_int32 check_once_cc_ccache_move(cc_ccache_t source, cc_ccache_t destination, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_move + + cc_int32 possible_return_values[3] = { + ccNoError, + ccErrInvalidCCache, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_credentials_t dst_creds[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; + cc_credentials_t creds = NULL; + cc_credentials_iterator_t cred_iterator = NULL; + unsigned int i = 0; + + cc_string_t src_principal = NULL; + cc_string_t dst_principal = NULL; + + if (destination) { + // verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response) + if (!err) { + err = cc_ccache_new_credentials_iterator(destination, &cred_iterator); + } + while (!err && (i < 10)) { + err = cc_credentials_iterator_next(cred_iterator, &creds); + if (creds) { + dst_creds[i++] = creds; + } + } + if (err == ccIteratorEnd) { + !err; + } + if (cred_iterator) { + cc_credentials_iterator_release(cred_iterator); + cred_iterator = NULL; + } + + // verify that destination's principal has changed to source's (strcmp) + if (!err) { + err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal); + } + } + + + if (!err) { + err = cc_ccache_move(source, destination); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + + if (!err) { + // verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response) + i = 0; + while (dst_creds[i] && (i < 10)) { + err = cc_ccache_remove_credentials(destination, dst_creds[i]); + check_if(!(!err || err == ccErrCredentialsNotFound || ccErrInvalidCredentials), "credentials in destination not removed as promised"); + cc_credentials_release(dst_creds[i]); + i++; + } + err = ccNoError; + } + + // verify that destination's principal has changed to source's (strcmp) + if (!err) { + err = cc_ccache_get_principal(destination, cc_credentials_v5, &dst_principal); + } + if (!err) { + check_if(strcmp(src_principal->data, dst_principal->data), "destination principal not overwritten by source"); + } + + // verify that handles for source are no longer valid (get_change_time) + if (src_principal) { + cc_string_release(src_principal); + src_principal = NULL; + } + if (!err) { + err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal); + check_if(err != ccErrInvalidCCache, "source ccache was not invalidated after move"); + } + + + if (cred_iterator) { cc_credentials_iterator_release(cred_iterator); } + if (src_principal) { cc_string_release(src_principal); } + if (dst_principal) { cc_string_release(dst_principal); } + + #endif /* cc_ccache_move */ + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_ccache_compare() { + BEGIN_TEST("cc_ccache_compare"); + + #ifndef cc_ccache_compare + log_error("cc_ccache_compare is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache_a = NULL; + cc_ccache_t ccache_b = NULL; + cc_uint32 equal = 0; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache_a); + } + if (!err) { + err = cc_context_open_default_ccache(context, &ccache_b); + } + + equal = 1; + check_once_cc_ccache_compare(ccache_a, ccache_a, &equal, ccNoError, "compare ccache with same pointer"); + equal = 1; + check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different handles to same ccache"); + + if (ccache_b) { + cc_ccache_release(ccache_b); + ccache_b = NULL; + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache_b); + } + equal = 0; + check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different ccaches"); + check_once_cc_ccache_compare(ccache_a, NULL, &equal, ccErrInvalidCCache, "NULL compare_to ccache"); + check_once_cc_ccache_compare(ccache_a, ccache_b, NULL, ccErrBadParam, "NULL out param"); + + if (ccache_a) { cc_ccache_release(ccache_a); } + if (ccache_b) { cc_ccache_release(ccache_b); } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_compare */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_compare(cc_ccache_t ccache, cc_ccache_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_compare + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidContext, + ccErrBadParam, + ccErrServerUnavailable, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_uint32 actually_equal = 0; + + if (equal) { + actually_equal = *equal; + } + + err = cc_ccache_compare(ccache, compare_to, equal); + + if (!err && equal) { + if (actually_equal) { + check_if(actually_equal != *equal, "equal ccaches not considered equal"); + } + else { + check_if(actually_equal != *equal, "non-equal ccaches considered equal"); + } + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + #endif /* cc_ccache_compare */ + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_ccache_get_kdc_time_offset() { + BEGIN_TEST("cc_ccache_get_kdc_time_offset"); + + #ifndef cc_ccache_get_kdc_time_offset + log_error("cc_ccache_get_kdc_time_offset is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_time_t time_offset = 0; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + time_offset = 0; + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccErrTimeOffsetNotSet, "brand new ccache (offset not yet set)"); + + time_offset = 10; + if (!err) { + err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, time_offset); + } + if (!err) { + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5 but not v4"); + } + if (!err) { + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccErrTimeOffsetNotSet, "asking for v4 offset when only v5 is set"); + } + if (!err) { + err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, time_offset); + } + if (!err) { + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccNoError, "asking for v4 offset when v4 and v5 are set"); + } + + + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL time_offset out param"); + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4_v5, &time_offset, ccErrBadCredentialsVersion, "v4_v5 creds_vers in param (invalid)"); + + if (ccache) { cc_ccache_release(ccache); } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_get_kdc_time_offset */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_get_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t *time_offset, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_get_kdc_time_offset + + cc_int32 possible_return_values[7] = { + ccNoError, + ccErrTimeOffsetNotSet, + ccErrCCacheNotFound, + ccErrInvalidCCache, + ccErrBadParam, + ccErrServerUnavailable, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t expected_offset; + + if (time_offset) { + expected_offset = *time_offset; + } + + err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, time_offset); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && time_offset) { + check_if(*time_offset != expected_offset, "kdc time offset doesn't match expected value"); + } + + #endif /* cc_ccache_get_kdc_time_offset */ + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_ccache_set_kdc_time_offset() { + BEGIN_TEST("cc_ccache_set_kdc_time_offset"); + + #ifndef cc_ccache_set_kdc_time_offset + log_error("cc_ccache_set_kdc_time_offset is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0, ccNoError, "first time setting offset (v5)"); + check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0, ccNoError, "first time setting offset (v4)"); + + check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4_v5, 0, ccErrBadCredentialsVersion, "invalid creds_vers (v4_v5)"); + + if (ccache) { cc_ccache_release(ccache); } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_set_kdc_time_offset */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_set_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t time_offset, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_set_kdc_time_offset + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrCCacheNotFound, + ccErrInvalidCCache, + ccErrBadParam, + ccErrServerUnavailable, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t stored_offset = 0; + + err = cc_ccache_set_kdc_time_offset(ccache, credentials_version, time_offset); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset); + } + + if (!err) { + check_if(time_offset != stored_offset, "kdc time offset doesn't match expected value"); + } + + #endif /* cc_ccache_set_kdc_time_offset */ + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_ccache_clear_kdc_time_offset() { + BEGIN_TEST("cc_ccache_clear_kdc_time_offset"); + + #ifndef cc_ccache_clear_kdc_time_offset + log_error("cc_ccache_clear_kdc_time_offset is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + + check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing an offset that was never set (v5)"); + check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing an offset that was never set (v4)"); + + err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0); + err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0); + + check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing v5"); + check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing v4"); + + check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4_v5, ccErrBadCredentialsVersion, "bad in param creds vers (v4_v5)"); + + if (ccache) { cc_ccache_release(ccache); } + + if (context) { + err = destroy_all_ccaches(context); + cc_context_release(context); + } + + #endif /* cc_ccache_clear_kdc_time_offset */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_clear_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_ccache_clear_kdc_time_offset + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrCCacheNotFound, + ccErrInvalidCCache, + ccErrBadParam, + ccErrServerUnavailable, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t stored_offset = 0; + + err = cc_ccache_clear_kdc_time_offset(ccache, credentials_version); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset); + check_if(err != ccErrTimeOffsetNotSet, "time offset not cleared"); + } + + #endif /* cc_ccache_clear_kdc_time_offset */ + + return err; +} + + diff --git a/src/ccapi/test/test_ccapi_ccache.h b/src/ccapi/test/test_ccapi_ccache.h new file mode 100644 index 000000000..31d00832f --- /dev/null +++ b/src/ccapi/test/test_ccapi_ccache.h @@ -0,0 +1,50 @@ +#ifndef _TEST_CCAPI_CCACHE_H_ +#define _TEST_CCAPI_CCACHE_H_ + +#include + + +int check_cc_ccache_release(); +cc_int32 check_once_cc_ccache_release(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); +int check_cc_ccache_destroy(); +cc_int32 check_once_cc_ccache_destroy(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); +int check_cc_ccache_set_default(); +cc_int32 check_once_cc_ccache_set_default(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); +int check_cc_ccache_get_credentials_version(); +cc_int32 check_once_cc_ccache_get_credentials_version(cc_ccache_t ccache, cc_uint32 expected_cred_vers, cc_int32 expected_err, const char *description); +int check_cc_ccache_get_name(); +cc_int32 check_once_cc_ccache_get_name(cc_ccache_t ccache, const char *expected_name, cc_int32 expected_err, const char *description); +int check_cc_ccache_get_principal(); +cc_int32 check_once_ccache_get_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *expected_principal, cc_int32 expected_err, const char *description); +int check_cc_ccache_set_principal(); +cc_int32 check_once_cc_ccache_set_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description); + +int check_cc_ccache_store_credentials(); +cc_int32 check_once_cc_ccache_store_credentials(cc_ccache_t ccache, const cc_credentials_union *credentials, cc_int32 expected_err, const char *description); +int check_cc_ccache_remove_credentials(); +cc_int32 check_once_cc_ccache_remove_credentials(cc_ccache_t ccache, cc_credentials_t in_creds, cc_int32 expected_err, const char *description); + +int check_cc_ccache_new_credentials_iterator(); +cc_int32 check_once_cc_ccache_new_credentials_iterator(cc_ccache_t ccache, cc_credentials_iterator_t *iterator, cc_int32 expected_err, const char *description); + +int check_cc_ccache_get_change_time(); +cc_int32 check_once_cc_ccache_get_change_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description); +int check_cc_ccache_get_last_default_time(); +cc_int32 check_once_ccache_get_last_default_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description); + +int check_cc_ccache_move(); +cc_int32 check_once_cc_ccache_move(cc_ccache_t source, cc_ccache_t destination, cc_int32 expected_err, const char *description); + +int check_cc_ccache_compare(); +cc_int32 check_once_cc_ccache_compare(cc_ccache_t ccache, cc_ccache_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description); + +int check_cc_ccache_get_kdc_time_offset(); +cc_int32 check_once_cc_ccache_get_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t *time_offset, cc_int32 expected_err, const char *description); + +int check_cc_ccache_set_kdc_time_offset(); +cc_int32 check_once_cc_ccache_set_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t time_offset, cc_int32 expected_err, const char *description); + +int check_cc_ccache_clear_kdc_time_offset(); +cc_int32 check_once_cc_ccache_clear_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_int32 expected_err, const char *description); + +#endif /* _TEST_CCAPI_CCACHE_H_ */ diff --git a/src/ccapi/test/test_ccapi_check.c b/src/ccapi/test/test_ccapi_check.c new file mode 100644 index 000000000..12192a657 --- /dev/null +++ b/src/ccapi/test/test_ccapi_check.c @@ -0,0 +1,37 @@ +#include "test_ccapi_check.h" + +int _check_if(int expression, const char *file, int line, const char *expression_string, const char *format, ...) { + if (expression) { + failure_count++; + // call with NULL format to get a generic error message + if (format == NULL) { + _log_error(file, line, expression_string); + } + // call with format and varargs for a more useful error message + else { + va_list ap; + va_start(ap, format); + _log_error_v(file, line, format, ap); + va_end(ap); + } + + if (current_test_activity) { + fprintf(stdout, " (%s)", current_test_activity); + } + } + + return (expression != 0); +} + +int array_contains_int(cc_int32 *array, int size, cc_int32 value) { + if (array != NULL && size > 0) { + int i = 0; + while (i < size && array[i] != value) { + i++; + } + if (i < size) { + return 1; + } + } + return 0; +} \ No newline at end of file diff --git a/src/ccapi/test/test_ccapi_check.h b/src/ccapi/test/test_ccapi_check.h new file mode 100644 index 000000000..c05a5152e --- /dev/null +++ b/src/ccapi/test/test_ccapi_check.h @@ -0,0 +1,43 @@ +#ifndef _TEST_CCAPI_CHECK_H_ +#define _TEST_CCAPI_CHECK_H_ + +#include +#include +#include "test_ccapi_log.h" +#include "test_ccapi_globals.h" + +int _check_if(int expression, const char *file, int line, const char *expression_string, const char *format, ...); + +#define check_int(a, b) \ + check_if(a != b, NULL) + +/* + * if expression evaluates to true, check_if increments the failure_count and prints: + * + * check_if(a!=a, NULL); + * ==> "/path/to/file:line: a!=a" + * + * check_if(a!=a, "This shouldn't be happening"); + * ==> "/path/to/file:line: This shouldn't be happening" + * + * check_if(a!=a, "This has happened %d times now", 3); + * ==> "/path/to/file:line: This has happened 3 times now" +*/ + +#define check_if(expression, format, ...) \ + _check_if(expression, __FILE__, __LINE__, #expression, format , ## __VA_ARGS__) + +#define check_if_not(expression, format, ...) \ + check_if(!(expression), format, ## __VA_ARGS__) + +// first check if err is what we were expecting to get back +// then check if err is even in the set of errors documented for the function +#define check_err(err, expected_err, possible_return_values) \ + do { \ + check_if(err != expected_err, "unexpected error %s (%d), expected %s (%d)", translate_ccapi_error(err), err, translate_ccapi_error(expected_err), expected_err); \ + check_if_not(array_contains_int(possible_return_values, possible_ret_val_count, err), "error not documented as a possible return value: %s (%d)", translate_ccapi_error(err), err); \ + } while( 0 ) + +int array_contains_int(cc_int32 *array, int size, cc_int32 value); + +#endif /* _TEST_CCAPI_CHECK_H_ */ diff --git a/src/ccapi/test/test_ccapi_constants.c b/src/ccapi/test/test_ccapi_constants.c new file mode 100644 index 000000000..5203fff11 --- /dev/null +++ b/src/ccapi/test/test_ccapi_constants.c @@ -0,0 +1,66 @@ +#include "test_ccapi_constants.h" +#include "test_ccapi_globals.h" +#include "test_ccapi_check.h" + +int check_constants() { + BEGIN_TEST("constants"); + /* API versions */ + + check_int(ccapi_version_2, 2); + check_int(ccapi_version_3, 3); + check_int(ccapi_version_4, 4); + check_int(ccapi_version_5, 5); + check_int(ccapi_version_6, 6); + + /* Errors */ + + check_int(ccNoError , 0 ); // 0 + check_int(ccIteratorEnd , 201); // 201 + check_int(ccErrBadParam , 202); // 202 + check_int(ccErrNoMem , 203); // 203 + check_int(ccErrInvalidContext , 204); // 204 + check_int(ccErrInvalidCCache , 205); // 205 + check_int(ccErrInvalidString , 206); // 206 + check_int(ccErrInvalidCredentials , 207); // 207 + check_int(ccErrInvalidCCacheIterator , 208); // 208 + check_int(ccErrInvalidCredentialsIterator , 209); // 209 + check_int(ccErrInvalidLock , 210); // 210 + check_int(ccErrBadName , 211); // 211 + check_int(ccErrBadCredentialsVersion , 212); // 212 + check_int(ccErrBadAPIVersion , 213); // 213 + check_int(ccErrContextLocked , 214); // 214 + check_int(ccErrContextUnlocked , 215); // 215 + check_int(ccErrCCacheLocked , 216); // 216 + check_int(ccErrCCacheUnlocked , 217); // 217 + check_int(ccErrBadLockType , 218); // 218 + check_int(ccErrNeverDefault , 219); // 219 + check_int(ccErrCredentialsNotFound , 220); // 220 + check_int(ccErrCCacheNotFound , 221); // 221 + check_int(ccErrContextNotFound , 222); // 222 + check_int(ccErrServerUnavailable , 223); // 223 + check_int(ccErrServerInsecure , 224); // 224 + check_int(ccErrServerCantBecomeUID , 225); // 225 + check_int(ccErrTimeOffsetNotSet , 226); // 226 + check_int(ccErrBadInternalMessage , 227); // 227 + check_int(ccErrNotImplemented , 228); // 228 + + /* Credentials versions */ + + check_int(cc_credentials_v4, 1); + check_int(cc_credentials_v5, 2); + check_int(cc_credentials_v4_v5, (cc_credentials_v4 | cc_credentials_v5)); + + /* Lock types */ + + check_int(cc_lock_read, 0); + check_int(cc_lock_write, 1); + check_int(cc_lock_upgrade, 2); + check_int(cc_lock_downgrade, 3); + + /* Locking Modes */ + + check_int(cc_lock_noblock, 0); + check_int(cc_lock_block, 1); + + END_TEST_AND_RETURN +} \ No newline at end of file diff --git a/src/ccapi/test/test_ccapi_constants.h b/src/ccapi/test/test_ccapi_constants.h new file mode 100644 index 000000000..ff6fd66a1 --- /dev/null +++ b/src/ccapi/test/test_ccapi_constants.h @@ -0,0 +1,6 @@ +#ifndef _TEST_CCAPI_CONSTANTS_H_ +#define _TEST_CCAPI_CONSTANTS_H_ + +int check_constants(); + +#endif /* _TEST_CCAPI_CONSTANTS_H_ */ diff --git a/src/ccapi/test/test_ccapi_context.c b/src/ccapi/test/test_ccapi_context.c new file mode 100644 index 000000000..b9365a619 --- /dev/null +++ b/src/ccapi/test/test_ccapi_context.c @@ -0,0 +1,1065 @@ +#include +#include "test_ccapi_context.h" +#include +#include "test_ccapi_check.h" +#include "test_ccapi_util.h" + +int check_cc_initialize() { + BEGIN_TEST("cc_initialize"); + + cc_int32 err = 0; + cc_context_t context = NULL; + + // try every api_version + err = check_once_cc_initialize(&context, ccapi_version_2, NULL, NULL, 11, NULL); // err == CC_NOT_SUPP, not reflected in documentation rev 8 + err = check_once_cc_initialize(&context, ccapi_version_3, NULL, NULL, ccNoError, NULL); // !err + err = check_once_cc_initialize(&context, ccapi_version_4, NULL, NULL, ccNoError, NULL); // " + err = check_once_cc_initialize(&context, ccapi_version_5, NULL, NULL, ccNoError, NULL); // " + err = check_once_cc_initialize(&context, ccapi_version_6, NULL, NULL, ccNoError, NULL); // " + + // try bad api_version + err = check_once_cc_initialize(&context, INT_MAX, NULL, NULL, ccErrBadAPIVersion, NULL); // err == ccErrBadAPIVersion + + // try bad param + err = check_once_cc_initialize(NULL, ccapi_version_3, NULL, NULL, ccErrBadParam, NULL); // err == ccErrBadParam + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_initialize(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_context_t context; + + BEGIN_CHECK_ONCE(description); + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrNoMem, + ccErrBadAPIVersion, + ccErrBadParam, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_initialize(out_context, in_version, out_supported_version, out_vendor); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (out_context) { context = *out_context; } + else { context = NULL; } + + // check output parameters + if (!err) { + check_if(context == NULL, NULL); + if (context) { + cc_context_release(context); + *out_context = NULL; + } + } else { + check_if(context != NULL, NULL); + } + + return err; +} + + +int check_cc_context_get_version() { + BEGIN_TEST("cc_context_get_version"); + + #ifndef cc_context_get_version + log_error("cc_context_get_version is not implemented yet"); + failure_count++; + #else + // This code is all untested, since there is no cc_context_get_version to test against + + cc_int32 err = 0; + cc_context_t context = NULL; + + // try every api_version + //err = check_once_cc_context_get_version(&context, ccapi_version_2, NULL, NULL, ccNoError); // err == CC_NOT_SUPP, not reflected in documentation rev 8 + err = check_once_cc_context_get_version(&context, ccapi_version_3, NULL, NULL, ccNoError); // !err + err = check_once_cc_context_get_version(&context, ccapi_version_4, NULL, NULL, ccNoError); // " + err = check_once_cc_context_get_version(&context, ccapi_version_5, NULL, NULL, ccNoError); // " + err = check_once_cc_context_get_version(&context, ccapi_version_6, NULL, NULL, ccNoError); // " + + // try bad api_version + err = check_once_cc_context_get_version(&context, INT_MAX, NULL, NULL, ccErrBadAPIVersion); // err == ccErrBadAPIVersion + + // try bad param + err = check_once_cc_context_get_version(NULL, ccapi_version_3, NULL, NULL, ccErrInvalidContext); // err == ccErrInvalidContext + + + #endif /* cc_context_get_version */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_get_version(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_get_version + // This code is all untested, since there is no cc_context_get_version to test against + + cc_context_t context = NULL; + cc_int32 reported_version; + + cc_int32 possible_return_values[3] = { + ccNoError, + ccErrInvalidContext, + ccErrBadParam, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_initialize(out_context, in_version, out_supported_version, out_vendor); + + if (err != ccNoError) { + log_error("failure in cc_initialize, unable to perform check"); + return err; + } + else { + context = *out_context; + err = cc_context_get_version(context, &reported_version); + + // check returned error + check_err(err, expected_err, possible_return_values); + } + + // check output parameters and free memory + if (!err) { + check_if(reported_version != in_version, NULL); + } else if (err == ccErrBadParam) { + check_if_not((context == NULL || &reported_version == NULL), "given ccErrBadParam but no param was bad"); + } + + if (context) { + cc_context_release(context); + *out_context = NULL; + } + + #endif /* cc_context_get_version */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_release() { + BEGIN_TEST("cc_context_release"); + + #ifndef cc_context_release + log_error("cc_context_release is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + + // try with valid context + err = check_once_cc_context_release(&context, ccNoError, NULL); + + // try with NULL + //err = check_once_cc_context_release(NULL, ccErrInvalidContext); + /* calling with NULL context crashes, because this macro expands to + ((NULL) -> functions -> release (NULL)) which is dereferencing NULL which is bad. */ + + if (context) { cc_context_release(context); } + + #endif /* cc_context_release */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_release(cc_context_t *out_context, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_release + + cc_context_t context = NULL; + + cc_int32 possible_return_values[2] = { + ccNoError, + ccErrInvalidContext, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (out_context) { + err = cc_initialize(out_context, ccapi_version_3, NULL, NULL); + if (!err) { + context = *out_context; + } + } + + if (err != ccNoError) { + log_error("failure in cc_initialize, unable to perform check"); + return err; + } + else { + err = cc_context_release(context); + // check returned error + check_err(err, expected_err, possible_return_values); + } + + *out_context = NULL; + + #endif /* cc_context_release */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_get_change_time() { + BEGIN_TEST("cc_context_get_change_time"); + + #ifndef cc_context_get_change_time + log_error("cc_context_get_change_time is not implemented yet"); + failure_count++; + #else + + /* + * Make a context + * make sure the change time changes after: + * a ccache is created + * a ccache is destroyed + * a credential is stored + * a credential is removed + * a ccache principal is changed + * the default ccache is changed + * clean up memory + */ + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_time_t last_change_time = 0; + cc_ccache_t ccache = NULL; + cc_credentials_union creds_union; + cc_credentials_iterator_t creds_iterator = NULL; + cc_credentials_t credentials = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + + // try bad parameters first + err = check_once_cc_context_get_change_time(context, NULL, ccErrBadParam, "NULL param, should fail"); + + // make sure we have a default ccache + err = cc_context_open_default_ccache(context, &ccache); + if (err == ccErrCCacheNotFound) { + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); + } + if (!err) { + err = cc_ccache_release(ccache); + } + // either the default ccache already existed or we just created it + // either way, the get_change_time should now give something > 0 + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "first-run, should be > 0"); + + // create a ccache + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after creating a new ccache"); + + // store a credential + if (!err) { + new_v5_creds_union(&creds_union, "BAR.ORG"); + err = cc_ccache_store_credentials(ccache, &creds_union); + release_v5_creds_union(&creds_union); + } + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after storing a credential"); + + if (!err) { + // change principal (fails with ccErrBadInternalMessage) + err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); + if (err) { + log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + err = ccNoError; + } + } + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing a principle"); + + // remove a credential + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); + } + if (!err) { + err = cc_credentials_iterator_next(creds_iterator, &credentials); + } + if (err == ccIteratorEnd) { + err = ccNoError; + } + if (!err) { + err = cc_ccache_remove_credentials(ccache, credentials); + } + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after removing a credential"); + + if (!err) { + // change default ccache + err = cc_ccache_set_default(ccache); + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing default ccache"); + } + + if (ccache) { + // destroy a ccache + err = cc_ccache_destroy(ccache); + check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after destroying a ccache"); + } + } + + if (context) { cc_context_release(context); } + + #endif /* cc_get_change_time */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_get_change_time(cc_context_t context, cc_time_t *time, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_get_change_time + + cc_int32 possible_return_values[3] = { + ccNoError, + ccErrInvalidContext, + ccErrBadParam, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_time_t last_change_time; + cc_time_t current_change_time = 0; + + if (time != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_context_get_change_time(context, ¤t_change_time); + } else { + err = cc_context_get_change_time(context, NULL); + } + + check_err(err, expected_err, possible_return_values); + + if (!err) { + last_change_time = *time; + check_if(current_change_time <= last_change_time, "context change time did not increase when it was supposed to (%d <= %d)", current_change_time, last_change_time); + *time = current_change_time; + } + + #endif /* cc_context_get_change_time */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_get_default_ccache_name() { + BEGIN_TEST("cc_context_get_default_ccache_name"); + + #ifndef cc_context_get_default_ccache_name + log_error("cc_context_get_default_ccache_name is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // try bad parameters first + err = check_once_cc_context_get_default_ccache_name(context, NULL, ccErrBadParam, NULL); + + // try with no default + err = destroy_all_ccaches(context); + err = cc_context_open_default_ccache(context, &ccache); + if (err != ccErrCCacheNotFound) { + log_error("didn't remove all ccaches"); + } + err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL); + + // try normally + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + if (ccache) { cc_ccache_release(ccache); } + err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL); + + } + + if (context) { cc_context_release(context); } + + #endif /* cc_context_get_default_ccache_name */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_get_default_ccache_name(cc_context_t context, cc_string_t *name, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_get_default_ccache_name + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidContext, + ccErrBadParam, + ccErrNoMem, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (name != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_context_get_default_ccache_name(context, name); + } else { + err = cc_context_get_default_ccache_name(context, NULL); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + // not really anything else to check + + if (name && *name) { cc_string_release(*name); } + + #endif /* cc_context_get_default_ccache_name */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_open_ccache() { + BEGIN_TEST("cc_context_open_ccache"); + + #ifndef cc_context_open_ccache + log_error("cc_context_open_ccache is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // make sure we have a default ccache + err = cc_context_open_default_ccache(context, &ccache); + if (err == ccErrCCacheNotFound) { + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); + } + if (!err) { + err = cc_ccache_release(ccache); + ccache = NULL; + } + + // try default ccache + err = cc_context_get_default_ccache_name(context, &name); + if (!err) { + err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccNoError, NULL); + } + + // try bad parameters + err = check_once_cc_context_open_ccache(context, NULL, &ccache, ccErrBadParam, NULL); + err = check_once_cc_context_open_ccache(context, name->data, NULL, ccErrBadParam, NULL); + + // try a ccache that doesn't exist (create one and then destroy it) + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + if (!err) { + err = cc_ccache_get_name(ccache, &name); + } + if (!err) { + err = cc_ccache_destroy(ccache); + ccache = NULL; + } + + err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccErrCCacheNotFound, NULL); + } + + if (context) { cc_context_release(context); } + + #endif /* cc_context_open_ccache */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_open_ccache(cc_context_t context, const char *name, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_string_t stored_name = NULL; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_open_ccache + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrBadName, + ccErrInvalidContext, + ccErrNoMem, + ccErrCCacheNotFound, + ccErrBadParam, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_context_open_ccache(context, name, ccache); + } else { + err = cc_context_open_ccache(context, name, NULL); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(*ccache == NULL, NULL); + + if (!err) { + err = cc_ccache_get_name(*ccache, &stored_name); + } + if (!err) { + check_if(strcmp(stored_name->data, name), NULL); + } + if (stored_name) { cc_string_release(stored_name); } + + + if (ccache && *ccache) { + cc_ccache_release(*ccache); + *ccache = NULL; + } + } + + #endif /* cc_context_open_ccache */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_open_default_ccache() { + BEGIN_TEST("cc_context_open_default_ccache"); + + #ifndef cc_context_open_default_ccache + log_error("cc_context_open_default_ccache is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // make sure we have a default ccache + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); + if (ccache) { cc_ccache_release(ccache); } + + // try default ccache + if (!err) { + err = check_once_cc_context_open_default_ccache(context, &ccache, ccNoError, NULL); + } + + // try bad parameters + err = check_once_cc_context_open_default_ccache(context, NULL, ccErrBadParam, NULL); + + // try with no default ccache (destroy all ccaches first) + err = destroy_all_ccaches(context); + + err = check_once_cc_context_open_default_ccache(context, &ccache, ccErrCCacheNotFound, NULL); + } + + if (context) { cc_context_release(context); } + + #endif /* cc_context_open_default_ccache */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_open_default_ccache(cc_context_t context, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_string_t given_name = NULL; + cc_string_t default_name = NULL; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_open_default_ccache + + cc_int32 possible_return_values[5] = { + ccNoError, + ccErrInvalidContext, + ccErrNoMem, + ccErrCCacheNotFound, + ccErrBadParam, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_context_open_default_ccache(context, ccache); + } else { + err = cc_context_open_default_ccache(context, NULL); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(*ccache == NULL, NULL); + + // make sure this ccache is the one we were looking to get back (compare name with cc_context_get_default_ccache_name) + err = cc_ccache_get_name(*ccache, &given_name); + err = cc_context_get_default_ccache_name(context, &default_name); + if (given_name && default_name) { + check_if(strcmp(given_name->data, default_name->data), "name of ccache returned by cc_context_open_default_ccache doesn't match name returned by cc_context_get_default_ccache_name"); + } + if (given_name) { cc_string_release(given_name); } + if (default_name) { cc_string_release(default_name); } + + if (ccache && *ccache) { + cc_ccache_release(*ccache); + *ccache = NULL; + } + } + + #endif /* cc_context_open_default_ccache */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_create_ccache() { + BEGIN_TEST("cc_context_create_ccache"); + + #ifndef cc_context_create_ccache + log_error("cc_context_create_ccache is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // try making a ccache with a non-unique name (the existing default's name) + if (!err) { + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); + } + if (!err) { + err = cc_ccache_get_name(ccache, &name); + } + if (ccache) { cc_ccache_release(ccache); } + if (!err) { + err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); + } + + // try making a ccache with a unique name (the now destroyed default's name) + if (ccache) { cc_ccache_destroy(ccache); } + if (!err) { + err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); + } + + // try bad parameters + err = check_once_cc_context_create_ccache(context, NULL, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccErrBadName, "NULL name"); // NULL name + err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers + err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal + err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache + } + + if (name) { cc_string_release(name); } + if (ccache) { cc_ccache_destroy(ccache); } + if (context) { cc_context_release(context); } + + #endif /* cc_context_create_ccache */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_create_ccache(cc_context_t context, const char *name, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_string_t stored_name = NULL; + cc_string_t stored_principal = NULL; + cc_uint32 stored_creds_vers = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_create_ccache + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrBadName, + ccErrBadParam, + ccErrInvalidContext, + ccErrNoMem, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_context_create_ccache(context, name, cred_vers, principal, ccache); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(*ccache == NULL, NULL); + + // make sure all of the ccache's info matches what we gave it + // name + err = cc_ccache_get_name(*ccache, &stored_name); + if (!err) { check_if(strcmp(stored_name->data, name), NULL); } + if (stored_name) { cc_string_release(stored_name); } + // cred_vers + // FIXME Documented function name of cc_ccache_get_credentials_version is a typo. + // FIXME Documented type of creds param the wrong signedness (should be unsigned) for cc_ccache_get_credentials_version, cc_context_create_ccache, cc_context_create_default_ccache, cc_context_create_new_ccache + err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); + if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } + // principal + err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); + if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } + if (stored_principal) { cc_string_release(stored_principal); } + + if (ccache && *ccache) { + cc_ccache_destroy(*ccache); + *ccache = NULL; + } + } + + #endif /* cc_context_create_ccache */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_create_default_ccache() { + BEGIN_TEST("cc_context_create_default_ccache"); + + #ifndef cc_context_create_default_ccache + log_error("cc_context_create_default_ccache is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // try making the default when there are no existing ccaches + err = destroy_all_ccaches(context); + if (!err) { + err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); + } + if (ccache) { cc_ccache_release(ccache); } + + // try making a new default when one already exists + if (!err) { + err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); + } + + // try bad parameters + err = check_once_cc_context_create_default_ccache(context, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers + err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal + err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache + } + + if (name) { cc_string_release(name); } + if (ccache) { cc_ccache_destroy(ccache); } + if (context) { cc_context_release(context); } + + #endif /* cc_context_create_default_ccache */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_create_default_ccache(cc_context_t context, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_string_t stored_principal = NULL; + cc_uint32 stored_creds_vers = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_create_default_ccache + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrBadName, // how can this be possible when the name isn't a parameter? + ccErrBadParam, + ccErrInvalidContext, + ccErrNoMem, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_context_create_default_ccache(context, cred_vers, principal, ccache); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + if (ccache) { check_if(*ccache == NULL, NULL); } + // make sure all of the ccache's info matches what we gave it + // cred_vers + err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); + if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } + // principal + err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); + if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } + if (stored_principal) { cc_string_release(stored_principal); } + + if (ccache && *ccache) { + cc_ccache_release(*ccache); + *ccache = NULL; + } + } + + #endif /* cc_context_create_default_ccache */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_create_new_ccache() { + BEGIN_TEST("cc_context_create_new_ccache"); + + #ifndef cc_context_create_new_ccache + log_error("cc_context_create_new_ccache is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + // try making when there are no existing ccaches (should have name of default) + err = destroy_all_ccaches(context); + if (!err) { + err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); + } + if (ccache) { cc_ccache_release(ccache); } + + // try making a new ccache when one already exists (should not have name of default) + if (!err) { + err = check_once_cc_context_create_new_ccache(context, 0, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); + } + if (ccache) { cc_ccache_release(ccache); } + + // try bad parameters + err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers + err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal + err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache + } + + if (name) { cc_string_release(name); } + if (ccache) { cc_ccache_destroy(ccache); } + if (context) { cc_context_release(context); } + + #endif /* cc_context_create_new_ccache */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_create_new_ccache(cc_context_t context, cc_int32 should_be_default, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { + cc_int32 err = 0; + cc_string_t name = NULL; + cc_string_t stored_name = NULL; + cc_string_t stored_principal = NULL; + cc_uint32 stored_creds_vers = 0; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_create_new_ccache + + cc_int32 possible_return_values[6] = { + ccNoError, + ccErrBadName, // how can this be possible when the name isn't a parameter? + ccErrBadParam, + ccErrInvalidContext, + ccErrNoMem, + ccErrBadCredentialsVersion, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_context_create_new_ccache(context, cred_vers, principal, ccache); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + if (ccache) { check_if(*ccache == NULL, NULL); } + // make sure all of the ccache's info matches what we gave it + if (!err) { + err = cc_context_get_default_ccache_name(context, &name); + } + if (!err) { + err = cc_ccache_get_name(*ccache, &stored_name); + } + if (!err) { + if (should_be_default) { + check_if(strcmp(stored_name->data, name->data), "new ccache does not have name of default"); + } + else { + check_if((strcmp(stored_name->data, name->data) == 0), "new cache has name of default"); + } + } + if (name) { cc_string_release(name); } + if (stored_name) { cc_string_release(stored_name); } + + // cred_vers + err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); + if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } + // principal + err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); + if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } + if (stored_principal) { cc_string_release(stored_principal); } + + if (ccache && *ccache) { + cc_ccache_release(*ccache); + *ccache = NULL; + } + } + + #endif /* cc_context_create_new_ccache */ + + END_CHECK_ONCE; + + return err; +} + +int check_cc_context_new_ccache_iterator() { + BEGIN_TEST("cc_context_new_ccache_iterator"); + + #ifndef cc_context_new_ccache_iterator + log_error("cc_context_new_ccache_iterator is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_string_t name = NULL; + cc_ccache_iterator_t iterator = NULL; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + if (!err) { + err = destroy_all_ccaches(context); + } + if (!err) { + // try making when there are no existing ccaches (shouldn't make a difference, but just in case) + check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when there are no existing ccaches"); + + err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + // try making when at least one ccache already exists (just to cover all our bases) + check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when at least one ccache already exists"); + + // try bad parameters + check_once_cc_context_new_ccache_iterator(context, NULL, ccErrBadParam, "NULL param"); // NULL iterator + } + // we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite + + if (name) { cc_string_release(name); } + if (ccache) { cc_ccache_destroy(ccache); } + if (context) { cc_context_release(context); } + + #endif /* cc_context_new_ccache_iterator */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_create_new_ccache + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrBadParam, + ccErrNoMem, + ccErrInvalidContext, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_context_new_ccache_iterator(context, iterator); + + // check returned error + check_err(err, expected_err, possible_return_values); + + // we'll do a comprehensive test of cc_ccache_iterator related functions later + + #endif /* cc_context_create_new_ccache */ + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_context_compare(){ + BEGIN_TEST("cc_context_compare"); + + #ifndef cc_context_compare + log_error("cc_context_compare is not implemented yet"); + failure_count++; + #else + + cc_int32 err = 0; + cc_context_t context_a = NULL; + cc_context_t context_b = NULL; + cc_uint32 equal = 0; + + err = cc_initialize(&context_a, ccapi_version_3, NULL, NULL); + if (!err) { + err = cc_initialize(&context_b, ccapi_version_3, NULL, NULL); + } + + check_once_cc_context_compare(context_a, context_a, &equal, ccNoError, "valid params, same contexts"); + check_once_cc_context_compare(context_a, context_b, &equal, ccNoError, "valid params, different contexts"); + check_once_cc_context_compare(context_a, NULL, &equal, ccErrInvalidContext, "NULL compare_to context"); + check_once_cc_context_compare(context_a, context_b, NULL, ccErrBadParam, "NULL out param"); + + if (context_a) { cc_context_release(context_a); } + if (context_b) { cc_context_release(context_b); } + + #endif /* cc_context_compare */ + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_context_compare(cc_context_t context, cc_context_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + #ifdef cc_context_compare + + cc_int32 possible_return_values[4] = { + ccNoError, + ccErrInvalidContext, + ccErrBadParam, + ccErrServerUnavailable, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_context_compare(context, compare_to, equal); + + if (!err) { + *equal = 0; + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + #endif /* cc_context_compare */ + + return err; +} diff --git a/src/ccapi/test/test_ccapi_context.h b/src/ccapi/test/test_ccapi_context.h new file mode 100644 index 000000000..e347692ea --- /dev/null +++ b/src/ccapi/test/test_ccapi_context.h @@ -0,0 +1,34 @@ +#ifndef _TEST_CCAPI_CONTEXT_H_ +#define _TEST_CCAPI_CONTEXT_H_ + +#include + +int check_cc_initialize(); +cc_int32 check_once_cc_initialize(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description); +int check_cc_context_get_version(); +cc_int32 check_once_cc_context_get_version(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description); +int check_get_version(); +cc_int32 check_once_get_version(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description); +int check_cc_context_release(); +cc_int32 check_once_cc_context_release(cc_context_t *out_context, cc_int32 expected_err, const char *description); +int check_cc_context_get_change_time(); +cc_int32 check_once_cc_context_get_change_time(cc_context_t context, cc_time_t *time, cc_int32 expected_err, const char *description); +int check_cc_context_get_default_ccache_name(); +cc_int32 check_once_cc_context_get_default_ccache_name(cc_context_t context, cc_string_t *name, cc_int32 expected_err, const char *description); +int check_cc_context_open_ccache(); +cc_int32 check_once_cc_context_open_ccache(cc_context_t context, const char *name, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); +int check_cc_context_open_default_ccache(); +cc_int32 check_once_cc_context_open_default_ccache(cc_context_t context, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); +int check_cc_context_create_ccache(); +cc_int32 check_once_cc_context_create_ccache(cc_context_t context, const char *name, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); +int check_cc_context_create_default_ccache(); +cc_int32 check_once_cc_context_create_default_ccache(cc_context_t context, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); +int check_cc_context_create_new_ccache(); +cc_int32 check_once_cc_context_create_new_ccache(cc_context_t context, cc_int32 should_be_default, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); +int check_cc_context_new_ccache_iterator(); +cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description); + +int check_cc_context_compare(); +cc_int32 check_once_cc_context_compare(cc_context_t context, cc_context_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description); + +#endif /* _TEST_CCAPI_CONTEXT_H_ */ diff --git a/src/ccapi/test/test_ccapi_globals.c b/src/ccapi/test/test_ccapi_globals.c new file mode 100644 index 000000000..c508c188c --- /dev/null +++ b/src/ccapi/test/test_ccapi_globals.c @@ -0,0 +1,62 @@ +#include "test_ccapi_globals.h" + +/* GLOBALS */ +unsigned int total_failure_count = 0; +unsigned int failure_count = 0; + +const char *current_test_name; +const char *current_test_activity; + +const char * ccapi_error_strings[30] = { + + "ccNoError", /* 0 */ + "ccIteratorEnd", /* 201 */ + "ccErrBadParam", + "ccErrNoMem", + "ccErrInvalidContext", + "ccErrInvalidCCache", + + "ccErrInvalidString", /* 206 */ + "ccErrInvalidCredentials", + "ccErrInvalidCCacheIterator", + "ccErrInvalidCredentialsIterator", + "ccErrInvalidLock", + + "ccErrBadName", /* 211 */ + "ccErrBadCredentialsVersion", + "ccErrBadAPIVersion", + "ccErrContextLocked", + "ccErrContextUnlocked", + + "ccErrCCacheLocked", /* 216 */ + "ccErrCCacheUnlocked", + "ccErrBadLockType", + "ccErrNeverDefault", + "ccErrCredentialsNotFound", + + "ccErrCCacheNotFound", /* 221 */ + "ccErrContextNotFound", + "ccErrServerUnavailable", + "ccErrServerInsecure", + "ccErrServerCantBecomeUID", + + "ccErrTimeOffsetNotSet", /* 226 */ + "ccErrBadInternalMessage", + "ccErrNotImplemented", + +}; + +const char *translate_ccapi_error(cc_int32 err) { + + if (err == 0) { + return ccapi_error_strings[0]; + } + else if (err >= 201 && err <= 228){ + return ccapi_error_strings[err - 200]; + } + else { + return "\"Invalid or private CCAPI error\""; + } + + return ""; +} \ No newline at end of file diff --git a/src/ccapi/test/test_ccapi_globals.h b/src/ccapi/test/test_ccapi_globals.h new file mode 100644 index 000000000..cebfb63d8 --- /dev/null +++ b/src/ccapi/test/test_ccapi_globals.h @@ -0,0 +1,47 @@ +#ifndef _TEST_CCAPI_GLOBALS_H_ +#define _TEST_CCAPI_GLOBALS_H_ + +#include + +/* GLOBALS */ +extern unsigned int total_failure_count; +extern unsigned int failure_count; + +extern const char *current_test_name; +extern const char *current_test_activity; + +extern const char * ccapi_error_strings[30]; + +const char *translate_ccapi_error(cc_int32 err); + +#define T_CCAPI_INIT \ + do { \ + current_test_name = NULL; \ + current_test_activity = NULL; \ + } while( 0 ) + +#define BEGIN_TEST(name) \ + do { \ + current_test_name = name; \ + failure_count = 0; \ + test_header(current_test_name); \ + } while( 0 ) + +#define BEGIN_CHECK_ONCE(x) \ + do { \ + if (x) { \ + current_test_activity = x; \ + } \ + } while( 0 ) + +#define END_CHECK_ONCE \ + do { \ + current_test_activity = NULL; \ + } while( 0 ) + +#define END_TEST_AND_RETURN \ + test_footer(current_test_name, failure_count); \ + total_failure_count += failure_count; \ + return failure_count; + +#endif /* _TEST_CCAPI_GLOBALS_H_ */ diff --git a/src/ccapi/test/test_ccapi_iterators.c b/src/ccapi/test/test_ccapi_iterators.c new file mode 100644 index 000000000..afc855687 --- /dev/null +++ b/src/ccapi/test/test_ccapi_iterators.c @@ -0,0 +1,244 @@ +#include "test_ccapi_iterators.h" +#include "test_ccapi_check.h" +#include "test_ccapi_util.h" + + +// --------------------------------------------------------------------------- + +int check_cc_ccache_iterator_next() { + BEGIN_TEST("cc_ccache_iterator_next"); + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_ccache_iterator_t iterator = NULL; + unsigned int i; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // iterate with no ccaches + if (!err) { + err = cc_context_new_ccache_iterator(context, &iterator); + } + check_once_cc_ccache_iterator_next(iterator, 0, ccNoError, "iterating over an empty collection"); + if (iterator) { + cc_ccache_iterator_release(iterator); + iterator = NULL; + } + + // iterate with one ccache + if (!err) { + destroy_all_ccaches(context); + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + if (!err) { + err = cc_context_new_ccache_iterator(context, &iterator); + } + check_once_cc_ccache_iterator_next(iterator, 1, ccNoError, "iterating over a collection of 1 ccache"); + if (iterator) { + cc_ccache_iterator_release(iterator); + iterator = NULL; + } + + // iterate with several ccaches + if (!err) { + destroy_all_ccaches(context); + } + for(i = 0; !err && (i < 1000); i++) + { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + } + if (!err) { + err = cc_context_new_ccache_iterator(context, &iterator); + } + check_once_cc_ccache_iterator_next(iterator, 1000, ccNoError, "iterating over a collection of 1000 ccache"); + if (iterator) { + cc_ccache_iterator_release(iterator); + iterator = NULL; + } + + + if (ccache) { cc_ccache_release(ccache); } + if (iterator) { cc_ccache_iterator_release(iterator); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_ccache_iterator_next(cc_ccache_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + cc_int32 possible_return_values[6] = { + ccNoError, + ccIteratorEnd, + ccErrBadParam, + ccErrNoMem, + ccErrInvalidCCacheIterator, + ccErrCCacheNotFound, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_ccache_t ccache = NULL; + cc_uint32 actual_count = 0; + + while (!err) { + err = cc_ccache_iterator_next(iterator, &ccache); + if (ccache) { + actual_count++; + cc_ccache_release(ccache); + ccache = NULL; + } + } + if (err == ccIteratorEnd) { + err = ccNoError; + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_credentials_iterator_next() { + BEGIN_TEST("cc_credentials_iterator_next"); + + cc_int32 err = 0; + cc_context_t context = NULL; + cc_ccache_t ccache = NULL; + cc_credentials_union creds_union; + cc_credentials_iterator_t iterator = NULL; + unsigned int i; + + err = cc_initialize(&context, ccapi_version_3, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches(context); + } + + // iterate with no creds + if (!err) { + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &iterator); + } + check_once_cc_credentials_iterator_next(iterator, 0, ccNoError, "iterating over an empty ccache"); + if (iterator) { + cc_ccache_iterator_release(iterator); + iterator = NULL; + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + // iterate with one cred + if (!err) { + destroy_all_ccaches(context); + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + if (!err) { + new_v5_creds_union(&creds_union, "BAR.ORG"); + err = cc_ccache_store_credentials(ccache, &creds_union); + release_v5_creds_union(&creds_union); + } + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &iterator); + } + check_once_cc_credentials_iterator_next(iterator, 1, ccNoError, "iterating over a ccache with 1 cred"); + if (iterator) { + cc_credentials_iterator_release(iterator); + iterator = NULL; + } + if (ccache) { + cc_ccache_release(ccache); + ccache = NULL; + } + + // iterate with several creds + if (!err) { + destroy_all_ccaches(context); + err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); + } + for(i = 0; !err && (i < 1000); i++) { + new_v5_creds_union(&creds_union, "BAR.ORG"); + err = cc_ccache_store_credentials(ccache, &creds_union); + release_v5_creds_union(&creds_union); + } + if (!err) { + err = cc_ccache_new_credentials_iterator(ccache, &iterator); + } + check_once_cc_credentials_iterator_next(iterator, 1000, ccNoError, "iterating over a ccache with 1000 creds"); + + if (ccache) { cc_ccache_release(ccache); } + if (iterator) { cc_credentials_iterator_release(iterator); } + if (context) { + destroy_all_ccaches(context); + cc_context_release(context); + } + + END_TEST_AND_RETURN +} + +cc_int32 check_once_cc_credentials_iterator_next(cc_credentials_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description) { + cc_int32 err = ccNoError; + + BEGIN_CHECK_ONCE(description); + + cc_int32 possible_return_values[5] = { + ccNoError, + ccIteratorEnd, + ccErrBadParam, + ccErrNoMem, + ccErrInvalidCredentialsIterator, + }; + #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + cc_credentials_t creds = NULL; + cc_uint32 actual_count = 0; + + while (!err) { + err = cc_credentials_iterator_next(iterator, &creds); + if (creds) { + actual_count++; + cc_credentials_release(creds); + creds = NULL; + } + } + if (err == ccIteratorEnd) { + err = ccNoError; + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); + + END_CHECK_ONCE; + + return err; +} \ No newline at end of file diff --git a/src/ccapi/test/test_ccapi_iterators.h b/src/ccapi/test/test_ccapi_iterators.h new file mode 100644 index 000000000..4ce81982d --- /dev/null +++ b/src/ccapi/test/test_ccapi_iterators.h @@ -0,0 +1,12 @@ +#ifndef _TEST_CCAPI_ITERATORS_H_ +#define _TEST_CCAPI_ITERATORS_H_ + +#include + +int check_cc_ccache_iterator_next(); +cc_int32 check_once_cc_ccache_iterator_next(cc_ccache_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description); + +int check_cc_credentials_iterator_next(); +cc_int32 check_once_cc_credentials_iterator_next(cc_credentials_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description); + +#endif /* _TEST_CCAPI_ITERATORS_H_ */ diff --git a/src/ccapi/test/test_ccapi_log.c b/src/ccapi/test/test_ccapi_log.c new file mode 100644 index 000000000..95a467ad6 --- /dev/null +++ b/src/ccapi/test/test_ccapi_log.c @@ -0,0 +1,45 @@ +#ifndef _TEST_CCAPI_LOG_C_ +#define _TEST_CCAPI_LOG_C_ + +#include "test_ccapi_log.h" + +void _log_error_v(const char *file, int line, const char *format, va_list ap) +{ + fprintf(stdout, "\n\t%s:%d: ", file, line); + if (!format) { + fprintf(stdout, "An unknown error occurred", file, line); + } else { + vfprintf(stdout, format, ap); + } + fflush(stdout); +} + +void _log_error(const char *file, int line, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + _log_error_v(file, line, format, ap); + va_end(ap); +} + +void test_header(const char *msg) { + if (msg != NULL) { + fprintf(stdout, "\nChecking %s... ", msg); + fflush(stdout); + } +} + +void test_footer(const char *msg, int err) { + if (msg != NULL) { + if (!err) { + fprintf(stdout, "OK\n"); + } + else { + fprintf(stdout, "\n*** %d failure%s in %s ***\n", err, (err == 1) ? "" : "s", msg); + } + } +} + + + +#endif /* _TEST_CCAPI_LOG_C_ */ diff --git a/src/ccapi/test/test_ccapi_log.h b/src/ccapi/test/test_ccapi_log.h new file mode 100644 index 000000000..abb79d593 --- /dev/null +++ b/src/ccapi/test/test_ccapi_log.h @@ -0,0 +1,17 @@ +#ifndef _TEST_CCAPI_LOG_H_ +#define _TEST_CCAPI_LOG_H_ + +#include +#include +#include "test_ccapi_globals.h" + +#define log_error(format, ...) \ + _log_error(__FILE__, __LINE__, format , ## __VA_ARGS__) + +void _log_error_v(const char *file, int line, const char *format, va_list ap); +void _log_error(const char *file, int line, const char *format, ...) __attribute__ ((format (printf, 3, 4))); + +void test_header(const char *msg); +void test_footer(const char *msg, int err); + +#endif /* _TEST_CCAPI_LOG_H_ */ diff --git a/src/ccapi/test/test_ccapi_util.c b/src/ccapi/test/test_ccapi_util.c new file mode 100644 index 000000000..d7dc3e105 --- /dev/null +++ b/src/ccapi/test/test_ccapi_util.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#include "test_ccapi_util.h" + + +// --------------------------------------------------------------------------- + +cc_int32 destroy_all_ccaches(cc_context_t context) { + cc_int32 err = ccNoError; + cc_ccache_t ccache = NULL; + + while (!err) { + err = cc_context_open_default_ccache(context, &ccache); + if (!err) { + err = cc_ccache_destroy(ccache); + } + } + if (err == ccErrCCacheNotFound) { + err = ccNoError; + } + else { + log_error("cc_context_open_default_ccache or cc_ccache_destroy failed with %s (%d)", translate_ccapi_error(err), err); + } + + return err; +} + + +// --------------------------------------------------------------------------- + +cc_int32 new_v5_creds_union (cc_credentials_union *out_union, const char *realm) +{ + cc_int32 err = ccNoError; + cc_credentials_union *cred_union = NULL; + cc_credentials_v5_t *v5creds = NULL; + static num_runs = 1; + char *client = NULL; + char *server = NULL; + + if (!out_union) { err = ccErrBadParam; } + + if (!err) { + v5creds = malloc (sizeof (*v5creds)); + if (!v5creds) { + err = ccErrNoMem; + } + } + + if (!err) { + asprintf(&client, "client@%s", realm); + asprintf(&server, "host/%d%s@%s", num_runs++, realm, realm); + if (!client || !server) { + err = ccErrNoMem; + } + } + + if (!err) { + v5creds->client = client; + v5creds->server = server; + v5creds->keyblock.type = 1; + v5creds->keyblock.length = 0; + v5creds->keyblock.data = NULL; + v5creds->authtime = time (NULL); + v5creds->starttime = time (NULL); + v5creds->endtime = time(NULL) + 1000; + v5creds->renew_till = time(NULL) + 10000; + v5creds->is_skey = 0; + v5creds->ticket_flags = TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE | TKT_FLG_RENEWABLE | TKT_FLG_INITIAL; + v5creds->addresses = NULL; + v5creds->ticket.type = 0; + v5creds->ticket.length = 0; + v5creds->ticket.data = NULL; + v5creds->second_ticket.type = 0; + v5creds->second_ticket.length = 0; + v5creds->second_ticket.data = NULL; + v5creds->authdata = NULL; + } + + + if (!err) { + cred_union = malloc (sizeof (*cred_union)); + if (cred_union) { + cred_union->version = cc_credentials_v5; + cred_union->credentials.credentials_v5 = v5creds; + } else { + err = ccErrNoMem; + } + } + if (!err) { + *out_union = *cred_union; + cred_union = NULL; + } + + return err; +} + + +// --------------------------------------------------------------------------- + +void release_v5_creds_union(cc_credentials_union *creds_union) { + cc_credentials_v5_t *v5creds = NULL; + + if (creds_union) { + if (creds_union->credentials.credentials_v5) { + v5creds = creds_union->credentials.credentials_v5; + if (v5creds->client) { free(v5creds->client); } + if (v5creds->server) { free(v5creds->server); } + if (v5creds->keyblock.data) { free(v5creds->keyblock.data); } + if (v5creds->ticket.data) { free(v5creds->ticket.data); } + if (v5creds->second_ticket.data) { free(v5creds->second_ticket.data); } + free(v5creds); + } + //free(creds_union); + } +} + + +// --------------------------------------------------------------------------- + +// return zero when both unions are considered equal, non-zero when not + +int compare_v5_creds_unions(const cc_credentials_union *a, const cc_credentials_union *b) { + int retval = -1; + + if (a && + b && + (a->version == cc_credentials_v5) && + (a->version == b->version) && + (strcmp(a->credentials.credentials_v5->client, b->credentials.credentials_v5->client) == 0) && + (strcmp(a->credentials.credentials_v5->server, b->credentials.credentials_v5->server) == 0)) + { + retval = 0; + } + + return retval; +} \ No newline at end of file diff --git a/src/ccapi/test/test_ccapi_util.h b/src/ccapi/test/test_ccapi_util.h new file mode 100644 index 000000000..8c9e51e51 --- /dev/null +++ b/src/ccapi/test/test_ccapi_util.h @@ -0,0 +1,14 @@ +#ifndef _TEST_CCAPI_UTIL_H_ +#define _TEST_CCAPI_UTIL_H_ + +#include +#include "test_ccapi_globals.h" +#include "test_ccapi_log.h" + +cc_int32 destroy_all_ccaches(cc_context_t context); + +cc_int32 new_v5_creds_union(cc_credentials_union *out_union, const char *realm); +void release_v5_creds_union(cc_credentials_union *creds_union); +int compare_v5_creds_unions(const cc_credentials_union *a, const cc_credentials_union *b); + +#endif /* _TEST_CCAPI_UTIL_H_ */ diff --git a/src/ccapi/test/test_constants.c b/src/ccapi/test/test_constants.c new file mode 100644 index 000000000..9f52e74b4 --- /dev/null +++ b/src/ccapi/test/test_constants.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "test_ccapi_check.h" +#include "test_ccapi_constants.h" +#include "test_ccapi_context.h" +#include "test_ccapi_ccache.h" + +int main (int argc, const char * argv[]) { + + cc_int32 err = ccNoError; + T_CCAPI_INIT; + err = check_constants(); + return err; +} diff --git a/src/include/CredentialsCache.h b/src/include/CredentialsCache.h new file mode 100644 index 000000000..51242bbef --- /dev/null +++ b/src/include/CredentialsCache.h @@ -0,0 +1,552 @@ +/* + * $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. + */ + +#ifndef __CREDENTIALSCACHE__ +#define __CREDENTIALSCACHE__ + +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) +#include +#endif + +#if defined(_WIN32) +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if TARGET_OS_MAC +#pragma pack(push,2) +#endif + +#if defined(_WIN32) +#define CCACHE_API __declspec(dllexport) + +#if _INTEGRAL_MAX_BITS >= 64 && _MSC_VER >= 1400 && !defined(_WIN64) && !defined(_USE_32BIT_TIME_T) +#if defined(_TIME_T_DEFINED) || defined(_INC_IO) || defined(_INC_TIME) || defined(_INC_WCHAR) +#error time_t has been defined as a 64-bit integer which is incompatible with Kerberos on this platform. +#endif /* _TIME_T_DEFINED */ +#define _USE_32BIT_TIME_T +#endif +#else +#define CCACHE_API +#endif + +#include + +/* + * Constants + */ + +/* API versions */ +enum { + ccapi_version_2 = 2, + ccapi_version_3 = 3, + ccapi_version_4 = 4, + ccapi_version_5 = 5, + ccapi_version_6 = 6, + ccapi_version_max = ccapi_version_6 +}; + +/* Errors */ +enum { + ccNoError = 0, + + ccIteratorEnd = 201, + ccErrBadParam, + ccErrNoMem, + ccErrInvalidContext, + ccErrInvalidCCache, + + ccErrInvalidString, /* 206 */ + ccErrInvalidCredentials, + ccErrInvalidCCacheIterator, + ccErrInvalidCredentialsIterator, + ccErrInvalidLock, + + ccErrBadName, /* 211 */ + ccErrBadCredentialsVersion, + ccErrBadAPIVersion, + ccErrContextLocked, + ccErrContextUnlocked, + + ccErrCCacheLocked, /* 216 */ + ccErrCCacheUnlocked, + ccErrBadLockType, + ccErrNeverDefault, + ccErrCredentialsNotFound, + + ccErrCCacheNotFound, /* 221 */ + ccErrContextNotFound, + ccErrServerUnavailable, + ccErrServerInsecure, + ccErrServerCantBecomeUID, + + ccErrTimeOffsetNotSet, /* 226 */ + ccErrBadInternalMessage, + ccErrNotImplemented, + ccErrClientNotFound +}; + +/* Credentials versions */ +enum cc_credential_versions { + cc_credentials_v4 = 1, + cc_credentials_v5 = 2, + cc_credentials_v4_v5 = 3 +}; + +/* Lock types */ +enum cc_lock_types { + cc_lock_read = 0, + cc_lock_write = 1, + cc_lock_upgrade = 2, + cc_lock_downgrade = 3 +}; + +/* Locking Modes */ +enum cc_lock_modes { + cc_lock_noblock = 0, + cc_lock_block = 1 +}; + +/* Basic types */ + +typedef uint32_t cc_uint32; +typedef int32_t cc_int32; +#if defined (WIN32) +typedef __int64 cc_int64; +typedef unsigned __int64 cc_uint64; +#else +typedef int64_t cc_int64; +typedef uint64_t cc_uint64; +#endif +typedef cc_uint32 cc_time_t; + +/* API types */ + +/* Forward declarations */ +struct cc_context_f; +typedef struct cc_context_f cc_context_f; + +struct cc_ccache_f; +typedef struct cc_ccache_f cc_ccache_f; + +struct cc_ccache_iterator_f; +typedef struct cc_ccache_iterator_f cc_ccache_iterator_f; + +struct cc_ccache_iterator_f; +typedef struct cc_credentials_iterator_f cc_credentials_iterator_f; + +struct cc_string_f; +typedef struct cc_string_f cc_string_f; + +struct cc_credentials_f; +typedef struct cc_credentials_f cc_credentials_f; + +/* Credentials types */ + +enum { /* Make sure all of these are multiples of four (for alignment sanity) */ + cc_v4_name_size = 40, + cc_v4_instance_size = 40, + cc_v4_realm_size = 40, + cc_v4_ticket_size = 1254, + cc_v4_key_size = 8 +}; + +enum cc_string_to_key_type { + cc_v4_stk_afs = 0, + cc_v4_stk_des = 1, + cc_v4_stk_columbia_special = 2, + cc_v4_stk_krb5 = 3, + cc_v4_stk_unknown = 4 +}; + +struct cc_credentials_v4_t { + cc_uint32 version; + char principal [cc_v4_name_size]; + char principal_instance [cc_v4_instance_size]; + char service [cc_v4_name_size]; + char service_instance [cc_v4_instance_size]; + char realm [cc_v4_realm_size]; + unsigned char session_key [cc_v4_key_size]; + cc_int32 kvno; + cc_int32 string_to_key_type; + cc_time_t issue_date; + cc_int32 lifetime; + cc_uint32 address; + cc_int32 ticket_size; + unsigned char ticket [cc_v4_ticket_size]; +}; +typedef struct cc_credentials_v4_t cc_credentials_v4_t; + +struct cc_data { + cc_uint32 type; + cc_uint32 length; + void* data; +}; +typedef struct cc_data cc_data; + +struct cc_credentials_v5_t { + char* client; + 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** addresses; + cc_data ticket; + cc_data second_ticket; + cc_data** authdata; +}; +typedef struct cc_credentials_v5_t cc_credentials_v5_t; + +struct cc_credentials_union { + cc_uint32 version; + union { + cc_credentials_v4_t* credentials_v4; + cc_credentials_v5_t* credentials_v5; + } credentials; +}; +typedef struct cc_credentials_union cc_credentials_union; + +/* Exposed parts */ + +struct cc_context_d { + const cc_context_f *functions; +#if TARGET_OS_MAC + const cc_context_f *vector_functions; +#endif +}; +typedef struct cc_context_d cc_context_d; +typedef cc_context_d *cc_context_t; + +struct cc_ccache_d { + const cc_ccache_f *functions; +#if TARGET_OS_MAC + const cc_ccache_f *vector_functions; +#endif +}; +typedef struct cc_ccache_d cc_ccache_d; +typedef cc_ccache_d *cc_ccache_t; + +struct cc_ccache_iterator_d { + const cc_ccache_iterator_f *functions; +#if TARGET_OS_MAC + const cc_ccache_iterator_f *vector_functions; +#endif +}; +typedef struct cc_ccache_iterator_d cc_ccache_iterator_d; +typedef cc_ccache_iterator_d *cc_ccache_iterator_t; + +struct cc_credentials_iterator_d { + const cc_credentials_iterator_f *functions; +#if TARGET_OS_MAC + const cc_credentials_iterator_f *vector_functions; +#endif +}; +typedef struct cc_credentials_iterator_d cc_credentials_iterator_d; +typedef cc_credentials_iterator_d *cc_credentials_iterator_t; + +struct cc_string_d { + const char *data; + const cc_string_f *functions; +#if TARGET_OS_MAC + const cc_string_f *vector_functions; +#endif +}; +typedef struct cc_string_d cc_string_d; +typedef cc_string_d *cc_string_t; + +struct cc_credentials_d { + const cc_credentials_union *data; + const cc_credentials_f *functions; +#if TARGET_OS_MAC + const cc_credentials_f *otherFunctions; +#endif +}; +typedef struct cc_credentials_d cc_credentials_d; +typedef cc_credentials_d *cc_credentials_t; + +/* Function pointer structs */ + +struct cc_context_f { + cc_int32 (*release) (cc_context_t in_context); + + cc_int32 (*get_change_time) (cc_context_t in_context, + cc_time_t *out_time); + + cc_int32 (*get_default_ccache_name) (cc_context_t in_context, + cc_string_t *out_name); + + cc_int32 (*open_ccache) (cc_context_t in_context, + const char *in_name, + cc_ccache_t *out_ccache); + + cc_int32 (*open_default_ccache) (cc_context_t in_context, + cc_ccache_t *out_ccache); + + cc_int32 (*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 (*create_default_ccache) (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache); + + cc_int32 (*create_new_ccache) (cc_context_t in_context, + cc_uint32 in_cred_vers, + const char *in_principal, + cc_ccache_t *out_ccache); + + cc_int32 (*new_ccache_iterator) (cc_context_t in_context, + cc_ccache_iterator_t *out_iterator); + + cc_int32 (*lock) (cc_context_t in_context, + cc_uint32 in_lock_type, + cc_uint32 in_block); + + cc_int32 (*unlock) (cc_context_t in_cc_context); + + cc_int32 (*compare) (cc_context_t in_cc_context, + cc_context_t in_compare_to_context, + cc_uint32 *out_equal); + + cc_int32 (*wait_for_change) (cc_context_t in_cc_context); +}; + +struct cc_ccache_f { + cc_int32 (*release) (cc_ccache_t io_ccache); + + cc_int32 (*destroy) (cc_ccache_t io_ccache); + + cc_int32 (*set_default) (cc_ccache_t io_ccache); + + cc_int32 (*get_credentials_version) (cc_ccache_t in_ccache, + cc_uint32 *out_credentials_version); + + cc_int32 (*get_name) (cc_ccache_t in_ccache, + cc_string_t *out_name); + + cc_int32 (*get_principal) (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_string_t *out_principal); + + cc_int32 (*set_principal) (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + const char *in_principal); + + cc_int32 (*store_credentials) (cc_ccache_t io_ccache, + const cc_credentials_union *in_credentials_union); + + cc_int32 (*remove_credentials) (cc_ccache_t io_ccache, + cc_credentials_t in_credentials); + + cc_int32 (*new_credentials_iterator) (cc_ccache_t in_ccache, + cc_credentials_iterator_t *out_credentials_iterator); + + cc_int32 (*move) (cc_ccache_t io_source_ccache, + cc_ccache_t io_destination_ccache); + + cc_int32 (*lock) (cc_ccache_t io_ccache, + cc_uint32 in_lock_type, + cc_uint32 in_block); + + cc_int32 (*unlock) (cc_ccache_t io_ccache); + + cc_int32 (*get_last_default_time) (cc_ccache_t in_ccache, + cc_time_t *out_last_default_time); + + cc_int32 (*get_change_time) (cc_ccache_t in_ccache, + cc_time_t *out_change_time); + + cc_int32 (*compare) (cc_ccache_t in_ccache, + cc_ccache_t in_compare_to_ccache, + cc_uint32 *out_equal); + + cc_int32 (*get_kdc_time_offset) (cc_ccache_t in_ccache, + cc_uint32 in_credentials_version, + cc_time_t *out_time_offset); + + cc_int32 (*set_kdc_time_offset) (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version, + cc_time_t in_time_offset); + + cc_int32 (*clear_kdc_time_offset) (cc_ccache_t io_ccache, + cc_uint32 in_credentials_version); + + cc_int32 (*wait_for_change) (cc_ccache_t in_ccache); +}; + +struct cc_string_f { + cc_int32 (*release) (cc_string_t in_string); +}; + +struct cc_credentials_f { + cc_int32 (*release) (cc_credentials_t io_credentials); + + cc_int32 (*compare) (cc_credentials_t in_credentials, + cc_credentials_t in_compare_to_credentials, + cc_uint32 *out_equal); +}; + + +struct cc_ccache_iterator_f { + cc_int32 (*release) (cc_ccache_iterator_t io_ccache_iterator); + + cc_int32 (*next) (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_t *out_ccache); + + cc_int32 (*clone) (cc_ccache_iterator_t in_ccache_iterator, + cc_ccache_iterator_t *out_ccache_iterator); +}; + +struct cc_credentials_iterator_f { + cc_int32 (*release) (cc_credentials_iterator_t io_credentials_iterator); + + cc_int32 (*next) (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_t *out_credentials); + + cc_int32 (*clone) (cc_credentials_iterator_t in_credentials_iterator, + cc_credentials_iterator_t *out_credentials_iterator); +}; + +/* API functions */ + +CCACHE_API cc_int32 cc_initialize (cc_context_t *out_context, + cc_int32 in_version, + cc_int32 *out_supported_version, + char const **out_vendor); + +/* Convenience macros */ + +#define cc_context_release(context) \ + ((context) -> functions -> release (context)) +#define cc_context_get_change_time(context, change_time) \ + ((context) -> functions -> get_change_time (context, change_time)) +#define cc_context_get_default_ccache_name(context, name) \ + ((context) -> functions -> get_default_ccache_name (context, name)) +#define cc_context_open_ccache(context, name, ccache) \ + ((context) -> functions -> open_ccache (context, name, ccache)) +#define cc_context_open_default_ccache(context, ccache) \ + ((context) -> functions -> open_default_ccache (context, ccache)) +#define cc_context_create_ccache(context, name, version, principal, ccache) \ + ((context) -> functions -> create_ccache (context, name, version, principal, ccache)) +#define cc_context_create_default_ccache(context, version, principal, ccache) \ + ((context) -> functions -> create_default_ccache (context, version, principal, ccache)) +#define cc_context_create_new_ccache(context, version, principal, ccache) \ + ((context) -> functions -> create_new_ccache (context, version, principal, ccache)) +#define cc_context_new_ccache_iterator(context, iterator) \ + ((context) -> functions -> new_ccache_iterator (context, iterator)) +#define cc_context_lock(context, type, block) \ + ((context) -> functions -> lock (context, type, block)) +#define cc_context_unlock(context) \ + ((context) -> functions -> unlock (context)) +#define cc_context_compare(context, compare_to, equal) \ + ((context) -> functions -> compare (context, compare_to, equal)) +#define cc_context_wait_for_change(context) \ + ((context) -> functions -> wait_for_change (context)) + +#define cc_ccache_release(ccache) \ + ((ccache) -> functions -> release (ccache)) +#define cc_ccache_destroy(ccache) \ + ((ccache) -> functions -> destroy (ccache)) +#define cc_ccache_set_default(ccache) \ + ((ccache) -> functions -> set_default (ccache)) +#define cc_ccache_get_credentials_version(ccache, version) \ + ((ccache) -> functions -> get_credentials_version (ccache, version)) +#define cc_ccache_get_name(ccache, name) \ + ((ccache) -> functions -> get_name (ccache, name)) +#define cc_ccache_get_principal(ccache, version, principal) \ + ((ccache) -> functions -> get_principal (ccache, version, principal)) +#define cc_ccache_set_principal(ccache, version, principal) \ + ((ccache) -> functions -> set_principal (ccache, version, principal)) +#define cc_ccache_store_credentials(ccache, credentials) \ + ((ccache) -> functions -> store_credentials (ccache, credentials)) +#define cc_ccache_remove_credentials(ccache, credentials) \ + ((ccache) -> functions -> remove_credentials (ccache, credentials)) +#define cc_ccache_new_credentials_iterator(ccache, iterator) \ + ((ccache) -> functions -> new_credentials_iterator (ccache, iterator)) +#define cc_ccache_lock(ccache, type, block) \ + ((ccache) -> functions -> lock (ccache, type, block)) +#define cc_ccache_unlock(ccache, unlock) \ + ((ccache) -> functions -> unlock (ccache, unlock)) +#define cc_ccache_get_last_default_time(ccache, last_default_time) \ + ((ccache) -> functions -> get_last_default_time (ccache, last_default_time)) +#define cc_ccache_get_change_time(ccache, change_time) \ + ((ccache) -> functions -> get_change_time (ccache, change_time)) +#define cc_ccache_move(source, destination) \ + ((source) -> functions -> move (source, destination)) +#define cc_ccache_compare(ccache, compare_to, equal) \ + ((ccache) -> functions -> compare (ccache, compare_to, equal)) +#define cc_ccache_get_kdc_time_offset(ccache, version, time_offset) \ + ((ccache) -> functions -> get_kdc_time_offset (ccache, version, time_offset)) +#define cc_ccache_set_kdc_time_offset(ccache, version, time_offset) \ + ((ccache) -> functions -> set_kdc_time_offset (ccache, version, time_offset)) +#define cc_ccache_clear_kdc_time_offset(ccache, version) \ + ((ccache) -> functions -> clear_kdc_time_offset (ccache, version)) +#define cc_ccache_wait_for_change(ccache) \ + ((ccache) -> functions -> wait_for_change (ccache)) + +#define cc_string_release(string) \ + ((string) -> functions -> release (string)) + +#define cc_credentials_release(credentials) \ + ((credentials) -> functions -> release (credentials)) +#define cc_credentials_compare(credentials, compare_to, equal) \ + ((credentials) -> functions -> compare (credentials, compare_to, equal)) + +#define cc_ccache_iterator_release(iterator) \ + ((iterator) -> functions -> release (iterator)) +#define cc_ccache_iterator_next(iterator, ccache) \ + ((iterator) -> functions -> next (iterator, ccache)) +#define cc_ccache_iterator_clone(iterator, new_iterator) \ + ((iterator) -> functions -> clone (iterator, new_iterator)) + +#define cc_credentials_iterator_release(iterator) \ + ((iterator) -> functions -> release (iterator)) +#define cc_credentials_iterator_next(iterator, credentials) \ + ((iterator) -> functions -> next (iterator, credentials)) +#define cc_credentials_iterator_clone(iterator, new_iterator) \ + ((iterator) -> functions -> clone (iterator, new_iterator)) + +#if TARGET_OS_MAC +#pragma pack(pop) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CREDENTIALSCACHE__ */ diff --git a/src/include/CredentialsCache2.h b/src/include/CredentialsCache2.h new file mode 100644 index 000000000..b0c45d59e --- /dev/null +++ b/src/include/CredentialsCache2.h @@ -0,0 +1,326 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * This is backwards compatibility for CCache API v2 clients to be able to run + * against the CCache API v3 library + */ + +#ifndef CCAPI_V2_H +#define CCAPI_V2_H + +#include + +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) +#include +#include +#ifdef DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER +#define CCAPI_DEPRECATED DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER +#endif +#endif + +#ifndef CCAPI_DEPRECATED +#define CCAPI_DEPRECATED +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if TARGET_OS_MAC +#pragma pack(push,2) +#endif + +/* Some old types get directly mapped to new types */ + +typedef cc_context_d apiCB; +typedef cc_ccache_d ccache_p; +typedef cc_credentials_iterator_d ccache_cit_creds; +typedef cc_ccache_iterator_d ccache_cit_ccache; +typedef cc_data cc_data_compat; +typedef cc_int32 cc_cred_vers; +typedef cc_int32 cc_result; + +/* This doesn't exist in API v3 */ +typedef cc_uint32 cc_flags; + +/* Credentials types are visible to the caller so we have to keep binary compatibility */ + +typedef struct cc_credentials_v5_compat { + char* client; + char* server; + cc_data_compat 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_compat** addresses; + cc_data_compat ticket; + cc_data_compat second_ticket; + cc_data_compat** authdata; +} cc_credentials_v5_compat; + +enum { + MAX_V4_CRED_LEN = 1250 +}; + +enum { + KRB_NAME_SZ = 40, + KRB_INSTANCE_SZ = 40, + KRB_REALM_SZ = 40 +}; + +typedef struct cc_credentials_v4_compat { + unsigned char kversion; + char principal[KRB_NAME_SZ+1]; + char principal_instance[KRB_INSTANCE_SZ+1]; + char service[KRB_NAME_SZ+1]; + char service_instance[KRB_INSTANCE_SZ+1]; + char realm[KRB_REALM_SZ+1]; + unsigned char session_key[8]; + cc_int32 kvno; + cc_int32 str_to_key; + long issue_date; + cc_int32 lifetime; + cc_uint32 address; + cc_int32 ticket_sz; + unsigned char ticket[MAX_V4_CRED_LEN]; + unsigned long oops; +} cc_credentials_v4_compat; + +typedef union cred_ptr_union_compat { + cc_credentials_v4_compat* pV4Cred; + cc_credentials_v5_compat* pV5Cred; +} cred_ptr_union_compat; + +typedef struct cred_union { + cc_int32 cred_type; /* cc_cred_vers */ + cred_ptr_union_compat cred; +} cred_union; + +/* NC info structure is gone in v3 */ + +struct infoNC { + char* name; + char* principal; + cc_int32 vers; +}; + +typedef struct infoNC infoNC; + +/* Some old type names */ + +typedef cc_credentials_v4_compat V4Cred_type; +typedef cc_credentials_v5_compat cc_creds; +struct ccache_cit; +typedef struct ccache_cit ccache_cit; + +enum { + CC_API_VER_2 = ccapi_version_2 +}; + +enum { + CC_NOERROR, + CC_BADNAME, + CC_NOTFOUND, + CC_END, + CC_IO, + CC_WRITE, + CC_NOMEM, + CC_FORMAT, + CC_LOCKED, + CC_BAD_API_VERSION, + CC_NO_EXIST, + CC_NOT_SUPP, + CC_BAD_PARM, + CC_ERR_CACHE_ATTACH, + CC_ERR_CACHE_RELEASE, + CC_ERR_CACHE_FULL, + CC_ERR_CRED_VERSION +}; + +enum { + CC_CRED_UNKNOWN, + CC_CRED_V4, + CC_CRED_V5, + CC_CRED_MAX +}; + +enum { + CC_LOCK_UNLOCK = 1, + CC_LOCK_READER = 2, + CC_LOCK_WRITER = 3, + CC_LOCK_NOBLOCK = 16 +}; + +CCACHE_API cc_int32 +cc_shutdown (apiCB **io_context) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_get_NC_info (apiCB *in_context, + infoNC ***out_info) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_get_change_time (apiCB *in_context, + cc_time_t *out_change_time) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_open (apiCB *in_context, + const char *in_name, + cc_int32 in_version, + cc_uint32 in_flags, + ccache_p **out_ccache) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +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) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_close (apiCB *in_context, + ccache_p **ioCCache) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_destroy (apiCB *in_context, + ccache_p **io_ccache) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_NCs_begin (apiCB *in_context, + ccache_cit **out_nc_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_NCs_next (apiCB *in_context, + ccache_p **out_ccache, + ccache_cit *in_nc_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_NCs_end (apiCB *in_context, + ccache_cit **io_nc_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_get_name (apiCB *in_context, + ccache_p *in_ccache, + char **out_name) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_get_cred_version (apiCB *in_context, + ccache_p *in_ccache, + cc_int32 *out_version) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_set_principal (apiCB *in_context, + ccache_p *in_ccache, + cc_int32 in_version, + char *in_principal) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_get_principal (apiCB *in_context, + ccache_p *in_ccache, + char **out_principal) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_store (apiCB *in_context, + ccache_p *in_ccache, + cred_union in_credentials) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_remove_cred (apiCB *in_context, + ccache_p *in_ccache, + cred_union in_credentials) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_creds_begin (apiCB *in_context, + const ccache_p *in_ccache, + ccache_cit **out_ccache_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_creds_next (apiCB *in_context, + cred_union **out_cred_union, + ccache_cit *in_ccache_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_seq_fetch_creds_end (apiCB *in_context, + ccache_cit **io_ccache_iterator) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_free_principal (apiCB *in_context, + char **io_principal) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_free_name (apiCB *in_context, + char **io_name) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_free_creds (apiCB *in_context, + cred_union **io_cred_union) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_free_NC_info (apiCB *in_context, + infoNC ***io_info) +CCAPI_DEPRECATED; + +CCACHE_API cc_int32 +cc_lock_request (apiCB *in_context, + const ccache_p *in_ccache, + const cc_int32 in_lock_type) +CCAPI_DEPRECATED; + +#if TARGET_OS_MAC +#pragma pack(pop) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CCAPI_V2_H */ diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c index 36bc780e2..babfea48b 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ b/src/lib/krb5/ccache/ccapi/stdcc.c @@ -230,7 +230,7 @@ static krb5_error_code stdccv3_get_timeoffset (krb5_context in_context, krb5_error_code err = 0; if (gCCVersion >= ccapi_version_5) { - krb5_os_context os_ctx = (krb5_os_context) in_context->os_context; + krb5_os_context os_ctx = (krb5_os_context) &in_context->os_context; cc_time_t time_offset = 0; err = cc_ccache_get_kdc_time_offset (in_ccache, cc_credentials_v5, @@ -257,7 +257,7 @@ static krb5_error_code stdccv3_set_timeoffset (krb5_context in_context, krb5_error_code err = 0; if (gCCVersion >= ccapi_version_5) { - krb5_os_context os_ctx = (krb5_os_context) in_context->os_context; + krb5_os_context os_ctx = (krb5_os_context) &in_context->os_context; if (!err && os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { err = cc_ccache_set_kdc_time_offset (in_ccache, diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index 2ab5da5d4..6d68cd922 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -97,7 +97,7 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, krb5_timestamp currenttime; krb5_principal_data princ_data; - req->ticket->enc_part2 == NULL; + req->ticket->enc_part2 = NULL; if (server && krb5_is_referral_realm(&server->realm)) { char *realm; princ_data = *server;