Path: blob/main/crypto/krb5/src/ccapi/lib/ccapi_ccache.c
39536 views
/* ccapi/lib/ccapi_ccache.c */1/*2* Copyright 2006, 2007 Massachusetts Institute of Technology.3* All Rights Reserved.4*5* Export of this software from the United States of America may6* require a specific license from the United States Government.7* It is the responsibility of any person or organization contemplating8* export to obtain such a license before exporting.9*10* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and11* distribute this software and its documentation for any purpose and12* without fee is hereby granted, provided that the above copyright13* notice appear in all copies and that both that copyright notice and14* this permission notice appear in supporting documentation, and that15* the name of M.I.T. not be used in advertising or publicity pertaining16* to distribution of the software without specific, written prior17* permission. Furthermore if you modify this software you must label18* your software as modified software and not distribute it in such a19* fashion that it might be confused with the original M.I.T. software.20* M.I.T. makes no representations about the suitability of21* this software for any purpose. It is provided "as is" without express22* or implied warranty.23*/2425#include "ccapi_ccache.h"2627#include "ccapi_string.h"28#include "ccapi_credentials.h"29#include "ccapi_credentials_iterator.h"30#include "ccapi_ipc.h"3132/* ------------------------------------------------------------------------ */3334typedef struct cci_ccache_d {35cc_ccache_f *functions;36#if TARGET_OS_MAC37cc_ccache_f *vector_functions;38#endif39cci_identifier_t identifier;40cc_time_t last_wait_for_change_time;41cc_uint32 compat_version;42} *cci_ccache_t;4344/* ------------------------------------------------------------------------ */4546struct cci_ccache_d cci_ccache_initializer = {47NULL48VECTOR_FUNCTIONS_INITIALIZER,49NULL,50051};5253cc_ccache_f cci_ccache_f_initializer = {54ccapi_ccache_release,55ccapi_ccache_destroy,56ccapi_ccache_set_default,57ccapi_ccache_get_credentials_version,58ccapi_ccache_get_name,59ccapi_ccache_get_principal,60ccapi_ccache_set_principal,61ccapi_ccache_store_credentials,62ccapi_ccache_remove_credentials,63ccapi_ccache_new_credentials_iterator,64ccapi_ccache_move,65ccapi_ccache_lock,66ccapi_ccache_unlock,67ccapi_ccache_get_last_default_time,68ccapi_ccache_get_change_time,69ccapi_ccache_compare,70ccapi_ccache_get_kdc_time_offset,71ccapi_ccache_set_kdc_time_offset,72ccapi_ccache_clear_kdc_time_offset,73ccapi_ccache_wait_for_change74};7576/* ------------------------------------------------------------------------ */7778cc_int32 cci_ccache_new (cc_ccache_t *out_ccache,79cci_identifier_t in_identifier)80{81cc_int32 err = ccNoError;82cci_ccache_t ccache = NULL;8384if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }85if (!in_identifier) { err = cci_check_error (ccErrBadParam); }8687if (!err) {88ccache = malloc (sizeof (*ccache));89if (ccache) {90*ccache = cci_ccache_initializer;91} else {92err = cci_check_error (ccErrNoMem);93}94}9596if (!err) {97ccache->functions = malloc (sizeof (*ccache->functions));98if (ccache->functions) {99*ccache->functions = cci_ccache_f_initializer;100} else {101err = cci_check_error (ccErrNoMem);102}103}104105if (!err) {106err = cci_identifier_copy (&ccache->identifier, in_identifier);107}108109if (!err) {110*out_ccache = (cc_ccache_t) ccache;111ccache = NULL; /* take ownership */112}113114ccapi_ccache_release ((cc_ccache_t) ccache);115116return cci_check_error (err);117}118119/* ------------------------------------------------------------------------ */120121cc_int32 cci_ccache_write (cc_ccache_t in_ccache,122k5_ipc_stream in_stream)123{124cc_int32 err = ccNoError;125cci_ccache_t ccache = (cci_ccache_t) in_ccache;126127if (!in_ccache) { err = cci_check_error (ccErrBadParam); }128if (!in_stream) { err = cci_check_error (ccErrBadParam); }129130if (!err) {131err = cci_identifier_write (ccache->identifier, in_stream);132}133134return cci_check_error (err);135}136137#ifdef TARGET_OS_MAC138#pragma mark -139#endif140141/* ------------------------------------------------------------------------ */142143cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache)144{145cc_int32 err = ccNoError;146cci_ccache_t ccache = (cci_ccache_t) io_ccache;147148if (!io_ccache) { err = ccErrBadParam; }149150if (!err) {151cci_identifier_release (ccache->identifier);152153free ((char *) ccache->functions);154free (ccache);155}156157return err;158}159160/* ------------------------------------------------------------------------ */161162cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache)163{164cc_int32 err = ccNoError;165cci_ccache_t ccache = (cci_ccache_t) io_ccache;166167if (!io_ccache) { err = cci_check_error (ccErrBadParam); }168169if (!err) {170err = cci_ipc_send (cci_ccache_destroy_msg_id,171ccache->identifier,172NULL,173NULL);174}175176if (!err) {177err = ccapi_ccache_release (io_ccache);178}179180return cci_check_error (err);181}182183/* ------------------------------------------------------------------------ */184185cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache)186{187cc_int32 err = ccNoError;188cci_ccache_t ccache = (cci_ccache_t) io_ccache;189190if (!io_ccache) { err = cci_check_error (ccErrBadParam); }191192if (!err) {193err = cci_ipc_send (cci_ccache_set_default_msg_id,194ccache->identifier,195NULL,196NULL);197}198199return cci_check_error (err);200}201202/* ------------------------------------------------------------------------ */203204cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache,205cc_uint32 *out_credentials_version)206{207cc_int32 err = ccNoError;208cci_ccache_t ccache = (cci_ccache_t) in_ccache;209k5_ipc_stream reply = NULL;210211if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }212if (!out_credentials_version) { err = cci_check_error (ccErrBadParam); }213214if (!err) {215err = cci_ipc_send (cci_ccache_get_credentials_version_msg_id,216ccache->identifier,217NULL,218&reply);219}220221if (!err) {222err = krb5int_ipc_stream_read_uint32 (reply, out_credentials_version);223}224225krb5int_ipc_stream_release (reply);226227return cci_check_error (err);228}229230/* ------------------------------------------------------------------------ */231232cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache,233cc_string_t *out_name)234{235cc_int32 err = ccNoError;236cci_ccache_t ccache = (cci_ccache_t) in_ccache;237k5_ipc_stream reply = NULL;238char *name = NULL;239240if (!in_ccache) { err = cci_check_error (ccErrBadParam); }241if (!out_name ) { err = cci_check_error (ccErrBadParam); }242243if (!err) {244err = cci_ipc_send (cci_ccache_get_name_msg_id,245ccache->identifier,246NULL,247&reply);248}249250if (!err) {251err = krb5int_ipc_stream_read_string (reply, &name);252}253254if (!err) {255err = cci_string_new (out_name, name);256}257258krb5int_ipc_stream_release (reply);259krb5int_ipc_stream_free_string (name);260261return cci_check_error (err);262}263264/* ------------------------------------------------------------------------ */265266cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache,267cc_uint32 in_credentials_version,268cc_string_t *out_principal)269{270cc_int32 err = ccNoError;271cci_ccache_t ccache = (cci_ccache_t) in_ccache;272k5_ipc_stream request = NULL;273k5_ipc_stream reply = NULL;274char *principal = NULL;275276if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }277if (!out_principal) { err = cci_check_error (ccErrBadParam); }278279if (!err) {280err = krb5int_ipc_stream_new (&request);281}282283if (!err) {284err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);285}286287if (!err) {288err = cci_ipc_send (cci_ccache_get_principal_msg_id,289ccache->identifier,290request,291&reply);292}293294if (!err) {295err = krb5int_ipc_stream_read_string (reply, &principal);296}297298if (!err) {299err = cci_string_new (out_principal, principal);300}301302krb5int_ipc_stream_release (request);303krb5int_ipc_stream_release (reply);304krb5int_ipc_stream_free_string (principal);305306return cci_check_error (err);307}308309/* ------------------------------------------------------------------------ */310311cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache,312cc_uint32 in_credentials_version,313const char *in_principal)314{315cc_int32 err = ccNoError;316cci_ccache_t ccache = (cci_ccache_t) io_ccache;317k5_ipc_stream request = NULL;318319if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }320if (!in_principal) { err = cci_check_error (ccErrBadParam); }321322if (!err) {323err = krb5int_ipc_stream_new (&request);324}325326if (!err) {327err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);328}329330if (!err) {331err = krb5int_ipc_stream_write_string (request, in_principal);332}333334if (!err) {335err = cci_ipc_send (cci_ccache_set_principal_msg_id,336ccache->identifier,337request,338NULL);339}340341krb5int_ipc_stream_release (request);342343return cci_check_error (err);344}345346/* ------------------------------------------------------------------------ */347348cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache,349const cc_credentials_union *in_credentials_union)350{351cc_int32 err = ccNoError;352cci_ccache_t ccache = (cci_ccache_t) io_ccache;353k5_ipc_stream request = NULL;354355if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }356if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }357358if (!err) {359err = krb5int_ipc_stream_new (&request);360}361362if (!err) {363err = cci_credentials_union_write (in_credentials_union, request);364}365366if (!err) {367err = cci_ipc_send (cci_ccache_store_credentials_msg_id,368ccache->identifier,369request,370NULL);371}372373krb5int_ipc_stream_release (request);374375return cci_check_error (err);376}377378/* ------------------------------------------------------------------------ */379380cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache,381cc_credentials_t in_credentials)382{383cc_int32 err = ccNoError;384cci_ccache_t ccache = (cci_ccache_t) io_ccache;385k5_ipc_stream request = NULL;386387if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }388if (!in_credentials) { err = cci_check_error (ccErrBadParam); }389390if (!err) {391err = krb5int_ipc_stream_new (&request);392}393394if (!err) {395err = cci_credentials_write (in_credentials, request);396}397398if (!err) {399err = cci_ipc_send (cci_ccache_remove_credentials_msg_id,400ccache->identifier,401request,402NULL);403}404405krb5int_ipc_stream_release (request);406407return cci_check_error (err);408}409410/* ------------------------------------------------------------------------ */411412cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache,413cc_credentials_iterator_t *out_credentials_iterator)414{415cc_int32 err = ccNoError;416cci_ccache_t ccache = (cci_ccache_t) in_ccache;417k5_ipc_stream reply = NULL;418cci_identifier_t identifier = NULL;419420if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }421if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }422423if (!err) {424err = cci_ipc_send (cci_ccache_new_credentials_iterator_msg_id,425ccache->identifier,426NULL,427&reply);428}429430if (!err) {431err = cci_identifier_read (&identifier, reply);432}433434if (!err) {435err = cci_credentials_iterator_new (out_credentials_iterator, identifier);436}437438krb5int_ipc_stream_release (reply);439cci_identifier_release (identifier);440441return cci_check_error (err);442}443444/* ------------------------------------------------------------------------ */445/* Note: message is sent as the destination to avoid extra work on the */446/* server when deleting it the source ccache. */447448cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache,449cc_ccache_t io_destination_ccache)450{451cc_int32 err = ccNoError;452cci_ccache_t source_ccache = (cci_ccache_t) io_source_ccache;453cci_ccache_t destination_ccache = (cci_ccache_t) io_destination_ccache;454k5_ipc_stream request = NULL;455456if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); }457if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }458459if (!err) {460err = krb5int_ipc_stream_new (&request);461}462463if (!err) {464err = cci_identifier_write (source_ccache->identifier, request);465}466467if (!err) {468err = cci_ipc_send (cci_ccache_move_msg_id,469destination_ccache->identifier,470request,471NULL);472}473474krb5int_ipc_stream_release (request);475476return cci_check_error (err);477}478479/* ------------------------------------------------------------------------ */480481cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache,482cc_uint32 in_lock_type,483cc_uint32 in_block)484{485cc_int32 err = ccNoError;486cci_ccache_t ccache = (cci_ccache_t) io_ccache;487k5_ipc_stream request = NULL;488489if (!io_ccache) { err = cci_check_error (ccErrBadParam); }490491if (!err) {492err = krb5int_ipc_stream_new (&request);493}494495if (!err) {496err = krb5int_ipc_stream_write_uint32 (request, in_lock_type);497}498499if (!err) {500err = krb5int_ipc_stream_write_uint32 (request, in_block);501}502503if (!err) {504err = cci_ipc_send (cci_ccache_lock_msg_id,505ccache->identifier,506request,507NULL);508}509510krb5int_ipc_stream_release (request);511512return cci_check_error (err);513}514515/* ------------------------------------------------------------------------ */516517cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache)518{519cc_int32 err = ccNoError;520cci_ccache_t ccache = (cci_ccache_t) io_ccache;521522if (!io_ccache) { err = cci_check_error (ccErrBadParam); }523524if (!err) {525err = cci_ipc_send (cci_ccache_unlock_msg_id,526ccache->identifier,527NULL,528NULL);529}530531return cci_check_error (err);532}533534/* ------------------------------------------------------------------------ */535536cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache,537cc_time_t *out_last_default_time)538{539cc_int32 err = ccNoError;540cci_ccache_t ccache = (cci_ccache_t) in_ccache;541k5_ipc_stream reply = NULL;542543if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }544if (!out_last_default_time) { err = cci_check_error (ccErrBadParam); }545546if (!err) {547err = cci_ipc_send (cci_ccache_get_last_default_time_msg_id,548ccache->identifier,549NULL,550&reply);551}552553if (!err) {554err = krb5int_ipc_stream_read_time (reply, out_last_default_time);555}556557krb5int_ipc_stream_release (reply);558559return cci_check_error (err);560}561562/* ------------------------------------------------------------------------ */563564cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache,565cc_time_t *out_change_time)566{567cc_int32 err = ccNoError;568cci_ccache_t ccache = (cci_ccache_t) in_ccache;569k5_ipc_stream reply = NULL;570571if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }572if (!out_change_time) { err = cci_check_error (ccErrBadParam); }573574if (!err) {575err = cci_ipc_send (cci_ccache_get_change_time_msg_id,576ccache->identifier,577NULL,578&reply);579}580581if (!err) {582err = krb5int_ipc_stream_read_time (reply, out_change_time);583}584585krb5int_ipc_stream_release (reply);586587return cci_check_error (err);588}589590/* ------------------------------------------------------------------------ */591592cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache)593{594cc_int32 err = ccNoError;595cci_ccache_t ccache = (cci_ccache_t) in_ccache;596k5_ipc_stream request = NULL;597k5_ipc_stream reply = NULL;598599if (!in_ccache) { err = cci_check_error (ccErrBadParam); }600601if (!err) {602err = krb5int_ipc_stream_new (&request);603}604605if (!err) {606err = krb5int_ipc_stream_write_time (request, ccache->last_wait_for_change_time);607}608609if (!err) {610err = cci_ipc_send (cci_ccache_wait_for_change_msg_id,611ccache->identifier,612request,613&reply);614}615616if (!err) {617err = krb5int_ipc_stream_read_time (reply, &ccache->last_wait_for_change_time);618}619620krb5int_ipc_stream_release (request);621krb5int_ipc_stream_release (reply);622623return cci_check_error (err);624}625626/* ------------------------------------------------------------------------ */627628cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache,629cc_ccache_t in_compare_to_ccache,630cc_uint32 *out_equal)631{632cc_int32 err = ccNoError;633cci_ccache_t ccache = (cci_ccache_t) in_ccache;634cci_ccache_t compare_to_ccache = (cci_ccache_t) in_compare_to_ccache;635636if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }637if (!in_compare_to_ccache) { err = cci_check_error (ccErrBadParam); }638if (!out_equal ) { err = cci_check_error (ccErrBadParam); }639640if (!err) {641err = cci_identifier_compare (ccache->identifier,642compare_to_ccache->identifier,643out_equal);644}645646return cci_check_error (err);647}648649/* ------------------------------------------------------------------------ */650651cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache,652cc_uint32 in_credentials_version,653cc_time_t *out_time_offset)654{655cc_int32 err = ccNoError;656cci_ccache_t ccache = (cci_ccache_t) in_ccache;657k5_ipc_stream request = NULL;658k5_ipc_stream reply = NULL;659660if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }661if (!out_time_offset) { err = cci_check_error (ccErrBadParam); }662663if (!err) {664err = krb5int_ipc_stream_new (&request);665}666667if (!err) {668err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);669}670671if (!err) {672err = cci_ipc_send (cci_ccache_get_kdc_time_offset_msg_id,673ccache->identifier,674request,675&reply);676}677678if (!err) {679err = krb5int_ipc_stream_read_time (reply, out_time_offset);680}681682krb5int_ipc_stream_release (request);683krb5int_ipc_stream_release (reply);684685return cci_check_error (err);686}687688/* ------------------------------------------------------------------------ */689690cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache,691cc_uint32 in_credentials_version,692cc_time_t in_time_offset)693{694cc_int32 err = ccNoError;695cci_ccache_t ccache = (cci_ccache_t) io_ccache;696k5_ipc_stream request = NULL;697698if (!io_ccache) { err = cci_check_error (ccErrBadParam); }699700if (!err) {701err = krb5int_ipc_stream_new (&request);702}703704if (!err) {705err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);706}707708if (!err) {709err = krb5int_ipc_stream_write_time (request, in_time_offset);710}711712if (!err) {713err = cci_ipc_send (cci_ccache_set_kdc_time_offset_msg_id,714ccache->identifier,715request,716NULL);717}718719krb5int_ipc_stream_release (request);720721return cci_check_error (err);722}723724/* ------------------------------------------------------------------------ */725726cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,727cc_uint32 in_credentials_version)728{729cc_int32 err = ccNoError;730cci_ccache_t ccache = (cci_ccache_t) io_ccache;731k5_ipc_stream request = NULL;732733if (!io_ccache) { err = cci_check_error (ccErrBadParam); }734735if (!err) {736err = krb5int_ipc_stream_new (&request);737}738739if (!err) {740err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);741}742743if (!err) {744err = cci_ipc_send (cci_ccache_clear_kdc_time_offset_msg_id,745ccache->identifier,746request,747NULL);748}749750krb5int_ipc_stream_release (request);751752return cci_check_error (err);753}754755#ifdef TARGET_OS_MAC756#pragma mark -757#endif758759/* ------------------------------------------------------------------------ */760761cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache,762cc_uint32 *out_compat_version)763{764cc_int32 err = ccNoError;765cci_ccache_t ccache = (cci_ccache_t) in_ccache;766767if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }768if (!out_compat_version) { err = cci_check_error (ccErrBadParam); }769770if (!err) {771*out_compat_version = ccache->compat_version;772}773774return cci_check_error (err);775}776777/* ------------------------------------------------------------------------ */778779cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,780cc_uint32 in_compat_version)781{782cc_int32 err = ccNoError;783cci_ccache_t ccache = (cci_ccache_t) io_ccache;784785if (!io_ccache) { err = cci_check_error (ccErrBadParam); }786787if (!err) {788ccache->compat_version = in_compat_version;789}790791return cci_check_error (err);792}793794795