Path: blob/main/crypto/krb5/src/ccapi/lib/ccapi_v2.c
39536 views
/* ccapi/lib/ccapi_v2.c */1/*2* Copyright 2006 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 "cci_common.h"26#include "ccapi_string.h"27#include "ccapi_context.h"28#include "ccapi_ccache.h"29#include "ccapi_ccache_iterator.h"30#include "ccapi_credentials.h"31#include "ccapi_credentials_iterator.h"32#include <CredentialsCache2.h>3334infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN };3536/* ------------------------------------------------------------------------ */3738static cc_int32 cci_remap_version (cc_int32 in_v2_version,39cc_uint32 *out_v3_version)40{41cc_result err = ccNoError;4243if (!out_v3_version) { err = cci_check_error (ccErrBadParam); }4445if (!err) {46if (in_v2_version == CC_CRED_V5) {47*out_v3_version = cc_credentials_v5;4849} else {50err = ccErrBadCredentialsVersion;51}52}5354return cci_check_error (err);55}5657/* ------------------------------------------------------------------------ */5859static cc_result _cci_remap_error (cc_result in_error,60const char *in_function,61const char *in_file,62int in_line)63{64_cci_check_error (in_error, in_function, in_file, in_line);6566if (in_error >= CC_NOERROR && in_error <= CC_ERR_CRED_VERSION) {67return in_error;68}6970switch (in_error) {71case ccNoError:72return CC_NOERROR;7374case ccIteratorEnd:75return CC_END;7677case ccErrBadParam:78case ccErrContextNotFound:79case ccErrInvalidContext:80case ccErrInvalidCredentials:81case ccErrInvalidCCacheIterator:82case ccErrInvalidCredentialsIterator:83case ccErrInvalidLock:84case ccErrBadLockType:85return CC_BAD_PARM;8687case ccErrNoMem:88return CC_NOMEM;8990case ccErrInvalidCCache:91case ccErrCCacheNotFound:92return CC_NO_EXIST;9394case ccErrCredentialsNotFound:95return CC_NOTFOUND;9697case ccErrBadName:98return CC_BADNAME;99100case ccErrBadCredentialsVersion:101return CC_ERR_CRED_VERSION;102103case ccErrBadAPIVersion:104return CC_BAD_API_VERSION;105106case ccErrContextLocked:107case ccErrContextUnlocked:108case ccErrCCacheLocked:109case ccErrCCacheUnlocked:110return CC_LOCKED;111112case ccErrServerUnavailable:113case ccErrServerInsecure:114case ccErrServerCantBecomeUID:115case ccErrBadInternalMessage:116case ccErrClientNotFound:117return CC_IO;118119case ccErrNotImplemented:120return CC_NOT_SUPP;121122default:123cci_debug_printf ("%s(): Unhandled error", __FUNCTION__);124return CC_BAD_PARM;125}126}127#define cci_remap_error(err) _cci_remap_error(err, __FUNCTION__, __FILE__, __LINE__)128129130#if TARGET_OS_MAC131#pragma mark -132#endif133134/* ------------------------------------------------------------------------ */135136cc_result cc_shutdown (apiCB **io_context)137{138cc_result err = ccNoError;139140if (!io_context) { err = cci_check_error (ccErrBadParam); }141142if (!err) {143err = ccapi_context_release (*io_context);144}145146if (!err) {147*io_context = NULL;148}149150return cci_remap_error (err);151}152153/* ------------------------------------------------------------------------ */154155cc_result cc_get_change_time (apiCB *in_context,156cc_time_t *out_change_time)157{158cc_result err = ccNoError;159160if (!in_context ) { err = cci_check_error (ccErrBadParam); }161if (!out_change_time) { err = cci_check_error (ccErrBadParam); }162163if (!err) {164err = ccapi_context_get_change_time (in_context, out_change_time);165}166167return cci_remap_error (err);168}169170/* ------------------------------------------------------------------------ */171172cc_result cc_get_NC_info (apiCB *in_context,173infoNC ***out_info)174{175cc_result err = CC_NOERROR;176infoNC **info = NULL;177size_t count = 0; /* Preflight the size */178size_t i;179180if (!in_context) { err = cci_check_error (ccErrBadParam); }181if (!out_info ) { err = cci_check_error (ccErrBadParam); }182183if (!err) {184ccache_cit *iterator = NULL;185186err = cc_seq_fetch_NCs_begin (in_context, &iterator);187188while (!err) {189ccache_p *ccache = NULL;190191err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);192193if (!err) { count++; }194195if (ccache) { cc_close (in_context, &ccache); }196}197if (err == CC_END) { err = CC_NOERROR; }198199if (!err) {200err = cc_seq_fetch_NCs_end (in_context, &iterator);201}202}203204if (!err) {205info = malloc (sizeof (*info) * (count + 1));206if (info) {207for (i = 0; i < count + 1; i++) { info[i] = NULL; }208} else {209err = cci_check_error (CC_NOMEM);210}211}212213if (!err) {214ccache_cit *iterator = NULL;215216err = cc_seq_fetch_NCs_begin (in_context, &iterator);217218for (i = 0; !err && i < count; i++) {219ccache_p *ccache = NULL;220221err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);222223if (!err) {224info[i] = malloc (sizeof (*info[i]));225if (info[i]) {226*info[i] = infoNC_initializer;227} else {228err = cci_check_error (CC_NOMEM);229}230}231232if (!err) {233err = cc_get_name (in_context, ccache, &info[i]->name);234}235236if (!err) {237err = cc_get_principal (in_context, ccache, &info[i]->principal);238}239240if (!err) {241err = cc_get_cred_version (in_context, ccache, &info[i]->vers);242}243244if (ccache) { cc_close (in_context, &ccache); }245}246247if (!err) {248err = cc_seq_fetch_NCs_end (in_context, &iterator);249}250}251252if (!err) {253*out_info = info;254info = NULL;255}256257if (info) { cc_free_NC_info (in_context, &info); }258259return cci_check_error (err);260}261262#if TARGET_OS_MAC263#pragma mark -264#endif265266/* ------------------------------------------------------------------------ */267268cc_int32 cc_open (apiCB *in_context,269const char *in_name,270cc_int32 in_version,271cc_uint32 in_flags,272ccache_p **out_ccache)273{274cc_result err = ccNoError;275cc_ccache_t ccache = NULL;276cc_uint32 compat_version;277cc_uint32 real_version;278279if (!in_context) { err = cci_check_error (ccErrBadParam); }280if (!in_name ) { err = cci_check_error (ccErrBadParam); }281if (!out_ccache) { err = cci_check_error (ccErrBadParam); }282283if (!err) {284err = cci_remap_version (in_version, &compat_version);285}286287if (!err) {288err = ccapi_context_open_ccache (in_context, in_name, &ccache);289}290291/* We must not allow a CCAPI v2 caller to open a v5-only ccache292as a v4 ccache and vice versa. Allowing that would break293(valid) assumptions made by CCAPI v2 callers. */294295if (!err) {296err = ccapi_ccache_get_credentials_version (ccache, &real_version);297}298299if (!err) {300/* check the version and set up the ccache to use it */301if (compat_version & real_version) {302err = cci_ccache_set_compat_version (ccache, compat_version);303} else {304err = ccErrBadCredentialsVersion;305}306}307308if (!err) {309*out_ccache = ccache;310ccache = NULL;311}312313if (ccache) { ccapi_ccache_release (ccache); }314315return cci_remap_error (err);316}317318/* ------------------------------------------------------------------------ */319320cc_result cc_create (apiCB *in_context,321const char *in_name,322const char *in_principal,323cc_int32 in_version,324cc_uint32 in_flags,325ccache_p **out_ccache)326{327cc_result err = ccNoError;328cc_ccache_t ccache = NULL;329cc_uint32 compat_version;330331if (!in_context) { err = cci_check_error (ccErrBadParam); }332if (!in_name ) { err = cci_check_error (ccErrBadParam); }333if (!out_ccache) { err = cci_check_error (ccErrBadParam); }334335if (!err) {336err = cci_remap_version (in_version, &compat_version);337}338339if (!err) {340err = ccapi_context_create_ccache (in_context, in_name, compat_version,341in_principal, &ccache);342}343344if (!err) {345err = cci_ccache_set_compat_version (ccache, compat_version);346}347348if (!err) {349*out_ccache = ccache;350ccache = NULL;351}352353if (ccache) { ccapi_ccache_release (ccache); }354355return cci_remap_error (err);356}357358/* ------------------------------------------------------------------------ */359360cc_result cc_close (apiCB *in_context,361ccache_p **io_ccache)362{363cc_result err = ccNoError;364365if (!in_context) { err = cci_check_error (ccErrBadParam); }366if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }367368if (!err) {369err = ccapi_ccache_release (*io_ccache);370}371372if (!err) {373*io_ccache = NULL;374}375376return cci_remap_error (err);377}378379/* ------------------------------------------------------------------------ */380381cc_result cc_destroy (apiCB *in_context,382ccache_p **io_ccache)383{384cc_result err = ccNoError;385386if (!in_context) { err = cci_check_error (ccErrBadParam); }387if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }388389if (!err) {390err = ccapi_ccache_destroy (*io_ccache);391}392393if (!err) {394*io_ccache = NULL;395}396397return cci_remap_error (err);398}399400/* ------------------------------------------------------------------------ */401402cc_result cc_get_name (apiCB *in_context,403ccache_p *in_ccache,404char **out_name)405{406cc_result err = ccNoError;407cc_string_t name = NULL;408409if (!in_context) { err = cci_check_error (ccErrBadParam); }410if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }411if (!out_name ) { err = cci_check_error (ccErrBadParam); }412413if (!err) {414err = ccapi_ccache_get_name (in_ccache, &name);415}416417if (!err) {418char *string = strdup (name->data);419if (string) {420*out_name = string;421} else {422err = cci_check_error (ccErrNoMem);423}424}425426if (name) { ccapi_string_release (name); }427428return cci_remap_error (err);429}430431/* ------------------------------------------------------------------------ */432433cc_result cc_get_cred_version (apiCB *in_context,434ccache_p *in_ccache,435cc_int32 *out_version)436{437cc_result err = ccNoError;438cc_uint32 compat_version;439440if (!in_context ) { err = cci_check_error (ccErrBadParam); }441if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }442if (!out_version) { err = cci_check_error (ccErrBadParam); }443444if (!err) {445err = cci_ccache_get_compat_version (in_ccache, &compat_version);446}447448if (!err) {449if (compat_version == cc_credentials_v5) {450*out_version = CC_CRED_V5;451452} else {453err = ccErrBadCredentialsVersion;454}455}456457return cci_remap_error (err);458}459460/* ------------------------------------------------------------------------ */461462cc_result cc_set_principal (apiCB *in_context,463ccache_p *io_ccache,464cc_int32 in_version,465char *in_principal)466{467cc_result err = ccNoError;468cc_uint32 version;469cc_uint32 compat_version;470471if (!in_context ) { err = cci_check_error (ccErrBadParam); }472if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }473if (!in_principal) { err = cci_check_error (ccErrBadParam); }474475if (!err) {476err = cci_remap_version (in_version, &version);477}478479if (!err) {480err = cci_ccache_get_compat_version (io_ccache, &compat_version);481}482483if (!err && version != compat_version) {484err = cci_check_error (ccErrBadCredentialsVersion);485}486487if (!err) {488err = ccapi_ccache_set_principal (io_ccache, version, in_principal);489}490491return cci_remap_error (err);492}493494/* ------------------------------------------------------------------------ */495496cc_result cc_get_principal (apiCB *in_context,497ccache_p *in_ccache,498char **out_principal)499{500cc_result err = ccNoError;501cc_uint32 compat_version;502cc_string_t principal = NULL;503504if (!in_context ) { err = cci_check_error (ccErrBadParam); }505if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }506if (!out_principal) { err = cci_check_error (ccErrBadParam); }507508if (!err) {509err = cci_ccache_get_compat_version (in_ccache, &compat_version);510}511512if (!err) {513err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal);514}515516if (!err) {517char *string = strdup (principal->data);518if (string) {519*out_principal = string;520} else {521err = cci_check_error (ccErrNoMem);522}523}524525if (principal) { ccapi_string_release (principal); }526527return cci_remap_error (err);528}529530/* ------------------------------------------------------------------------ */531532cc_result cc_store (apiCB *in_context,533ccache_p *io_ccache,534cred_union in_credentials)535{536cc_result err = ccNoError;537cc_credentials_union *creds_union = NULL;538539if (!in_context) { err = cci_check_error (ccErrBadParam); }540if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }541542if (!err) {543err = cci_cred_union_to_credentials_union (&in_credentials,544&creds_union);545}546547if (!err) {548err = ccapi_ccache_store_credentials (io_ccache, creds_union);549}550551if (creds_union) { cci_credentials_union_release (creds_union); }552return cci_remap_error (err);553}554555/* ------------------------------------------------------------------------ */556557cc_result cc_remove_cred (apiCB *in_context,558ccache_p *in_ccache,559cred_union in_credentials)560{561cc_result err = ccNoError;562cc_credentials_iterator_t iterator = NULL;563cc_uint32 found = 0;564565if (!in_context) { err = cci_check_error (ccErrBadParam); }566if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }567568if (!err) {569err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator);570}571572while (!err && !found) {573cc_credentials_t creds = NULL;574575err = ccapi_credentials_iterator_next (iterator, &creds);576577if (!err) {578err = cci_cred_union_compare_to_credentials_union (&in_credentials,579creds->data,580&found);581}582583if (!err && found) {584err = ccapi_ccache_remove_credentials (in_ccache, creds);585}586587ccapi_credentials_release (creds);588}589if (err == ccIteratorEnd) { err = cci_check_error (ccErrCredentialsNotFound); }590591return cci_remap_error (err);592}593594#if TARGET_OS_MAC595#pragma mark -596#endif597598/* ------------------------------------------------------------------------ */599600cc_result cc_seq_fetch_NCs_begin (apiCB *in_context,601ccache_cit **out_iterator)602{603cc_result err = ccNoError;604cc_ccache_iterator_t iterator = NULL;605606if (!in_context ) { err = cci_check_error (ccErrBadParam); }607if (!out_iterator) { err = cci_check_error (ccErrBadParam); }608609if (!err) {610err = ccapi_context_new_ccache_iterator (in_context, &iterator);611}612613if (!err) {614*out_iterator = (ccache_cit *) iterator;615iterator = NULL; /* take ownership */616}617618if (iterator) { ccapi_ccache_iterator_release (iterator); }619620return cci_remap_error (err);621}622623/* ------------------------------------------------------------------------ */624625cc_result cc_seq_fetch_NCs_next (apiCB *in_context,626ccache_p **out_ccache,627ccache_cit *in_iterator)628{629cc_result err = ccNoError;630cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator;631cc_ccache_t ccache = NULL;632const char *saved_ccache_name;633634if (!in_context ) { err = cci_check_error (ccErrBadParam); }635if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }636if (!in_iterator) { err = cci_check_error (ccErrBadParam); }637638if (!err) {639err = cci_ccache_iterator_get_saved_ccache_name (iterator,640&saved_ccache_name);641}642643if (!err) {644if (saved_ccache_name) {645err = ccapi_context_open_ccache (in_context, saved_ccache_name,646&ccache);647648if (!err) {649err = cci_ccache_set_compat_version (ccache, cc_credentials_v5);650}651652if (!err) {653err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL);654}655656} else {657cc_uint32 version = 0;658659err = ccapi_ccache_iterator_next (iterator, &ccache);660661if (!err) {662err = ccapi_ccache_get_credentials_version (ccache, &version);663}664665if (!err) {666err = cci_ccache_set_compat_version (ccache, version);667}668}669}670671if (!err) {672*out_ccache = ccache;673ccache = NULL; /* take ownership */674}675676if (ccache) { ccapi_ccache_release (ccache); }677678return cci_remap_error (err);679}680681/* ------------------------------------------------------------------------ */682683cc_result cc_seq_fetch_NCs_end (apiCB *in_context,684ccache_cit **io_iterator)685{686cc_result err = ccNoError;687cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) *io_iterator;688689if (!in_context ) { err = cci_check_error (ccErrBadParam); }690if (!io_iterator) { err = cci_check_error (ccErrBadParam); }691692if (!err) {693err = ccapi_ccache_iterator_release (iterator);694}695696if (!err) {697*io_iterator = NULL;698}699700return cci_remap_error (err);701}702703#if TARGET_OS_MAC704#pragma mark -705#endif706707/* ------------------------------------------------------------------------ */708709cc_result cc_seq_fetch_creds_begin (apiCB *in_context,710const ccache_p *in_ccache,711ccache_cit **out_iterator)712{713cc_result err = ccNoError;714cc_credentials_iterator_t iterator = NULL;715cc_uint32 compat_version;716717if (!in_context ) { err = cci_check_error (ccErrBadParam); }718if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }719if (!out_iterator) { err = cci_check_error (ccErrBadParam); }720721if (!err) {722err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache,723&compat_version);724}725726if (!err) {727err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache,728&iterator);729}730731if (!err) {732err = cci_credentials_iterator_set_compat_version (iterator,733compat_version);734}735736if (!err) {737*out_iterator = (ccache_cit *) iterator;738iterator = NULL; /* take ownership */739}740741if (iterator) { ccapi_credentials_iterator_release (iterator); }742743return cci_remap_error (err);744}745746/* ------------------------------------------------------------------------ */747748cc_result cc_seq_fetch_creds_next (apiCB *in_context,749cred_union **out_creds,750ccache_cit *in_iterator)751{752cc_result err = ccNoError;753cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator;754cc_uint32 compat_version;755756if (!in_context ) { err = cci_check_error (ccErrBadParam); }757if (!out_creds ) { err = cci_check_error (ccErrBadParam); }758if (!in_iterator) { err = cci_check_error (ccErrBadParam); }759760if (!err) {761err = cci_credentials_iterator_get_compat_version (iterator,762&compat_version);763}764765while (!err) {766cc_credentials_t credentials = NULL;767768err = ccapi_credentials_iterator_next (iterator, &credentials);769770if (!err && (credentials->data->version & compat_version)) {771/* got the next credentials for the correct version */772err = cci_credentials_union_to_cred_union (credentials->data,773out_creds);774break;775}776777if (credentials) { ccapi_credentials_release (credentials); }778}779780return cci_remap_error (err);781}782783/* ------------------------------------------------------------------------ */784785cc_result cc_seq_fetch_creds_end (apiCB *in_context,786ccache_cit **io_iterator)787{788cc_result err = ccNoError;789cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) *io_iterator;790791if (!in_context ) { err = cci_check_error (ccErrBadParam); }792if (!io_iterator) { err = cci_check_error (ccErrBadParam); }793794if (!err) {795err = ccapi_credentials_iterator_release (iterator);796}797798if (!err) {799*io_iterator = NULL;800}801802return cci_remap_error (err);803}804805#if TARGET_OS_MAC806#pragma mark -807#endif808809/* ------------------------------------------------------------------------ */810811cc_result cc_free_principal (apiCB *in_context,812char **io_principal)813{814cc_result err = ccNoError;815816if (!in_context ) { err = cci_check_error (ccErrBadParam); }817if (!io_principal) { err = cci_check_error (ccErrBadParam); }818819if (!err) {820free (*io_principal);821*io_principal = NULL;822}823824return cci_remap_error (err);825}826827/* ------------------------------------------------------------------------ */828829cc_result cc_free_name (apiCB *in_context,830char **io_name)831{832cc_result err = ccNoError;833834if (!in_context) { err = cci_check_error (ccErrBadParam); }835if (!io_name ) { err = cci_check_error (ccErrBadParam); }836837if (!err) {838free (*io_name);839*io_name = NULL;840}841842return cci_remap_error (err);843}844845/* ------------------------------------------------------------------------ */846847cc_result cc_free_creds (apiCB *in_context,848cred_union **io_credentials)849{850cc_result err = ccNoError;851852if (!in_context ) { err = cci_check_error (ccErrBadParam); }853if (!io_credentials) { err = cci_check_error (ccErrBadParam); }854855if (!err) {856err = cci_cred_union_release (*io_credentials);857if (!err) { *io_credentials = NULL; }858}859860return cci_remap_error (err);861}862863/* ------------------------------------------------------------------------ */864865cc_result cc_free_NC_info (apiCB *in_context,866infoNC ***io_info)867{868cc_result err = ccNoError;869870if (!in_context) { err = cci_check_error (ccErrBadParam); }871if (!io_info ) { err = cci_check_error (ccErrBadParam); }872873if (!err && *io_info) {874infoNC **data = *io_info;875size_t i;876877for (i = 0; data[i] != NULL; i++) {878cc_free_principal (in_context, &data[i]->principal);879cc_free_name (in_context, &data[i]->name);880free (data[i]);881}882free (data);883884*io_info = NULL;885}886887return cci_remap_error (err);888}889890891