From 3c323c8486c538abcba3ec9bb4a6e8a4af20496c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 27 Oct 2004 20:48:07 +0000 Subject: [PATCH] * Initial commit of C CCAPI implementation ticket: 2753 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16840 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/ccapi/ChangeLog | 4 + src/lib/ccapi/client/ChangeLog | 4 + src/lib/ccapi/client/NTMakefile | 22 + src/lib/ccapi/client/cacheapi.c | 118 ++ src/lib/ccapi/client/ccache.c | 1098 ++++++++++++++ src/lib/ccapi/client/ccache.h | 146 ++ src/lib/ccapi/client/ccache_iterator.c | 179 +++ src/lib/ccapi/client/ccache_iterator.h | 85 ++ src/lib/ccapi/client/ccstring.c | 94 ++ src/lib/ccapi/client/ccstring.h | 65 + src/lib/ccapi/client/context.c | 849 +++++++++++ src/lib/ccapi/client/context.h | 131 ++ src/lib/ccapi/client/credentials.c | 181 +++ src/lib/ccapi/client/credentials.h | 94 ++ src/lib/ccapi/client/credentials_iterator.c | 187 +++ src/lib/ccapi/client/credentials_iterator.h | 72 + src/lib/ccapi/client/mac/ChangeLog | 4 + src/lib/ccapi/client/windows/ChangeLog | 4 + src/lib/ccapi/include/ChangeLog | 4 + src/lib/ccapi/include/CredentialsCache.h | 567 +++++++ src/lib/ccapi/include/CredentialsCache2.h | 308 ++++ src/lib/ccapi/include/marshall.h | 93 ++ src/lib/ccapi/include/msg.h | 146 ++ src/lib/ccapi/include/msg_headers.h | 429 ++++++ src/lib/ccapi/mac/ChangeLog | 4 + src/lib/ccapi/marshall.c | 378 +++++ src/lib/ccapi/msg.c | 582 +++++++ src/lib/ccapi/server/ChangeLog | 4 + src/lib/ccapi/server/NTMakefile | 30 + src/lib/ccapi/server/ccache.c | 703 +++++++++ src/lib/ccapi/server/context.c | 325 ++++ src/lib/ccapi/server/datastore.h | 231 +++ src/lib/ccapi/server/lists.c | 996 ++++++++++++ src/lib/ccapi/server/mac/ChangeLog | 4 + src/lib/ccapi/server/rpc_auth.c | 63 + src/lib/ccapi/server/rpc_auth.h | 71 + src/lib/ccapi/server/serv_ops.c | 1500 +++++++++++++++++++ src/lib/ccapi/server/serv_ops.h | 321 ++++ src/lib/ccapi/server/windows/ChangeLog | 4 + src/lib/ccapi/unit-test/ChangeLog | 4 + src/lib/ccapi/unit-test/t_ccache.c | 115 ++ src/lib/ccapi/unit-test/t_context.c | 115 ++ src/lib/ccapi/unit-test/t_lists.c | 100 ++ src/lib/ccapi/unit-test/t_msg.c | 88 ++ src/lib/ccapi/unit-test/t_server.c | 185 +++ src/lib/ccapi/windows/ChangeLog | 4 + 46 files changed, 10711 insertions(+) create mode 100644 src/lib/ccapi/ChangeLog create mode 100644 src/lib/ccapi/client/ChangeLog create mode 100644 src/lib/ccapi/client/NTMakefile create mode 100644 src/lib/ccapi/client/cacheapi.c create mode 100644 src/lib/ccapi/client/ccache.c create mode 100644 src/lib/ccapi/client/ccache.h create mode 100644 src/lib/ccapi/client/ccache_iterator.c create mode 100644 src/lib/ccapi/client/ccache_iterator.h create mode 100644 src/lib/ccapi/client/ccstring.c create mode 100644 src/lib/ccapi/client/ccstring.h create mode 100644 src/lib/ccapi/client/context.c create mode 100644 src/lib/ccapi/client/context.h create mode 100644 src/lib/ccapi/client/credentials.c create mode 100644 src/lib/ccapi/client/credentials.h create mode 100644 src/lib/ccapi/client/credentials_iterator.c create mode 100644 src/lib/ccapi/client/credentials_iterator.h create mode 100644 src/lib/ccapi/client/mac/ChangeLog create mode 100644 src/lib/ccapi/client/windows/ChangeLog create mode 100644 src/lib/ccapi/include/ChangeLog create mode 100644 src/lib/ccapi/include/CredentialsCache.h create mode 100644 src/lib/ccapi/include/CredentialsCache2.h create mode 100644 src/lib/ccapi/include/marshall.h create mode 100644 src/lib/ccapi/include/msg.h create mode 100644 src/lib/ccapi/include/msg_headers.h create mode 100644 src/lib/ccapi/mac/ChangeLog create mode 100644 src/lib/ccapi/marshall.c create mode 100644 src/lib/ccapi/msg.c create mode 100644 src/lib/ccapi/server/ChangeLog create mode 100644 src/lib/ccapi/server/NTMakefile create mode 100644 src/lib/ccapi/server/ccache.c create mode 100644 src/lib/ccapi/server/context.c create mode 100644 src/lib/ccapi/server/datastore.h create mode 100644 src/lib/ccapi/server/lists.c create mode 100644 src/lib/ccapi/server/mac/ChangeLog create mode 100644 src/lib/ccapi/server/rpc_auth.c create mode 100644 src/lib/ccapi/server/rpc_auth.h create mode 100644 src/lib/ccapi/server/serv_ops.c create mode 100644 src/lib/ccapi/server/serv_ops.h create mode 100644 src/lib/ccapi/server/windows/ChangeLog create mode 100644 src/lib/ccapi/unit-test/ChangeLog create mode 100644 src/lib/ccapi/unit-test/t_ccache.c create mode 100644 src/lib/ccapi/unit-test/t_context.c create mode 100644 src/lib/ccapi/unit-test/t_lists.c create mode 100644 src/lib/ccapi/unit-test/t_msg.c create mode 100644 src/lib/ccapi/unit-test/t_server.c create mode 100644 src/lib/ccapi/windows/ChangeLog diff --git a/src/lib/ccapi/ChangeLog b/src/lib/ccapi/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/client/ChangeLog b/src/lib/ccapi/client/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/client/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/client/NTMakefile b/src/lib/ccapi/client/NTMakefile new file mode 100644 index 000000000..09ef9df38 --- /dev/null +++ b/src/lib/ccapi/client/NTMakefile @@ -0,0 +1,22 @@ +!INCLUDE + +CFLAGS = -I../include + +CCAPI_OBJS = cacheapi.obj context.obj ccache.obj credentials.obj ccache_iterator.obj \ + credentials_iterator.obj ccstring.obj marshall.obj msg.obj + +CCAPI_LIB = ccapi.lib + +$(CCAPI_LIB): $(CCAPI_OBJS) + $(implib) /NOLOGO /OUT:$@ $** + +CCAPI_DLLFILE = krbcc32.dll + + + +$(CCAPI_DLLFILE): $(CCAPI_LIB) + $(DLLGUILINK) -def:windows\krbcc32.def + $(DLLPREP) + +clean: + del *.obj *.lib diff --git a/src/lib/ccapi/client/cacheapi.c b/src/lib/ccapi/client/cacheapi.c new file mode 100644 index 000000000..2c874bec0 --- /dev/null +++ b/src/lib/ccapi/client/cacheapi.c @@ -0,0 +1,118 @@ +/* $Copyright: + * + * Copyright 2004 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 +#include +#include "ccache.h" +#include "ccache_iterator.h" +#include "context.h" +#include "msg.h" +#include "msg_headers.h" + +cc_int32 +cc_initialize ( cc_context_t* outContext, + cc_int32 inVersion, + cc_int32* outSupportedVersion, + char const** outVendor) +{ + static char vendor[128] = ""; + cc_msg_t *request; + ccmsg_init_t *request_header; + cc_msg_t *response; + ccmsg_init_resp_t *response_header; + cc_int32 code; + + if ((inVersion != ccapi_version_2) && + (inVersion != ccapi_version_3) && + (inVersion != ccapi_version_4) && + (inVersion != ccapi_version_5)) { + + if (outSupportedVersion != NULL) { + *outSupportedVersion = ccapi_version_5; + } + return ccErrBadAPIVersion; + } + + request_header = (ccmsg_init_t*)malloc(sizeof(ccmsg_init_t)); + if (request_header == NULL) + return ccErrNoMem; + + request_header->in_version = inVersion; + + code = cci_msg_new(ccmsg_INIT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_init_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_init_resp_t *)response->header; + *outSupportedVersion = response_header->out_version; + code = cc_context_int_new(outContext, response_header->out_ctx, response_header->out_version); + + if (!vendor[0]) { + char * string; + code = cci_msg_retrieve_blob(response, response_header->vendor_offset, response_header->vendor_length, &string); + strncpy(vendor, string, sizeof(vendor)-1); + vendor[sizeof(vendor)-1] = '\0'; + free(string); + } + *outVendor = vendor; + + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + diff --git a/src/lib/ccapi/client/ccache.c b/src/lib/ccapi/client/ccache.c new file mode 100644 index 000000000..5de3880e4 --- /dev/null +++ b/src/lib/ccapi/client/ccache.c @@ -0,0 +1,1098 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + + +/* ccache.c */ + +#include +#include +#include +#include "credentials.h" +#include "ccache.h" +#include "msg.h" +#include "msg_headers.h" + +cc_int32 +cc_int_ccache_new( cc_ccache_t * pccache, cc_handle hctx, cc_handle hccache ) +{ + cc_int_ccache_t ccache = (cc_int_ccache_t)malloc(sizeof(cc_int_ccache_d)); + if ( ccache == NULL ) + return ccErrNoMem; + + ccache->functions = (cc_ccache_f*)malloc(sizeof(cc_ccache_f)); + if ( ccache->functions == NULL ) { + free(ccache); + return ccErrNoMem; + } + + ccache->functions->release = cc_int_ccache_release; + ccache->functions->destroy = cc_int_ccache_destroy; + ccache->functions->set_default = cc_int_ccache_set_default; + ccache->functions->get_credentials_version = cc_int_ccache_get_credentials_version; + ccache->functions->get_name = cc_int_ccache_get_name; + ccache->functions->get_principal = cc_int_ccache_get_principal; + ccache->functions->set_principal = cc_int_ccache_set_principal; + ccache->functions->store_credentials = cc_int_ccache_store_credentials; + ccache->functions->remove_credentials = cc_int_ccache_remove_credentials; + ccache->functions->new_credentials_iterator = cc_int_ccache_new_credentials_iterator; + ccache->functions->move = cc_int_ccache_move; + ccache->functions->lock = cc_int_ccache_lock; + ccache->functions->unlock = cc_int_ccache_unlock; + ccache->functions->get_last_default_time = cc_int_ccache_get_last_default_time; + ccache->functions->get_change_time = cc_int_ccache_get_change_time; + ccache->functions->compare = cc_int_ccache_compare; + ccache->functions->get_kdc_time_offset = cc_int_ccache_get_kdc_time_offset; + ccache->functions->set_kdc_time_offset = cc_int_ccache_set_kdc_time_offset; + ccache->functions->clear_kdc_time_offset = cc_int_ccache_clear_kdc_time_offset; + + ccache->magic = CC_CCACHE_MAGIC; + ccache->ctx = hctx; + ccache->handle = hccache; + + *pccache = (cc_ccache_t)ccache; + + return ccNoError; +} + +cc_int32 +cc_int_ccache_release( cc_ccache_t ccache ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_release_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_release_t*)malloc(sizeof(ccmsg_ccache_release_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_RELEASE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_release_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + free(int_ccache->functions); + free(int_ccache); + return code; +} + + +cc_int32 +cc_int_ccache_destroy( cc_ccache_t ccache ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_destroy_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_destroy_t*)malloc(sizeof(ccmsg_ccache_destroy_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_DESTROY, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_destroy_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + free(ccache); + return code; +} + + +cc_int32 +cc_int_ccache_set_default( cc_ccache_t ccache ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_set_default_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_set_default_t*)malloc(sizeof(ccmsg_ccache_set_default_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_SET_DEFAULT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_set_default_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_get_credentials_version( cc_ccache_t ccache, + cc_uint32* credentials_version) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_creds_version_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_creds_version_t*)malloc(sizeof(ccmsg_ccache_get_creds_version_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_GET_CREDS_VERSION, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_creds_version_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_get_creds_version_resp_t * response_header = (ccmsg_ccache_get_creds_version_resp_t*)response->header; + *credentials_version = response_header->version; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_get_name( cc_ccache_t ccache, + cc_string_t* name ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_name_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_name_t*)malloc(sizeof(ccmsg_ccache_get_name_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_GET_NAME, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_name_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + char * string; + ccmsg_ccache_get_name_resp_t * response_header = (ccmsg_ccache_get_name_resp_t*)response->header; + code = cci_msg_retrieve_blob(response, response_header->name_offset, + response_header->name_len, &string); + if (code == ccNoError) { + code = cc_string_new(&name, string); + free(string); + } + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_get_principal( cc_ccache_t ccache, + cc_uint32 credentials_version, + cc_string_t* principal ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_principal_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_principal_t*)malloc(sizeof(ccmsg_ccache_get_principal_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->version = credentials_version; + + code = cci_msg_new(ccmsg_CCACHE_GET_PRINCIPAL, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_principal_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + char * string; + ccmsg_ccache_get_principal_resp_t * response_header = (ccmsg_ccache_get_principal_resp_t*)response->header; + code = cci_msg_retrieve_blob(response, response_header->principal_offset, + response_header->principal_len, &string); + if (code == ccNoError) { + code = cc_string_new(&principal, string); + free(string); + } + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_set_principal( cc_ccache_t ccache, + cc_uint32 credentials_version, + const char* principal ) +{ + cc_uint32 blob_pos; + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_set_principal_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_set_principal_t*)malloc(sizeof(ccmsg_ccache_set_principal_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->version = credentials_version; + + code = cci_msg_new(ccmsg_CCACHE_GET_PRINCIPAL, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_data_blob(request, (void*)principal, strlen(principal) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + + request_header->principal_offset = blob_pos; + request_header->principal_len = strlen(principal) + 1; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_set_principal_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_new_credentials_iterator( cc_ccache_t ccache, + cc_credentials_iterator_t* iterator ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_creds_iterator_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_creds_iterator_t*)malloc(sizeof(ccmsg_ccache_creds_iterator_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_CREDS_ITERATOR, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_creds_iterator_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_creds_iterator_resp_t * response_header = (ccmsg_ccache_creds_iterator_resp_t*)response->header; + code = cc_int_credentials_iterator_new(iterator, response_header->iterator); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_store_credentials( cc_ccache_t ccache, + const cc_credentials_union* credentials ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_store_creds_t *request_header; + cc_msg_t *response; + char *flat_cred = 0; + cc_uint32 flat_cred_len = 0; + cc_uint32 blob_pos; + cc_int32 code; + + if ( ccache == NULL || credentials == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_store_creds_t*)malloc(sizeof(ccmsg_ccache_store_creds_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_STORE_CREDS, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + switch ( credentials->version ) { + case cc_credentials_v4: + code = cci_creds_v4_marshall(credentials->credentials.credentials_v4, &flat_cred, &flat_cred_len); + break; + case cc_credentials_v5: + code = cci_creds_v5_marshall(credentials->credentials.credentials_v5, &flat_cred, &flat_cred_len); + break; + default: + cci_msg_destroy(request); + free(request_header); + return ccErrBadCredentialsVersion; + } + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + + code = cci_msg_add_data_blob(request, (void*)flat_cred, flat_cred_len, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + + request_header->creds_version = credentials->version; + request_header->creds_offset = blob_pos; + request_header->creds_len = flat_cred_len; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_store_creds_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + free(flat_cred); + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_remove_credentials( cc_ccache_t ccache, + cc_credentials_t credentials ) +{ + cc_int_ccache_t int_ccache; + cc_int_credentials_t int_creds; + cc_msg_t *request; + ccmsg_ccache_rem_creds_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL || credentials == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + int_creds = (cc_int_credentials_t)credentials; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + if ( int_creds->magic != CC_CREDS_MAGIC ) + return ccErrInvalidCredentials; + + request_header = (ccmsg_ccache_rem_creds_t*)malloc(sizeof(ccmsg_ccache_rem_creds_t)); + if (request_header == NULL) + return ccErrNoMem; + + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->creds = int_creds->handle; + + code = cci_msg_new(ccmsg_CCACHE_REM_CREDS, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_rem_creds_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + + +cc_int32 +cc_int_ccache_move( cc_ccache_t source, + cc_ccache_t destination ) +{ + cc_int_ccache_t int_ccache_source; + cc_int_ccache_t int_ccache_dest; + cc_msg_t *request; + ccmsg_ccache_move_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( source == NULL || destination == NULL ) + return ccErrBadParam; + + int_ccache_source = (cc_int_ccache_t)source; + int_ccache_dest = (cc_int_ccache_t)destination; + + if ( int_ccache_source->magic != CC_CCACHE_MAGIC || + int_ccache_dest->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + if ( int_ccache_source->ctx != int_ccache_dest->ctx ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_move_t*)malloc(sizeof(ccmsg_ccache_move_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_MOVE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_ccache_source->ctx; + request_header->ccache_source = int_ccache_source->handle; + request_header->ccache_dest = int_ccache_dest->handle; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_move_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int_ccache_lock( cc_ccache_t ccache, + cc_uint32 lock_type, + cc_uint32 block ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_lock_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL || + (lock_type != cc_lock_read && lock_type != cc_lock_write) || + (block != cc_lock_block && block != cc_lock_noblock) ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_lock_t*)malloc(sizeof(ccmsg_ccache_lock_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_LOCK, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->lock_type; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_lock_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + + // TODO: if (block == cc_lock_block) ..... + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_unlock( cc_ccache_t ccache ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_unlock_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_unlock_t*)malloc(sizeof(ccmsg_ccache_unlock_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_UNLOCK, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_unlock_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + + +cc_int32 +cc_int_ccache_get_last_default_time( cc_ccache_t ccache, + cc_time_t* time_offset ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_last_default_time_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_last_default_time_t*)malloc(sizeof(ccmsg_ccache_get_last_default_time_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_GET_LAST_DEFAULT_TIME, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_last_default_time_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_get_last_default_time_resp_t * response_header = (ccmsg_ccache_get_last_default_time_resp_t*)response->header; + *time_offset = response_header->last_default_time; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_get_change_time( cc_ccache_t ccache, + cc_time_t* time ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_change_time_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_change_time_t*)malloc(sizeof(ccmsg_ccache_get_change_time_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + + code = cci_msg_new(ccmsg_CCACHE_GET_CHANGE_TIME, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_change_time_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_get_change_time_resp_t * response_header = (ccmsg_ccache_get_change_time_resp_t*)response->header; + *time = response_header->time; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_compare( cc_ccache_t ccache, + cc_ccache_t compare_to, + cc_uint32* equal ) +{ + cc_int_ccache_t int_ccache; + cc_int_ccache_t int_compare_to; + cc_msg_t *request; + ccmsg_ccache_compare_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + int_compare_to = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC || + int_compare_to->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_compare_t*)malloc(sizeof(ccmsg_ccache_compare_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache1 = int_ccache->handle; + request_header->ccache2 = int_compare_to->handle; + + code = cci_msg_new(ccmsg_CCACHE_COMPARE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_compare_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_compare_resp_t * response_header = (ccmsg_ccache_compare_resp_t*)response->header; + *equal = response_header->is_equal; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_get_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t* time_offset ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_get_kdc_time_offset_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_get_kdc_time_offset_t*)malloc(sizeof(ccmsg_ccache_get_kdc_time_offset_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->creds_version = credentials_version; + + code = cci_msg_new(ccmsg_CCACHE_GET_KDC_TIME_OFFSET, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_get_kdc_time_offset_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_get_kdc_time_offset_resp_t * response_header = (ccmsg_ccache_get_kdc_time_offset_resp_t*)response->header; + *time_offset = response_header->offset; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_set_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t time_offset ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_set_kdc_time_offset_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_set_kdc_time_offset_t*)malloc(sizeof(ccmsg_ccache_set_kdc_time_offset_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->creds_version = credentials_version; + + code = cci_msg_new(ccmsg_CCACHE_SET_KDC_TIME_OFFSET, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_set_kdc_time_offset_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_ccache_clear_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version ) +{ + cc_int_ccache_t int_ccache; + cc_msg_t *request; + ccmsg_ccache_clear_kdc_time_offset_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_ccache = (cc_int_ccache_t)ccache; + + if ( int_ccache->magic != CC_CCACHE_MAGIC ) + return ccErrInvalidCCache; + + request_header = (ccmsg_ccache_clear_kdc_time_offset_t*)malloc(sizeof(ccmsg_ccache_clear_kdc_time_offset_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_ccache->ctx; + request_header->ccache = int_ccache->handle; + request_header->creds_version = credentials_version; + + code = cci_msg_new(ccmsg_CCACHE_CLEAR_KDC_TIME_OFFSET, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_clear_kdc_time_offset_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + + diff --git a/src/lib/ccapi/client/ccache.h b/src/lib/ccapi/client/ccache.h new file mode 100644 index 000000000..e3b3993ee --- /dev/null +++ b/src/lib/ccapi/client/ccache.h @@ -0,0 +1,146 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* ccache.h */ + +#define CC_CCACHE_MAGIC ('C'<<24 | 'C'<<16 | 'A'<<8 | 'C') + +struct cc_int_ccache_d { + cc_ccache_f* functions; +#if TARGET_OS_MAC + const cc_ccache_f* otherFunctions; +#endif + cc_uint32 magic; + cc_handle handle; + cc_handle ctx; +}; +typedef struct cc_int_ccache_d cc_int_ccache_d; +typedef cc_int_ccache_d* cc_int_ccache_t; + + +cc_int32 +cc_int_ccache_new( cc_ccache_t * pccache, cc_handle hctx, cc_handle hccache ); + +cc_int32 +cc_int_ccache_release( cc_ccache_t ccache ); + +cc_int32 +cc_int_ccache_destroy( cc_ccache_t ccache ); + +cc_int32 +cc_int_ccache_set_default( cc_ccache_t ccache ); + +cc_int32 +cc_int_ccache_get_credentials_version( cc_ccache_t ccache, + cc_uint32* credentials_version); + +cc_int32 +cc_int_ccache_get_name( cc_ccache_t ccache, + cc_string_t* name ); + +cc_int32 +cc_int_ccache_get_principal( cc_ccache_t ccache, + cc_uint32 credentials_version, + cc_string_t* principal ); + +cc_int32 +cc_int_ccache_set_principal( cc_ccache_t ccache, + cc_uint32 credentials_version, + const char* principal ); + +cc_int32 +cc_int_ccache_store_credentials( cc_ccache_t ccache, + const cc_credentials_union* credentials ); + +cc_int32 +cc_int_ccache_remove_credentials( cc_ccache_t ccache, + cc_credentials_t credentials ); + +cc_int32 +cc_int_ccache_new_credentials_iterator( cc_ccache_t ccache, + cc_credentials_iterator_t* iterator ); + +cc_int32 +cc_int_ccache_move( cc_ccache_t source, + cc_ccache_t destination ); + +cc_int32 +cc_int_ccache_lock( cc_ccache_t ccache, + cc_uint32 block, + cc_uint32 lock_type ); + +cc_int32 +cc_int_ccache_unlock( cc_ccache_t ccache ); + +cc_int32 +cc_int_ccache_get_last_default_time( cc_ccache_t ccache, + cc_time_t* time ); + +cc_int32 +cc_int_ccache_get_change_time( cc_ccache_t ccache, + cc_time_t* time ); + +cc_int32 +cc_int_ccache_compare( cc_ccache_t ccache, + cc_ccache_t compare_to, + cc_uint32* equal ); + +cc_int32 +cc_int_ccache_get_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t* time_offset ); + +cc_int32 +cc_int_ccache_set_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t time_offset ); + +cc_int32 +cc_int_ccache_clear_kdc_time_offset( cc_ccache_t ccache, + cc_int32 credentials_version ); + + +cc_int32 +cc_int_ccache_compat_clone( cc_int_ccache_t ccache, + cc_int_ccache_t *clone ); + diff --git a/src/lib/ccapi/client/ccache_iterator.c b/src/lib/ccapi/client/ccache_iterator.c new file mode 100644 index 000000000..03266b1bb --- /dev/null +++ b/src/lib/ccapi/client/ccache_iterator.c @@ -0,0 +1,179 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* ccache_iterator.c */ + +#include +#include +#include +#include "ccache_iterator.h" +#include "msg.h" +#include "msg_headers.h" + + +cc_int32 +cc_int_ccache_iterator_new( cc_ccache_iterator_t * piter, + cc_handle ctx, + cc_handle handle ) +{ + cc_int_ccache_iterator_t iter; + + if ( piter == NULL ) + return ccErrBadParam; + + iter = (cc_int_ccache_iterator_t) malloc( sizeof(cc_int_ccache_iterator_d) ); + if ( iter == NULL ) + return ccErrNoMem; + + iter->functions = (cc_ccache_iterator_f*)malloc( sizeof(cc_ccache_iterator_f)); + if ( iter->functions ) { + free(iter); + return ccErrNoMem; + } + + iter->functions->release = cc_int_ccache_iterator_release; + iter->functions->next = cc_int_ccache_iterator_next; + iter->magic = CC_CCACHE_ITER_MAGIC; + iter->ctx = ctx; + iter->handle = handle; + + *piter = (cc_ccache_iterator_t)iter; + return ccNoError; +} + +cc_int32 +cc_int_ccache_iterator_release( cc_ccache_iterator_t iter ) +{ + cc_int_ccache_iterator_t int_iter; + cc_msg_t *request; + ccmsg_ccache_iterator_release_t *request_header; + cc_msg_t *response; + cc_int32 code; + + + if ( iter == NULL ) + return ccErrBadParam; + + int_iter = (cc_int_ccache_iterator_t) iter; + + if ( int_iter->magic != CC_CCACHE_ITER_MAGIC ) + return ccErrInvalidCCacheIterator; + + request_header = (ccmsg_ccache_iterator_release_t*)malloc(sizeof(ccmsg_ccache_iterator_release_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_iter->ctx; + request_header->iterator = int_iter->handle; + code = cci_msg_new(ccmsg_CCACHE_ITERATOR_RELEASE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_iterator_release_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + + free(int_iter->functions); + free(int_iter); + return ccNoError; +} + +cc_int32 +cc_int_ccache_iterator_next( cc_ccache_iterator_t iter, + cc_ccache_t * ccache ) +{ + cc_int_ccache_iterator_t int_iter; + cc_msg_t *request; + ccmsg_ccache_iterator_next_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( ccache == NULL ) + return ccErrBadParam; + + int_iter = (cc_int_ccache_iterator_t)iter; + + if ( int_iter->magic != CC_CCACHE_ITER_MAGIC ) + return ccErrInvalidCCacheIterator; + + request_header = (ccmsg_ccache_iterator_next_t*)malloc(sizeof(ccmsg_ccache_iterator_next_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_iter->ctx; + request_header->iterator = int_iter->handle; + + code = cci_msg_new(ccmsg_CCACHE_ITERATOR_NEXT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_iterator_next_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + ccmsg_ccache_iterator_next_resp_t * response_header = (ccmsg_ccache_iterator_next_resp_t*)response->header; + code = cc_ccache_new(ccache, int_iter->ctx, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} diff --git a/src/lib/ccapi/client/ccache_iterator.h b/src/lib/ccapi/client/ccache_iterator.h new file mode 100644 index 000000000..c55d72ee6 --- /dev/null +++ b/src/lib/ccapi/client/ccache_iterator.h @@ -0,0 +1,85 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* ccache_iterator.h */ + +#define CC_CCACHE_ITER_MAGIC ('C'<<24 | 'C'<<16 | 'I'<<8 | 'T') + +struct cc_int_ccache_iterator_d { + cc_ccache_iterator_f* functions; +#if TARGET_OS_MAC + cc_ccache_iterator_f* otherFunctions; +#endif + cc_uint32 magic; + cc_handle handle; + cc_handle ctx; + + cc_uint32 repeat_count; + cc_ccache_t compat_copy; +}; +typedef struct cc_int_ccache_iterator_d cc_int_ccache_iterator_d; +typedef cc_int_ccache_iterator_d* cc_int_ccache_iterator_t; + + +cc_int32 +cc_int_ccache_iterator_new( cc_ccache_iterator_t * piter, + cc_handle ctx, + cc_handle handle ); + +cc_int32 +cc_int_ccache_iterator_release( cc_ccache_iterator_t iter ); + +cc_int32 +cc_int_ccache_iterator_next( cc_ccache_iterator_t iter, + cc_ccache_t * ccache ); + +cc_int32 +cc_int_ccache_iterator_set_repeat_count( cc_int_ccache_iterator_t iter, + cc_uint32 count ); + +cc_int32 +cc_int_ccache_iterator_get_repeat_count( cc_int_ccache_iterator_t iter, + cc_uint32 * count ); + + + diff --git a/src/lib/ccapi/client/ccstring.c b/src/lib/ccapi/client/ccstring.c new file mode 100644 index 000000000..419bfef77 --- /dev/null +++ b/src/lib/ccapi/client/ccstring.c @@ -0,0 +1,94 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* ccstring.c */ + +#include +#include +#include +#include +#include "ccstring.h" + +cc_int32 +cc_int_string_new( cc_string_t * pstring, char * data ) +{ + cc_int_string_t string = (cc_int_string_t)malloc(sizeof(cc_int_string_d)); + if ( string == NULL ) + return ccErrNoMem; + + string->functions = (cc_string_f *)malloc(sizeof(cc_string_f)); + if ( string->functions == NULL ) { + free(string); + return ccErrNoMem; + } + + string->magic = CC_STRING_MAGIC; + string->functions->release = cc_int_string_release; + + string->data = strdup(data); + if ( string->data == NULL ) { + free(string->functions); + free(string); + return ccErrNoMem; + } + + *pstring = (cc_string_t)string; + return ccNoError; +} + +cc_int32 +cc_int_string_release( cc_string_t str ) +{ + cc_int_string_t int_string; + if ( str == NULL ) + return ccErrBadParam; + + int_string = (cc_int_string_t)str; + if ( int_string->magic != CC_STRING_MAGIC ) + return ccErrInvalidString; + + free(int_string->functions); + free(int_string->data); + free(int_string); + return ccNoError; +} diff --git a/src/lib/ccapi/client/ccstring.h b/src/lib/ccapi/client/ccstring.h new file mode 100644 index 000000000..9e0ad223f --- /dev/null +++ b/src/lib/ccapi/client/ccstring.h @@ -0,0 +1,65 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* ccstring.h */ + +#define CC_STRING_MAGIC ('S'<<24 | 'T'<<16 | 'R'<<8 | 'I') + +struct cc_int_string_d { + char* data; + cc_string_f* functions; +#if TARGET_OS_MAC + cc_string_f* otherFunctions; +#endif + cc_uint32 magic; +}; +typedef struct cc_int_string_d cc_int_string_d; +typedef cc_int_string_d* cc_int_string_t; + +cc_int32 +cc_int_string_new( cc_string_t * pstring, char * data ); + +cc_int32 +cc_int_string_release( cc_string_t string ); + + diff --git a/src/lib/ccapi/client/context.c b/src/lib/ccapi/client/context.c new file mode 100644 index 000000000..86c41b8e7 --- /dev/null +++ b/src/lib/ccapi/client/context.c @@ -0,0 +1,849 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* context.c */ + +#include +#include +#include +#include "context.h" +#include "msg.h" +#include "msg_headers.h" + +cc_int32 +cc_int_context_new( cc_context_t * pcontext, cc_handle handle, cc_uint32 version ) +{ + cc_int_context_t context = (cc_int_context_t)malloc(sizeof(cc_int_context_d)); + if (context == NULL) + return ccErrNoMem; + + context->functions = (cc_context_f*)malloc(sizeof(cc_context_f)); + if (context->functions == NULL) { + free(context); + return ccErrNoMem; + } + + context->functions->release = cc_int_context_release; + context->functions->get_change_time = cc_int_context_get_change_time; + context->functions->get_default_ccache_name = cc_int_context_get_default_ccache_name; + context->functions->open_ccache = cc_int_context_open_ccache; + context->functions->open_default_ccache = cc_int_context_open_default_ccache; + context->functions->create_ccache = cc_int_context_create_ccache; + context->functions->create_default_ccache = cc_int_context_create_default_ccache; + context->functions->create_new_ccache = cc_int_context_create_new_ccache; + context->functions->new_ccache_iterator = cc_int_context_new_ccache_iterator; + context->functions->lock = cc_int_context_lock; + context->functions->unlock = cc_int_context_unlock; + context->functions->compare = cc_int_context_compare; + + context->magic = CC_CONTEXT_MAGIC; + context->handle = handle; + context->api_version = version; + + *pcontext = (cc_context_t)context; + return ccNoError; +} + +cc_int32 +cc_int_context_release( cc_context_t context ) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_release_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( context == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_release_t*)malloc(sizeof(ccmsg_ctx_release_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_context->handle; + + code = cci_msg_new(ccmsg_CTX_RELEASE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_release_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + free(int_context->functions); + free(int_context); + return code; +} + +cc_int32 +cc_int_context_get_change_time( cc_context_t context, + cc_time_t* time) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_get_change_time_t *request_header; + cc_msg_t *response; + ccmsg_ctx_get_change_time_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || time == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_get_change_time_t*)malloc(sizeof(ccmsg_ctx_get_change_time_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_context->handle; + + code = cci_msg_new(ccmsg_CTX_GET_CHANGE_TIME, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_get_change_time_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ctx_get_change_time_resp_t*)response->header; + *time = response_header->time; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_get_default_ccache_name( cc_context_t context, + cc_string_t* name ) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_get_default_ccache_name_t *request_header; + cc_msg_t *response; + ccmsg_ctx_get_default_ccache_name_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || name == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_get_default_ccache_name_t*)malloc(sizeof(ccmsg_ctx_get_default_ccache_name_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_context->handle; + + code = cci_msg_new(ccmsg_CTX_GET_DEFAULT_CCACHE_NAME, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_get_default_ccache_name_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + char * string; + response_header = (ccmsg_ctx_get_default_ccache_name_resp_t*)response->header; + code = cci_msg_retrieve_blob(response, response_header->name_offset, + response_header->name_len, &string); + if (code == ccNoError) { + code = cc_string_new(&name, string); + free(string); + } + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_compare( cc_context_t context, + cc_context_t compare_to, + cc_uint32* equal ) +{ + cc_int_context_t int_context, int_compare_to; + cc_msg_t *request; + ccmsg_ctx_compare_t *request_header; + cc_msg_t *response; + ccmsg_ctx_compare_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || compare_to == NULL || + equal == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + int_compare_to = (cc_int_context_t)compare_to; + + if ( int_context->magic != CC_CONTEXT_MAGIC || + int_compare_to->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_compare_t*)malloc(sizeof(ccmsg_ctx_compare_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx1 = int_context->handle; + request_header->ctx2 = int_compare_to->handle; + + code = cci_msg_new(ccmsg_CTX_COMPARE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_compare_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ctx_compare_resp_t*)response->header; + *equal = response_header->is_equal; + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + + +cc_int32 +cc_int_context_new_ccache_iterator( cc_context_t context, + cc_ccache_iterator_t* iterator ) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_new_ccache_iterator_t *request_header; + cc_msg_t *response; + ccmsg_ctx_new_ccache_iterator_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || iterator == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_new_ccache_iterator_t*)malloc(sizeof(ccmsg_ctx_new_ccache_iterator_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_context->handle; + + code = cci_msg_new(ccmsg_CTX_NEW_CCACHE_ITERATOR, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_new_ccache_iterator_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ctx_new_ccache_iterator_resp_t*)response->header; + code = cc_int_ccache_iterator_new(iterator, int_context->handle, response_header->iterator); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_open_ccache( cc_context_t context, + const char* name, + cc_ccache_t* ccache ) +{ + cc_uint32 blob_pos; + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ccache_open_t *request_header; + cc_msg_t *response; + ccmsg_ccache_open_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || name == NULL || ccache == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_open_t*)malloc(sizeof(ccmsg_ccache_open_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_OPEN, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_data_blob(request, (void *)name, strlen(name) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + request_header->name_offset = blob_pos; + request_header->name_len = strlen(name) + 1; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_open_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ccache_open_resp_t*)response->header; + code = cc_cache_new(ccache, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_open_default_ccache( cc_context_t context, + cc_ccache_t* ccache) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ccache_open_default_t *request_header; + cc_msg_t *response; + ccmsg_ccache_open_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || ccache == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_open_default_t*)malloc(sizeof(ccmsg_ccache_open_default_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_OPEN_DEFAULT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_open_default_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ccache_open_resp_t*)response->header; + code = cc_cache_new(ccache, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_create_ccache( cc_context_t context, + const char* name, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ) +{ + cc_uint32 blob_pos; + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ccache_create_t *request_header; + cc_msg_t *response; + ccmsg_ccache_create_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || name == NULL || + cred_vers == 0 || cred_vers > cc_credentials_v4_v5 || + principal == NULL || ccache == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_create_t*)malloc(sizeof(ccmsg_ccache_create_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_CREATE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_data_blob(request, (void *)name, strlen(name) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + request_header->version = cred_vers; + request_header->name_offset = blob_pos; + request_header->name_len = strlen(name) + 1; + + code = cci_msg_add_data_blob(request, (void *)principal, strlen(principal) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + request_header->principal_offset = blob_pos; + request_header->principal_len = strlen(principal) + 1; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_create_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ccache_create_resp_t*)response->header; + code = cc_cache_new(ccache, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_create_default_ccache( cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ) +{ + cc_uint32 blob_pos; + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ccache_create_default_t *request_header; + cc_msg_t *response; + ccmsg_ccache_create_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || + cred_vers == 0 || cred_vers > cc_credentials_v4_v5 || + principal == NULL || ccache == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_create_default_t*)malloc(sizeof(ccmsg_ccache_create_default_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_CREATE_DEFAULT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + request_header->version = cred_vers; + + code = cci_msg_add_data_blob(request, (void *)principal, strlen(principal) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + request_header->principal_offset = blob_pos; + request_header->principal_len = strlen(principal) + 1; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_create_default_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ccache_create_resp_t*)response->header; + code = cc_cache_new(ccache, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_create_new_ccache( cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ) +{ + cc_uint32 blob_pos; + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ccache_create_unique_t *request_header; + cc_msg_t *response; + ccmsg_ccache_create_resp_t *response_header; + cc_int32 code; + + if ( context == NULL || + cred_vers == 0 || cred_vers > cc_credentials_v4_v5 || + principal == NULL || ccache == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ccache_create_unique_t*)malloc(sizeof(ccmsg_ccache_create_unique_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CCACHE_CREATE_UNIQUE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + request_header->version = cred_vers; + + code = cci_msg_add_data_blob(request, (void *)principal, strlen(principal) + 1, &blob_pos); + if (code != ccNoError) { + cci_msg_destroy(request); + free(request_header); + return code; + } + request_header->principal_offset = blob_pos; + request_header->principal_len = strlen(principal) + 1; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ccache_create_unique_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_ccache_create_resp_t*)response-> header; + code = cc_cache_new(ccache, response_header->ccache); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_lock( cc_context_t context, + cc_uint32 lock_type, + cc_uint32 block ) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_lock_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( context == NULL || + (lock_type != cc_lock_read && lock_type != cc_lock_write) || + (block != cc_lock_block && block != cc_lock_noblock) ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_lock_t*)malloc(sizeof(ccmsg_ctx_lock_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CTX_LOCK, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + request_header->lock_type; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_lock_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + + // TODO: if (block == cc_lock_block) ..... + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_unlock( cc_context_t context ) +{ + cc_int_context_t int_context; + cc_msg_t *request; + ccmsg_ctx_unlock_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( context == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + request_header = (ccmsg_ctx_unlock_t*)malloc(sizeof(ccmsg_ctx_unlock_t)); + if (request_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CTX_UNLOCK, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + request_header->ctx = int_context->handle; + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_ctx_unlock_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_clone( cc_context_t inContext, + cc_context_t* outContext, + cc_int32 requestedVersion, + cc_int32* supportedVersion, + char const** vendor ) +{ + cc_int_context_t int_context, new_context; + static char vendor_st[128] = ""; + cc_msg_t *request; + ccmsg_clone_t *request_header; + cc_msg_t *response; + ccmsg_clone_resp_t *response_header; + cc_int32 code; + + if ( inContext == NULL || + outContext == NULL || + supportedVersion == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + if ((requestedVersion != ccapi_version_2) && + (requestedVersion != ccapi_version_3) && + (requestedVersion != ccapi_version_4) && + (requestedVersion != ccapi_version_5)) { + + if (supportedVersion != NULL) { + *supportedVersion = ccapi_version_5; + } + return ccErrBadAPIVersion; + } + + request_header = (ccmsg_clone_t*)malloc(sizeof(ccmsg_clone_t)); + if (request_header == NULL) + return ccErrNoMem; + + request_header->ctx = int_context->handle; + request_header->in_version = requestedVersion; + + code = cci_msg_new(ccmsg_INIT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_init_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + response_header = (ccmsg_clone_resp_t *)response->header; + *supportedVersion = response_header->out_version; + code = cc_int_context_new(outContext, response_header->out_ctx, response_header->out_version); + + if (!vendor_st[0]) { + char * string; + code = cci_msg_retrieve_blob(response, response_header->vendor_offset, response_header->vendor_length, &string); + strncpy(vendor_st, string, sizeof(vendor_st)-1); + vendor_st[sizeof(vendor_st)-1] = '\0'; + free(string); + } + *vendor = vendor_st; + + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} + +cc_int32 +cc_int_context_get_version( cc_context_t context, + cc_int32* version ) +{ + cc_int_context_t int_context; + cc_int32 code; + + if ( context == NULL || + version == NULL ) + return ccErrBadParam; + + int_context = (cc_int_context_t)context; + + if ( int_context->magic != CC_CONTEXT_MAGIC ) + return ccErrInvalidContext; + + *version = int_context->api_version; + return ccNoError; +} + + diff --git a/src/lib/ccapi/client/context.h b/src/lib/ccapi/client/context.h new file mode 100644 index 000000000..cd5ca678d --- /dev/null +++ b/src/lib/ccapi/client/context.h @@ -0,0 +1,131 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* context.h */ + +#define CC_CONTEXT_MAGIC ('C'<<24 | 'C'<<16 | 'T'<<8 | 'X') + +struct cc_int_context { + cc_context_f* functions; + + cc_uint32 magic; +#ifdef CCAPI_V2_COMPAT + cc_uint32 version; +#endif + cc_uint32 api_version; + cc_handle handle; +}; +typedef struct cc_int_context cc_int_context_d; +typedef cc_int_context_d* cc_int_context_t; + +cc_int32 +cc_int_context_new( cc_context_t *pcontext, cc_handle handle, cc_uint32 version ); + +cc_int32 +cc_int_context_release( cc_context_t context ); + +cc_int32 +cc_int_context_get_change_time( cc_context_t context, + cc_time_t* time); + +cc_int32 +cc_int_context_get_default_ccache_name( cc_context_t context, + cc_string_t* name ); + +cc_int32 +cc_int_context_open_ccache( cc_context_t context, + const char* name, + cc_ccache_t* ccache ); + +cc_int32 +cc_int_context_open_default_ccache( cc_context_t context, + cc_ccache_t* ccache ); + +cc_int32 +cc_int_context_create_ccache( cc_context_t context, + const char* name, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ); + +cc_int32 +cc_int_context_create_default_ccache( cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ); + +cc_int32 +cc_int_context_create_new_ccache( cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache ); + +cc_int32 +cc_int_context_new_ccache_iterator( cc_context_t context, + cc_ccache_iterator_t* iterator ); + +cc_int32 +cc_int_context_lock( cc_context_t context, + cc_uint32 lock_type, + cc_uint32 block ); + +cc_int32 +cc_int_context_unlock( cc_context_t context ); + +cc_int32 +cc_int_context_compare( cc_context_t context, + cc_context_t compare_to, + cc_uint32* equal ); + +cc_int32 +cc_int_context_clone( cc_context_t inContext, + cc_context_t* outContext, + cc_int32 requestedVersion, + cc_int32* supportedVersion, + char const** vendor ); + +cc_int32 +cc_int_context_get_version( cc_context_t context, + cc_int32* version ); + + diff --git a/src/lib/ccapi/client/credentials.c b/src/lib/ccapi/client/credentials.c new file mode 100644 index 000000000..b0a3df2b7 --- /dev/null +++ b/src/lib/ccapi/client/credentials.c @@ -0,0 +1,181 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* credentials.c */ + +#include +#include +#include +#include "credentials.h" +#include "msg.h" +#include "msg_headers.h" + + +cc_int32 +cc_int_credentials_new( cc_credentials_t *pcredentials, cc_uint32 version, + cc_handle ctx, cc_handle ccache, cc_handle handle, + char * data, cc_uint32 len ) +{ + cc_int_credentials_t credentials; + cc_int32 code; + + if ( pcredentials == NULL ) + return ccErrBadParam; + + credentials = (cc_int_credentials_t)malloc(sizeof(cc_int_credentials_d)); + if ( credentials == NULL ) + return ccErrNoMem; + + credentials->data = (cc_credentials_union *)malloc(sizeof(cc_credentials_union)); + if ( credentials->data == NULL ) { + free(credentials); + return ccErrNoMem; + } + + credentials->functions = (cc_credentials_f *)malloc(sizeof(cc_credentials_f)); + if ( credentials->functions == NULL ) { + free(credentials->data); + free(credentials); + return ccErrNoMem; + } + + credentials->functions->release = cc_int_credentials_release; + credentials->functions->compare = cc_int_credentials_compare; + credentials->magic = CC_CREDS_MAGIC; + credentials->ctx = ctx; + credentials->ccache = ccache; + credentials->handle = handle; + + switch ( version ) { + case cc_credentials_v4: + code = cci_cred_v4_unmarshall(data, len, credentials->data); + break; + case cc_credentials_v5: + code = cci_cred_v5_unmarshall(data, len, credentials->data); + break; + default: + free(credentials); + return ccErrBadCredentialsVersion; + } + + *pcredentials = (cc_credentials_t)credentials; + return ccNoError; +} + + +cc_int32 +cc_int_credentials_release( cc_credentials_t creds ) +{ + cc_int_credentials_t int_creds; + unsigned short i; + + if ( creds == NULL ) + return ccErrBadParam; + + int_creds = (cc_int_credentials_t)creds; + + if ( int_creds->magic != CC_CREDS_MAGIC ) + return ccErrInvalidCredentials; + + switch (int_creds->data->version) { + case cc_credentials_v4: + free(int_creds->data->credentials.credentials_v4); + break; + case cc_credentials_v5: + if ( int_creds->data->credentials.credentials_v5->client ) + free(int_creds->data->credentials.credentials_v5->client); + if ( int_creds->data->credentials.credentials_v5->server ) + free(int_creds->data->credentials.credentials_v5->server ); + if ( int_creds->data->credentials.credentials_v5->keyblock.data ) + free(int_creds->data->credentials.credentials_v5->keyblock.data); + if ( int_creds->data->credentials.credentials_v5->ticket.data ) + free(int_creds->data->credentials.credentials_v5->ticket.data); + if ( int_creds->data->credentials.credentials_v5->second_ticket.data ) + free(int_creds->data->credentials.credentials_v5->second_ticket.data); + if ( int_creds->data->credentials.credentials_v5->addresses ) { + for ( i=0; int_creds->data->credentials.credentials_v5->addresses[i]; i++) { + if (int_creds->data->credentials.credentials_v5->addresses[i]->data) + free(int_creds->data->credentials.credentials_v5->addresses[i]->data); + } + free(int_creds->data->credentials.credentials_v5->addresses); + } + if ( int_creds->data->credentials.credentials_v5->authdata ) { + for ( i=0; int_creds->data->credentials.credentials_v5->authdata[i]; i++) { + if ( int_creds->data->credentials.credentials_v5->authdata[i]->data ) + free(int_creds->data->credentials.credentials_v5->authdata[i]->data); + } + free(int_creds->data->credentials.credentials_v5->authdata); + } + break; + default: + return ccErrBadCredentialsVersion; + } + + free(int_creds->functions); + free(int_creds->data); + free(int_creds); + return ccNoError; +} + +cc_int32 +cc_int_credentials_compare( cc_credentials_t credentials, + cc_credentials_t compare_to, + cc_uint32* equal ) +{ + cc_int_credentials_t int_credentials; + cc_int_credentials_t int_compare_to; + + if ( credentials == NULL || compare_to == NULL || equal == NULL ) + return ccErrBadParam; + + + if ( int_credentials->magic != CC_CREDS_MAGIC || + int_compare_to->magic != CC_CREDS_MAGIC ) + return ccErrInvalidCredentials; + + int_credentials = (cc_int_credentials_t)credentials; + int_compare_to = (cc_int_credentials_t)compare_to; + + *equal = (int_credentials->handle == int_compare_to->handle); + return ccNoError; +} diff --git a/src/lib/ccapi/client/credentials.h b/src/lib/ccapi/client/credentials.h new file mode 100644 index 000000000..320c61825 --- /dev/null +++ b/src/lib/ccapi/client/credentials.h @@ -0,0 +1,94 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* credentials.h */ + +#define CC_CREDS_MAGIC ('C'<<24 | 'R'<<16 | 'E'<<8 | 'D') + +struct cc_int_credentials_d { + cc_credentials_union* data; + cc_credentials_f* functions; +#if TARGET_OS_MAC + cc_credentials_f* otherFunctions; +#endif + cc_uint32 magic; + cc_handle ctx; + cc_handle ccache; + cc_handle handle; +}; +typedef struct cc_int_credentials_d cc_int_credentials_d; +typedef cc_int_credentials_d* cc_int_credentials_t; + +cc_int32 +cc_int_credentials_new( cc_credentials_t * pcredentials, cc_uint32 version, + cc_handle ctx, cc_handle ccache, cc_handle handle, + char * data, cc_uint32 len); + +cc_int32 +cc_int_credentials_release( cc_credentials_t credentials ); + +cc_int32 +cc_int_credentials_compare( cc_credentials_t credentials, + cc_credentials_t compare_to, + cc_uint32* equal ); + +cc_int32 +cci_creds_v4_marshall( cc_credentials_v4_t * creds, + char ** flat, + cc_uint32 * len); + +cc_int32 +cci_creds_v5_marshall( cc_credentials_v5_t * creds, + char ** flat, + cc_uint32 * len); + +cc_int32 +cci_creds_v4_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds); + +cc_int32 +cci_creds_v5_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds); + diff --git a/src/lib/ccapi/client/credentials_iterator.c b/src/lib/ccapi/client/credentials_iterator.c new file mode 100644 index 000000000..b7333daf3 --- /dev/null +++ b/src/lib/ccapi/client/credentials_iterator.c @@ -0,0 +1,187 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* credentials_iterator.c */ + +#include +#include +#include +#include "credentials_iterator.h" +#include "msg.h" +#include "msg_headers.h" + + +cc_int32 +cc_int_credentials_iterator_new( cc_credentials_iterator_t * piter, + cc_handle ctx, + cc_handle ccache, + cc_handle handle ) +{ + cc_int_credentials_iterator_t iter; + + if ( piter == NULL ) + return ccErrBadParam; + + iter = (cc_int_credentials_iterator_t) malloc( sizeof(cc_int_credentials_iterator_d) ); + if ( iter == NULL ) + return ccErrNoMem; + + iter->functions = (cc_credentials_iterator_f*)malloc(sizeof(cc_credentials_iterator_f)); + if ( iter->functions == NULL ) { + free(iter); + return ccErrNoMem; + } + + iter->functions->release = cc_int_credentials_iterator_release; + iter->functions->next = cc_int_credentials_iterator_next; + iter->magic = CC_CREDS_ITER_MAGIC; + iter->ctx = ctx; + iter->ccache = ccache; + iter->handle = handle; + + *piter = (cc_credentials_iterator_t) iter; + return ccNoError; +} + +cc_int32 +cc_int_credentials_iterator_release( cc_credentials_iterator_t iter ) +{ + cc_int_credentials_iterator_t int_iter; + cc_msg_t *request; + ccmsg_creds_iterator_release_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( iter == NULL ) + return ccErrBadParam; + + int_iter = (cc_int_credentials_iterator_t) iter; + + if ( int_iter->magic != CC_CREDS_ITER_MAGIC ) + return ccErrInvalidCredentialsIterator; + + request_header = (ccmsg_creds_iterator_release_t*)malloc(sizeof(ccmsg_creds_iterator_release_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_iter->ctx; + request_header->ccache = int_iter->ccache; + request_header->iterator = int_iter->handle; + code = cci_msg_new(ccmsg_CREDS_ITERATOR_RELEASE, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_creds_iterator_release_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + code = ccNoError; + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + + free(int_iter->functions); + free(int_iter); + return ccNoError; +} + +cc_int32 +cc_int_credentials_iterator_next( cc_credentials_iterator_t iter, + cc_credentials_t * credentials ) +{ + cc_int_credentials_iterator_t int_iter; + cc_msg_t *request; + ccmsg_creds_iterator_next_t *request_header; + cc_msg_t *response; + cc_int32 code; + + if ( credentials == NULL ) + return ccErrBadParam; + + int_iter = (cc_int_credentials_iterator_t)iter; + + if ( int_iter->magic != CC_CREDS_ITER_MAGIC ) + return ccErrInvalidCredentialsIterator; + + request_header = (ccmsg_creds_iterator_next_t*)malloc(sizeof(ccmsg_creds_iterator_next_t)); + if (request_header == NULL) + return ccErrNoMem; + request_header->ctx = int_iter->ctx; + request_header->ccache = int_iter->ccache; + request_header->iterator = int_iter->handle; + + code = cci_msg_new(ccmsg_CREDS_ITERATOR_NEXT, &request); + if (code != ccNoError) { + free(request_header); + return code; + } + + code = cci_msg_add_header(request, request_header, sizeof(ccmsg_creds_iterator_next_t)); + + code = cci_perform_rpc(request, &response); + + if (response->type == ccmsg_NACK) { + ccmsg_nack_t * nack_header = (ccmsg_nack_t *)response->header; + code = nack_header->err_code; + } else if (response->type == ccmsg_ACK) { + char * blob; + ccmsg_creds_iterator_next_resp_t * response_header = (ccmsg_creds_iterator_next_resp_t*)response->header; + code = cci_msg_retrieve_blob(response, response_header->creds_offset, response_header->creds_len, &blob); + code = cc_credentials_new(credentials, response_header->version, + int_iter->ctx, int_iter->ccache, response_header->creds_handle, + blob, response_header->creds_len); + free(blob); + } else { + code = ccErrBadInternalMessage; + } + cci_msg_destroy(request); + cci_msg_destroy(response); + return code; +} diff --git a/src/lib/ccapi/client/credentials_iterator.h b/src/lib/ccapi/client/credentials_iterator.h new file mode 100644 index 000000000..2a6f8edf2 --- /dev/null +++ b/src/lib/ccapi/client/credentials_iterator.h @@ -0,0 +1,72 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* credentials_iterator.h */ + +#define CC_CREDS_ITER_MAGIC ('C'<<24 | 'R'<<16 | 'I'<<8 | 'T') + +struct cc_int_credentials_iterator_d { + cc_credentials_iterator_f* functions; +#if TARGET_OS_MAC + cc_credentials_iterator_f* otherFunctions; +#endif + cc_uint32 magic; + cc_handle handle; + cc_handle ccache; + cc_handle ctx; +}; +typedef struct cc_int_credentials_iterator_d cc_int_credentials_iterator_d; +typedef cc_int_credentials_iterator_d* cc_int_credentials_iterator_t; + + +cc_int32 +cc_int_credentials_iterator_new( cc_credentials_iterator_t * piter, cc_handle ctx, cc_handle ccache, cc_handle iter ); + +cc_int32 +cc_int_credentials_iterator_release( cc_credentials_iterator_t iter ); + +cc_int32 +cc_int_credentials_iterator_next( cc_credentials_iterator_t iter, + cc_credentials_t * credentials ); + + diff --git a/src/lib/ccapi/client/mac/ChangeLog b/src/lib/ccapi/client/mac/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/client/mac/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/client/windows/ChangeLog b/src/lib/ccapi/client/windows/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/client/windows/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/include/ChangeLog b/src/lib/ccapi/include/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/include/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/include/CredentialsCache.h b/src/lib/ccapi/include/CredentialsCache.h new file mode 100644 index 000000000..dd60fa46d --- /dev/null +++ b/src/lib/ccapi/include/CredentialsCache.h @@ -0,0 +1,567 @@ +/* $Copyright: + * + * Copyright 1998-2004 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). + * $ + */ + +/* $Header$ */ + +/* + * Declarations for Credentials Cache API Library + * + * API specification: + * + * Revision 1: Frank Dabek, 6/4/1998 + * Revision 2: meeroh, 2/24/1999 + * Revision 3: meeroh, 11/12/1999 + * Revision 4: jaltman, 10/27/2004 + * + */ + +#ifndef __CREDENTIALSCACHE__ +#define __CREDENTIALSCACHE__ + +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) + #include + #if TARGET_RT_MAC_CFM + #error "Use KfM 4.0 SDK headers for CFM compilation." + #endif +#endif + +#if TARGET_OS_MAC + #include +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma import on + #pragma enumsalwaysint on + #endif + #pragma options align=mac68k +#endif + +#include + +/* + * Constants + */ + +/* API versions */ +enum { + ccapi_version_2 = 2, + ccapi_version_3 = 3, + ccapi_version_4 = 4, + ccapi_version_5 = 5 +}; + +/* 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 +}; + +/* Credentials versions */ +enum { + cc_credentials_v4 = 1, + cc_credentials_v5 = 2, + cc_credentials_v4_v5 = 3 +}; + +/* Lock types */ +enum { + cc_lock_read = 1, + cc_lock_write = 2 +}; + +/* Locking Modes */ +enum { + cc_lock_noblock = 0, + cc_lock_block = 1 +}; + +/* + * Basic types + */ + +typedef char cc_int8; +typedef unsigned char cc_uint8; +typedef int cc_int32; +typedef unsigned int cc_uint32; +typedef time_t cc_time_t; +typedef void * cc_handle; + +/* + * 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 +}; + +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 [8]; + 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_int32 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* otherFunctions; +#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* otherFunctions; +#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* otherFunctions; +#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* otherFunctions; +#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* otherFunctions; +#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 context); + cc_int32 (*get_change_time) ( + cc_context_t context, + cc_time_t* time); + cc_int32 (*get_default_ccache_name) ( + cc_context_t context, + cc_string_t* name); + cc_int32 (*open_ccache) ( + cc_context_t context, + const char* name, + cc_ccache_t* ccache); + cc_int32 (*open_default_ccache) ( + cc_context_t context, + cc_ccache_t* ccache); + cc_int32 (*create_ccache) ( + cc_context_t context, + const char* name, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache); + cc_int32 (*create_default_ccache) ( + cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache); + cc_int32 (*create_new_ccache) ( + cc_context_t context, + cc_uint32 cred_vers, + const char* principal, + cc_ccache_t* ccache); + cc_int32 (*new_ccache_iterator) ( + cc_context_t context, + cc_ccache_iterator_t* iterator); + cc_int32 (*lock) ( + cc_context_t context, + cc_uint32 lock_type, + cc_uint32 block); + cc_int32 (*unlock) ( + cc_context_t context); + cc_int32 (*compare) ( + cc_context_t context, + cc_context_t compare_to, + cc_uint32* equal); +}; + +struct cc_ccache_f { + cc_int32 (*release) ( + cc_ccache_t ccache); + cc_int32 (*destroy) ( + cc_ccache_t ccache); + cc_int32 (*set_default) ( + cc_ccache_t ccache); + cc_int32 (*get_credentials_version) ( + cc_ccache_t ccache, + cc_uint32* credentials_version); + cc_int32 (*get_name) ( + cc_ccache_t ccache, + cc_string_t* name); + cc_int32 (*get_principal) ( + cc_ccache_t ccache, + cc_uint32 credentials_version, + cc_string_t* principal); + cc_int32 (*set_principal) ( + cc_ccache_t ccache, + cc_uint32 credentials_version, + const char* principal); + cc_int32 (*store_credentials) ( + cc_ccache_t ccache, + const cc_credentials_union* credentials); + cc_int32 (*remove_credentials) ( + cc_ccache_t ccache, + cc_credentials_t credentials); + cc_int32 (*new_credentials_iterator) ( + cc_ccache_t ccache, + cc_credentials_iterator_t* iterator); + cc_int32 (*move) ( + cc_ccache_t source, + cc_ccache_t destination); + cc_int32 (*lock) ( + cc_ccache_t ccache, + cc_uint32 block, + cc_uint32 lock_type); + cc_int32 (*unlock) ( + cc_ccache_t ccache); + cc_int32 (*get_last_default_time) ( + cc_ccache_t ccache, + cc_time_t* time); + cc_int32 (*get_change_time) ( + cc_ccache_t ccache, + cc_time_t* time); + cc_int32 (*compare) ( + cc_ccache_t ccache, + cc_ccache_t compare_to, + cc_uint32* equal); + cc_int32 (*get_kdc_time_offset) ( + cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t* time_offset); + cc_int32 (*set_kdc_time_offset) ( + cc_ccache_t ccache, + cc_int32 credentials_version, + cc_time_t time_offset); + + cc_int32 (*clear_kdc_time_offset) ( + cc_ccache_t ccache, + cc_int32 credentials_version); +}; + +struct cc_string_f { + cc_int32 (*release) ( + cc_string_t string); +}; + +struct cc_credentials_f { + cc_int32 (*release) ( + cc_credentials_t credentials); + cc_int32 (*compare) ( + cc_credentials_t credentials, + cc_credentials_t compare_to, + cc_uint32* equal); +}; + + +struct cc_ccache_iterator_f { + cc_int32 (*release) ( + cc_ccache_iterator_t iter); + cc_int32 (*next) ( + cc_ccache_iterator_t iter, + cc_ccache_t* ccache); +}; + +struct cc_credentials_iterator_f { + cc_int32 (*release) ( + cc_credentials_iterator_t iter); + cc_int32 (*next) ( + cc_credentials_iterator_t iter, + cc_credentials_t* ccache); +}; + +/* + * API functions + */ + +cc_int32 cc_initialize ( + cc_context_t* outContext, + cc_int32 inVersion, + cc_int32* outSupportedVersion, + char const** outVendor); + +/* + * Convenience macros + */ + +#define cc_context_release(context) \ + ((context) -> functions -> release (context)) +#define cc_context_get_change_time(context, time) \ + ((context) -> functions -> get_change_time (context, 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, lock) \ + ((context) -> functions -> lock (context, type, lock)) +#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_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, lock) \ + ((ccache) -> functions -> lock (ccache, lock)) +#define cc_ccache_unlock(ccache, unlock) \ + ((ccache) -> functions -> unlock (ccache, unlock)) +#define cc_ccache_get_last_default_time(ccache, time) \ + ((ccache) -> functions -> get_last_default_time (ccache, time)) +#define cc_ccache_get_change_time(ccache, time) \ + ((ccache) -> functions -> get_change_time (ccache, 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) \ + ((ccache) -> functions -> get_kdc_time_offset (version, time)) +#define cc_ccache_set_kdc_time_offset(ccache, version, time) \ + ((ccache) -> functions -> set_kdc_time_offset (version, time)) +#define cc_ccache_clear_kdc_time_offset(ccache, version) \ + ((ccache) -> functions -> clear_kdc_time_offset (version)) + +#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_credentials_iterator_release(iterator) \ + ((iterator) -> functions -> release (iterator)) +#define cc_credentials_iterator_next(iterator, credentials) \ + ((iterator) -> functions -> next (iterator, credentials)) + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma enumsalwaysint reset + #pragma import reset + #endif + #pragma options align=reset +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CREDENTIALSCACHE__ */ diff --git a/src/lib/ccapi/include/CredentialsCache2.h b/src/lib/ccapi/include/CredentialsCache2.h new file mode 100644 index 000000000..401e093f4 --- /dev/null +++ b/src/lib/ccapi/include/CredentialsCache2.h @@ -0,0 +1,308 @@ +/* $Copyright: + * + * Copyright 1998-2004 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). + * $ + */ +/* + * This is backwards compatibility for CCache API v2 clients to be able to run + * against the CCache API v3 library + */ + +#ifndef __CREDENTIALSCACHE2__ +#define __CREDENTIALSCACHE2__ + +#include +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) + #include + #if TARGET_RT_MAC_CFM + #error "Use KfM 4.0 SDK headers for CFM compilation." + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma import on + #pragma enumsalwaysint on + #endif + #pragma options align=mac68k +#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 +}; + +cc_int32 cc_shutdown ( + apiCB** ioContext); + +cc_int32 cc_get_NC_info ( + apiCB* inContext, + infoNC*** outInfo); + +cc_int32 cc_get_change_time ( + apiCB* inContext, + cc_time_t* outTime); + +cc_int32 cc_open ( + apiCB* inContext, + const char* inName, + cc_int32 inVersion, + cc_uint32 inFlags, + ccache_p** outCCache); + +cc_int32 cc_create ( + apiCB* inContext, + const char* inName, + const char* inPrincipal, + cc_int32 inVersion, + cc_uint32 inFlags, + ccache_p** outCCache); + +cc_int32 cc_close ( + apiCB* inContext, + ccache_p** ioCCache); + +cc_int32 cc_destroy ( + apiCB* inContext, + ccache_p** ioCCache); + +cc_int32 cc_seq_fetch_NCs_begin ( + apiCB* inContext, + ccache_cit** outIterator); + +cc_int32 cc_seq_fetch_NCs_next ( + apiCB* inContext, + ccache_p** outCCache, + ccache_cit* inIterator); + +cc_int32 cc_seq_fetch_NCs_end ( + apiCB* inContext, + ccache_cit** ioIterator); + +cc_int32 cc_get_name ( + apiCB* inContext, + ccache_p* inCCache, + char** outName); + +cc_int32 cc_get_cred_version ( + apiCB* inContext, + ccache_p* inCCache, + cc_int32* outVersion); + +cc_int32 cc_set_principal ( + apiCB* inContext, + ccache_p* inCCache, + cc_int32 inVersion, + char* inPrincipal); + +cc_int32 cc_get_principal ( + apiCB* inContext, + ccache_p* inCCache, + char** outPrincipal); + +cc_int32 cc_store ( + apiCB* inContext, + ccache_p* inCCache, + cred_union inCredentials); + +cc_int32 cc_remove_cred ( + apiCB* inContext, + ccache_p* inCCache, + cred_union inCredentials); + +cc_int32 cc_seq_fetch_creds_begin ( + apiCB* inContext, + const ccache_p* inCCache, + ccache_cit** outIterator); + +cc_int32 cc_seq_fetch_creds_next ( + apiCB* inContext, + cred_union** outCreds, + ccache_cit* inIterator); + +cc_int32 cc_seq_fetch_creds_end ( + apiCB* inContext, + ccache_cit** ioIterator); + +cc_int32 cc_free_principal ( + apiCB* inContext, + char** ioPrincipal); + +cc_int32 cc_free_name ( + apiCB* inContext, + char** ioName); + +cc_int32 cc_free_creds ( + apiCB* inContext, + cred_union** creds); + +cc_int32 cc_free_NC_info ( + apiCB* inContext, + infoNC*** ioInfo); + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma enumsalwaysint reset + #pragma import reset + #endif + #pragma options align=reset +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CREDENTIALSCACHE2__ */ \ No newline at end of file diff --git a/src/lib/ccapi/include/marshall.h b/src/lib/ccapi/include/marshall.h new file mode 100644 index 000000000..19b9463b0 --- /dev/null +++ b/src/lib/ccapi/include/marshall.h @@ -0,0 +1,93 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +#define FLAT_CREDS_V5_VERSION 1 +struct cc_flat_data { + cc_uint32 type; + cc_uint32 length; + cc_uint32 data; +}; +typedef struct cc_flat_data cc_flat_data; + +struct cci_flat_creds_v5 { + cc_uint32 version; /* version of this structure */ + cc_flat_data client; + cc_flat_data server; + cc_flat_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_uint32 address_count; + cc_uint32 addresses; /* offset to array */ + cc_flat_data ticket; + cc_flat_data second_ticket; + cc_uint32 authdata_count; + cc_uint32 authdata; /* offset to array */ +}; + +cc_int32 +cci_creds_v4_marshall( cc_credentials_v4_t * creds, + char ** flat, + cc_uint32 * len); + +cc_int32 +cci_creds_v4_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds); + +cc_int32 +cci_creds_v5_marshall( cc_credentials_v5_t * creds, + char ** pflat, + cc_uint32 * plen); + +cc_int32 +cci_creds_v5_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds_union); + + + + diff --git a/src/lib/ccapi/include/msg.h b/src/lib/ccapi/include/msg.h new file mode 100644 index 000000000..0d712d666 --- /dev/null +++ b/src/lib/ccapi/include/msg.h @@ -0,0 +1,146 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Verifiable, extensible message format. + * + * Format: + * + * + * + * + * + * + * + * + * + * ... + * + * + * If the header has variable length data it is included in the data blobs. + * The header field has the offset from the beginning of the message of the 1st + * byte of the data and the length of the data. + * + */ + +#ifndef __CC_MSG_H__ +#define __CC_MSG_H__ + +#include "CredentialsCache.h" + +struct cc_msg_t { + cc_uint32 type; /*type of message*/ + cc_uint8 *flat; /*flattened representation of this message*/ + cc_uint8 *header; /*fixed length header determined by message type*/ + cc_uint32 flat_len; /*length of flat rep*/ + cc_uint32 header_len; /*length of header*/ + cc_uint32 magic; /*magic number for verification purposes*/ + cc_generic_list_head_t* data_blobs; /*variable length data*/ +}; +typedef struct cc_msg_t cc_msg_t; + +/*Types of messages*/ +enum { + ccmsg_ACK, + ccmsg_NACK, + ccmsg_INIT, + ccmsg_CTX_RELEASE, + ccmsg_CTX_GET_CHANGE_TIME, + ccmsg_CTX_GET_DEFAULT_CCACHE_NAME, + ccmsg_CTX_COMPARE, + ccmsg_CTX_NEW_CCACHE_ITERATOR, + ccmsg_CTX_LOCK, + ccmsg_CTX_UNLOCK, + ccmsg_CTX_CLONE, + ccmsg_CCACHE_OPEN, + ccmsg_CCACHE_OPEN_DEFAULT, + ccmsg_CCACHE_CREATE, + ccmsg_CCACHE_CREATE_DEFAULT, + ccmsg_CCACHE_CREATE_UNIQUE, + ccmsg_CCACHE_RELEASE, + ccmsg_CCACHE_DESTROY, + ccmsg_CCACHE_SET_DEFAULT, + ccmsg_CCACHE_GET_CREDS_VERSION, + ccmsg_CCACHE_GET_NAME, + ccmsg_CCACHE_GET_PRINCIPAL, + ccmsg_CCACHE_SET_PRINCIPAL, + ccmsg_CCACHE_CREDS_ITERATOR, + ccmsg_CCACHE_STORE_CREDS, + ccmsg_CCACHE_REM_CREDS, + ccmsg_CCACHE_GET_LAST_DEFAULT_TIME, + ccmsg_CCACHE_GET_CHANGE_TIME, + ccmsg_CCACHE_MOVE, + ccmsg_CCACHE_COMPARE, + ccmsg_CCACHE_GET_KDC_TIME_OFFSET, + ccmsg_CCACHE_SET_KDC_TIME_OFFSET, + ccmsg_CCACHE_CLEAR_KDC_TIME_OFFSET, + ccmsg_CCACHE_ITERATOR_RELEASE, + ccmsg_CCACHE_ITERATOR_NEXT, + ccmsg_CCACHE_LOCK, + ccmsg_CCACHE_UNLOCK, + ccmsg_CREDS_ITERATOR_RELEASE, + ccmsg_CREDS_ITERATOR_NEXT, + ccmsg_CREDS_RELEASE, + ccmsg_CREDS_V4, + ccmsg_CREDS_V5 +}; + +#define CC_MSG_MAX_SIZE 1073741824 /*2^30*/ +#define CC_MSG_MAX_TYPE ccmsg_CREDS_V5 +#define BLOB_LEN (sizeof(cc_uint32)) +#define MAGIC_DATA_LEN (sizeof(cc_uint32)) +#define MAGIC_HEAD_LEN (sizeof(cc_uint32)) + +cc_int32 cci_msg_new(cc_uint32 type, cc_msg_t** msgpp); +cc_int32 cci_msg_calc_size(cc_msg_t* msg, cc_uint32 * sizep); +cc_int32 cci_msg_calc_header_size(cc_msg_t* msg, cc_uint32 * sizep); +cc_int32 cci_msg_add_data_blob(cc_msg_t* msg, void *data, cc_uint32 len, cc_uint32 * sizep); +cc_int32 cci_msg_add_header(cc_msg_t* msg, void *header, cc_uint32 header_len); +cc_int32 cci_msg_calc_blob_pos(cc_msg_t* msg, void *data, cc_uint32 len, cc_uint32 * sizep); +cc_int32 cci_msg_flatten(cc_msg_t* msg, void **); +cc_int32 cci_msg_calc_magic(void *flat, int flat_len, cc_uint32 * sizep); +cc_int32 cci_msg_verify(void* flat, int flat_len, cc_uint32 * sizep); +cc_int32 cci_msg_unflatten(void *flat, int flat_len, cc_msg_t** msgpp); +cc_int32 cci_msg_retrieve_blob(cc_msg_t* msg, cc_uint32 blob_offset, cc_uint32 blob_len, void **); +cc_int32 cci_msg_destroy(cc_msg_t* msg); +#endif /*__CC_MSG_H__*/ diff --git a/src/lib/ccapi/include/msg_headers.h b/src/lib/ccapi/include/msg_headers.h new file mode 100644 index 000000000..a27c2d2f1 --- /dev/null +++ b/src/lib/ccapi/include/msg_headers.h @@ -0,0 +1,429 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Message type specific header structures. + * + */ + +#ifndef __MSG_HEADERS_H__ +#define __MSG_HEADERS_H__ + +#include "CredentialsCache.h" + +/* + * All header structs must have sizes divisible by 4, and + * all individual fields within the structs must also have + * size divisible by 4. This is to ensure correct alignment + * and stop different compilers from inserting padding bytes in + * different places. + */ + +struct ccmsg_ctx_only_t { + cc_handle ctx; +}; +typedef struct ccmsg_ctx_only_t ccmsg_ctx_only_t; + +struct ccmsg_nack_t { + cc_uint32 err_code; /*error code that caused failure*/ +}; +typedef struct ccmsg_nack_t ccmsg_nack_t; + +struct ccmsg_init_t { + cc_uint32 in_version; /*client API version*/ +}; +struct ccmsg_init_resp_t { + cc_handle out_ctx; /*handle on this ctx*/ + cc_uint32 out_version; /*server API version*/ + cc_uint32 vendor_offset; /*offset of vendor blob*/ + cc_uint32 vendor_length; /*length of vendor blob*/ +}; +typedef struct ccmsg_init_t ccmsg_init_t; +typedef struct ccmsg_init_resp_t ccmsg_init_resp_t; + +struct ccmsg_clone_t { + cc_handle ctx; + cc_uint32 in_version; /*client API version*/ +}; +struct ccmsg_clone_resp_t { + cc_handle out_ctx; /*handle on this ctx*/ + cc_uint32 out_version; /*server API version*/ + cc_uint32 vendor_offset; /*offset of vendor blob*/ + cc_uint32 vendor_length; /*length of vendor blob*/ +}; +typedef struct ccmsg_clone_t ccmsg_clone_t; +typedef struct ccmsg_clone_resp_t ccmsg_clone_resp_t; + +struct ccmsg_ctx_release_t { + cc_handle ctx; /*# of ctx to release*/ +}; +typedef struct ccmsg_ctx_release_t ccmsg_ctx_release_t; + +struct ccmsg_ctx_get_change_time_t { + cc_handle ctx; +}; +struct ccmsg_ctx_get_change_time_resp_t { + cc_time_t time; +}; +typedef struct ccmsg_ctx_get_change_time_t ccmsg_ctx_get_change_time_t; +typedef struct ccmsg_ctx_get_change_time_resp_t ccmsg_ctx_get_change_time_resp_t; + +struct ccmsg_ctx_get_default_ccache_name_t { + cc_handle ctx; +}; +struct ccmsg_ctx_get_default_ccache_name_resp_t { + cc_uint32 name_offset; + cc_uint32 name_len; +}; +typedef struct ccmsg_ctx_get_default_ccache_name_t ccmsg_ctx_get_default_ccache_name_t; +typedef struct ccmsg_ctx_get_default_ccache_name_resp_t ccmsg_ctx_get_default_ccache_name_resp_t; + +struct ccmsg_ctx_compare_t { + cc_handle ctx1; + cc_handle ctx2; +}; +struct ccmsg_ctx_compare_resp_t { + cc_uint32 is_equal; +}; +typedef struct ccmsg_ctx_compare_t ccmsg_ctx_compare_t; +typedef struct ccmsg_ctx_compare_resp_t ccmsg_ctx_compare_resp_t; + +struct ccmsg_ctx_new_ccache_iterator_t { + cc_handle ctx; +}; +struct ccmsg_ctx_new_ccache_iterator_resp_t { + cc_handle iterator; +}; +typedef struct ccmsg_ctx_new_ccache_iterator_t ccmsg_ctx_new_ccache_iterator_t; +typedef struct ccmsg_ctx_new_ccache_iterator_resp_t ccmsg_ctx_new_ccache_iterator_resp_t; + +struct ccmsg_ctx_lock_t { + cc_handle ctx; + cc_uint32 lock_type; +}; +typedef struct ccmsg_ctx_lock_t ccmsg_ctx_lock_t; + +struct ccmsg_ctx_unlock_t { + cc_handle ctx; +}; +typedef struct ccmsg_ctx_unlock_t ccmsg_ctx_unlock_t; + +struct ccmsg_ccache_open_t { + cc_handle ctx; + cc_uint32 name_offset; + cc_uint32 name_len; +}; +struct ccmsg_ccache_open_resp_t { + cc_handle ccache; +}; +typedef struct ccmsg_ccache_open_t ccmsg_ccache_open_t; +typedef struct ccmsg_ccache_open_resp_t ccmsg_ccache_open_resp_t; + +struct ccmsg_ccache_open_default_t { + cc_handle ctx; +}; +typedef struct ccmsg_ccache_open_default_t ccmsg_ccache_open_default_t; + +struct ccmsg_ccache_create_t { + cc_handle ctx; + cc_uint32 version; + cc_uint32 principal_offset; + cc_uint32 principal_len; + cc_uint32 name_offset; + cc_uint32 name_len; +}; +struct ccmsg_ccache_create_default_t { + cc_handle ctx; + cc_uint32 version; + cc_uint32 principal_offset; + cc_uint32 principal_len; +}; +struct ccmsg_ccache_create_unique_t { + cc_handle ctx; + cc_uint32 version; + cc_uint32 principal_offset; + cc_uint32 principal_len; +}; + +struct ccmsg_ccache_create_resp_t { + cc_handle ccache; +}; +typedef struct ccmsg_ccache_create_t ccmsg_ccache_create_t; +typedef struct ccmsg_ccache_create_default_t ccmsg_ccache_create_default_t; +typedef struct ccmsg_ccache_create_unique_t ccmsg_ccache_create_unique_t; +typedef struct ccmsg_ccache_create_resp_t ccmsg_ccache_create_resp_t; + +struct ccmsg_ccache_release_t { + cc_handle ctx; + cc_handle ccache; +}; +typedef struct ccmsg_ccache_release_t ccmsg_ccache_release_t; + +struct ccmsg_ccache_destroy_t { + cc_handle ctx; + cc_handle ccache; +}; +typedef struct ccmsg_ccache_destroy_t ccmsg_ccache_destroy_t; + +struct ccmsg_ccache_set_default_t { + cc_handle ctx; + cc_handle ccache; +}; +typedef struct ccmsg_ccache_set_default_t ccmsg_ccache_set_default_t; + +struct ccmsg_ccache_get_creds_version_t { + cc_handle ctx; + cc_handle ccache; +}; +struct ccmsg_ccache_get_creds_version_resp_t { + cc_uint32 version; +}; +typedef struct ccmsg_ccache_get_creds_version_t ccmsg_ccache_get_creds_version_t; +typedef struct ccmsg_ccache_get_creds_version_resp_t ccmsg_ccache_get_creds_version_resp_t; + +struct ccmsg_ccache_get_name_t { + cc_handle ctx; + cc_handle ccache; +}; +struct ccmsg_ccache_get_name_resp_t { + cc_uint32 name_offset; + cc_uint32 name_len; +}; +typedef struct ccmsg_ccache_get_name_t ccmsg_ccache_get_name_t; +typedef struct ccmsg_ccache_get_name_resp_t ccmsg_ccache_get_name_resp_t; + +struct ccmsg_ccache_get_principal_t { + cc_handle ctx; + cc_handle ccache; + cc_uint32 version; +}; +struct ccmsg_ccache_get_principal_resp_t { + cc_uint32 principal_offset; + cc_uint32 principal_len; +}; +typedef struct ccmsg_ccache_get_principal_t ccmsg_ccache_get_principal_t; +typedef struct ccmsg_ccache_get_principal_resp_t ccmsg_ccache_get_principal_resp_t; + +struct ccmsg_ccache_set_principal_t { + cc_handle ctx; + cc_handle ccache; + cc_uint32 version; + cc_uint32 principal_offset; + cc_uint32 principal_len; +}; +typedef struct ccmsg_ccache_set_principal_t ccmsg_ccache_set_principal_t; + +struct ccmsg_ccache_creds_iterator_t { + cc_handle ctx; + cc_handle ccache; +}; +struct ccmsg_ccache_creds_iterator_resp_t { + cc_handle iterator; +}; +typedef struct ccmsg_ccache_creds_iterator_t ccmsg_ccache_creds_iterator_t; +typedef struct ccmsg_ccache_creds_iterator_resp_t ccmsg_ccache_creds_iterator_resp_t; + +struct ccmsg_ccache_store_creds_t { + cc_handle ctx; + cc_handle ccache; + cc_uint32 creds_version; + cc_uint32 creds_offset; + cc_uint32 creds_len; +}; +typedef struct ccmsg_ccache_store_creds_t ccmsg_ccache_store_creds_t; + +struct ccmsg_ccache_rem_creds_t { + cc_handle ctx; + cc_handle ccache; + cc_handle creds; +}; +typedef struct ccmsg_ccache_rem_creds_t ccmsg_ccache_rem_creds_t; + +struct ccmsg_ccache_lock_t { + cc_handle ctx; + cc_handle ccache; + cc_uint32 lock_type; +}; +typedef struct ccmsg_ccache_lock_t ccmsg_ccache_lock_t; + +struct ccmsg_ccache_unlock_t { + cc_handle ctx; + cc_handle ccache; +}; +typedef struct ccmsg_ccache_unlock_t ccmsg_ccache_unlock_t; + +struct ccmsg_ccache_move_t { + cc_handle ctx; + cc_handle ccache_source; + cc_handle ccache_dest; +}; +typedef struct ccmsg_ccache_move_t ccmsg_ccache_move_t; + +struct ccmsg_ccache_get_last_default_time_t { + cc_handle ctx; + cc_handle ccache; +}; +struct ccmsg_ccache_get_last_default_time_resp_t { + cc_time_t last_default_time; +}; +typedef struct ccmsg_ccache_get_last_default_time_t ccmsg_ccache_get_last_default_time_t; +typedef struct ccmsg_ccache_get_last_default_time_resp_t ccmsg_ccache_get_last_default_time_resp_t; + +struct ccmsg_ccache_get_change_time_t { + cc_handle ctx; + cc_handle ccache; +}; +struct ccmsg_ccache_get_change_time_resp_t { + cc_time_t time; +}; +typedef struct ccmsg_ccache_get_change_time_t ccmsg_ccache_get_change_time_t; +typedef struct ccmsg_ccache_get_change_time_resp_t ccmsg_ccache_get_change_time_resp_t; + +struct ccmsg_ccache_compare_t { + cc_handle ctx; + cc_handle ccache1; + cc_handle ccache2; +}; +struct ccmsg_ccache_compare_resp_t { + cc_uint32 is_equal; +}; +typedef struct ccmsg_ccache_compare_t ccmsg_ccache_compare_t; +typedef struct ccmsg_ccache_compare_resp_t ccmsg_ccache_compare_resp_t; + +struct ccmsg_ccache_get_kdc_time_offset_t { + cc_handle ctx; + cc_handle ccache; + cc_int32 creds_version; +}; +struct ccmsg_ccache_get_kdc_time_offset_resp_t { + cc_time_t offset; +}; +typedef struct ccmsg_ccache_get_kdc_time_offset_t ccmsg_ccache_get_kdc_time_offset_t; +typedef struct ccmsg_ccache_get_kdc_time_offset_resp_t ccmsg_ccache_get_kdc_time_offset_resp_t; + +struct ccmsg_ccache_set_kdc_time_offset_t { + cc_handle ctx; + cc_handle ccache; + cc_time_t offset; + cc_int32 creds_version; +}; +typedef struct ccmsg_ccache_set_kdc_time_offset_t ccmsg_ccache_set_kdc_time_offset_t; + +struct ccmsg_ccache_clear_kdc_time_offset_t { + cc_handle ctx; + cc_handle ccache; + cc_int32 creds_version; +}; +typedef struct ccmsg_ccache_clear_kdc_time_offset_t ccmsg_ccache_clear_kdc_time_offset_t; + +struct ccmsg_ccache_iterator_release_t { + cc_handle ctx; + cc_handle iterator; +}; +typedef struct ccmsg_ccache_iterator_release_t ccmsg_ccache_iterator_release_t; + +struct ccmsg_ccache_iterator_next_t { + cc_handle ctx; + cc_handle iterator; +}; +struct ccmsg_ccache_iterator_next_resp_t { + cc_handle ccache; +}; +typedef struct ccmsg_ccache_iterator_next_t ccmsg_ccache_iterator_next_t; +typedef struct ccmsg_ccache_iterator_next_resp_t ccmsg_ccache_iterator_next_resp_t; + +struct ccmsg_creds_iterator_release_t { + cc_handle ctx; + cc_handle ccache; + cc_handle iterator; +}; +typedef struct ccmsg_creds_iterator_release_t ccmsg_creds_iterator_release_t; + +struct ccmsg_creds_iterator_next_t { + cc_handle ctx; + cc_handle ccache; + cc_handle iterator; +}; +struct ccmsg_creds_iterator_next_resp_t { + cc_uint32 version; + cc_handle creds_handle; + cc_uint32 creds_offset; + cc_uint32 creds_len; +}; +typedef struct ccmsg_creds_iterator_next_t ccmsg_creds_iterator_next_t; +typedef struct ccmsg_creds_iterator_next_resp_t ccmsg_creds_iterator_next_resp_t; + +struct ccmsg_creds_v4_t { + cc_uint32 offset; + cc_uint32 len; +}; +typedef struct ccmsg_creds_v4_t ccmsg_creds_v4_t; + +struct ccmsg_creds_v5_t { + cc_uint32 client_offset; + cc_uint32 client_len; + cc_uint32 server_offset; + cc_uint32 server_len; + cc_uint32 keyblock_offset; + cc_uint32 keyblock_len; + cc_time_t authtime; + cc_time_t starttime; + cc_time_t endtime; + cc_time_t renewtime; + cc_uint32 is_skey; + cc_uint32 ticket_flags; + cc_uint32 address_count; + cc_uint32 address_offset; + cc_uint32 address_len; + cc_uint32 ticket_offset; + cc_uint32 ticket_len; + cc_uint32 ticket2_offset; + cc_uint32 ticket2_len; + cc_uint32 authdata_count; + cc_uint32 authdata_offset; + cc_uint32 authdata_len; +}; +typedef struct ccmsg_creds_v5_t ccmsg_creds_v5_t; + + +#endif /*__MSG_HEADERS_H__*/ diff --git a/src/lib/ccapi/mac/ChangeLog b/src/lib/ccapi/mac/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/mac/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/marshall.c b/src/lib/ccapi/marshall.c new file mode 100644 index 000000000..7027d6561 --- /dev/null +++ b/src/lib/ccapi/marshall.c @@ -0,0 +1,378 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* marshall.c */ + +#include +#include +#include +#include "msg.h" +#include "msg_headers.h" +#include "marshall.h" + +cc_int32 +cci_creds_v4_marshall( cc_credentials_v4_t * creds, + char ** flat, + cc_uint32 * len) +{ + cc_msg_t * msg; + ccmsg_creds_v4_t * header; + cc_uint32 blob_pos; + cc_int32 code; + + if ( creds == NULL || flat == NULL || len == NULL ) + return ccErrBadParam; + + header = (ccmsg_creds_v4_t *)malloc(sizeof(ccmsg_creds_v4_t)); + if ( header == NULL ) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_CREDS_V4, &msg); + + code = cci_msg_add_header(msg, header, sizeof(ccmsg_creds_v4_t)); + + code = cci_msg_add_data_blob(msg, creds, sizeof(cc_credentials_v4_t), &blob_pos); + + header->offset = blob_pos; + header->len = sizeof(cc_credentials_v4_t); + + code = cci_msg_flatten( msg, NULL ); + + *flat = msg->flat; + *len = msg->flat_len; + msg->flat = NULL; + msg->flat_len = 0; + + cci_msg_destroy(msg); + + return ccNoError; +} + +cc_int32 +cci_creds_v4_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds) +{ + cc_msg_t * msg; + ccmsg_creds_v4_t * header; + cc_int32 code; + + if ( flat == NULL || len == 0 || creds == NULL ) + return ccErrBadParam; + + code = cci_msg_unflatten( flat, len, &msg ); + + header = (ccmsg_creds_v4_t *)msg->header; + + creds->version = cc_credentials_v4; + code = cci_msg_retrieve_blob(msg, header->offset, header->len, &creds->credentials.credentials_v4); + + cci_msg_destroy(msg); + + return ccNoError; +} + + +cc_int32 +cci_creds_cc_data_array_count_entries( cc_data ** array, cc_uint32 * pcount) +{ + cc_uint32 count; + + if (array == NULL) { + *pcount = 0; + return ccNoError; + } + + for ( count=0; array[count] != NULL ; count++) ; + + *pcount = count; + return ccNoError; +} + +cc_int32 +cci_creds_v5_compute_flat_size( cc_credentials_v5_t * creds, cc_uint32 * plen) +{ + cc_uint32 len; + cc_uint32 i, count; + + len = sizeof(struct cci_flat_creds_v5); + + if (creds->client) + len += strlen(creds->client) + 1; + + if (creds->server) + len += strlen(creds->server) + 1; + + len += creds->keyblock.length; + + cci_creds_cc_data_array_count_entries( creds->addresses, &count ); + len += count * sizeof(cc_flat_data); + for ( i=0; iaddresses[i]->length; + } + + len += creds->ticket.length; + len += creds->second_ticket.length; + + cci_creds_cc_data_array_count_entries( creds->authdata, &count ); + len += count * sizeof(cc_flat_data); + for ( i=0; iauthdata[i]->length; + } + + *plen = len; + return ccNoError; +} + +cc_int32 +cci_creds_v5_marshall( cc_credentials_v5_t * creds, + char ** pflat, + cc_uint32 * plen) +{ + cc_uint32 len; + char * flat; + struct cci_flat_creds_v5 * header; + cc_uint32 offset; + cc_uint32 i; + + if ( creds == NULL || pflat == NULL || plen == NULL ) + return ccErrBadParam; + + cci_creds_v5_compute_flat_size(creds, &len); + + flat = (char *)malloc(len); + if ( flat == NULL ) + return ccErrNoMem; + memset(flat, 0, len); + + offset = sizeof(struct cci_flat_creds_v5); + header = (struct cci_flat_creds_v5 *)flat; + header->version = FLAT_CREDS_V5_VERSION; + if (creds->client) { + header->client.length = strlen(creds->client) + 1; + header->client.data = offset; + memcpy(flat + offset, creds->client, header->client.length); + offset += header->client.length; + } + + if (creds->server) { + header->server.length = strlen(creds->server) + 1; + header->server.data = offset; + memcpy(flat + offset, creds->server, header->server.length); + offset += header->server.length; + } + + header->keyblock.type = creds->keyblock.type; + if (creds->keyblock.length) { + header->keyblock.length = creds->keyblock.length; + header->keyblock.data = offset; + memcpy(flat + offset, creds->keyblock.data, header->keyblock.length); + offset += header->keyblock.length; + } + + header->authtime = creds->authtime; + header->starttime = creds->starttime; + header->endtime = creds->endtime; + header->renew_till = creds->renew_till; + header->is_skey = creds->is_skey; + header->ticket_flags = creds->ticket_flags; + + cci_creds_cc_data_array_count_entries( creds->addresses, &header->address_count ); + if ( header->address_count ) { + cc_flat_data * addresses = (cc_flat_data *)flat + offset; + header->addresses = offset; + offset += header->address_count * sizeof(cc_flat_data); + + for ( i=0; iaddress_count; i++ ) { + addresses[i].type = creds->addresses[i]->type; + if (creds->addresses[i]->length) { + addresses[i].length = creds->addresses[i]->length; + addresses[i].data = offset; + memcpy(flat + offset, creds->addresses[i]->data, addresses[i].length); + offset += addresses[i].length; + } + } + } + + header->ticket.type = creds->ticket.type; + if (creds->ticket.length) { + header->ticket.length = creds->ticket.length; + header->ticket.data = offset; + memcpy(flat + offset, creds->ticket.data, header->ticket.length); + offset += header->ticket.length; + } + + header->second_ticket.type = creds->second_ticket.type; + if (creds->second_ticket.length) { + header->second_ticket.length = creds->second_ticket.length; + header->second_ticket.data = offset; + memcpy(flat + offset, creds->second_ticket.data, header->second_ticket.length); + offset += header->second_ticket.length; + } + + cci_creds_cc_data_array_count_entries( creds->authdata, &header->authdata_count ); + if ( header->authdata_count ) { + cc_flat_data * authdata = (cc_flat_data *)flat + offset; + header->authdata = offset; + offset += header->authdata_count * sizeof(cc_flat_data); + + for ( i=0; iauthdata_count; i++ ) { + authdata[i].type = creds->authdata[i]->type; + if (creds->authdata[i]->length) { + authdata[i].length = creds->authdata[i]->length; + authdata[i].data = offset; + memcpy(flat + offset, creds->authdata[i]->data, authdata[i].length); + offset += authdata[i].length; + } + } + } + + *pflat = flat; + *plen = len; + return ccNoError; +} + + +// TODO: a much better job of checking for out of memory errors +// and validating that we do not read beyond the flat input +// data buffer + +cc_int32 +cci_creds_v5_unmarshall( char * flat, + cc_uint32 len, + cc_credentials_union * creds_union) +{ + struct cci_flat_creds_v5 * header; + cc_credentials_v5_t * creds; + cc_flat_data * flat_data; + cc_uint32 i; + cc_int32 code; + + if ( flat == NULL || len == 0 || creds_union == NULL ) + return ccErrBadParam; + + creds_union->version = cc_credentials_v5; + + header = (struct cci_flat_creds_v5 *)flat; + + if ( header->version != FLAT_CREDS_V5_VERSION ) + return ccErrBadParam; + + creds = (cc_credentials_v5_t *)malloc(sizeof(cc_credentials_v5_t)); + if ( creds == NULL ) + return ccErrNoMem; + memset(creds, 0, sizeof(ccmsg_creds_v5_t)); + + if ( header->client.length ) { + creds->client = (char *)malloc(header->client.length); + memcpy(creds->client, flat + header->client.data, header->client.length); + } + + if ( header->server.length ) { + creds->server = (char *)malloc(header->server.length); + memcpy(creds->server, flat + header->server.data, header->server.length); + } + + creds->keyblock.type = header->keyblock.type; + if ( header->keyblock.length ) { + creds->keyblock.length = header->keyblock.length; + creds->keyblock.data = malloc(creds->keyblock.length); + memcpy(creds->keyblock.data, flat + header->keyblock.data, creds->keyblock.length); + } + + creds->authtime = header->authtime; + creds->starttime = header->starttime; + creds->endtime = header->endtime; + creds->renew_till = header->renew_till; + creds->is_skey = header->is_skey; + creds->ticket_flags = header->ticket_flags; + + creds->addresses = (cc_data **) malloc((header->address_count + 1) * sizeof(cc_data *)); + flat_data = (cc_flat_data *)flat + header->addresses; + for ( i=0 ; i < header->address_count ; i++ ) { + creds->addresses[i] = (cc_data *)malloc(sizeof(cc_data)); + creds->addresses[i]->type = flat_data[i].type; + creds->addresses[i]->length = flat_data[i].length; + if ( flat_data[i].length ) { + creds->addresses[i]->data = malloc(flat_data[i].length); + memcpy(creds->addresses[i]->data, flat + flat_data[i].data, flat_data[i].length); + } else { + creds->addresses[i]->data = NULL; + } + } + creds->addresses[i] = NULL; + + creds->ticket.type = header->ticket.type; + if ( header->ticket.length ) { + creds->ticket.length = header->ticket.length; + creds->ticket.data = malloc(creds->ticket.length); + memcpy(creds->ticket.data, flat + header->ticket.data, creds->ticket.length); + } + + creds->second_ticket.type = header->second_ticket.type; + if ( header->second_ticket.length ) { + creds->second_ticket.length = header->second_ticket.length; + creds->second_ticket.data = malloc(creds->second_ticket.length); + memcpy(creds->second_ticket.data, flat + header->second_ticket.data, creds->second_ticket.length); + } + + creds->authdata = (cc_data **) malloc((header->authdata_count + 1) * sizeof(cc_data *)); + flat_data = (cc_flat_data *)flat + header->authdata; + for ( i=0 ; i < header->authdata_count ; i++ ) { + creds->authdata[i] = (cc_data *)malloc(sizeof(cc_data)); + creds->authdata[i]->type = flat_data[i].type; + creds->authdata[i]->length = flat_data[i].length; + if ( flat_data[i].length ) { + creds->authdata[i]->data = malloc(flat_data[i].length); + memcpy(creds->authdata[i]->data, flat + flat_data[i].data, flat_data[i].length); + } else { + creds->authdata[i]->data = NULL; + } + } + creds->authdata[i] = NULL; + + creds_union->credentials.credentials_v5 = creds; + + return ccNoError; +} + diff --git a/src/lib/ccapi/msg.c b/src/lib/ccapi/msg.c new file mode 100644 index 000000000..f5f074aa0 --- /dev/null +++ b/src/lib/ccapi/msg.c @@ -0,0 +1,582 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Verifiable, extensible message format. + */ + +#include "CredentialsCache.h" +#include "msg.h" +#include "datastore.h" + +#include +#include +#include +#include + +/** + * cci_msg_new() + * + * Purpose: Allocate and initialize a new cc_msg_t structure + * + * Return: non-NULL, the msg + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_msg_new(cc_uint32 type, cc_msg_t** msgpp) +{ + // type should be validated. If invalid set error to ccErrBadParam + cc_msg_t* msg; + + if ( type > CC_MSG_MAX_TYPE || msgpp == NULL ) + return ccErrBadParam; + + msg = (cc_msg_t*)malloc(sizeof(cc_msg_t)); + if (msg == NULL) + return ccErrNoMem; + + msg->type = type; + msg->flat = NULL; + msg->header = NULL; + msg->flat_len = 0; + msg->header_len = 0; + msg->magic = 0; + cci_generic_list_new(&msg->data_blobs); + if (msg->data_blobs == NULL) { + // pass on error from previous call + free(msg); + return ccErrNoMem; + } + + *msgpp = msg; + return ccNoError; +} + +/** + * cci_msg_calc_header_size() + * + * Purpose: Calculates the size of the header + * + * Return: the size in bytes + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_msg_calc_header_size(cc_msg_t* msg, cc_uint32 * lenp) +{ + int header_len = 12; /* header size, entire size, type */ + + if ( msg == NULL || lenp == NULL ) + return ccErrBadParam; + + header_len += msg->header_len; + *lenp = header_len; + return ccNoError; +} + +/** + * cci_msg_calc_size() + * + * Purpose: Calculates the size of the message + * (does not include the magic bytes) + * + * Return: the size in bytes + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_msg_calc_size(cc_msg_t* msg, cc_uint32 * lenp) +{ + cc_uint32 flat_len; + cc_generic_list_node_t* gen_node; + cc_generic_iterate_t* gen_iterator; + cc_int32 code; + + if ( msg == NULL || lenp == NULL ) + return ccErrBadParam; + + code = cci_msg_calc_header_size(msg, &flat_len); + if (code != ccNoError) + goto bad; + + code = cci_generic_list_iterator(msg->data_blobs, &gen_iterator); + if ( code != ccNoError ) + goto bad; + + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + if (code != ccNoError) + break; + flat_len += gen_node->len + BLOB_LEN; + } + cci_generic_free_iterator(gen_iterator); + if (code != ccNoError) + goto bad; + + flat_len += MAGIC_HEAD_LEN + MAGIC_DATA_LEN; + *lenp = flat_len; + + bad: + return code; +} + +/** + * cci_msg_add_data_blob() + * + * Purpose: Adds 'len' bytes of data to the msg + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_add_data_blob(cc_msg_t* msg, void *data, cc_uint32 len, cc_uint32 *lenp) +{ + cc_int32 code; + + if (msg == NULL || data == NULL || len <= 0 || lenp == NULL) + return ccErrBadParam; + + code = cci_generic_list_append(msg->data_blobs, data, len, NULL); + if ( code != ccNoError ) + return code; + return cci_msg_calc_blob_pos(msg, data, len, lenp); +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_calc_blob_pos(cc_msg_t* msg, void *data, cc_uint32 len, cc_uint32 * posp) +{ + cc_uint32 pos; + cc_generic_list_node_t* gen_node; + cc_generic_iterate_t* gen_iterator; + cc_int32 code; + + code = cci_msg_calc_header_size(msg, &pos); + pos += sizeof(cc_uint32); /*+ sizeof(cc_uint32) for magic*/ + + code = cci_generic_list_iterator(msg->data_blobs, &gen_iterator); + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + if (gen_node->len != len && gen_node->data != data) { + pos += gen_node->len + sizeof(cc_uint32); + } else { + cci_generic_free_iterator(gen_iterator); + *posp = pos + sizeof(cc_uint32); + return ccNoError; + } + } + + cci_generic_free_iterator(gen_iterator); + return ccIteratorEnd; +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_add_header(cc_msg_t* msg, void *header, cc_uint32 header_len) +{ + if ( msg == NULL || header == NULL ) + return ccErrBadParam; + + msg->header = header; + msg->header_len = header_len; + return ccNoError; +} + + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_flatten(cc_msg_t* msg, void **flatpp) +{ + cc_generic_list_node_t* gen_node; + cc_generic_iterate_t* gen_iterator; + char *cur_pos; + cc_uint32 zero = 0; + cc_uint32 magic = 0; + cc_uint32 msg_len; + cc_int32 code; + + if (msg == NULL || flatpp == NULL) + return ccErrBadParam; + + code = cci_msg_calc_size(msg,&msg->flat_len); + if ( code != ccNoError ) + return code; + + if (msg->flat_len > CC_MSG_MAX_SIZE) + return ccErrBadParam; + + msg->flat = (void *)malloc(msg->flat_len); + if (msg->flat == NULL) + return ccErrNoMem; + + cur_pos = msg->flat; + + memcpy(cur_pos,&msg->header_len,sizeof(cc_uint32)); + cur_pos+=sizeof(cc_uint32); + + memcpy(cur_pos,&msg->flat_len,sizeof(cc_uint32)); + cur_pos+=sizeof(cc_uint32); + + memcpy(cur_pos,&msg->type,sizeof(cc_uint32)); + cur_pos+=sizeof(cc_uint32); + + memcpy(cur_pos, msg->header, msg->header_len); + cur_pos += msg->header_len; + + memcpy(cur_pos, &zero, sizeof(cc_uint32)); /*will be magic number later*/ + cur_pos += sizeof(cc_uint32); + + code = cci_generic_list_iterator(msg->data_blobs,&gen_iterator); + if ( code != ccNoError ) { + free(msg->flat); + return code; + } + + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + if (code != ccNoError) { + free(gen_iterator); + free(msg->flat); + return code; + } + memcpy(cur_pos, &gen_node->len, sizeof(cc_uint32)); + cur_pos+=sizeof(cc_uint32); + + memcpy(cur_pos, gen_node->data, gen_node->len); + cur_pos += gen_node->len; + } + free(gen_iterator); + + memcpy(cur_pos, &zero, sizeof(cc_uint32)); /*magic number will go here later*/ + cur_pos += sizeof(cc_uint32); + + if (cur_pos - (char *)msg->flat != msg->flat_len) { + printf("ERRORR cur_pos - msg->flat = %d\n",msg->flat_len); + } + + cci_msg_calc_magic(msg->flat, msg->flat_len, &magic); + printf("magic = %d\n",magic); + + cci_msg_calc_header_size(msg, &msg_len); + memcpy((char *)msg->flat + msg_len, &magic, sizeof(cc_uint32)); + memcpy((char *)msg->flat + msg->flat_len - sizeof(cc_uint32), &magic, sizeof(cc_uint32)); + + if ( flatpp != NULL ) + *flatpp = msg->flat; + return ccNoError; +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_calc_magic(void *flat, int flat_len, cc_uint32 * magicp) +{ + cc_uint32 magic = 0; + int i; + + for (i = 0; i < flat_len; i += sizeof(cc_uint32)) { + magic = magic ^ *(int *)((char *)flat + i); + } + *magicp = magic; + return ccNoError; +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_verify(void *flat, int flat_len, cc_uint32 * validp) +{ + cc_uint32 *magic1, *magic2; + cc_uint32 *pheader_len; + cc_uint32 *ptotal_len; + cc_uint32 *pblob_len; + cc_uint32 *ptype; + cc_uint32 num_blobs = 0; + cc_uint32 zero = 0; + cc_uint32 msg_magic, msg_magic2; + + if (flat == NULL || flat_len <= 0 || validp == NULL) + return ccErrBadParam; + + pheader_len = flat; + ptotal_len = (cc_uint32 *)((char *)pheader_len + sizeof(cc_uint32)); + ptype = (cc_uint32 *)((char *)ptotal_len + sizeof(cc_uint32)); + + if (*ptotal_len != flat_len) { + *validp = 0; + return ccNoError; + } + + if (*pheader_len > flat_len) { + /*too weak. We could verify header_len against type spec header.*/ + *validp = 0; + return ccNoError; + } + if (*ptype > CC_MSG_MAX_TYPE) { + *validp = 0; + return ccNoError; + } + + magic1 = (cc_uint32 *)((char *)ptype + sizeof(cc_uint32) + *pheader_len); + if ((char *)magic1 - (char *)flat == (flat_len - 8)) { + /*There are no data blobs*/ + magic2 = (cc_uint32 *)((char *)magic1 + sizeof(cc_uint32)); + num_blobs = 0; + } else { + pblob_len = (cc_uint32 *)((char *)magic1 + sizeof(cc_uint32)); + num_blobs = 1; + + while (*pblob_len + sizeof(cc_uint32) + ((char *)pblob_len - (char *)flat) < (flat_len - sizeof(cc_uint32))) { + pblob_len = (cc_uint32 *)((char *)pblob_len + *pblob_len + sizeof(cc_uint32)); + num_blobs++; + } + + if (*pblob_len + sizeof(cc_uint32) + ((char *)pblob_len - (char *)flat) != (flat_len - sizeof(cc_uint32))) { + /*blobs didn't line up*/ + *validp = 0; + return ccNoError; + } + magic2 = (cc_uint32 *)((char *)pblob_len + *pblob_len + sizeof(cc_uint32)); /*2nd magic should be directly after the last blob*/ + } + + if (*magic1 != *magic2) { + *validp = 0; + return ccNoError; + } + msg_magic = *magic1; + + printf("%d %d\n", (char *)magic1 - (char *)flat, (char *)magic2 - (char *)flat); + + memcpy(magic1, &zero, sizeof(cc_uint32)); + memcpy(magic2, &zero, sizeof(cc_uint32)); + cci_msg_calc_magic(flat, flat_len, &msg_magic2); + if (msg_magic != msg_magic2) { + *validp = 0; + return ccNoError; + } + memcpy(magic1, &msg_magic, sizeof(cc_uint32)); + memcpy(magic2, &msg_magic, sizeof(cc_uint32)); + + *validp = 1; + return ccNoError; +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_unflatten(void *flat, int flat_len, cc_msg_t** msgpp) +{ + cc_msg_t* msg; + char *cur_pos; + cc_uint32 blob_len; + char *blob; + cc_uint32 valid; + cc_int32 code; + + if ( flat == NULL || flat_len <= 0 || msgpp == NULL ) + return ccErrBadParam; + + code = cci_msg_new(0, &msg); + if (code) + return code; + + cci_msg_verify(flat, flat_len, &valid); + if (valid != 1) { + cci_msg_destroy(msg); + return ccErrBadParam; + } + + cur_pos = flat; + msg->flat = flat; + + msg->header_len = *(cc_uint32 *)cur_pos; + cur_pos += sizeof(cc_uint32); + + msg->flat_len = *(cc_uint32 *)cur_pos; + cur_pos += sizeof(cc_uint32); + + msg->type = *(cc_uint32 *)cur_pos; + cur_pos += sizeof(cc_uint32); + + msg->header = (void *)malloc(msg->header_len); + if (msg->header == NULL) { + cci_msg_destroy(msg); + return ccErrNoMem; + } + memcpy(msg->header, cur_pos, msg->header_len); + cur_pos += msg->header_len; + + msg->magic = *(cc_uint32 *)cur_pos; + cur_pos += sizeof(cc_uint32); + + if (cur_pos - (char *)flat != flat_len - 8) { /*at least 1 blob*/ + blob_len = *(cc_uint32 *)cur_pos; + while (blob_len + (cur_pos - (char *)flat) + sizeof(cc_uint32) <= flat_len - sizeof(cc_uint32)) { + blob = (void *)malloc(blob_len); + if (blob == NULL) { + cci_msg_destroy(msg); + return ccErrNoMem; + } + memcpy(blob, cur_pos + sizeof(cc_uint32), blob_len); + cci_generic_list_append(msg->data_blobs, blob, blob_len, NULL); + + cur_pos += sizeof(cc_uint32) + blob_len; + blob_len = *(int *)cur_pos; + } + } + *msgpp = msg; + return ccNoError; +} + +cc_int32 +cci_msg_retrieve_blob(cc_msg_t* msg, cc_uint32 blob_offset, cc_uint32 blob_len, void **blobp) +{ + cc_generic_iterate_t* gen_iterator; + cc_generic_list_node_t* gen_node; + void *ret; + cc_uint32 blob_pos; + cc_int32 code; + + /*Ensure that the message has been unflattened*/ + if ( msg == NULL || msg->flat == NULL || blob_offset > msg->flat_len || + blob_len > msg->flat_len - blob_offset || blobp == NULL) + return ccErrBadParam; + + code = cci_generic_list_iterator(msg->data_blobs, &gen_iterator); + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + code = cci_msg_calc_blob_pos(msg, gen_node->data, gen_node->len, &blob_pos); + if (blob_pos == blob_offset && gen_node->len == blob_len) { + free(gen_iterator); + ret = (void *)malloc(blob_len); + if (ret == NULL) + return ccErrNoMem; + memcpy(ret,(char *)msg->flat + blob_offset, blob_len); + *blobp = ret; + return ccNoError; + } + } + free(gen_iterator); + return ccIteratorEnd; +} + +/** + * cc_msg_ + * + * Purpose: + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_msg_destroy(cc_msg_t* msg) +{ + if (msg->flat != NULL) + free(msg->flat); + if (msg->header != NULL) + free(msg->flat); + cci_generic_list_destroy(msg->data_blobs); + free(msg); + return ccNoError; +} + diff --git a/src/lib/ccapi/server/ChangeLog b/src/lib/ccapi/server/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/server/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/server/NTMakefile b/src/lib/ccapi/server/NTMakefile new file mode 100644 index 000000000..671b6905f --- /dev/null +++ b/src/lib/ccapi/server/NTMakefile @@ -0,0 +1,30 @@ +# Makefile for the CCAPI Generic Server + +!INCLUDE + +CFLAGS = -I../include + +CCAPI_LIB = ../lib/ccapi.lib +WINLIBS = user32.lib advapi32.lib +CCSOBJS = context.obj ccache.obj lists.obj rpc_auth.obj serv_ops.obj + +all: t_lists.exe t_msg.exe t_ccache.exe t_context.exe ccapi_server.exe + +t_lists.exe: t_lists.obj $(CCSOBJS) $(CCAPI_LIB) + link -out:$@ t_lists.obj $(CCSOBJS) $(CCAPI_LIB) $(WINLIBS) + +t_msg.exe: t_msg.obj $(CCSOBJS) $(CCAPI_LIB) + link -out:$@ t_msg.obj $(CCSOBJS) $(CCAPI_LIB) $(WINLIBS) + +t_ccache.exe: t_ccache.obj $(CCSOBJS) $(CCAPI_LIB) + link -out:$@ t_ccache.obj $(CCSOBJS) $(CCAPI_LIB) $(WINLIBS) + +t_context.exe: t_context.obj $(CCSOBJS) $(CCAPI_LIB) + link -out:$@ t_context.obj $(CCSOBJS) $(CCAPI_LIB) $(WINLIBS) + +ccapi_server.exe: main.obj $(CCSOBJS) $(CCAPI_LIB) + link -out:$@ main.obj $(CCSOBJS) $(CCAPI_LIB) $(WINLIBS) + +clean: + del *.obj *.exe + diff --git a/src/lib/ccapi/server/ccache.c b/src/lib/ccapi/server/ccache.c new file mode 100644 index 000000000..2c3a745af --- /dev/null +++ b/src/lib/ccapi/server/ccache.c @@ -0,0 +1,703 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Manages ccache objects. + * + */ + +#include +#include +#include +#include +#include "CredentialsCache.h" +#include "datastore.h" + +/** + * ccache_new() + * + * Purpose: Allocate and initialize new credentials cache for the specified principal + * and version + * + * Return: ccNoError - success + * ccErrInvalidString - name or principal is NULL + * ccErrBadCredentialsVersion - unsupported creds type + * ccErrBadParam - outCcachepp is NULL + * ccErrNoMem - malloc failed + */ +cc_int32 +cci_ccache_new( char *name, char *principal, int cred_vers, + cc_server_ccache_t** outCCachepp) +{ + cc_server_ccache_t* ccache; + + if (name == NULL || principal == NULL) + return ccErrInvalidString; + + if (cred_vers != cc_credentials_v4 && cred_vers != cc_credentials_v5 && + cred_vers != cc_credentials_v4_v5) + return ccErrBadCredentialsVersion; + + if (outCCachepp == NULL) + return ccErrBadParam; + + ccache = (cc_server_ccache_t*)malloc(sizeof(cc_server_ccache_t)); + if (ccache == NULL) + return ccErrNoMem; + + ccache->name = name; + ccache->principal_v4 = NULL; + ccache->principal_v5 = NULL; + ccache->changed = time(NULL); + ccache->kdc_offset = 0; + ccache->last_default = 0; + cci_generic_list_new(&ccache->active_iterators); + cci_credentials_list_new(&ccache->creds); + ccache->is_default = 0; + ccache->kdc_set = 0; + ccache->versions = cred_vers; + ccache->mycontext = NULL; + + cci_ccache_set_principal(ccache, cred_vers, principal); + *outCCachepp = ccache; + return ccNoError; +} + +/** + * cci_ccache_check_version() + * + * Purpose: Check to see if the ccache and the creds have compatible versions. + * + * Return: ccNoError and compat = 1 if they are compatible + * ccNoError and compat = 0 if they are not compatible + * + * Errors: ccErrInvalidCCache - ccache is NULL + * ccErrBadParam - either creds or compat are NULL + */ +cc_int32 +cci_ccache_check_version( const cc_server_ccache_t *ccache, + const cc_credentials_union* creds, + cc_uint32* compat) +{ + if (ccache == NULL) + return ccErrInvalidCCache; + + if (creds == NULL || compat == NULL) + return ccErrBadParam; + + if (ccache->versions == cc_credentials_v4_v5) + *compat = 1; + else if (ccache->versions == creds->version) + *compat = 1; + else + *compat = 0; + + return ccNoError; +} + +/** +cci_ccache_check_principal() + +Check to see if the client principal from the credentials matches +the principal associated with the cache. + +* Return: ccNoError and compat = 1 if they are compatible +* ccNoError and compat = 0 if they are not compatible +* +* Errors: ccErrInvalidCCache - ccache is NULL +* ccErrBadParam - either creds or compat are NULL +* ccErrBadCredentialVersion - unsupported credential type +*/ +cc_int32 +cci_ccache_check_principal( const cc_server_ccache_t *ccache, + const cc_credentials_union* creds, + cc_uint32* compat) +{ + if (ccache == NULL) + return ccErrInvalidCCache; + + if (creds == NULL || compat == NULL) + return ccErrBadParam; + + if (creds->version == cc_credentials_v4) { + if (strcmp(creds->credentials.credentials_v4->principal, ccache->principal_v4) == 0) + *compat = 1; + else + *compat = 0; + } else if (creds->version == cc_credentials_v5) { + if (strcmp(creds->credentials.credentials_v5->client, ccache->principal_v5) == 0) + *compat = 1; + else + *compat = 0; + } else { + return ccErrBadCredentialsVersion; + } + return ccNoError; +} + + +/** + * cci_ccache_store_creds() + * + * Purpose: Stores the provided credentials into the provided cache. Validates the + * ability of the cache to store credentials of the given version and client + * principal. + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrNoMem + * ccErrBadCredentialsVersion + * ccErrBadInvalidCredentials + * ccErrInvalidCache + * ccErrBadParam + */ +cc_int32 +cci_ccache_store_creds(cc_server_ccache_t *ccache, const cc_credentials_union* credentials) +{ + cc_server_credentials_t* stored_cred=NULL; + cc_uint32 valid_version, valid_principal; + cc_int32 code; + + if (ccache == NULL) + return ccErrInvalidCCache; + + if (credentials == NULL) + return ccErrBadParam; + + code = cci_ccache_check_version(ccache, credentials, &valid_version); + if (code != ccNoError) { + /* pass error on to caller */ + goto bad; + } + code = cci_ccache_check_principal(ccache, credentials, &valid_principal); + if (code != ccNoError) { + /* pass error on to caller */ + goto bad; + } + if (valid_version && valid_principal) { + stored_cred = (cc_server_credentials_t*)malloc(sizeof(cc_server_credentials_t)); + if (stored_cred == NULL) { + code = ccErrNoMem; + goto bad; + } + memcpy(&stored_cred->creds, credentials, sizeof(cc_credentials_union)); + + if (credentials->version == cc_credentials_v4) { + stored_cred->creds.credentials.credentials_v4 = (cc_credentials_v4_t*)malloc(sizeof(cc_credentials_v4_t)); + if (stored_cred->creds.credentials.credentials_v4 == NULL) { + code = ccErrNoMem; + goto bad; + } + + memcpy(stored_cred->creds.credentials.credentials_v4, credentials->credentials.credentials_v4, sizeof(cc_credentials_v4_t)); + } else if (credentials->version == cc_credentials_v5) { + stored_cred->creds.credentials.credentials_v5 = (cc_credentials_v5_t*)malloc(sizeof(cc_credentials_v5_t)); + if (stored_cred->creds.credentials.credentials_v5 == NULL) { + code = ccErrNoMem; + goto bad; + } + + memcpy(stored_cred->creds.credentials.credentials_v5, credentials->credentials.credentials_v5, sizeof(cc_credentials_v5_t)); + } else { + code = ccErrBadCredentialsVersion; + goto bad; + } + + code = cci_credentials_list_append(ccache->creds, stored_cred, NULL); + if ( code != ccNoError ) { + /* pass error on to caller */ + goto bad; + } + if (ccache->creds->head->data == (cc_uint8 *)stored_cred) + stored_cred->is_default = 1; /*we're first on the list, so we're default*/ + + cci_ccache_changed(ccache); + return ccNoError; + } else { +#ifdef DEBUG + printf("vers: %d\tprincipal: %d\n", + valid_version, valid_principal); +#endif /* DEBUG */ + code = ccErrInvalidCredentials; + goto bad; + } + + bad: + if (stored_cred) + free(stored_cred); + return code; /* error */ +} + +/** + * cci_ccache_changed() + * + * Purpose: Updates the last update time for the ccache and its associated context. + * Provides a location from which interested parties should be notified + * of cache updates. + * + * Return: none + * + * Errors: none + */ +void +cci_ccache_changed(cc_server_ccache_t* ccache) +{ + ccache->changed = time(NULL); + if (ccache->mycontext != NULL) + ccache->mycontext->changed = time(NULL); + + /* XXX - notify registered listeners when implemented */ +} + +/** + * cci_ccache_rem_creds() + * + * Purpose: Removes the specified credential object from the specified cache if + * it exists + * + * Return: 0 on success (credential is not in the cache) + * -1 on error + * + * Errors: ccErrBadParam, ccErrNoMem (from cc_credentials_list_iterator) + * + * Verify: does the memory associated with stored_cred->creds need to be freed? + * + */ +cc_int32 +cci_ccache_rem_creds(cc_server_ccache_t *ccache, const cc_credentials_union* credentials) +{ + cc_credentials_iterate_t* credentials_iterator=NULL, *active; + cc_generic_iterate_t* generic_iterator=NULL; + cc_credentials_list_node_t* credentials_node; + cc_generic_list_node_t* generic_node; + cc_server_credentials_t* stored_cred; + cc_int8 changed = 0; + cc_int32 code = 0; + + if (ccache == NULL) + return ccErrInvalidCCache; + + if (credentials == NULL) + return ccErrBadParam; + + code = cci_credentials_list_iterator(ccache->creds, &credentials_iterator); + if (code != ccNoError) { + /* pass error to caller */ + goto cleanup; + } + + while (cci_credentials_iterate_has_next(credentials_iterator)) { + code = cci_credentials_iterate_next(credentials_iterator, &credentials_node); + stored_cred = (cc_server_credentials_t*)credentials_node->data; + if (memcmp(&stored_cred->creds,credentials,sizeof(cc_credentials_union)) == 0) { + /* XXX - do we need to free(stored_cred->creds) ? */ + free(credentials_node->data); + changed = 1; + + /*If any iterator's next points to the deleted node, make it point to the next node*/ + code = cci_generic_list_iterator(ccache->active_iterators, &generic_iterator); + while (cci_generic_iterate_has_next(generic_iterator)) { + code = cci_generic_iterate_next(generic_iterator, &generic_node); + active = (cc_credentials_iterate_t*)generic_node->data; + if (active->next == credentials_node) + active->next = active->next->next; + } + code = cci_generic_free_iterator(generic_iterator); + generic_iterator = NULL; + + if (credentials_node == ccache->creds->head) { /*removing the default, must make next cred default*/ + code = cci_credentials_list_remove_element(ccache->creds, credentials_node); + + if (ccache->creds->head != NULL) + ((cc_server_credentials_t*)ccache->creds->head->data)->is_default = 1; + } else { + code = cci_credentials_list_remove_element(ccache->creds, credentials_node); + } + break; + } + } + + cleanup: + if (changed) + cci_ccache_changed(ccache); + if (credentials_iterator) + cci_credentials_free_iterator(credentials_iterator); + if (generic_iterator) + cci_generic_free_iterator(generic_iterator); + return code; +} + +/** + * cci_ccache_move() + * + * Purpose: Destroys the existing contents of the destination and copies + * all credentials from the source to the destination + * + * Return: 0 on success + * -1 on error + * + * Errors: ccBadNoMem + * + */ + +cc_int32 +cci_ccache_move(cc_server_ccache_t *source, cc_server_ccache_t* destination) +{ + cc_generic_list_node_t* node; + cc_generic_iterate_t* iterator; + cc_credentials_iterate_t* cur; + cc_int32 code; + + if (source == NULL || destination == NULL) + return ccErrBadParam; + + code = cci_credentials_list_destroy(destination->creds); + if ( code != ccNoError ) + return code; + + code = cci_credentials_list_copy(source->creds, &destination->creds); + if ( code != ccNoError ) + return code; + + destination->versions = source->versions; + destination->kdc_offset = source->kdc_offset; + destination->last_default = 0; + + /*reset all active iterators to point to the head of the new creds list*/ + if (destination->active_iterators->head != NULL) { + code = cci_generic_list_iterator(destination->active_iterators, &iterator); + while (cci_generic_iterate_has_next(iterator)) { + code = cci_generic_iterate_next(iterator, &node); + cur = (cc_credentials_iterate_t*)node->data; + cur->next = destination->creds->head; + } + code = cci_generic_free_iterator(iterator); + } + + cci_ccache_changed(destination); + return code; +} + +/** + * cci_ccache_get_kdc_time_offset() + * + * Purpose: Retrieves the kdc_time_offset from the ccache if set + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrBadParam, ccErrTimeOffsetNotSet + * + */ +cc_int32 +cci_ccache_get_kdc_time_offset(cc_server_ccache_t* ccache, cc_time_t* offset) +{ + if (ccache == NULL) + return ccErrInvalidCCache; + + if (offset == NULL) + return ccErrBadParam; + + if (!ccache->kdc_set) + return ccErrTimeOffsetNotSet; + + *offset = ccache->kdc_offset; + return ccNoError; +} + +/** + * cci_ccache_set_kdc_time_offset() + * + * Purpose: Sets the kdc time offset in the designated ccache + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_ccache_set_kdc_time_offset(cc_server_ccache_t* ccache, cc_time_t offset) +{ + if (ccache == NULL) + return ccErrInvalidCCache; + + ccache->kdc_offset = offset; + ccache->kdc_set = 1; + cci_ccache_changed(ccache); + + return ccNoError; +} + +/** + * cci_ccache_clear_kdc_time_offset() + * + * Purpose: Clear the kdc time offset in the designated ccache + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_ccache_clear_kdc_time_offset(cc_server_ccache_t* ccache) +{ + if (ccache == NULL) + return ccErrInvalidCCache; + + ccache->kdc_offset = 0; + ccache->kdc_set = 0; + cci_ccache_changed(ccache); + + return ccNoError; +} + +/** + * cci_ccache_new_iterator() + * + * Purpose: Retrieve an iterator for the designated cache + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrBadParam, ccBadNoMem + */ +cc_int32 +cci_ccache_new_iterator(cc_server_ccache_t* ccache, cc_credentials_iterate_t** iterator) +{ + cc_int32 code; + + if (ccache == NULL) + return ccErrInvalidCCache; + + if (iterator == NULL) + return ccErrBadParam; + + code = cci_credentials_list_iterator(ccache->creds, iterator); + if (code != ccNoError) + return code; + + code = cci_generic_list_prepend(ccache->active_iterators, *iterator, sizeof(cc_credentials_iterate_t), NULL); + if (code != ccNoError) + return code; + + return ccNoError; +} + +/** + * cci_ccache_get_principal() + * + * Purpose: Retrieves the client principal associated with the designated cache. + * The value is returned + * Return: + * + * Errors: + */ +cc_int32 +cci_ccache_get_principal(cc_server_ccache_t* ccache, cc_int32 version, char ** principal) +{ + char *p = NULL; + + switch ( version ) { + case cc_credentials_v4: + p = ccache->principal_v4; + break; + case cc_credentials_v5: + p = ccache->principal_v5; + break; + default: + return ccErrBadCredentialsVersion; + } + + *principal = (char *)malloc(strlen(p)+1); + if ( *principal == NULL ) + return ccErrNoMem; + + strcpy(*principal, p); + return ccNoError; +} + +/** + * Purpose: Releases the memory associated with a ccache principal + * + * Return: + * + * Errors: + * + */ +cc_int32 +cci_ccache_free_principal(char * principal) +{ + if ( principal == NULL ) + return ccErrBadParam; + + free(principal); + return ccNoError; +} + +/** + * ccache_set_principal() + * + * Purpose: Assigns a principal to the designated ccache and credential version. + * If the api version is 2, the cache is cleared of all existing + * credentials. + * + * Return: 0 on success + * -1 on error + * + * Errors: ccErrNoMem, ccErrBadCredentialsVersion + */ +cc_int32 +cci_ccache_set_principal( cc_server_ccache_t* ccache, cc_int32 cred_version, + char* principal) +{ + cc_generic_iterate_t* generic_iterator; + cc_generic_list_node_t* generic_node; + cc_ccache_iterate_t* ccache_iterator; + cc_int32 code = ccNoError; + + if (ccache == NULL) + return ccErrInvalidCCache; + + if (principal == NULL) + return ccErrInvalidString; + + switch (cred_version) { + case cc_credentials_v4: + case cc_credentials_v4_v5: + ccache->principal_v4 = (char *)malloc(strlen(principal) + 1); + if (ccache->principal_v4 == NULL) + return ccErrNoMem; + strcpy(ccache->principal_v4, principal); + if (cred_version != cc_credentials_v4_v5) + break; + /* fall-through if we are v4_v5 */ + case cc_credentials_v5: + ccache->principal_v5 = (char *)malloc(strlen(principal) + 1); + if (ccache->principal_v5 == NULL) { + if (cred_version == cc_credentials_v4_v5) { + free(ccache->principal_v4); + ccache->principal_v4 = NULL; + } + return ccErrNoMem; + } + strcpy(ccache->principal_v5, principal); + break; + default: + return ccErrBadCredentialsVersion; + } + + /*For API version 2 clients set_principal implies a flush of all creds*/ + if (ccache->mycontext != NULL && ccache->mycontext->api_version == ccapi_version_2) { + cci_credentials_list_destroy(ccache->creds); + cci_credentials_list_new(&ccache->creds); + + /*clean up active_iterators*/ + code = cci_generic_list_iterator(ccache->active_iterators, &generic_iterator); + if (code == ccNoError) { + while (cci_generic_iterate_has_next(generic_iterator)) { + code = cci_generic_iterate_next(generic_iterator, &generic_node); + ccache_iterator = (cc_ccache_iterate_t*)generic_node->data; + ccache_iterator->next = NULL; + } + } + } + + cci_ccache_changed(ccache); + + return code; +} + +/** + * cci_ccache_destroy() + * + * Purpose: Destroys an existing ccache + * + * Return: 0 on success + * -1 on errors + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_ccache_destroy(cc_server_ccache_t* ccache) +{ + cc_int32 code; + + if ( ccache == NULL ) + return ccErrInvalidCCache; + + code = cci_generic_list_destroy(ccache->active_iterators); + code = cci_credentials_list_destroy(ccache->creds); + + if (ccache->mycontext != NULL) + code = cci_context_rem_ccache(ccache->mycontext, ccache); + + return code; +} + +/** + * cci_ccache_compare() + * + * Purpose: Returns a boolean value indicating if two caches are identical + * Implemented as pointer equivalence. + * + * Return: 1 if TRUE + * 0 if FALSE + * + * Errors: No errors + */ +cc_int32 +cci_ccache_compare(cc_server_ccache_t* ccache1, cc_server_ccache_t* ccache2, cc_uint32 *result) +{ + if ( ccache1 == NULL || ccache2 == NULL ) + return ccErrInvalidCCache; + + if (ccache1 == ccache2) + *result = 1; + else + *result = 0; + + return ccNoError; +} + diff --git a/src/lib/ccapi/server/context.c b/src/lib/ccapi/server/context.c new file mode 100644 index 000000000..f405a4def --- /dev/null +++ b/src/lib/ccapi/server/context.c @@ -0,0 +1,325 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Functions to manipulate datastore layer contexts. + * + */ + +#include +#include +#include +#include + +#include "CredentialsCache.h" +#include "datastore.h" + +int cc_myversion = 5; +char cc_vendor[] = "MIT C lang CCache V5"; +char cc_default_ccache_name[] = "krb5cc"; + + +cc_int32 +cci_context_new( int api_version, cc_auth_info_t* auth_info, + cc_session_info_t* session_info, cc_server_context_t** outContextpp ) +{ + cc_server_context_t* ctx; + + if ( outContextpp == NULL ) + return ccErrBadParam; + + ctx = (cc_server_context_t*)malloc(sizeof(cc_server_context_t)); + if (ctx == NULL) + return ccErrNoMem; + + cci_ccache_list_new(&ctx->ccaches); + cci_generic_list_new(&ctx->active_iterators); + ctx->api_version = api_version; + ctx->auth_info = auth_info; + ctx->session_info = session_info; + ctx->changed = time(NULL); + + *outContextpp = ctx; + return ccNoError; +} + +cc_int32 +cci_context_get_default_ccache_name(cc_server_context_t* ctx, char ** outNamepp) +{ + cc_server_ccache_t* default_ccache; + + if (outNamepp == NULL) + return ccErrBadParam; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (ctx->ccaches->head != NULL) { + default_ccache = (cc_server_ccache_t*)ctx->ccaches->head->data; + *outNamepp = default_ccache->name; + } else { + *outNamepp = cc_default_ccache_name; + } + return ccNoError; +} + + +cc_int32 +cci_context_find_ccache( cc_server_context_t* ctx, char *name, + cc_server_ccache_t** outCcachepp ) +{ + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_server_ccache_t* ccache; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (name == NULL) + return ccErrInvalidString; + + if (outCcachepp == NULL) + return ccErrBadParam; + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + ccache = (cc_server_ccache_t *)ccache_node->data; + if (strcmp(ccache->name, name) == 0) { + free(ccache_iterator); + *outCcachepp = ccache; + return ccNoError; + } + } + free(ccache_iterator); + return ccErrCCacheNotFound; +} + +cc_int32 +cci_context_open_ccache( cc_server_context_t* ctx, char *name, + cc_server_ccache_t** outCcachepp ) +{ + return cci_context_find_ccache(ctx, name, outCcachepp); +} + + +cc_int32 +cci_context_create_ccache( cc_server_context_t* ctx, char *name, int creds_version, + char *principal, cc_server_ccache_t** outCcachepp ) +{ + cc_server_ccache_t* ccache; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (outCcachepp == NULL) + return ccErrBadParam; + + if (name == NULL || principal == NULL) + return ccErrInvalidString; + + if (creds_version != cc_credentials_v4 && creds_version != cc_credentials_v5 && + creds_version != cc_credentials_v4_v5) + return ccErrBadCredentialsVersion; + + code = cci_context_find_ccache(ctx, name, &ccache); + if (code == ccNoError) { + code = cci_ccache_set_principal(ccache, creds_version, principal); + } else { + code = cci_ccache_new(name, principal, creds_version, &ccache); + if (code != ccNoError) + return code; /*let caller deal with error*/ + + ccache->mycontext = ctx; + ctx->changed = time(NULL); + cci_ccache_list_append(ctx->ccaches, ccache, NULL); + + if (ctx->ccaches->head->data == (cc_uint8 *)ccache) { + ccache->is_default = 1; + } + } + *outCcachepp = ccache; + return ccNoError; +} + +cc_int32 +cci_context_create_default_ccache( cc_server_context_t* ctx, int creds_version, + char *principal, cc_server_ccache_t** outCcachepp ) +{ + cc_server_ccache_t* ccache, *old_default; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (outCcachepp == NULL) + return ccErrBadParam; + + if (principal == NULL) + return ccErrInvalidString; + + if (creds_version != cc_credentials_v4 && creds_version != cc_credentials_v5 && + creds_version != cc_credentials_v4_v5) + return ccErrBadCredentialsVersion; + + code = cci_context_find_ccache(ctx, cc_default_ccache_name, &ccache); + if (code == ccNoError) { + cci_ccache_set_principal(ccache, creds_version, principal); + } else { + code = cci_ccache_new(cc_default_ccache_name, principal, creds_version, &ccache); + if (code != ccNoError) + return code; /*let caller deal with error*/ + + ccache->mycontext = ctx; + ccache->is_default = 1; + ctx->changed = time(NULL); + + if (ctx->ccaches->head != NULL) { + old_default = (cc_server_ccache_t *)ctx->ccaches->head->data; + old_default->is_default = 0; + old_default->last_default = time(NULL); + } + + cci_ccache_list_prepend(ctx->ccaches, ccache, NULL); + } + *outCcachepp = ccache; + return ccNoError; +} + +cc_int32 +cci_context_ccache_iterator(cc_server_context_t* ctx, cc_ccache_iterate_t** iterpp) +{ + cc_ccache_iterate_t* ccache_iterator; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (iterpp == NULL) + return ccErrBadParam; + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + if (code != ccNoError) + return code; + cci_generic_list_prepend(ctx->active_iterators, ccache_iterator, sizeof(cc_ccache_iterate_t), NULL); + + *iterpp = ccache_iterator; + return ccNoError; +} + +cc_int32 +cci_context_compare(cc_server_context_t* a, cc_server_context_t* b) +{ + if (a == b) + return 1; + else + return 0; +} + +cc_int32 +cci_context_destroy(cc_server_context_t* ctx) +{ + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_server_ccache_t* ccache; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + cci_generic_list_destroy(ctx->active_iterators); + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + ccache = (cc_server_ccache_t *)ccache_node->data; + ccache_node->data = NULL; + cci_ccache_destroy(ccache); + } + cci_ccache_list_destroy(ctx->ccaches); + + return ccNoError; +} + +cc_int32 +cci_context_rem_ccache(cc_server_context_t* ctx, cc_server_ccache_t* ccache) +{ + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_iterate_t* active_ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_server_ccache_t* list_ccache; + cc_generic_list_node_t* gen_node; + cc_generic_iterate_t* gen_iterator; + cc_int32 code; + + if (ctx == NULL) + return ccErrInvalidContext; + + if (ccache == NULL) + return ccErrInvalidCCache; + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + list_ccache = (cc_server_ccache_t *)ccache_node->data; + + if (list_ccache == ccache) { + code = cci_generic_list_iterator(ctx->active_iterators, &gen_iterator); + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + active_ccache_iterator = (cc_server_ccache_t *)gen_node->data; + if (active_ccache_iterator->next == ccache_node) { + active_ccache_iterator->next = active_ccache_iterator->next->next; + } + } + free(gen_iterator); + code = cci_ccache_list_remove_element(ctx->ccaches, ccache_node); + break; + } + } + free(ccache_iterator); + return ccNoError; +} + diff --git a/src/lib/ccapi/server/datastore.h b/src/lib/ccapi/server/datastore.h new file mode 100644 index 000000000..a92c60636 --- /dev/null +++ b/src/lib/ccapi/server/datastore.h @@ -0,0 +1,231 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ +/* + * Prototypes and data structures for datastore. + * + */ + + +#ifndef __CCDATASTOREH__ +#define __CCDATASTOREH__ + +#include "CredentialsCache.h" +#include "rpc_auth.h" + +enum cc_list_type { + generic = 0, + context, + cache, + credentials +}; + +struct cc_generic_list_node_t { + cc_uint8* data; + cc_uint32 len; + struct cc_generic_list_node_t* next; + struct cc_generic_list_node_t* prev; +}; +typedef struct cc_generic_list_node_t cc_generic_list_node_t; + +struct cc_generic_list_head_t { + enum cc_list_type type; + cc_generic_list_node_t* head; + cc_generic_list_node_t* tail; +}; +typedef struct cc_generic_list_head_t cc_generic_list_head_t; + + +struct cc_generic_iterate_t { + cc_generic_list_node_t* next; +}; +typedef struct cc_generic_iterate_t cc_generic_iterate_t; + +typedef cc_generic_list_head_t cc_context_list_head_t; +typedef cc_generic_list_node_t cc_context_list_node_t; + +typedef cc_generic_list_head_t cc_ccache_list_head_t; +typedef cc_generic_list_node_t cc_ccache_list_node_t; + +typedef cc_generic_list_head_t cc_credentials_list_head_t; +typedef cc_generic_list_node_t cc_credentials_list_node_t; + +struct cc_context_iterate_t { + cc_context_list_node_t* next; +}; +typedef struct cc_context_iterate_t cc_context_iterate_t; + +struct cc_ccache_iterate_t { + cc_ccache_list_node_t* next; +}; +typedef struct cc_ccache_iterate_t cc_ccache_iterate_t; + +struct cc_credentials_iterate_t { + cc_credentials_list_node_t* next; +}; +typedef struct cc_credentials_iterate_t cc_credentials_iterate_t; + +struct cc_lock_t { + cc_uint32 read_locks; /* count of read locks (>= 0) */ + cc_uint32 write_locks; /* count of write locks (0 or 1) */ + void * platform_data; /* platform specific implementation data */ +}; +typedef struct cc_lock cc_lock_t; + + +struct cc_server_context_t { + cc_ccache_list_head_t* ccaches; /*our ccaches*/ + cc_generic_list_head_t* active_iterators; /*active ccache iterators*/ + cc_int32 api_version; /*Version our client passed in on init (ccapi_version_X) */ + cc_auth_info_t* auth_info; /*auth info passed in from RPC*/ + cc_session_info_t* session_info; /*session info passed in from RPC*/ + cc_time_t changed; /*date of last change to this context*/ + cc_int32 error; /*last error code*/ + cc_lock_t locks; /*are we locked?*/ +}; +typedef struct cc_server_context_t cc_server_context_t; + +struct cc_server_ccache_t { + char* name; /*name of this ccache*/ + char* principal_v4; /*v4 principal associated with this cache*/ + char* principal_v5; /*v5 principal associated with this cache*/ + cc_uint32 versions; /*versions of creds supported (from cc_credentials enum in CredentialsCache.h)*/ + cc_time_t changed; /*date of last change to ccache*/ + cc_int32 kdc_set; /*is the KDC time offset initialized?*/ + cc_time_t kdc_offset; /*offset of our clock relative kdc*/ + cc_time_t last_default; /*the last date when we were default*/ + cc_int32 is_default; /*is this the default cred on this ccache?*/ + cc_generic_list_head_t* active_iterators; /*iterators which clients have opened on this cache*/ + cc_credentials_list_head_t* creds; /*list of creds stored in this ccache*/ + cc_server_context_t* mycontext; /*context to which I belong*/ + cc_lock_t locks; /*are we locked?*/ +}; +typedef struct cc_server_ccache_t cc_server_ccache_t; + +struct cc_server_credentials_t { + cc_int32 is_default; /*Are we the default cred? (first in list)*/ + cc_credentials_union creds; +}; +typedef struct cc_server_credentials_t cc_server_credentials_t; + + +/*Note: cci means Credential Cache Internal, to differentiate from exported API macros*/ + +cc_int32 cci_generic_iterate_has_next(cc_generic_iterate_t *iterate); +cc_int32 cci_generic_iterate_next(cc_generic_iterate_t *iterate, cc_generic_list_node_t**); + +cc_int32 cci_generic_list_new(cc_generic_list_head_t **); +cc_int32 cci_generic_list_append(cc_generic_list_head_t *head, void *data, cc_uint32 len, cc_generic_list_node_t**); +cc_int32 cci_generic_list_prepend(cc_generic_list_head_t *head, void *data, cc_uint32 len, cc_generic_list_node_t**); +cc_int32 cci_generic_list_remove_element(cc_generic_list_head_t* head, cc_generic_list_node_t* rem); +cc_int32 cci_generic_free_element(cc_generic_list_node_t* node); +cc_int32 cci_generic_list_destroy(cc_generic_list_head_t* head); +cc_int32 cci_generic_list_copy(cc_generic_list_head_t* head, cc_generic_list_head_t**); +cc_int32 cci_generic_list_iterator(cc_generic_list_head_t *head, cc_generic_iterate_t**); +cc_int32 cci_generic_free_iterator(cc_generic_iterate_t* iterator); + +cc_int32 cci_context_iterate_has_next(struct cc_context_iterate_t *iterate); +cc_int32 cci_context_iterate_next(struct cc_context_iterate_t *iterate, cc_context_list_node_t**); + +cc_int32 cci_ccache_iterate_has_next(struct cc_ccache_iterate_t *iterate); +cc_int32 cci_ccache_iterate_next(struct cc_ccache_iterate_t *iterate, cc_ccache_list_node_t**); + +cc_int32 cci_credentials_iterate_has_next(cc_credentials_iterate_t *iterate); +cc_int32 cci_credentials_iterate_next(cc_credentials_iterate_t *iterate, cc_credentials_list_node_t **); + +cc_int32 cci_context_list_new(cc_context_list_head_t**); +cc_int32 cci_context_list_append(cc_context_list_head_t *head, cc_server_context_t *data, cc_context_list_node_t**); +cc_int32 cci_context_list_prepend(cc_context_list_head_t *head, cc_server_context_t *data, cc_context_list_node_t**); +cc_int32 cci_context_list_remove_element(cc_context_list_head_t* head, cc_context_list_node_t* rem); +cc_int32 cci_context_list_iterator(cc_context_list_head_t *head, struct cc_context_iterate_t**); +cc_int32 cci_context_free_iterator(struct cc_context_iterate_t *iterator); +cc_int32 cci_context_list_destroy(cc_context_list_head_t* head) ; +cc_int32 cci_context_list_copy(cc_context_list_head_t* head, cc_context_list_head_t**); + +cc_int32 cci_ccache_list_new(cc_ccache_list_head_t**); +cc_int32 cci_ccache_list_append(cc_ccache_list_head_t *head, cc_server_ccache_t *data, cc_ccache_list_node_t**); +cc_int32 cci_ccache_list_prepend(cc_ccache_list_head_t *head, cc_server_ccache_t *data, cc_ccache_list_node_t**); +cc_int32 cci_ccache_list_remove_element(cc_ccache_list_head_t* head, cc_ccache_list_node_t* rem); +cc_int32 cci_ccache_list_iterator(cc_ccache_list_head_t *head, struct cc_ccache_iterate_t**); +cc_int32 cci_ccache_free_iterator(struct cc_ccache_iterate_t *iterator); +cc_int32 cci_ccache_list_destroy(cc_ccache_list_head_t* head) ; +cc_int32 cci_ccache_list_copy(cc_ccache_list_head_t* head, cc_ccache_list_head_t**); + + +cc_int32 cci_credentials_list_new(cc_credentials_list_head_t**); +cc_int32 cci_credentials_list_append(cc_credentials_list_head_t *head, cc_server_credentials_t *data, cc_credentials_list_node_t**); +cc_int32 cci_credentials_list_prepend(cc_credentials_list_head_t *head, cc_server_credentials_t *data, cc_credentials_list_node_t**); +cc_int32 cci_credentials_list_remove_element(cc_credentials_list_head_t* head, cc_credentials_list_node_t* rem); +cc_int32 cci_credentials_list_iterator(cc_credentials_list_head_t *head, cc_credentials_iterate_t**); +cc_int32 cci_credentials_free_iterator(cc_credentials_iterate_t* iterator); +cc_int32 cci_credentials_list_destroy(cc_credentials_list_head_t* head) ; +cc_int32 cci_credentials_list_copy(cc_credentials_list_head_t* head, cc_credentials_list_head_t**) ; + + +cc_int32 cci_context_new(int api_version, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_server_context_t** ) ; +cc_int32 cci_context_get_default_ccache_name(cc_server_context_t* ctx, char **); +cc_int32 cci_context_find_ccache(cc_server_context_t* ctx, char *name, cc_server_ccache_t**); +cc_int32 cci_context_open_ccache(cc_server_context_t* ctx, char *name, cc_server_ccache_t** ); +cc_int32 cci_context_create_ccache(cc_server_context_t* ctx, char *name, int creds_version, char *principal, cc_server_ccache_t**); +cc_int32 cci_context_create_default_ccache(cc_server_context_t* ctx, int creds_version, char *principal, cc_server_ccache_t**); +cc_int32 cci_context_ccache_iterator(cc_server_context_t* ctx, cc_ccache_iterate_t**); +cc_int32 cci_context_compare(cc_server_context_t* a, cc_server_context_t* b); +cc_int32 cci_context_destroy(cc_server_context_t* ctx); +cc_int32 cci_context_rem_ccache(cc_server_context_t* ctx, cc_server_ccache_t* ccache); + +cc_int32 cci_ccache_new(char *name, char *principal, int cred_vers, cc_server_ccache_t**); +cc_int32 cci_ccache_check_version(const cc_server_ccache_t *ccache, const cc_credentials_union* creds, cc_uint32* compat); +cc_int32 cci_ccache_check_principal(const cc_server_ccache_t *ccache, const cc_credentials_union* creds, cc_uint32* compat); +cc_int32 cci_ccache_store_creds(cc_server_ccache_t *ccache, const cc_credentials_union* credentials); +cc_int32 cci_ccache_rem_creds(cc_server_ccache_t *ccache, const cc_credentials_union* credentials); +cc_int32 cci_ccache_move(cc_server_ccache_t *source, cc_server_ccache_t* destination); +cc_int32 cci_ccache_get_kdc_time_offset(cc_server_ccache_t* ccache, cc_time_t* offset); +cc_int32 cci_ccache_set_kdc_time_offset(cc_server_ccache_t* ccache, cc_time_t offset); +cc_int32 cci_ccache_clear_kdc_time_offset(cc_server_ccache_t* ccache); +cc_int32 cci_ccache_new_iterator(cc_server_ccache_t* ccache, cc_credentials_iterate_t** iterator); +cc_int32 cci_ccache_get_principal(cc_server_ccache_t* ccache, cc_int32 version, char ** principal); +cc_int32 cci_ccache_set_principal(cc_server_ccache_t* ccache, cc_int32 version, char * principal); +cc_int32 cci_ccache_free_principal(char * principal); +cc_int32 cci_ccache_destroy(cc_server_ccache_t* ccache); +void cci_ccache_changed(cc_server_ccache_t* ccache); +cc_int32 cci_ccache_compare(cc_server_ccache_t* ccache1, cc_server_ccache_t* ccache2, cc_uint32 *result); +#endif /*__CCDATASTOREH__*/ diff --git a/src/lib/ccapi/server/lists.c b/src/lib/ccapi/server/lists.c new file mode 100644 index 000000000..882ecb7a0 --- /dev/null +++ b/src/lib/ccapi/server/lists.c @@ -0,0 +1,996 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + + +/* + * Lists implementation. + * + */ + +#include +#include +#include + +#include "CredentialsCache.h" +#include "datastore.h" + +/** + * cci_generic_iterate_has_next() + * + * Purpose: Determine if an iterator has a next element + * + * Return: 1 if another element exists + * 0 if no additional elements exist + * + * Errors: None + * + */ +cc_int32 +cci_generic_iterate_has_next(cc_generic_iterate_t *iterate) +{ + return ((iterate == NULL || iterate->next == NULL) ? 0 : 1); +} + +/** + * cci_generic_iterate_next() + * + * Purpose: Retrieve the next element from an iterator and advance + * the iterator + * + * Return: non-NULL, the next element in the iterator + * NULL, the iterator list is empty or iterator is invalid + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_generic_iterate_next(cc_generic_iterate_t *iterator, cc_generic_list_node_t** nodepp) +{ + cc_generic_list_node_t* ret; + + if (iterator == NULL || nodepp == NULL) + return ccErrBadParam; + + ret = iterator->next; + if (iterator->next != NULL) + iterator->next = iterator->next->next; + + *nodepp = ret; + return ccNoError; +} + +/** + * cci_context_iterate_has_next() + * + * Purpose: Determine if a context iterator has a next element + * + * Return: 1 if another element exists + * 0 if no additional elements exist + */ +cc_int32 +cci_context_iterate_has_next(cc_context_iterate_t *iterate) +{ + if ( iterate == NULL ) + return 0; + + return cci_generic_iterate_has_next((cc_generic_iterate_t*)iterate); +} + +/** + * cci_context_iterate_next() + * + * Purpose: Retrieve the next element from a context iterator and advance + * the iterator + * + * Return: non-NULL, the next element in the iterator + * NULL, the iterator list is empty or iterator is invalid + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_context_iterate_next(cc_context_iterate_t *iterate, cc_context_list_node_t ** nodepp) +{ + if ( iterate == NULL || nodepp == NULL) + return ccErrBadParam; + + return cci_generic_iterate_next((cc_generic_iterate_t*)iterate,(cc_context_list_node_t**)nodepp); +} + +/** + * cci_ccache_iterate_has_next() + * + * Purpose: Determine if a cache iterator has a next element + * + * Return: 1 if another element exists + * 0 if no additional elements exist + * -1 if error + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_ccache_iterate_has_next(cc_ccache_iterate_t *iterate) +{ + if ( iterate == NULL ) + return 0; + return cci_generic_iterate_has_next((cc_generic_iterate_t*)iterate); +} + +/** + * cci_ccache_iterate_next() + * + * Purpose: Retrieve the next element from a ccache iterator and advance + * the iterator + * + * Return: non-NULL, the next element in the iterator + * NULL, the iterator list is empty or iterator is invalid + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_ccache_iterate_next(cc_ccache_iterate_t *iterate, cc_ccache_list_node_t ** nodepp) +{ + if ( iterate == NULL || nodepp == NULL) + return ccErrBadParam; + + return cci_generic_iterate_next((cc_generic_iterate_t*)iterate, (cc_ccache_list_node_t**)nodepp); +} + +/** + * cci_credentials_iterate_has_next() + * + * Purpose: Determine if a credentials iterator has a next element + * + * Return: 1 if another element exists + * 0 if no additional elements exist + * -1 if error + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_credentials_iterate_has_next(cc_credentials_iterate_t *iterate) +{ + if ( iterate == NULL ) + return 0; + + return cci_generic_iterate_has_next((cc_generic_iterate_t*)iterate); +} + +/** + * cci_credentials_iterate_next() + * + * Purpose: Retrieve the next element from a credentials iterator and advance + * the iterator + * + * Return: non-NULL, the next element in the iterator + * NULL, the iterator list is empty or iterator is invalid + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_credentials_iterate_next(cc_credentials_iterate_t *iterate, cc_credentials_list_node_t** nodepp) +{ + if ( iterate == NULL || nodepp == NULL ) + return ccErrBadParam; + return cci_generic_iterate_next((cc_generic_iterate_t*)iterate, (cc_credentials_list_node_t**)nodepp); +} + +/** + * cci_generic_list_new() + * + * Purpose: Allocate new generic list + * + * Return: non-NULL, an empty list + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_generic_list_new(cc_generic_list_head_t ** listpp) +{ + cc_generic_list_head_t* ret = (cc_generic_list_head_t *)malloc(sizeof(cc_generic_list_head_t)); + if (ret == NULL) + return ccErrNoMem; + + ret->type = generic; + ret->head = ret->tail = NULL; + *listpp = ret; + + return ccNoError; +} + +/** + * cci_generic_list_append() + * + * Purpose: Appends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_generic_list_append(cc_generic_list_head_t *head, void *data, cc_uint32 len, cc_generic_list_node_t** nodepp) +{ + cc_generic_list_node_t* new_node; + + if ( data == NULL || len == 0 ) + return ccErrBadParam; + + new_node = (cc_generic_list_node_t *)malloc(sizeof(cc_generic_list_node_t)); + if (new_node == NULL) + return ccErrNoMem; + + new_node->data = malloc(len); + if ( new_node->data == NULL ) { + free(new_node); + return ccErrNoMem; + } + + memcpy(new_node->data,data,len); + new_node->len = len; + + if (head->head == NULL) { /*empty list*/ + head->head = new_node; + head->tail = new_node; + new_node->next = new_node->prev = NULL; + } else { + new_node->prev = head->tail; + head->tail->next = new_node; + head->tail = new_node; + new_node->next = NULL; + } + if (nodepp != NULL) + *nodepp = new_node; + return ccNoError; +} + +/** + * cci_generic_list_prepend() + * + * Purpose: Prepends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem, ccErrBadParam + * + */ +cc_int32 +cci_generic_list_prepend(cc_generic_list_head_t *head, void *data, cc_uint32 len, cc_generic_list_node_t** nodepp) +{ + cc_generic_list_node_t* new_node; + + if ( data == NULL || len == 0 ) + return ccErrBadParam; + + new_node = (cc_generic_list_node_t *)malloc(sizeof(cc_generic_list_node_t)); + if (new_node == NULL) + return ccErrNoMem; + + new_node->data = malloc(len); + if ( new_node->data == NULL ) { + free(new_node); + return ccErrNoMem; + } + + memcpy(new_node->data,data,len); + new_node->len = len; + + if (head->head == NULL) { /*empty list*/ + head->head = new_node; + head->tail = new_node; + new_node->prev = new_node->next = NULL; + } else { + new_node->next = head->head; + head->head->prev = new_node; + new_node->prev = NULL; + head->head = new_node; + } + + if (nodepp != NULL) + *nodepp = new_node; + + return ccNoError; +} + +/** + * cci_generic_list_remove_element() + * + * Purpose: Remove a node from the list + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_generic_list_remove_element(cc_generic_list_head_t* head, cc_generic_list_node_t* rem) +{ + if (head->head == NULL || rem == NULL) + return ccErrBadParam; + + if (head->head == rem && head->tail == rem) { /*removing only element of list*/ + head->head = head->tail = NULL; + } else if (head->head == rem) { /*removing head*/ + head->head = head->head->next; + } else if (head->tail == rem) { /*removing tail*/ + head->tail = head->tail->prev; + head->tail->next = NULL; + } else { + rem->prev->next = rem->next; + rem->next->prev = rem->prev; + } + free(rem); + return ccNoError; +} + +/** + * cci_generic_free_element() + * + * Purpose: Free the memory associated with a node + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_generic_free_element(cc_generic_list_node_t* node) +{ + if ( node == NULL ) + return ccErrBadParam; + + if ( node->data ) { + free(node->data); + node->data = NULL; + } + node->len = 0; + node->next = node->prev = NULL; + free(node); + return ccNoError; +} + + +/** + * cci_generic_list_destroy() + * + * Purpose: Deallocate a list and all of its contents + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_generic_list_destroy(cc_generic_list_head_t* head) +{ + cc_generic_list_node_t *cur, *next; + cc_int32 ret = ccNoError; + + if ( head == NULL ) + return ccErrBadParam; + + for (cur = head->head; ret == ccNoError && cur != NULL; cur = next) { + next = cur->next; + ret = cci_generic_free_element(cur); + } + free(head); + return(ret); +} + +/** + * cci_context_list_destroy() + * + * Purpose: Deallocate a list and all of its contents + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_context_list_destroy(cc_context_list_head_t* head) +{ + return cci_generic_list_destroy((cc_generic_list_head_t*)head); +} + +/** + * cci_ccache_list_destroy() + * + * Purpose: Deallocate a list and all of its contents + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_ccache_list_destroy(cc_ccache_list_head_t* head) +{ + return cci_generic_list_destroy((cc_generic_list_head_t*)head); +} + +/** + * cci_credentials_list_destroy() + * + * Purpose: Deallocate a list and all of its contents + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_credentials_list_destroy(cc_credentials_list_head_t* head) +{ + return cci_generic_list_destroy((cc_generic_list_head_t*)head); +} + +/** + * cci_generic_list_copy() + * + * Purpose: Copy a list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrBadParam, ccErrNoMem + * + */ +cc_int32 +cci_generic_list_copy(cc_generic_list_head_t* head, cc_generic_list_head_t** headpp) +{ + cc_generic_list_head_t* copy; + cc_generic_list_node_t *src_node, *dst_node; + cc_int32 code; + + if (head == NULL || headpp == NULL) + return ccErrBadParam; + + code = cci_generic_list_new(©); + if (code != ccNoError) + return code; + + for (src_node = head->head; src_node != NULL; src_node = src_node->next) { + code = cci_generic_list_append(copy, src_node->data, src_node->len, &dst_node); + if (code != ccNoError) { + cci_generic_list_destroy(copy); + return code; + } + } + *headpp = copy; + return ccNoError; +} + +/** + * cci_context_list_copy() + * + * Purpose: Copy a list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrBadParam, ccErrNoMem + * + */ +cc_int32 +cci_context_list_copy(cc_context_list_head_t* head, cc_context_list_head_t** headpp ) +{ + return cci_generic_list_copy((cc_generic_list_head_t*)head, (cc_context_list_head_t **)headpp); +} + +/** + * cci_ccache_list_copy() + * + * Purpose: Copy a list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrBadParam, ccErrNoMem + */ +cc_int32 +cci_ccache_list_copy(cc_ccache_list_head_t* head, cc_ccache_list_head_t** headpp) +{ + return cci_generic_list_copy((cc_generic_list_head_t*)head, (cc_ccache_list_head_t **)headpp); +} + +/** + * cci_credentials_list_copy() + * + * Purpose: Copy a list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrBadParam, ccErrNoMem + * + */ +cc_int32 +cci_credentials_list_copy(cc_credentials_list_head_t* head, cc_credentials_list_head_t** headpp) +{ + return cci_generic_list_copy((cc_generic_list_head_t*)head, (cc_credentials_list_head_t **)headpp); +} + + +/** + * cci_generic_list_iterator() + * + * Purpose: Allocate an iterator for the specified list + * + * Return: non-NULL, an iterator + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_generic_list_iterator(cc_generic_list_head_t *head, cc_generic_iterate_t** headpp) +{ + cc_generic_iterate_t* iterator; + + if ( head == NULL || headpp == NULL ) + return ccErrBadParam; + + iterator = (cc_generic_iterate_t*)malloc(sizeof(cc_generic_iterate_t)); + if (iterator == NULL) + return ccErrNoMem; + + iterator->next = head->head; + *headpp = iterator; + return ccNoError; +} + +/** + * cci_generic_free_iterator() + * + * Purpose: Deallocate memory associated with an iterator + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_generic_free_iterator(cc_generic_iterate_t* iterator) +{ + if ( iterator == NULL ) + return ccErrBadParam; + + iterator->next = NULL; + free(iterator); + return ccNoError; +} + + +/** + * cci_context_list_new() + * + * Purpose: Allocate a new context list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_context_list_new(cc_context_list_head_t ** headpp) +{ + cc_context_list_head_t *ret; + + if ( headpp == NULL ) + return ccErrBadParam; + + ret = (cc_context_list_head_t *)malloc(sizeof(cc_context_list_head_t)); + if (ret == NULL) + return ccErrNoMem; + ret->head = ret->tail = NULL; + *headpp = ret; + return ccNoError; +} + +/** + * cci_context_list_append() + * + * Purpose: Appends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_context_list_append(cc_context_list_head_t *head, cc_server_context_t *data, cc_context_list_node_t** nodepp) +{ + return cci_generic_list_append((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_context_t), (cc_context_list_node_t**)nodepp); +} + +/** + * cci_context_list_prepend() + * + * Purpose: Prepends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_context_list_prepend(cc_context_list_head_t *head, cc_server_context_t *data, cc_context_list_node_t** nodepp ) +{ + return cci_generic_list_prepend((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_context_t), (cc_context_list_node_t**)nodepp); +} + +/** + * cci_context_list_remove_element + * + * Purpose: Remove a node from the list + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + */ +cc_int32 +cci_context_list_remove_element(cc_context_list_head_t* head, cc_context_list_node_t* rem) +{ + return cci_generic_list_remove_element((cc_generic_list_head_t*)head, (cc_generic_list_node_t*)rem); +} + +/** + * cci_context_list_iterator() + * + * Purpose: Allocate an iterator for the specified list + * + * Return: non-NULL, an iterator + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_context_list_iterator(cc_context_list_head_t *head, cc_context_iterate_t** iterpp) +{ + cc_context_iterate_t* iterator; + + if ( head == NULL || iterpp == NULL ) + return ccErrBadParam; + + iterator = (cc_context_iterate_t*)malloc(sizeof(cc_context_iterate_t)); + if (iterator == NULL) + return ccErrNoMem; + + iterator->next = head->head; + *iterpp = iterator; + return ccNoError; +} + +/** + * cci_context_free_iterator() + * + * Purpose: Deallocate memory associated with an iterator + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_context_free_iterator(cc_context_iterate_t* iterator) +{ + if ( iterator == NULL ) + return ccErrBadParam; + + iterator->next = NULL; + free(iterator); + return ccNoError; +} + +/** + * cci_ccache_list_new() + * + * Purpose: Allocate a new ccache list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrNoMem + */ +cc_int32 +cci_ccache_list_new(cc_ccache_list_head_t ** listpp) +{ + cc_ccache_list_head_t *ret; + + if ( listpp == NULL ) + return ccErrBadParam; + + ret = (cc_ccache_list_head_t *)malloc(sizeof(cc_ccache_list_head_t)); + if (ret == NULL) + return ccErrNoMem; + + ret->head = ret->tail = NULL; + *listpp = ret; + return ccNoError; +} + +/** + * cci_ccache_list_append() + * + * Purpose: Appends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_ccache_list_append(cc_ccache_list_head_t *head, cc_server_ccache_t *data, cc_ccache_list_node_t** nodepp) +{ + return cci_generic_list_append((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_ccache_t), (cc_ccache_list_node_t**)nodepp); +} + +/** + * cci_ccache_list_prepend() + * + * Purpose: Prepends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_ccache_list_prepend(cc_ccache_list_head_t *head, cc_server_ccache_t *data, cc_ccache_list_node_t** nodepp) +{ + return cci_generic_list_prepend((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_ccache_t), (cc_ccache_list_node_t**)nodepp); +} + +/** + * cci_ccache_list_remove_element() + * + * Purpose: Remove a node from the list + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_ccache_list_remove_element(cc_ccache_list_head_t* head, cc_ccache_list_node_t* rem) +{ + return cci_generic_list_remove_element((cc_generic_list_head_t*)head, (cc_generic_list_node_t*)rem); +} + +/** + * cci_ccache_list_iterator() + * + * Purpose: Allocate an iterator for the specified list + * + * Return: non-NULL, an iterator + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_ccache_list_iterator(cc_ccache_list_head_t *head, cc_ccache_iterate_t** iterpp) +{ + cc_ccache_iterate_t* iterator; + + if ( head == NULL || iterpp == NULL ) + return ccErrBadParam; + + iterator = (cc_ccache_iterate_t*)malloc(sizeof(cc_ccache_iterate_t)); + if (iterator == NULL) + return ccErrNoMem; + + iterator->next = head->head; + *iterpp = iterator; + return ccNoError; +} + +/** + * cci_ccache_free_iterator() + * + * Purpose: Deallocate memory associated with an iterator + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_ccache_free_iterator(cc_ccache_iterate_t* iterator) +{ + if ( iterator == NULL ) + return ccErrBadParam; + + iterator->next = NULL; + free(iterator); + return ccNoError; +} + +/** + * cci_credentials_list_new() + * + * Purpose: Allocate a new ccache list + * + * Return: non-NULL, a new list + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_credentials_list_new(cc_credentials_list_head_t ** list) +{ + if ( list == NULL ) + return ccErrBadParam; + + *list = (cc_credentials_list_head_t *)malloc(sizeof(cc_credentials_list_head_t)); + if (*list == NULL) + return ccErrNoMem; + + (*list)->head = (*list)->tail = NULL; + return ccNoError; +} + +/** + * cci_credentials_list_append() + * + * Purpose: Appends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_credentials_list_append(cc_credentials_list_head_t *head, cc_server_credentials_t *data, cc_credentials_list_node_t** nodepp ) +{ + return cci_generic_list_append((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_credentials_t), (cc_credentials_list_node_t**)nodepp); +} + +/** + * cci_credentials_list_prepend() + * + * Purpose: Prepends a new node containing a copy of 'len' bytes of 'data' + * + * Return: non-NULL, a pointer to the newly allocated node + * NULL, failure + * + * Errors: ccErrNoMem,ccErrBadParam + * + */ +cc_int32 +cci_credentials_list_prepend(cc_credentials_list_head_t *head, cc_server_credentials_t *data, cc_credentials_list_node_t** nodepp) +{ + return cci_generic_list_prepend((cc_generic_list_head_t *)head, (void *)data, sizeof(cc_server_credentials_t), (cc_credentials_list_node_t**)nodepp); +} + +/** + * cci_credentials_list_remove_element() + * + * Purpose: Remove a node from the list + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_credentials_list_remove_element(cc_credentials_list_head_t* head, cc_credentials_list_node_t* rem) +{ + return cci_generic_list_remove_element((cc_generic_list_head_t*)head, (cc_generic_list_node_t*)rem); +} + +/** + * cci_credentials_list_iterator() + * + * Purpose: Allocate an iterator for the specified list + * + * Return: non-NULL, an iterator + * NULL, failure + * + * Errors: ccErrNoMem + * + */ +cc_int32 +cci_credentials_list_iterator(cc_credentials_list_head_t *head, cc_credentials_iterate_t** iterpp) +{ + cc_credentials_iterate_t* iterator; + + if ( head == NULL || iterpp == NULL ) + return ccErrBadParam; + + iterator = (cc_credentials_iterate_t*)malloc(sizeof(cc_credentials_iterate_t)); + if (iterator == NULL) + return ccErrNoMem; + + iterator->next = head->head; + *iterpp = iterator; + return ccNoError; +} + +/** + * cci_credentials_free_iterator() + * + * Purpose: Deallocate memory associated with an iterator + * + * Return: 0, success + * -1, failure + * + * Errors: ccErrBadParam + * + */ +cc_int32 +cci_credentials_free_iterator(cc_credentials_iterate_t* iterator) +{ + if ( iterator == NULL ) + return ccErrBadParam; + + iterator->next = NULL; + free(iterator); + return ccNoError; +} + diff --git a/src/lib/ccapi/server/mac/ChangeLog b/src/lib/ccapi/server/mac/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/server/mac/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/server/rpc_auth.c b/src/lib/ccapi/server/rpc_auth.c new file mode 100644 index 000000000..dd338e010 --- /dev/null +++ b/src/lib/ccapi/server/rpc_auth.c @@ -0,0 +1,63 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Stubs for rpc_auth. + */ + +#include "CredentialsCache.h" +#include "rpc_auth.h" + +cc_int32 +cci_rpc_is_authorized( cc_auth_info_t* msg_auth, cc_session_info_t* msg_session, cc_auth_info_t* stored_auth, + cc_session_info_t* stored_session, cc_uint32 * authorizedp) +{ + if (msg_auth == stored_auth && msg_session == stored_session) + *authorizedp = 1; + else + *authorizedp = 0; + + return ccNoError; +} + + diff --git a/src/lib/ccapi/server/rpc_auth.h b/src/lib/ccapi/server/rpc_auth.h new file mode 100644 index 000000000..21d7db501 --- /dev/null +++ b/src/lib/ccapi/server/rpc_auth.h @@ -0,0 +1,71 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + + +/* + * Types for RPC auth + session info + * + */ + +#ifndef __RPC_AUTH_H__ +#define __RPC_AUTH_H__ + +#include "CredentialsCache.h" + +/*preliminary*/ +struct cc_auth_info_t { + cc_uint8 *info; + cc_uint32 len; +}; +typedef struct cc_auth_info_t cc_auth_info_t; + +/*preliminary*/ +struct cc_session_info_t { + cc_uint8 *info; + cc_uint32 len; +}; +typedef struct cc_session_info_t cc_session_info_t; + +cc_int32 cci_rpc_is_authorized(cc_auth_info_t* msg_auth, cc_session_info_t* msg_session, cc_auth_info_t* stored_auth, cc_session_info_t* stored_session, cc_uint32 *authorizedp); + +#endif /*__RPC_AUTH_H__*/ diff --git a/src/lib/ccapi/server/serv_ops.c b/src/lib/ccapi/server/serv_ops.c new file mode 100644 index 000000000..30a108a34 --- /dev/null +++ b/src/lib/ccapi/server/serv_ops.c @@ -0,0 +1,1500 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Server side implementation of each API function. + */ + +#include "CredentialsCache.h" +#include "serv_ops.h" +#include "datastore.h" +#include "rpc_auth.h" +#include "msg_headers.h" + +#include +#include + +cc_context_list_head_t* AllContexts = NULL; +type_to_op_mapping_t* TypeToOpMapping = NULL; + +extern int cc_err_code; +extern int cc_myversion; +extern char cc_vendor[]; + +cc_int32 +cci_serv_initialize(void) +{ + cc_int32 code; + + code = cci_context_list_new(&AllContexts); + if ( code != ccNoError ) + return code; + TypeToOpMapping = (type_to_op_mapping_t*)malloc(sizeof(type_to_op_mapping_t)); + if (TypeToOpMapping == NULL) { + cci_context_list_destroy(AllContexts); + return ccErrNoMem; + } + + TypeToOpMapping->operations[ccmsg_INIT] = ccop_INIT; + TypeToOpMapping->operations[ccmsg_CTX_RELEASE] = ccop_CTX_RELEASE; + TypeToOpMapping->operations[ccmsg_CTX_GET_CHANGE_TIME] = ccop_CTX_GET_CHANGE_TIME; + TypeToOpMapping->operations[ccmsg_CTX_GET_DEFAULT_CCACHE_NAME] = ccop_CTX_GET_DEFAULT_CCACHE_NAME; + TypeToOpMapping->operations[ccmsg_CTX_COMPARE] = ccop_CTX_COMPARE; + TypeToOpMapping->operations[ccmsg_CTX_NEW_CCACHE_ITERATOR] = ccop_CTX_NEW_CCACHE_ITERATOR; + TypeToOpMapping->operations[ccmsg_CTX_LOCK] = ccop_CTX_LOCK; + TypeToOpMapping->operations[ccmsg_CTX_UNLOCK] = ccop_CTX_UNLOCK; + TypeToOpMapping->operations[ccmsg_CTX_CLONE] = ccop_CTX_CLONE; + TypeToOpMapping->operations[ccmsg_CCACHE_OPEN] = ccop_CCACHE_OPEN; + TypeToOpMapping->operations[ccmsg_CCACHE_OPEN_DEFAULT] = ccop_CCACHE_OPEN_DEFAULT; + TypeToOpMapping->operations[ccmsg_CCACHE_CREATE] = ccop_CCACHE_CREATE; + TypeToOpMapping->operations[ccmsg_CCACHE_CREATE_DEFAULT] = ccop_CCACHE_CREATE_DEFAULT; + TypeToOpMapping->operations[ccmsg_CCACHE_CREATE_UNIQUE] = ccop_CCACHE_CREATE_UNIQUE; + TypeToOpMapping->operations[ccmsg_CCACHE_RELEASE] = ccop_CCACHE_RELEASE; + TypeToOpMapping->operations[ccmsg_CCACHE_DESTROY] = ccop_CCACHE_DESTROY; + TypeToOpMapping->operations[ccmsg_CCACHE_SET_DEFAULT] = ccop_CCACHE_SET_DEFAULT; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_CREDS_VERSION] = ccop_CCACHE_GET_CREDS_VERSION; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_NAME] = ccop_CCACHE_GET_NAME; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_PRINCIPAL] = ccop_CCACHE_GET_PRINCIPAL; + TypeToOpMapping->operations[ccmsg_CCACHE_SET_PRINCIPAL] = ccop_CCACHE_SET_PRINCIPAL; + TypeToOpMapping->operations[ccmsg_CCACHE_CREDS_ITERATOR] = ccop_CCACHE_CREDS_ITERATOR; + TypeToOpMapping->operations[ccmsg_CCACHE_STORE_CREDS] = ccop_CCACHE_STORE_CREDS; + TypeToOpMapping->operations[ccmsg_CCACHE_REM_CREDS] = ccop_CCACHE_REM_CREDS; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_LAST_DEFAULT_TIME] = ccop_CCACHE_GET_LAST_DEFAULT_TIME; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_CHANGE_TIME] = ccop_CCACHE_GET_CHANGE_TIME; + TypeToOpMapping->operations[ccmsg_CCACHE_COMPARE] = ccop_CCACHE_COMPARE; + TypeToOpMapping->operations[ccmsg_CCACHE_GET_KDC_TIME_OFFSET] = ccop_CCACHE_GET_KDC_TIME_OFFSET; + TypeToOpMapping->operations[ccmsg_CCACHE_SET_KDC_TIME_OFFSET] = ccop_CCACHE_SET_KDC_TIME_OFFSET; + TypeToOpMapping->operations[ccmsg_CCACHE_CLEAR_KDC_TIME_OFFSET] = ccop_CCACHE_CLEAR_KDC_TIME_OFFSET; + TypeToOpMapping->operations[ccmsg_CCACHE_ITERATOR_RELEASE] = ccop_CCACHE_ITERATOR_RELEASE; + TypeToOpMapping->operations[ccmsg_CCACHE_ITERATOR_NEXT] = ccop_CCACHE_ITERATOR_NEXT; + TypeToOpMapping->operations[ccmsg_CREDS_ITERATOR_RELEASE] = ccop_CREDS_ITERATOR_RELEASE; + TypeToOpMapping->operations[ccmsg_CREDS_ITERATOR_NEXT] = ccop_CREDS_ITERATOR_NEXT; + TypeToOpMapping->operations[ccmsg_CREDS_RELEASE] = ccop_CREDS_RELEASE; + + return ccNoError; +}; + +cc_int32 +cci_serv_process_msg(cc_msg_t * msg, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** resp_msg) +{ + cc_server_context_t* ctx; + ccmsg_ctx_only_t* header = (ccmsg_ctx_only_t *)msg->header; + cc_int32 code; + + if (msg == NULL || msg->header == NULL || auth_info == NULL || session_info == NULL) + return ccErrBadParam; + + if (AllContexts == NULL) { + code = cci_serv_initialize(); + if ( code != ccNoError ) + return code; + } + + if (msg->type == ccmsg_INIT) { + return TypeToOpMapping->operations[msg->type] (NULL, auth_info, session_info, msg, resp_msg); + } else { + if (msg->header_len < sizeof(ccmsg_ctx_only_t)) { + return ccErrBadParam; + } + + code = cci_serv_find_ctx_by_handle(header->ctx, auth_info, session_info, &ctx); + if (code != ccNoError) { + cci_serv_make_nack(ccErrContextNotFound, auth_info, session_info, resp_msg); + return code; + } + return TypeToOpMapping->operations[msg->type] (ctx, auth_info, session_info, msg, resp_msg); + } +} + +/*deprecated*/ +cc_int32 +cci_serv_find_ctx(cc_auth_info_t* auth_info, cc_session_info_t* session_info, + cc_server_context_t** ctxpp) +{ + cc_context_iterate_t* ctx_iterator; + cc_context_list_node_t* ctx_node; + cc_server_context_t* ctx; + cc_int32 code; + cc_uint32 authorized; + + code = cci_context_list_iterator(AllContexts, &ctx_iterator); + if (code != ccNoError) + return code; + + while (cci_context_iterate_has_next(ctx_iterator)) { + code = cci_context_iterate_next(ctx_iterator, &ctx_node); + if (code != ccNoError) { + cci_context_free_iterator(ctx_iterator); + return code; + } + ctx = (cc_server_context_t *)ctx_node->data; + code = cci_rpc_is_authorized(auth_info, session_info, ctx->auth_info, ctx->session_info, &authorized); + if (code != ccNoError) { + cci_context_free_iterator(ctx_iterator); + return code; + } + + if (authorized) { + cci_context_free_iterator(ctx_iterator); + *ctxpp = ctx; + return ccNoError; + } + } + cci_context_free_iterator(ctx_iterator); + return ccIteratorEnd; +} + +cc_int32 +cci_serv_find_ctx_by_handle(cc_handle ctx_num, cc_auth_info_t* auth, cc_session_info_t* session, cc_server_context_t** ctxpp) +{ + cc_server_context_t* input_ctx = (cc_server_context_t*)ctx_num; + cc_context_iterate_t* ctx_iterator; + cc_context_list_node_t* ctx_node; + cc_server_context_t* ctx; + cc_uint32 authorized; + cc_int32 code; + + code = cci_context_list_iterator(AllContexts, &ctx_iterator); + if (code != ccNoError) + return code; + + while (cci_context_iterate_has_next(ctx_iterator)) { + code = cci_context_iterate_next(ctx_iterator, &ctx_node); + ctx = (cc_server_context_t *)ctx_node->data; + if (code != ccNoError) { + cci_context_free_iterator(ctx_iterator); + return code; + } + + code = cci_rpc_is_authorized(auth, session, ctx->auth_info, ctx->session_info, &authorized); + if (code != ccNoError) { + cci_context_free_iterator(ctx_iterator); + return code; + } + + if (ctx == input_ctx && authorized) { + cci_context_free_iterator(ctx_iterator); + *ctxpp = ctx; + return ccNoError; + } + } + cci_context_free_iterator(ctx_iterator); + return ccIteratorEnd; +} + +cc_int32 +cci_serv_find_ccache_by_handle(cc_server_context_t* ctx, cc_handle ccache, cc_server_ccache_t** ccachepp ) +{ + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_server_ccache_t* stored_ccache; + cc_server_ccache_t* target_ccache = (cc_server_ccache_t*)ccache; + cc_int32 code; + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + if (code != ccNoError) + return code; + + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + if (code != ccNoError) { + cci_ccache_free_iterator(ccache_iterator); + return code; + } + + stored_ccache = (cc_server_ccache_t *)ccache_node->data; + + if (stored_ccache == target_ccache) { + cci_ccache_free_iterator(ccache_iterator); + *ccachepp = stored_ccache; + return ccNoError; + } + } + cci_ccache_free_iterator(ccache_iterator); + return ccIteratorEnd; +} + +cc_int32 +cci_serv_find_ccache_iterator_by_handle(cc_server_context_t* ctx, cc_handle iterator, cc_generic_list_node_t** nodepp ) +{ + cc_generic_iterate_t* gen_iterator; + cc_generic_list_node_t* gen_node; + cc_ccache_iterate_t* stored_iterator; + cc_ccache_iterate_t* target_iterator = (cc_ccache_iterate_t*)iterator; + cc_int32 code; + + code = cci_generic_list_iterator(ctx->active_iterators, &gen_iterator); + if (code != ccNoError) + return code; + + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + if (code != ccNoError) { + cci_generic_free_iterator(gen_iterator); + return code; + } + + stored_iterator = (cc_ccache_iterate_t *)gen_node->data; + if (stored_iterator == target_iterator) { + cci_generic_free_iterator(gen_iterator); + *nodepp = gen_node; + return ccNoError; + } + } + cci_generic_free_iterator(gen_iterator); + return ccIteratorEnd; +} + +cc_int32 +cci_serv_find_creds_iterator_by_handle(cc_server_ccache_t* ccache, cc_handle iterator, cc_generic_list_node_t** nodepp) +{ + cc_generic_iterate_t* gen_iterator; + cc_generic_list_node_t* gen_node; + cc_ccache_iterate_t* stored_iterator; + cc_ccache_iterate_t* target_iterator = (cc_ccache_iterate_t*)iterator; + cc_int32 code; + + code = cci_generic_list_iterator(ccache->active_iterators, &gen_iterator); + if (code != ccNoError) + return code; + + while (cci_generic_iterate_has_next(gen_iterator)) { + code = cci_generic_iterate_next(gen_iterator, &gen_node); + if (code != ccNoError) { + cci_generic_free_iterator(gen_iterator); + return code; + } + + stored_iterator = (cc_ccache_iterate_t *)gen_node->data; + if (stored_iterator == target_iterator) { + cci_generic_free_iterator(gen_iterator); + *nodepp = gen_node; + return ccNoError; + } + } + cci_generic_free_iterator(gen_iterator); + return ccIteratorEnd; +} + +cc_int32 +cci_serv_make_nack(cc_int32 err_code, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** resp_msg) +{ + ccmsg_nack_t* nack_header; + cc_int32 code; + + code = cci_msg_new(ccmsg_NACK, resp_msg); + if (code != ccNoError) + return code; + + nack_header = (ccmsg_nack_t*)malloc(sizeof(ccmsg_nack_t)); + if (nack_header == NULL) { + cci_msg_destroy(*resp_msg); + *resp_msg = 0; + return ccErrNoMem; + } + + nack_header->err_code = err_code;; + code = cci_msg_add_header(*resp_msg, nack_header, sizeof(ccmsg_nack_t)); + if (code != ccNoError) { + cci_msg_destroy(*resp_msg); + *resp_msg = 0; + return code; + } + + return ccNoError; +} + +cc_int32 +cci_serv_make_ack(void * header, cc_int32 header_len, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** resp_msg) +{ + cc_int32 code; + + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) + return code; + + if (header != NULL) { + code = cci_msg_add_header(*resp_msg, header, header_len); + if (code != ccNoError) { + cci_msg_destroy(*resp_msg); + resp_msg = 0; + return code; + } + } + return ccNoError; +} + +cc_int32 +ccop_INIT( cc_server_context_t* ctx, /* not used */ + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_uint32 blob_pos; + cc_server_context_t *new_ctx; + ccmsg_init_resp_t *resp_header; + ccmsg_init_t *header = (ccmsg_init_t *)msg->header; + cc_context_list_node_t* ctx_node; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_init_t)) { + return ccErrBadParam; + } + + code = cci_context_new(header->in_version, auth_info, session_info, &new_ctx); + if (code != ccNoError) { + return code; + } + + code = cci_context_list_append(AllContexts, ctx, &ctx_node); + if (code != ccNoError) { + cci_context_destroy(new_ctx); + return code; + } + + resp_header = (ccmsg_init_resp_t*)malloc(sizeof(ccmsg_init_resp_t)); + if (resp_header == NULL) { + cci_context_destroy(new_ctx); + return ccErrNoMem; + } + + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) { + free(resp_header); + cci_context_destroy(new_ctx); + return code; + } + code = cci_msg_add_data_blob(*resp_msg, cc_vendor, strlen(cc_vendor) + 1, &blob_pos); + if (code != ccNoError) { + free(resp_header); + cci_context_destroy(new_ctx); + cci_msg_destroy(*resp_msg); + *resp_msg = 0; + return code; + } + + resp_header->out_ctx = new_ctx; + resp_header->out_version = cc_myversion; + resp_header->vendor_offset = blob_pos; + resp_header->vendor_length = strlen(cc_vendor) + 1; + code = cci_msg_add_header(*resp_msg, resp_header, sizeof(ccmsg_init_resp_t)); + if (code != ccNoError) { + free(resp_header); + cci_context_destroy(new_ctx); + cci_msg_destroy(*resp_msg); + *resp_msg = 0; + return code; + } + + return ccNoError; +} + +cc_int32 +ccop_CTX_RELEASE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ctx_release_t* header = (ccmsg_ctx_release_t *)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ctx_release_t)) { + return ccErrBadParam; + } + + code = cci_context_destroy(header->ctx); + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_GET_CHANGE_TIME( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ctx_get_change_time_resp_t* resp_header; + ccmsg_ctx_get_change_time_t *header = (ccmsg_ctx_get_change_time_t *)msg->header; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ctx_get_change_time_t)) { + return ccErrBadParam; + } + + resp_header = (ccmsg_ctx_get_change_time_resp_t*)malloc(sizeof(ccmsg_ctx_get_change_time_resp_t)); + if (resp_header == NULL) { + return ccErrNoMem; + } + + resp_header->time = ctx->changed; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ctx_get_change_time_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_GET_DEFAULT_CCACHE_NAME( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + char * name; + ccmsg_ctx_get_default_ccache_name_resp_t* resp_header; + ccmsg_ctx_get_default_ccache_name_t* header = (ccmsg_ctx_get_default_ccache_name_t *)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ctx_get_default_ccache_name_t)) { + return ccErrBadParam; + } + + code = cci_context_get_default_ccache_name(ctx, &name); + if (code != ccNoError) + return code; + + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ctx_get_default_ccache_name_resp_t*)malloc(sizeof(ccmsg_ctx_get_default_ccache_name_resp_t)); + if (resp_header == NULL) { + cci_msg_destroy(*resp_msg); + *resp_msg = 0; + return ccErrNoMem; + } + + code = cci_msg_add_data_blob(*resp_msg, name, strlen(name) + 1, &resp_header->name_offset); + resp_header->name_len = strlen(name) + 1; + return ccNoError; +} + +cc_int32 +ccop_CTX_COMPARE(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_server_context_t *ctx2; + ccmsg_ctx_compare_resp_t* resp_header; + ccmsg_ctx_compare_t* header = (ccmsg_ctx_compare_t *)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ctx_compare_t)) + return ccErrBadParam; + + code = cci_serv_find_ctx_by_handle(header->ctx2, auth_info, session_info, &ctx2); + + resp_header = (ccmsg_ctx_compare_resp_t*)malloc(sizeof(ccmsg_ctx_compare_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->is_equal = cci_context_compare(ctx, ctx2); + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ctx_compare_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_NEW_CCACHE_ITERATOR(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_ccache_iterate_t* ccache_iterator; + ccmsg_ctx_new_ccache_iterator_resp_t* resp_header; + ccmsg_ctx_new_ccache_iterator_t* header = (ccmsg_ctx_new_ccache_iterator_t*)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ctx_new_ccache_iterator_t)) + return ccErrBadParam; + + code = cci_context_ccache_iterator(ctx,&ccache_iterator); + + resp_header = (ccmsg_ctx_new_ccache_iterator_resp_t*)malloc(sizeof(ccmsg_ctx_new_ccache_iterator_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->iterator = ccache_iterator; + + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ctx_new_ccache_iterator_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_LOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_UNLOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CTX_CLONE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_OPEN(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + char *name; + cc_server_ccache_t* ccache; + ccmsg_ccache_open_resp_t* resp_header; + ccmsg_ccache_open_t* header = (ccmsg_ccache_open_t*)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_open_t)) + return ccErrBadParam; + + code = cci_msg_retrieve_blob(msg, header->name_offset, header->name_len, &name); + code = cci_context_find_ccache(ctx, name, &ccache); + + free(name); + + if (ccache == NULL) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_open_resp_t*)malloc(sizeof(ccmsg_ccache_open_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->ccache = ccache; + cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_open_resp_t), auth_info, session_info, resp_msg); + return ccNoError; +} + +cc_int32 +ccop_CCACHE_OPEN_DEFAULT(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_open_default_t* header = (ccmsg_ccache_open_default_t*)msg->header; + ccmsg_ccache_open_resp_t* resp_header; + cc_server_ccache_t* ccache; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_open_default_t)) + return ccErrBadParam; + + if (ctx->ccaches->head->data == NULL) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + ccache = (cc_server_ccache_t*) ctx->ccaches->head->data; + + resp_header = (ccmsg_ccache_open_resp_t*)malloc(sizeof(ccmsg_ccache_open_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->ccache = ccache; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_open_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_CREATE(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_create_resp_t* resp_header; + ccmsg_ccache_create_t* header = (ccmsg_ccache_create_t*)msg->header; + cc_server_ccache_t* ccache; + char* principal; + char* name; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_create_t)) + return ccErrBadParam; + + code = cci_msg_retrieve_blob(msg, header->principal_offset, header->principal_len, &principal); + if (code != ccNoError) + return code; + principal[header->principal_len] = '\0'; /*Ensure null termination*/ + + code = cci_msg_retrieve_blob(msg, header->name_offset, header->name_len, &name); + if (code != ccNoError) + return code; + name[header->name_len] = '\0'; /*Ensure null termination*/ + + code = cci_context_create_ccache(ctx, name, header->version, principal, &ccache); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ccache_create_resp_t*)malloc(sizeof(ccmsg_ccache_create_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->ccache = ccache; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_create_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_CREATE_DEFAULT( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_create_resp_t* resp_header; + ccmsg_ccache_create_t* header = (ccmsg_ccache_create_t*)msg->header; + cc_server_ccache_t* ccache; + char* principal; + char* name; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_create_t)) + return ccErrBadParam; + + code = cci_msg_retrieve_blob(msg, header->principal_offset, header->principal_len, &principal); + if (code != ccNoError) + return code; + principal[header->principal_len] = '\0'; /*Ensure null termination*/ + + code = cci_context_get_default_ccache_name(ctx, &name); + if (code != ccNoError) + return code; + + code = cci_context_create_ccache(ctx, name, header->version, principal, &ccache); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ccache_create_resp_t*)malloc(sizeof(ccmsg_ccache_create_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->ccache = ccache; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_create_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_CREATE_UNIQUE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_create_resp_t* resp_header; + ccmsg_ccache_create_t* header = (ccmsg_ccache_create_t*)msg->header; + cc_server_ccache_t* ccache; + char* principal; + char* name; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_create_t)) + return ccErrBadParam; + + code = cci_msg_retrieve_blob(msg, header->principal_offset, header->principal_len, &principal); + if (code != ccNoError) + return code; + principal[header->principal_len] = '\0'; /*Ensure null termination*/ + + // TODO: Generate a unique ccache name + + code = cci_context_create_ccache(ctx, name, header->version, principal, &ccache); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ccache_create_resp_t*)malloc(sizeof(ccmsg_ccache_create_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->ccache = ccache; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_create_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_RELEASE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO: This is probably wrong. + return ccop_CCACHE_DESTROY(ctx, auth_info, session_info, msg, resp_msg); +} + +cc_int32 +ccop_CCACHE_DESTROY( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_release_t* header = (ccmsg_ccache_release_t*)msg->header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_release_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + cci_ccache_destroy(ccache); + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_SET_DEFAULT(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_server_ccache_t* ccache, *stored_ccache, *old_default; + ccmsg_ccache_set_default_t* header = (ccmsg_ccache_set_default_t*)msg->header; + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_set_default_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + if (ccache == (cc_server_ccache_t*)ctx->ccaches->head->data) /*already default*/ + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); + + old_default = (cc_server_ccache_t*)ctx->ccaches->head->data; + old_default->last_default = time(NULL); + + code = cci_ccache_list_iterator(ctx->ccaches, &ccache_iterator); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator,&ccache_node); + stored_ccache = (cc_server_ccache_t*)ccache_node->data; + + if (stored_ccache == ccache) { + ccache_node->data = NULL; /*don't want list removal code free()ing ccache*/ + cci_ccache_list_remove_element(ctx->ccaches, ccache_node); + cci_ccache_list_prepend(ctx->ccaches, ccache, NULL); + break; + } + } + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_GET_CREDS_VERSION(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_creds_version_t* header = (ccmsg_ccache_get_creds_version_t*)msg->header; + ccmsg_ccache_get_creds_version_resp_t* resp_header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_creds_version_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_get_creds_version_resp_t*)malloc(sizeof(ccmsg_ccache_get_creds_version_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->version = ccache->versions; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_get_creds_version_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_GET_NAME(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_name_t* header = (ccmsg_ccache_get_name_t*)msg->header; + ccmsg_ccache_get_name_resp_t* resp_header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_name_resp_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (ccache == NULL) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_get_name_resp_t*)malloc(sizeof(ccmsg_ccache_get_name_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) + return code; + + code = cci_msg_add_data_blob(*resp_msg, ccache->name, strlen(ccache->name) + 1, &resp_header->name_offset); + resp_header->name_len = strlen(ccache->name) + 1; + cci_msg_add_header(*resp_msg, resp_header, sizeof(ccmsg_ccache_get_name_resp_t)); + + return ccNoError; +} + +cc_int32 +ccop_CCACHE_GET_PRINCIPAL(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_principal_t* header = (ccmsg_ccache_get_principal_t*)msg->header; + ccmsg_ccache_get_principal_resp_t* resp_header; + cc_server_ccache_t* ccache; + char * principal; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_principal_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_ccache_get_principal(ccache, header->version, &principal); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ccache_get_principal_resp_t*)malloc(sizeof(ccmsg_ccache_get_principal_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + code = cci_msg_add_data_blob(*resp_msg, principal, strlen(principal) + 1, &resp_header->principal_offset); + cci_msg_add_header(*resp_msg, resp_header, sizeof(ccmsg_ccache_get_principal_resp_t)); + + return ccNoError; +} + +cc_int32 +ccop_CCACHE_SET_PRINCIPAL(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_set_principal_t* header = (ccmsg_ccache_set_principal_t*)msg->header; + cc_server_ccache_t* ccache; + char *principal; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_set_principal_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_msg_retrieve_blob(msg, header->principal_offset, header->principal_len, &principal); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + code = cci_ccache_set_principal(ccache, header->version, principal); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_CREDS_ITERATOR(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_server_ccache_t* ccache; + cc_credentials_iterate_t* creds_iterator; + ccmsg_ccache_creds_iterator_t* header = (ccmsg_ccache_creds_iterator_t*)msg->header; + ccmsg_ccache_creds_iterator_resp_t* resp_header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_creds_iterator_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_ccache_new_iterator(ccache, &creds_iterator); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_ccache_creds_iterator_resp_t*)malloc(sizeof(ccmsg_ccache_creds_iterator_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->iterator = creds_iterator; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_creds_iterator_resp_t), auth_info, session_info, resp_msg); +} + + +static cc_int32 +cci_credentials_union_release( cc_credentials_union * creds ) +{ + int i; + + switch (creds->version) { + case cc_credentials_v4: + free(creds->credentials.credentials_v4); + break; + case cc_credentials_v5: + if ( creds->credentials.credentials_v5->client ) + free(creds->credentials.credentials_v5->client); + if ( creds->credentials.credentials_v5->server ) + free(creds->credentials.credentials_v5->server ); + if ( creds->credentials.credentials_v5->keyblock.data ) + free(creds->credentials.credentials_v5->keyblock.data); + if ( creds->credentials.credentials_v5->ticket.data ) + free(creds->credentials.credentials_v5->ticket.data); + if ( creds->credentials.credentials_v5->second_ticket.data ) + free(creds->credentials.credentials_v5->second_ticket.data); + if ( creds->credentials.credentials_v5->addresses ) { + for ( i=0; creds->credentials.credentials_v5->addresses[i]; i++) { + if (creds->credentials.credentials_v5->addresses[i]->data) + free(creds->credentials.credentials_v5->addresses[i]->data); + } + free(creds->credentials.credentials_v5->addresses); + } + if ( creds->credentials.credentials_v5->authdata ) { + for ( i=0; creds->credentials.credentials_v5->authdata[i]; i++) { + if ( creds->credentials.credentials_v5->authdata[i]->data ) + free(creds->credentials.credentials_v5->authdata[i]->data); + } + free(creds->credentials.credentials_v5->authdata); + } + break; + default: + return ccErrBadCredentialsVersion; + } + return ccNoError; +} + +cc_int32 +ccop_CCACHE_STORE_CREDS(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_store_creds_t* header = (ccmsg_ccache_store_creds_t*)msg->header; + cc_server_ccache_t* ccache; + char *flat_creds; + cc_credentials_union *creds; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_store_creds_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + // TODO: This code is too simplistic. cc_credential_unions are not flat + // structures and must be flattened. That means that although we can + // store a flat blob in the message we will need to decode the blob + // into the actual object. + code = cci_msg_retrieve_blob(msg, header->creds_offset, header->creds_len, &flat_creds); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + creds = (cc_credentials_union *)malloc(sizeof(cc_credentials_union)); + if ( creds == NULL ) + return ccErrNoMem; + + switch ( creds->version ) { + case cc_credentials_v4: + code = cci_creds_v4_unmarshall(flat_creds, header->creds_len, creds); + break; + case cc_credentials_v5: + code = cci_creds_v5_unmarshall(flat_creds, header->creds_len, creds); + break; + default: + return cci_serv_make_nack(ccErrBadCredentialsVersion, auth_info, session_info, resp_msg); + } + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + code = cci_ccache_store_creds(ccache, creds); + cci_credentials_union_release(creds); + if (code != ccNoError) { + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + } + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_REM_CREDS(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_rem_creds_t* header = (ccmsg_ccache_rem_creds_t*)msg->header; + cc_server_ccache_t* ccache; + cc_credentials_union *creds; + cc_int32 code; + + *resp_msg = 0; + if (msg->header_len != sizeof(ccmsg_ccache_rem_creds_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_ccache_rem_creds(ccache, header->creds); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_LOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_UNLOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_MOVE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + // TODO + return cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); +} + + +cc_int32 +ccop_CCACHE_GET_LAST_DEFAULT_TIME(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_last_default_time_t* header = (ccmsg_ccache_get_last_default_time_t*)msg->header; + ccmsg_ccache_get_last_default_time_resp_t* resp_header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_last_default_time_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_get_last_default_time_resp_t*)malloc(sizeof(ccmsg_ccache_get_last_default_time_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->last_default_time = ccache->last_default; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_get_last_default_time_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_GET_CHANGE_TIME( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_change_time_resp_t* resp_header; + ccmsg_ccache_get_change_time_t *header = (ccmsg_ccache_get_change_time_t *)msg->header; + cc_server_ccache_t* ccache = (cc_server_ccache_t *)header->ccache; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_change_time_t)) { + return ccErrBadParam; + } + + resp_header = (ccmsg_ccache_get_change_time_resp_t*)malloc(sizeof(ccmsg_ccache_get_change_time_resp_t)); + if (resp_header == NULL) { + return ccErrNoMem; + } + + resp_header->time = ccache->changed; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_get_change_time_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_COMPARE(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_compare_t* header = (ccmsg_ccache_compare_t*)msg->header; + ccmsg_ccache_compare_resp_t* resp_header; + cc_server_ccache_t* ccache1, *ccache2; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_compare_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache1, &ccache1); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache2, &ccache2); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_compare_resp_t*)malloc(sizeof(ccmsg_ccache_compare_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + cci_ccache_compare(ccache1, ccache2, &resp_header->is_equal); + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_compare_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_GET_KDC_TIME_OFFSET(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_get_kdc_time_offset_t* header = (ccmsg_ccache_get_kdc_time_offset_t*)msg->header; + ccmsg_ccache_get_kdc_time_offset_resp_t* resp_header; + cc_server_ccache_t* ccache; + cc_time_t offset; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_get_kdc_time_offset_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + // TODO How is the header->creds_version supposed to be used? + + code = cci_ccache_get_kdc_time_offset(ccache, &offset); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + resp_header = (ccmsg_ccache_get_kdc_time_offset_resp_t*)malloc(sizeof(ccmsg_ccache_get_kdc_time_offset_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + resp_header->offset = offset; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_get_kdc_time_offset_resp_t), auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_SET_KDC_TIME_OFFSET(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_set_kdc_time_offset_t* header = (ccmsg_ccache_set_kdc_time_offset_t*)msg->header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_set_kdc_time_offset_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + // TODO How is the header->creds_version supposed to be used? + + cci_ccache_set_kdc_time_offset(ccache, header->offset); + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_CLEAR_KDC_TIME_OFFSET(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_clear_kdc_time_offset_t* header = (ccmsg_ccache_clear_kdc_time_offset_t*)msg->header; + cc_server_ccache_t* ccache; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_clear_kdc_time_offset_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + // TODO How is the header->creds_version supposed to be used? + + cci_ccache_clear_kdc_time_offset(ccache); + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_ITERATOR_RELEASE(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_generic_list_node_t* gen_node; + ccmsg_ccache_iterator_release_t* header = (ccmsg_ccache_iterator_release_t*)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_iterator_release_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_iterator_by_handle(ctx, header->iterator, &gen_node); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + code = cci_generic_list_remove_element(ctx->active_iterators, gen_node); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CCACHE_ITERATOR_NEXT(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_ccache_iterator_release_t* header = (ccmsg_ccache_iterator_release_t*)msg->header; + ccmsg_ccache_iterator_next_resp_t* resp_header; + cc_generic_list_node_t* gen_node; + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t *ccache_node; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_ccache_iterator_next_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_iterator_by_handle(ctx, header->iterator, &gen_node); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + ccache_iterator = (cc_ccache_iterate_t*)gen_node->data; + if (cci_ccache_iterate_has_next(ccache_iterator)) { + resp_header = (ccmsg_ccache_iterator_next_resp_t*)malloc(sizeof(ccmsg_ccache_iterator_next_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + if (code != ccNoError) + return cci_serv_make_nack(code, auth_info, session_info, resp_msg); + + resp_header->ccache = ccache_node; + return cci_serv_make_ack(resp_header, sizeof(ccmsg_ccache_iterator_next_resp_t), auth_info, session_info, resp_msg); + } else { + return cci_serv_make_nack(ccIteratorEnd, auth_info, session_info, resp_msg); + } +} + +cc_int32 +ccop_CREDS_ITERATOR_RELEASE(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + cc_generic_list_node_t* gen_node; + cc_server_ccache_t* ccache; + ccmsg_creds_iterator_release_t* header = (ccmsg_creds_iterator_release_t*)msg->header; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_creds_iterator_release_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_serv_find_creds_iterator_by_handle(ccache, header->iterator, &gen_node); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + code = cci_generic_list_remove_element(ccache->active_iterators, gen_node); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + return cci_serv_make_ack(NULL, 0, auth_info, session_info, resp_msg); +} + +cc_int32 +ccop_CREDS_ITERATOR_NEXT(cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + ccmsg_creds_iterator_next_t* header = (ccmsg_creds_iterator_next_t*)msg->header; + ccmsg_creds_iterator_next_resp_t* resp_header; + cc_credentials_iterate_t* creds_iterator; + cc_generic_list_node_t* gen_node; + cc_credentials_list_node_t* creds_node; + cc_server_ccache_t* ccache; + cc_server_credentials_t* stored_creds; + cc_credentials_union *creds_union; + cc_int32 code; + + *resp_msg = 0; + + if (msg->header_len != sizeof(ccmsg_creds_iterator_next_t)) + return ccErrBadParam; + + code = cci_serv_find_ccache_by_handle(ctx, header->ccache, &ccache); + if (code != ccNoError) + return cci_serv_make_nack(ccErrCCacheNotFound, auth_info, session_info, resp_msg); + + code = cci_serv_find_creds_iterator_by_handle(ccache, header->iterator, &gen_node); + if (code != ccNoError) + return cci_serv_make_nack(ccErrBadParam, auth_info, session_info, resp_msg); + + creds_iterator = (cc_credentials_iterate_t*)gen_node->data; + if (cci_credentials_iterate_has_next(creds_iterator)) { + code = cci_msg_new(ccmsg_ACK, resp_msg); + if (code != ccNoError) + return code; + + resp_header = (ccmsg_creds_iterator_next_resp_t*)malloc(sizeof(ccmsg_creds_iterator_next_resp_t)); + if (resp_header == NULL) + return ccErrNoMem; + + code = cci_credentials_iterate_next(creds_iterator, &creds_node); + stored_creds = (cc_server_credentials_t*)creds_node->data; + creds_union = &stored_creds->creds; + + code = cci_msg_add_data_blob(*resp_msg, creds_union, sizeof(cc_credentials_union), &resp_header->creds_offset); + code = cci_msg_add_header(*resp_msg, resp_header, sizeof(ccmsg_creds_iterator_next_resp_t)); + } else { + cci_serv_make_nack(ccIteratorEnd, auth_info, session_info, resp_msg); + } + return ccNoError; +} + +cc_int32 +ccop_CREDS_RELEASE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, cc_msg_t **resp_msg) +{ + + cci_serv_make_nack(ccErrNotImplemented, auth_info, session_info, resp_msg); + return ccNoError; +} diff --git a/src/lib/ccapi/server/serv_ops.h b/src/lib/ccapi/server/serv_ops.h new file mode 100644 index 000000000..f43956685 --- /dev/null +++ b/src/lib/ccapi/server/serv_ops.h @@ -0,0 +1,321 @@ +/* $Copyright: + * + * Copyright 2004 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). + * $ + */ + +/* + * Prototypes for serv_ops.c + */ + +#ifndef __SERV_OPS_H__ +#define __SERV_OPS_H__ + +#include "CredentialsCache.h" +#include "rpc_auth.h" +#include "msg.h" +#include "datastore.h" + +struct type_to_op_mapping_t { + cc_int32 (*operations[CC_MSG_MAX_TYPE]) ( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); +}; +typedef struct type_to_op_mapping_t type_to_op_mapping_t; + +cc_int32 cci_serv_initialize(void); +cc_int32 cci_serv_process_msg(cc_msg_t * msg, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** resp_msg); +cc_int32 cci_serv_find_ctx(cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_server_context_t** contextp); +cc_int32 cci_serv_find_ctx_by_handle(cc_handle ctx_handle, cc_auth_info_t *auth, cc_session_info_t* session, cc_server_context_t** contextp); +cc_int32 cci_serv_find_ccache_by_handle(cc_server_context_t* ctx, cc_handle ccache_handle, cc_server_ccache_t** ccachep) ; +cc_int32 cci_serv_find_ccache_iterator_by_handle(cc_server_context_t* ctx, cc_handle iterator, cc_generic_list_node_t** nodep); +cc_int32 cci_serv_find_creds_iterator_by_handle(cc_server_ccache_t* ccache, cc_handle iterator, cc_generic_list_node_t** nodep); +cc_int32 cci_serv_make_nack(cc_int32 err_code, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** msgp); +cc_int32 cci_serv_make_ack(void * header, cc_int32 header_len, cc_auth_info_t* auth_info, cc_session_info_t* session_info, cc_msg_t** msgp); + +cc_int32 ccop_INIT( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CTX_RELEASE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CTX_GET_CHANGE_TIME( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CTX_GET_DEFAULT_CCACHE_NAME( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CTX_COMPARE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CTX_NEW_CCACHE_ITERATOR( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CTX_LOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CTX_UNLOCK( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CTX_CLONE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_OPEN( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_OPEN_DEFAULT( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_CREATE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CCACHE_CREATE_DEFAULT( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CCACHE_CREATE_UNIQUE( cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_RELEASE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_DESTROY( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_SET_DEFAULT( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_GET_CREDS_VERSION( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_GET_NAME( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_GET_PRINCIPAL( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_SET_PRINCIPAL( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_CREDS_ITERATOR( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_STORE_CREDS( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_REM_CREDS( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_GET_LAST_DEFAULT_TIME( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 +ccop_CCACHE_GET_CHANGE_TIME( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg) ; + +cc_int32 ccop_CCACHE_COMPARE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_GET_KDC_TIME_OFFSET( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_SET_KDC_TIME_OFFSET( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_CLEAR_KDC_TIME_OFFSET( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_ITERATOR_RELEASE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CCACHE_ITERATOR_NEXT( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CREDS_ITERATOR_RELEASE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CREDS_ITERATOR_NEXT( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); + +cc_int32 ccop_CREDS_RELEASE( + cc_server_context_t* ctx, + cc_auth_info_t* auth_info, + cc_session_info_t* session_info, + cc_msg_t *msg, + cc_msg_t **resp_msg); +#endif /*__SERV_OPS_H__*/ diff --git a/src/lib/ccapi/server/windows/ChangeLog b/src/lib/ccapi/server/windows/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/server/windows/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/unit-test/ChangeLog b/src/lib/ccapi/unit-test/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/unit-test/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + diff --git a/src/lib/ccapi/unit-test/t_ccache.c b/src/lib/ccapi/unit-test/t_ccache.c new file mode 100644 index 000000000..6ef33ea23 --- /dev/null +++ b/src/lib/ccapi/unit-test/t_ccache.c @@ -0,0 +1,115 @@ +/* $Copyright: + * + * Copyright 2004 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 +#include +#include +#include "CredentialsCache.h" +#include "datastore.h" + +int main() { + cc_server_credentials_t *cred1, *cred2, *cred3; + cc_credentials_iterate_t* iterator; + cc_server_credentials_t* stored_cred; + cc_credentials_list_node_t *node; + cc_server_ccache_t *c1, *c2; + char p1[] = "Spike"; + char p2[] = "Jeff"; + int i; + cc_int32 code; + + code = cci_ccache_new("The first", p1, cc_credentials_v4_v5, &c1); + code = cci_ccache_new("The 2nd", p2, cc_credentials_v4_v5, &c2); + + cred1 = (cc_server_credentials_t*)malloc(sizeof(cc_server_credentials_t)); + memset(cred1,0,sizeof(cc_server_credentials_t)); + cred2 = (cc_server_credentials_t*)malloc(sizeof(cc_server_credentials_t)); + memset(cred2,0,sizeof(cc_server_credentials_t)); + cred3 = (cc_server_credentials_t*)malloc(sizeof(cc_server_credentials_t)); + memset(cred3,0,sizeof(cc_server_credentials_t)); + + cred1->creds.version = cred2->creds.version = cc_credentials_v4; + cred3->creds.version = cc_credentials_v5; + + cred1->creds.credentials.credentials_v4 = (cc_credentials_v4_t*)malloc(sizeof(cc_credentials_v4_t)); + memset(cred1->creds.credentials.credentials_v4,0,sizeof(cc_credentials_v4_t)); + cred2->creds.credentials.credentials_v4 = (cc_credentials_v4_t*)malloc(sizeof(cc_credentials_v4_t)); + memset(cred2->creds.credentials.credentials_v4,0,sizeof(cc_credentials_v4_t)); + cred3->creds.credentials.credentials_v5 = (cc_credentials_v5_t*)malloc(sizeof(cc_credentials_v5_t)); + memset(cred3->creds.credentials.credentials_v5,0,sizeof(cc_credentials_v5_t)); + + strncpy(cred1->creds.credentials.credentials_v4->principal, p1, strlen(p1)); + strncpy(cred2->creds.credentials.credentials_v4->principal, p1, strlen(p1)); + cred3->creds.credentials.credentials_v5->client = p1; + + code = cci_ccache_store_creds(c1, &cred1->creds); + printf("(c1, cred1) -> %d\n",code); + + code = cci_ccache_store_creds(c1, &cred2->creds); + printf("(c1, cred2) -> %d\n",code); + + code = cci_ccache_store_creds(c2, &cred3->creds); + printf("(c2, cred3) -> %d\n",code); + + code = cci_ccache_store_creds(c1, &cred3->creds); + printf("(c1, cred3) -> %d\n",code); + + i = 0; + code = cci_ccache_move(c1, c2); + code = cci_ccache_destroy(c1); + code = cci_ccache_new_iterator(c2, &iterator); + while (cci_credentials_iterate_has_next(iterator)) { + i++; + code = cci_credentials_iterate_next(iterator, &node); + stored_cred = (cc_server_credentials_t *)node->data; + printf("%d %d %s\n", stored_cred->is_default, stored_cred->creds.version, stored_cred->creds.credentials.credentials_v4->principal); + + if (i == 1) { + code = cci_ccache_rem_creds(c2,&cred2->creds); + printf("(c2 rem cred2) -> %d\n",code); + } + } + return 0; +} + diff --git a/src/lib/ccapi/unit-test/t_context.c b/src/lib/ccapi/unit-test/t_context.c new file mode 100644 index 000000000..9e35d9abf --- /dev/null +++ b/src/lib/ccapi/unit-test/t_context.c @@ -0,0 +1,115 @@ +/* $Copyright: + * + * Copyright 2004 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 +#include +#include + +#include "CredentialsCache.h" +#include "datastore.h" + + +/*testing code*/ +int main() { + int uid = 1; + int session = 1; + cc_server_ccache_t *ccache; + cc_credentials_union* creds; + cc_ccache_iterate_t* ccache_iterator; + cc_ccache_list_node_t* ccache_node; + cc_credentials_iterate_t* creds_iterator; + cc_credentials_list_node_t* creds_node; + cc_server_credentials_t* server_creds; + cc_auth_info_t* auth_info = NULL; + cc_session_info_t* session_info = NULL; + cc_server_context_t* ctx = NULL; + char *name; + int i; + cc_int32 code; + + code = cci_context_new(5, auth_info, session_info, &ctx); + code = cci_context_create_default_ccache(ctx, cc_credentials_v4, "Spike", &ccache); + code = cci_context_get_default_ccache_name(ctx, &name); + code = cci_context_open_ccache(ctx, name, &ccache); + + for (i = 0; i < 5; i++) { + creds = (cc_credentials_union*)malloc(sizeof(cc_credentials_union)); + creds->version = cc_credentials_v4; + creds->credentials.credentials_v4 = (cc_credentials_v4_t*)malloc(sizeof(cc_credentials_v4_t)); + strcpy(creds->credentials.credentials_v4->principal, "Spike"); + + code = cci_ccache_store_creds(ccache, creds); + } + + code = cci_context_create_ccache(ctx, "ccache 2", cc_credentials_v4, "Jeff", &ccache); + code = cci_context_open_ccache(ctx, "ccache 2", &ccache); + + for (i = 0; i < 5; i++) { + creds = (cc_credentials_union*)malloc(sizeof(cc_credentials_union)); + creds->version = cc_credentials_v4; + creds->credentials.credentials_v4 = (cc_credentials_v4_t*)malloc(sizeof(cc_credentials_v4_t)); + strcpy(creds->credentials.credentials_v4->principal, "Jeff"); + + cci_ccache_store_creds(ccache, creds); + } + + code = cci_context_ccache_iterator(ctx, &ccache_iterator); + while (cci_ccache_iterate_has_next(ccache_iterator)) { + code = cci_ccache_iterate_next(ccache_iterator, &ccache_node); + ccache = (cc_server_ccache_t *)ccache_node->data; + printf("%x for %s %s default = %d v %d\n", + ccache, ccache->principal_v4, ccache->principal_v5, + ccache->is_default, ccache->versions); + + code = cci_ccache_new_iterator(ccache, &creds_iterator); + while (cci_credentials_iterate_has_next(creds_iterator)) { + code = cci_credentials_iterate_next(creds_iterator, &creds_node); + server_creds = (cc_server_credentials_t *)creds_node->data; + printf("\t%s %d\n", + server_creds->creds.credentials.credentials_v4->principal, + creds->version); + } + } + return 0; +} diff --git a/src/lib/ccapi/unit-test/t_lists.c b/src/lib/ccapi/unit-test/t_lists.c new file mode 100644 index 000000000..4c8450bb7 --- /dev/null +++ b/src/lib/ccapi/unit-test/t_lists.c @@ -0,0 +1,100 @@ +/* $Copyright: + * + * Copyright 2004 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 +#include + +#include "CredentialsCache.h" +#include "datastore.h" + + +int main() { + cc_generic_list_head_t* head; + cc_generic_list_head_t* copy;// = cc_generic_list_copy(head); + cc_generic_list_node_t *head_node,*tail,*middle, *node; + cc_generic_iterate_t* iterate; + int x1 = 1; + int x2 = 2; + int x3 = 3; + int x4 = 4; + int x5 = 5; + int x6 = 6; + cc_int32 code; + + code = cci_generic_list_new(&head); + code = cci_generic_list_append(head,&x4,sizeof(x4),NULL); + code = cci_generic_list_append(head,&x5,sizeof(x5),NULL); + code = cci_generic_list_append(head,&x6,sizeof(x6),&tail); + + code = cci_generic_list_prepend(head,&x3,sizeof(x3),&middle); + code = cci_generic_list_prepend(head,&x2,sizeof(x2),NULL); + code = cci_generic_list_prepend(head,&x1,sizeof(x1), &head_node); + + code = cci_generic_list_iterator(head, &iterate); + while (cci_generic_iterate_has_next(iterate)) { + code = cci_generic_iterate_next(iterate, &node); + printf("%d\n",*((int *)(node->data))); + } + printf("----------\n"); + cci_generic_list_remove_element(head,head_node); + cci_generic_list_remove_element(head,middle); + cci_generic_list_remove_element(head,tail); + + code = cci_generic_list_iterator(head, &iterate); + while (cci_generic_iterate_has_next(iterate)) { + code = cci_generic_iterate_next(iterate, &node); + printf("%d\n",*((int *)(node->data))); + } + + printf("----------\n"); + code = cci_generic_list_copy(head, ©); + code = cci_generic_list_iterator(copy, &iterate); + while (cci_generic_iterate_has_next(iterate)) { + code = cci_generic_iterate_next(iterate, &node); + printf("%d\n",*((int *)(node->data))); + } + + cci_generic_list_destroy(copy); + return 0; +} diff --git a/src/lib/ccapi/unit-test/t_msg.c b/src/lib/ccapi/unit-test/t_msg.c new file mode 100644 index 000000000..b3a31a871 --- /dev/null +++ b/src/lib/ccapi/unit-test/t_msg.c @@ -0,0 +1,88 @@ +/* $Copyright: + * + * Copyright 2004 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 "CredentialsCache.h" +#include "msg.h" +#include "datastore.h" + +#include +#include +#include +#include + +/*testing code*/ +int main() +{ + cc_msg_t* msg; + double header = 4.05; + char blob1[] = "This is blob one.1234"; + int blob2 = 2; + char blob3[] = "This is blob 3."; + int pos1,pos2,pos3; + void *flat; + char *p; + cc_uint32 valid = 0; + cc_int32 code; + + code = cci_msg_new(ccmsg_INIT, &msg); + code = cci_msg_add_header(msg, &header, sizeof(double)); + //cc_msg_add_header(msg, NULL, 0); + code = cci_msg_add_data_blob(msg, blob1, strlen(blob1) + 1,&pos1); + code = cci_msg_add_data_blob(msg, &blob2, sizeof(int),&pos2); + code = cci_msg_add_data_blob(msg, blob3, strlen(blob3) + 1,&pos3); + + cci_msg_flatten(msg,&flat); + + printf("%s\n",(char *)((char *)msg->flat + pos1)); + printf("%d\n",*(int *)((char *)msg->flat + pos2)); + printf("%s\n",(char *)((char *)msg->flat + pos3)); + + cci_msg_verify(msg->flat, msg->flat_len, &valid); + printf("%d\n",valid); + + code = cci_msg_unflatten(msg->flat, msg->flat_len, &msg); + + code = cci_msg_retrieve_blob(msg, pos3, strlen(blob3) + 1, &p); + printf("%s PPP\n",p); + return 0; +} diff --git a/src/lib/ccapi/unit-test/t_server.c b/src/lib/ccapi/unit-test/t_server.c new file mode 100644 index 000000000..d4d998466 --- /dev/null +++ b/src/lib/ccapi/unit-test/t_server.c @@ -0,0 +1,185 @@ +/* $Copyright: + * + * Copyright 2004 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 "CredentialsCache.h" +#include "serv_ops.h" +#include "datastore.h" +#include "rpc_auth.h" +#include "msg_headers.h" + +#include + +static int +read_flat_msg(char ** flat_msg, cc_uint32 * flat_len) +{ + + /* TODO - read length of message */ + *flat_len = 999; + + *flat_msg = (char *)malloc(*flat_len); + + /* TODO - read message into buffer */ + + return 0; +} + +static int +send_flat_msg(char * flag_msg, cc_uint32 flat_len) +{ + + return 0; +} + +static int +obtain_auth_info(cc_auth_info_t ** auth) +{ + if (auth == NULL) + return ccErrBadParam; + + *auth = malloc(sizeof(cc_auth_info_t)); + if (auth == NULL) + return ccErrNoMem; + + memset(*auth,0,sizeof(cc_auth_info_t)); + + /* TODO: obtain real auth data from connection */ + + return ccNoError; +} + +static int +destroy_auth_info(cc_auth_info_t * auth) +{ + if (auth == NULL) + return ccErrBadParam; + + if (auth->info) + free(auth->info); + + free(auth); + + return ccNoError; +} + +static int +obtain_session_info(cc_session_info_t ** session) +{ + if (session == NULL) + return ccErrBadParam; + + *session = malloc(sizeof(cc_session_info_t)); + if (session == NULL) + return ccErrNoMem; + + memset(*session,0,sizeof(cc_session_info_t)); + + /* TODO: obtain real session data from connection */ + + return ccNoError; +} + +static int +destroy_session_info(cc_session_info_t * session) +{ + if (session == NULL) + return ccErrBadParam; + + if (session->info) + free(session->info); + + free(session); + + return ccNoError; +} + + +int +main(void) +{ + cc_msg_t * msg; + cc_msg_t * resp; + cc_auth_info_t * auth_info; + cc_session_info_t * session_info; + cc_int32 code; + + if ( cci_serv_initialize() != ccNoError ) + return 1; + + while ( 1 ) { + msg = (cc_msg_t *)malloc(sizeof(cc_msg_t)); + + /* read message */ + if (read_flat_msg(&msg->flat, &msg->flat_len)) + continue; + + /* unflatten message */ + code = cci_msg_unflatten(msg->flat, msg->flat_len, &msg); + + /* obtain auth info */ + code = obtain_auth_info(&auth_info); + + /* obtain session info */ + code = obtain_session_info(&session_info); + + /* process message */ + code = cci_serv_process_msg(msg, auth_info, session_info, &resp); + + /* flatten response */ + code = cci_msg_flatten(resp, NULL); + + /* send response */ + code = send_flat_msg(resp->flat, resp->flat_len); + + code = destroy_auth_info(auth_info); + + code = destroy_session_info(session_info); + + /* free message */ + code = cci_msg_destroy(msg); + + /* free response */ + code = cci_msg_destroy(resp); + } + return 0; +} diff --git a/src/lib/ccapi/windows/ChangeLog b/src/lib/ccapi/windows/ChangeLog new file mode 100644 index 000000000..aaa59da72 --- /dev/null +++ b/src/lib/ccapi/windows/ChangeLog @@ -0,0 +1,4 @@ +2004-10-27 Jeffrey Altman + + * Initial commit of C CCAPI implementation + -- 2.26.2