/* $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; }