From: Alexandra Ellwood Date: Wed, 6 Feb 2008 20:22:32 +0000 (+0000) Subject: Need CCAPI v2 support for Windows X-Git-Tag: krb5-1.7-alpha1~740 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=266fde72702c39317d6a82c2aaf3de460bee633c;p=thirdparty%2Fkrb5.git Need CCAPI v2 support for Windows Added initial checkin of CCAPI v2 shim layer. ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20220 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/ccapi/common/cci_cred_union.c b/src/ccapi/common/cci_cred_union.c index 55da1e264b..902013dec1 100644 --- a/src/ccapi/common/cci_cred_union.c +++ b/src/ccapi/common/cci_cred_union.c @@ -594,7 +594,7 @@ static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds, /* ------------------------------------------------------------------------ */ -cc_uint32 cci_cred_union_release (cc_credentials_union *io_cred_union) +cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union) { cc_int32 err = ccNoError; @@ -614,31 +614,31 @@ cc_uint32 cci_cred_union_release (cc_credentials_union *io_cred_union) /* ------------------------------------------------------------------------ */ -cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union, - cci_stream_t io_stream) +cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union, + cci_stream_t io_stream) { cc_int32 err = ccNoError; - cc_credentials_union *cred_union = NULL; + cc_credentials_union *credentials_union = NULL; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!err) { - cred_union = malloc (sizeof (*cred_union)); - if (!cred_union) { err = cci_check_error (ccErrNoMem); } + credentials_union = calloc (1, sizeof (*credentials_union)); + if (!credentials_union) { err = cci_check_error (ccErrNoMem); } } if (!err) { - err = cci_stream_read_uint32 (io_stream, &cred_union->version); + err = cci_stream_read_uint32 (io_stream, &credentials_union->version); } if (!err) { - if (cred_union->version == cc_credentials_v4) { - err = cci_credentials_v4_read (&cred_union->credentials.credentials_v4, + if (credentials_union->version == cc_credentials_v4) { + err = cci_credentials_v4_read (&credentials_union->credentials.credentials_v4, io_stream); - } else if (cred_union->version == cc_credentials_v5) { - err = cci_credentials_v5_read (&cred_union->credentials.credentials_v5, + } else if (credentials_union->version == cc_credentials_v5) { + err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5, io_stream); @@ -648,19 +648,19 @@ cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union, } if (!err) { - *out_credentials_union = cred_union; - cred_union = NULL; + *out_credentials_union = credentials_union; + credentials_union = NULL; } - if (cred_union) { cci_cred_union_release (cred_union); } + if (credentials_union) { cci_credentials_union_release (credentials_union); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ -cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union, - cci_stream_t io_stream) +cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union, + cci_stream_t io_stream) { cc_int32 err = ccNoError; @@ -687,3 +687,413 @@ cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union return cci_check_error (err); } + +#ifdef TARGET_OS_MAC +#pragma mark - +#pragma mark -- CCAPI v2 Compat -- +#endif + +/* ------------------------------------------------------------------------ */ + +cc_credentials_v5_compat cci_credentials_v5_compat_initializer = { + NULL, + NULL, + { 0, 0, NULL }, + 0, 0, 0, 0, 0, 0, + NULL, + { 0, 0, NULL }, + { 0, 0, NULL }, + NULL +}; + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_release (cred_union *io_cred_union) +{ + cc_int32 err = ccNoError; + + if (!io_cred_union) { err = ccErrBadParam; } + + if (!err) { + if (io_cred_union->cred_type == CC_CRED_V4) { + memset (io_cred_union->cred.pV4Cred, 0, sizeof (cc_credentials_v4_compat)); + free (io_cred_union->cred.pV4Cred); + + } else if (io_cred_union->cred_type == CC_CRED_V5) { + free (io_cred_union->cred.pV5Cred->client); + free (io_cred_union->cred.pV5Cred->server); + cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock); + cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses); + cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket); + cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket); + cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata); + free (io_cred_union->cred.pV5Cred); + } + free (io_cred_union); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_copy_contents (cc_data *io_ccdata, + cc_data *in_ccdata) +{ + cc_int32 err = ccNoError; + char *data = NULL; + + if (!io_ccdata) { err = cci_check_error (ccErrBadParam); } + if (!in_ccdata) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_ccdata->length > 0) { + data = malloc (in_ccdata->length); + if (data) { + memcpy (data, in_ccdata->data, in_ccdata->length); + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + io_ccdata->type = in_ccdata->type; + io_ccdata->length = in_ccdata->length; + io_ccdata->data = data; + data = NULL; + } + + free (data); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_uint32 cci_cc_data_array_copy (cc_data ***io_ccdata_array, + cc_data **in_ccdata_array) +{ + cc_int32 err = ccNoError; + cc_uint32 count = 0; + cc_data **array = NULL; + cc_uint32 i; + + if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++); + } + + if (!err && count > 0) { + array = malloc ((count + 1) * sizeof (*array)); + if (array) { + for (i = 0; i <= count; i++) { array[i] = NULL; } + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + for (i = 0; !err && i < count; i++) { + array[i] = malloc (sizeof (cc_data)); + if (!array[i]) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]); + } + } + } + + if (!err) { + *io_ccdata_array = array; + array = NULL; + } + + cci_cc_data_array_release (array); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union, + cred_union **out_cred_union) +{ + cc_int32 err = ccNoError; + cred_union *compat_cred_union = NULL; + + if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } + if (!out_cred_union ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + compat_cred_union = calloc (1, sizeof (*compat_cred_union)); + if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + if (in_credentials_union->version == cc_credentials_v4) { + cc_credentials_v4_compat *compat_v4creds = NULL; + + compat_v4creds = malloc (sizeof (*compat_v4creds)); + if (!compat_v4creds) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + cc_credentials_v4_t *v4creds = in_credentials_union->credentials.credentials_v4; + + compat_cred_union->cred_type = CC_CRED_V4; + compat_cred_union->cred.pV4Cred = compat_v4creds; + + compat_v4creds->kversion = v4creds->version; + strncpy (compat_v4creds->principal, v4creds->principal, KRB_NAME_SZ+1); + strncpy (compat_v4creds->principal_instance, v4creds->principal_instance, KRB_INSTANCE_SZ+1); + strncpy (compat_v4creds->service, v4creds->service, KRB_NAME_SZ+1); + strncpy (compat_v4creds->service_instance, v4creds->service_instance, KRB_INSTANCE_SZ+1); + strncpy (compat_v4creds->realm, v4creds->realm, KRB_REALM_SZ+1); + memcpy (compat_v4creds->session_key, v4creds->session_key, 8); + compat_v4creds->kvno = v4creds->kvno; + compat_v4creds->str_to_key = v4creds->string_to_key_type; + compat_v4creds->issue_date = v4creds->issue_date; + compat_v4creds->lifetime = v4creds->lifetime; + compat_v4creds->address = v4creds->address; + compat_v4creds->ticket_sz = v4creds->ticket_size; + memcpy (compat_v4creds->ticket, v4creds->ticket, MAX_V4_CRED_LEN); + compat_v4creds->oops = 0; + } + + } else if (in_credentials_union->version == cc_credentials_v5) { + cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5; + cc_credentials_v5_compat *compat_v5creds = NULL; + + compat_v5creds = malloc (sizeof (*compat_v5creds)); + if (compat_v5creds) { + *compat_v5creds = cci_credentials_v5_compat_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + + if (!err) { + compat_v5creds->client = strdup (v5creds->client); + if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + compat_v5creds->server = strdup (v5creds->server); + if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock); + } + + if (!err) { + err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses); + } + + if (!err) { + err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket); + } + + if (!err) { + err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket); + } + + if (!err) { + err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata); + } + + if (!err) { + compat_cred_union->cred_type = CC_CRED_V5; + compat_cred_union->cred.pV5Cred = compat_v5creds; + + compat_v5creds->keyblock = v5creds->keyblock; + compat_v5creds->authtime = v5creds->authtime; + compat_v5creds->starttime = v5creds->starttime; + compat_v5creds->endtime = v5creds->endtime; + compat_v5creds->renew_till = v5creds->renew_till; + compat_v5creds->is_skey = v5creds->is_skey; + compat_v5creds->ticket_flags = v5creds->ticket_flags; + } + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + *out_cred_union = compat_cred_union; + compat_cred_union = NULL; + } + + if (compat_cred_union) { cci_cred_union_release (compat_cred_union); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union, + cc_credentials_union **out_credentials_union) +{ + cc_int32 err = ccNoError; + cc_credentials_union *creds_union = NULL; + + if (!in_cred_union ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + creds_union = calloc (1, sizeof (*creds_union)); + if (!creds_union) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + if (in_cred_union->cred_type == CC_CRED_V4) { + cc_credentials_v4_compat *compat_v4creds = in_cred_union->cred.pV4Cred; + cc_credentials_v4_t *v4creds = NULL; + + if (!err) { + v4creds = malloc (sizeof (*v4creds)); + if (!v4creds) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + creds_union->version = cc_credentials_v4; + creds_union->credentials.credentials_v4 = v4creds; + + v4creds->version = compat_v4creds->kversion; + strncpy (v4creds->principal, compat_v4creds->principal, KRB_NAME_SZ); + strncpy (v4creds->principal_instance, compat_v4creds->principal_instance, KRB_INSTANCE_SZ); + strncpy (v4creds->service, compat_v4creds->service, KRB_NAME_SZ); + strncpy (v4creds->service_instance, compat_v4creds->service_instance, KRB_INSTANCE_SZ); + strncpy (v4creds->realm, compat_v4creds->realm, KRB_REALM_SZ); + memcpy (v4creds->session_key, compat_v4creds->session_key, 8); + v4creds->kvno = compat_v4creds->kvno; + v4creds->string_to_key_type = compat_v4creds->str_to_key; + v4creds->issue_date = compat_v4creds->issue_date; + v4creds->lifetime = compat_v4creds->lifetime; + v4creds->address = compat_v4creds->address; + v4creds->ticket_size = compat_v4creds->ticket_sz; + memcpy (v4creds->ticket, compat_v4creds->ticket, MAX_V4_CRED_LEN); + } + + } else if (in_cred_union->cred_type == CC_CRED_V5) { + cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred; + cc_credentials_v5_t *v5creds = NULL; + + if (!err) { + v5creds = malloc (sizeof (*v5creds)); + if (v5creds) { + *v5creds = cci_credentials_v5_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + v5creds->client = strdup (compat_v5creds->client); + if (!v5creds->client) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + v5creds->server = strdup (compat_v5creds->server); + if (!v5creds->server) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock); + } + + if (!err) { + err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses); + } + + if (!err) { + err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket); + } + + if (!err) { + err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket); + } + + if (!err) { + err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata); + } + + if (!err) { + creds_union->version = cc_credentials_v5; + creds_union->credentials.credentials_v5 = v5creds; + + v5creds->authtime = compat_v5creds->authtime; + v5creds->starttime = compat_v5creds->starttime; + v5creds->endtime = compat_v5creds->endtime; + v5creds->renew_till = compat_v5creds->renew_till; + v5creds->is_skey = compat_v5creds->is_skey; + v5creds->ticket_flags = compat_v5creds->ticket_flags; + } + + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + *out_credentials_union = creds_union; + creds_union = NULL; + } + + if (creds_union) { cci_credentials_union_release (creds_union); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat, + const cc_credentials_union *in_credentials_union, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + cc_uint32 equal = 0; + + if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); } + if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_cred_union_compat->cred_type == CC_CRED_V4 && + in_credentials_union->version == cc_credentials_v4) { + cc_credentials_v4_compat *old_creds_v4 = in_cred_union_compat->cred.pV4Cred; + cc_credentials_v4_t *new_creds_v4 = in_credentials_union->credentials.credentials_v4; + + if (old_creds_v4 && new_creds_v4 && + !strcmp (old_creds_v4->principal, + new_creds_v4->principal) && + !strcmp (old_creds_v4->principal_instance, + new_creds_v4->principal_instance) && + !strcmp (old_creds_v4->service, + new_creds_v4->service) && + !strcmp (old_creds_v4->service_instance, + new_creds_v4->service_instance) && + !strcmp (old_creds_v4->realm, new_creds_v4->realm) && + (old_creds_v4->issue_date == (long) new_creds_v4->issue_date)) { + equal = 1; + } + + } else if (in_cred_union_compat->cred_type == CC_CRED_V5 && + in_credentials_union->version == cc_credentials_v5) { + cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred; + cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5; + + /* Really should use krb5_parse_name and krb5_principal_compare */ + if (old_creds_v5 && new_creds_v5 && + !strcmp (old_creds_v5->client, new_creds_v5->client) && + !strcmp (old_creds_v5->server, new_creds_v5->server) && + (old_creds_v5->starttime == new_creds_v5->starttime)) { + return 1; + } + } + } + + if (!err) { + *out_equal = equal; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/common/cci_cred_union.h b/src/ccapi/common/cci_cred_union.h index f734d6a355..3264d350a5 100644 --- a/src/ccapi/common/cci_cred_union.h +++ b/src/ccapi/common/cci_cred_union.h @@ -28,14 +28,26 @@ #define CCI_CRED_UNION_H #include "cci_types.h" +#include -cc_uint32 cci_cred_union_release (cc_credentials_union *io_credentials); +cc_uint32 cci_credentials_union_release (cc_credentials_union *io_credentials); -cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union, - cci_stream_t io_stream); +cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union, + cci_stream_t io_stream); -cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union, - cci_stream_t io_stream); +cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union, + cci_stream_t io_stream); +cc_uint32 cci_cred_union_release (cred_union *io_cred_union); + +cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union, + cred_union **out_cred_union); + +cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union, + cc_credentials_union **out_credentials_union); + +cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat, + const cc_credentials_union *in_credentials_union, + cc_uint32 *out_equal); #endif /* CCI_CRED_UNION_H */ diff --git a/src/ccapi/lib/ccapi_ccache.c b/src/ccapi/lib/ccapi_ccache.c index f168c0a328..c36a2b0ef3 100644 --- a/src/ccapi/lib/ccapi_ccache.c +++ b/src/ccapi/lib/ccapi_ccache.c @@ -45,6 +45,7 @@ typedef struct cci_ccache_d { #endif cci_identifier_t identifier; cc_time_t last_wait_for_change_time; + cc_uint32 compat_version; } *cci_ccache_t; /* ------------------------------------------------------------------------ */ @@ -379,7 +380,7 @@ cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache, } if (!err) { - err = cci_cred_union_write (in_credentials_union, request); + err = cci_credentials_union_write (in_credentials_union, request); } if (!err) { @@ -770,3 +771,42 @@ cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, return cci_check_error (err); } + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache, + cc_uint32 *out_compat_version) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) in_ccache; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_compat_version) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_compat_version = ccache->compat_version; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache, + cc_uint32 in_compat_version) +{ + cc_int32 err = ccNoError; + cci_ccache_t ccache = (cci_ccache_t) io_ccache; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache->compat_version = in_compat_version; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_ccache.h b/src/ccapi/lib/ccapi_ccache.h index 82a9f6c1c4..73091b7a0d 100644 --- a/src/ccapi/lib/ccapi_ccache.h +++ b/src/ccapi/lib/ccapi_ccache.h @@ -96,4 +96,11 @@ cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache, cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, cc_uint32 in_credentials_version); +cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache, + cc_uint32 *out_compat_version); + +cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache, + cc_uint32 in_compat_version); + + #endif /* CCAPI_CCACHE_H */ diff --git a/src/ccapi/lib/ccapi_ccache_iterator.c b/src/ccapi/lib/ccapi_ccache_iterator.c index 815da36f19..26162af327 100644 --- a/src/ccapi/lib/ccapi_ccache_iterator.c +++ b/src/ccapi/lib/ccapi_ccache_iterator.c @@ -36,6 +36,7 @@ typedef struct cci_ccache_iterator_d { cc_ccache_iterator_f *vector_functions; #endif cci_identifier_t identifier; + char *saved_ccache_name; } *cci_ccache_iterator_t; /* ------------------------------------------------------------------------ */ @@ -43,6 +44,7 @@ typedef struct cci_ccache_iterator_d { struct cci_ccache_iterator_d cci_ccache_iterator_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, + NULL, NULL }; @@ -125,6 +127,7 @@ cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator) if (!err) { free ((char *) ccache_iterator->functions); cci_identifier_release (ccache_iterator->identifier); + free (ccache_iterator->saved_ccache_name); free (ccache_iterator); } @@ -222,3 +225,49 @@ cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, return cci_check_error (err); } + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator, + const char **out_saved_ccache_name) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; + + if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!out_saved_ccache_name) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_saved_ccache_name = ccache_iterator->saved_ccache_name; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator, + const char *in_saved_ccache_name) +{ + cc_int32 err = ccNoError; + cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator; + char *new_saved_ccache_name = NULL; + + if (!io_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_saved_ccache_name) { + new_saved_ccache_name = strdup (in_saved_ccache_name); + if (!new_saved_ccache_name) { err = ccErrNoMem; } + } + + if (!err) { + free (ccache_iterator->saved_ccache_name); + + ccache_iterator->saved_ccache_name = new_saved_ccache_name; + new_saved_ccache_name = NULL; /* take ownership */ + } + + free (new_saved_ccache_name); + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_ccache_iterator.h b/src/ccapi/lib/ccapi_ccache_iterator.h index 0a5a4f4567..8b07b07639 100644 --- a/src/ccapi/lib/ccapi_ccache_iterator.h +++ b/src/ccapi/lib/ccapi_ccache_iterator.h @@ -43,4 +43,10 @@ cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator, cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_iterator_t *out_ccache_iterator); +cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator, + const char **out_saved_ccache_name); + +cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator, + const char *in_saved_ccache_name); + #endif /* CCAPI_CCACHE_ITERATOR_H */ diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c index 7a165cf980..3b8d60e3eb 100644 --- a/src/ccapi/lib/ccapi_context.c +++ b/src/ccapi/lib/ccapi_context.c @@ -122,9 +122,6 @@ cc_int32 cc_initialize (cc_context_t *out_context, if (!err) { switch (in_version) { case ccapi_version_2: - err = CC_BAD_API_VERSION; - break; - case ccapi_version_3: case ccapi_version_4: case ccapi_version_5: diff --git a/src/ccapi/lib/ccapi_credentials.c b/src/ccapi/lib/ccapi_credentials.c index 4e1f48e016..3c40478fbe 100644 --- a/src/ccapi/lib/ccapi_credentials.c +++ b/src/ccapi/lib/ccapi_credentials.c @@ -53,7 +53,7 @@ cc_credentials_f cci_credentials_f_initializer = { ccapi_credentials_compare }; -cc_credentials_union cci_cred_union_initializer = { +cc_credentials_union cci_credentials_union_initializer = { 0, { NULL } }; @@ -92,7 +92,7 @@ cc_int32 cci_credentials_read (cc_credentials_t *out_credentials, } if (!err) { - err = cci_cred_union_read (&credentials->data, in_stream); + err = cci_credentials_union_read (&credentials->data, in_stream); } if (!err) { @@ -156,7 +156,7 @@ cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials) if (!io_credentials) { err = ccErrBadParam; } if (!err) { - cci_cred_union_release (credentials->data); + cci_credentials_union_release (credentials->data); free ((char *) credentials->functions); cci_identifier_release (credentials->identifier); free (credentials); diff --git a/src/ccapi/lib/ccapi_credentials_iterator.c b/src/ccapi/lib/ccapi_credentials_iterator.c index a99e52b499..4f38d07456 100644 --- a/src/ccapi/lib/ccapi_credentials_iterator.c +++ b/src/ccapi/lib/ccapi_credentials_iterator.c @@ -36,6 +36,7 @@ typedef struct cci_credentials_iterator_d { cc_credentials_iterator_f *vector_functions; #endif cci_identifier_t identifier; + cc_uint32 compat_version; } *cci_credentials_iterator_t; /* ------------------------------------------------------------------------ */ @@ -43,7 +44,8 @@ typedef struct cci_credentials_iterator_d { struct cci_credentials_iterator_d cci_credentials_iterator_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, - NULL + NULL, + 0 }; cc_credentials_iterator_f cci_credentials_iterator_f_initializer = { @@ -192,3 +194,42 @@ cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credent return cci_check_error (err); } + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator, + cc_uint32 *out_compat_version) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; + + if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_compat_version ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_compat_version = credentials_iterator->compat_version; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator, + cc_uint32 in_compat_version) +{ + cc_int32 err = ccNoError; + cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + credentials_iterator->compat_version = in_compat_version; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/lib/ccapi_credentials_iterator.h b/src/ccapi/lib/ccapi_credentials_iterator.h index 7ffbd23011..12647d4ee2 100644 --- a/src/ccapi/lib/ccapi_credentials_iterator.h +++ b/src/ccapi/lib/ccapi_credentials_iterator.h @@ -43,4 +43,10 @@ cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credenti cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_iterator_t *out_credentials_iterator); +cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator, + cc_uint32 *out_compat_version); + +cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator, + cc_uint32 in_compat_version); + #endif /* CCAPI_CREDENTIALS_ITERATOR_H */ diff --git a/src/ccapi/lib/ccapi_v2.c b/src/ccapi/lib/ccapi_v2.c index 0036c70d31..8a25ae6e9f 100644 --- a/src/ccapi/lib/ccapi_v2.c +++ b/src/ccapi/lib/ccapi_v2.c @@ -25,21 +25,109 @@ */ #include "cci_common.h" +#include "ccapi_string.h" +#include "ccapi_context.h" +#include "ccapi_ccache.h" +#include "ccapi_ccache_iterator.h" +#include "ccapi_credentials.h" +#include "ccapi_credentials_iterator.h" #include +infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN }; + /* ------------------------------------------------------------------------ */ -cc_result cc_shutdown (apiCB **io_context) +static cc_int32 cci_remap_version (cc_int32 in_v2_version, + cc_uint32 *out_v3_version) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!out_v3_version) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_v2_version == CC_CRED_V4) { + *out_v3_version = cc_credentials_v4; + + } else if (in_v2_version == CC_CRED_V5) { + *out_v3_version = cc_credentials_v5; + + } else { + err = ccErrBadCredentialsVersion; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_result cci_remap_error (cc_result in_error) +{ + switch (in_error) { + case ccNoError: + return CC_NOERROR; + + case ccIteratorEnd: + return CC_END; + + case ccErrBadParam: + case ccErrInvalidCredentials: + case ccErrInvalidCCacheIterator: + case ccErrInvalidCredentialsIterator: + case ccErrBadLockType: + return CC_BAD_PARM; + + case ccErrNoMem: + return CC_NOMEM; + + case ccErrInvalidContext: + case ccErrInvalidCCache: + case ccErrCCacheNotFound: + return CC_NO_EXIST; + + case ccErrCredentialsNotFound: + return CC_NOTFOUND; + + case ccErrBadName: + return CC_BADNAME; + + case ccErrContextLocked: + case ccErrContextUnlocked: + case ccErrCCacheLocked: + case ccErrCCacheUnlocked: + return CC_LOCKED; + + case ccErrServerUnavailable: + case ccErrServerInsecure: + return CC_IO; + + default: + cci_debug_printf ("%s(): Unhandled error", __FUNCTION__); + return CC_BAD_PARM; + } } +#if TARGET_OS_MAC +#pragma mark - +#endif + /* ------------------------------------------------------------------------ */ -cc_result cc_get_NC_info (apiCB *in_context, - infoNC ***out_info) +cc_result cc_shutdown (apiCB **io_context) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!io_context) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_context_release (*io_context); + } + + if (!err) { + *io_context = NULL; + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -47,9 +135,115 @@ cc_result cc_get_NC_info (apiCB *in_context, cc_result cc_get_change_time (apiCB *in_context, cc_time_t *out_change_time) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_change_time) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_context_get_change_time (in_context, out_change_time); + } + + return cci_remap_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_get_NC_info (apiCB *in_context, + infoNC ***out_info) +{ + cc_result err = CC_NOERROR; + infoNC **info = NULL; + cc_uint64 count = 0; /* Preflight the size */ + cc_uint64 i; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!out_info ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache_cit *iterator = NULL; + + err = cc_seq_fetch_NCs_begin (in_context, &iterator); + + while (!err) { + ccache_p *ccache = NULL; + + err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator); + + if (!err) { count++; } + + if (ccache) { cc_close (in_context, &ccache); } + } + if (err == CC_END) { err = CC_NOERROR; } + + if (!err) { + err = cc_seq_fetch_NCs_end (in_context, &iterator); + } + } + + if (!err) { + info = malloc (sizeof (*info) * (count + 1)); + if (info) { + for (i = 0; i < count + 1; i++) { info[i] = NULL; } + } else { + err = cci_check_error (CC_NOMEM); + } + } + + if (!err) { + ccache_cit *iterator = NULL; + + err = cc_seq_fetch_NCs_begin (in_context, &iterator); + + for (i = 0; !err && i < count; i++) { + ccache_p *ccache = NULL; + infoNC *item = NULL; + + err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator); + + if (!err) { + info[i] = malloc (sizeof (*item)); + if (info[i]) { + *info[i] = infoNC_initializer; + } else { + err = cci_check_error (CC_NOMEM); + } + } + + if (!err) { + err = cc_get_name (in_context, ccache, &info[i]->name); + } + + if (!err) { + err = cc_get_principal (in_context, ccache, &info[i]->principal); + } + + if (!err) { + err = cc_get_cred_version (in_context, ccache, &info[i]->vers); + } + + if (ccache) { cc_close (in_context, &ccache); } + } + + if (!err) { + err = cc_seq_fetch_NCs_end (in_context, &iterator); + } + } + + if (!err) { + *out_info = info; + info = NULL; + } + + if (info) { cc_free_NC_info (in_context, &info); } + + return cci_check_error (err); } +#if TARGET_OS_MAC +#pragma mark - +#endif + /* ------------------------------------------------------------------------ */ cc_int32 cc_open (apiCB *in_context, @@ -58,7 +252,48 @@ cc_int32 cc_open (apiCB *in_context, cc_uint32 in_flags, ccache_p **out_ccache) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_ccache_t ccache = NULL; + cc_uint32 compat_version; + cc_uint32 real_version; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_remap_version (in_version, &compat_version); + } + + if (!err) { + err = ccapi_context_open_ccache (in_context, in_name, &ccache); + } + + /* We must not allow a CCAPI v2 caller to open a v5-only ccache + as a v4 ccache and vice versa. Allowing that would break + (valid) assumptions made by CCAPI v2 callers. */ + + if (!err) { + err = ccapi_ccache_get_credentials_version (ccache, &real_version); + } + + if (!err) { + /* check the version and set up the ccache to use it */ + if (compat_version & real_version) { + err = cci_ccache_set_compat_version (ccache, compat_version); + } else { + err = ccErrInvalidCCache; + } + } + + if (!err) { + *out_ccache = ccache; + ccache = NULL; + } + + if (ccache) { ccapi_ccache_release (ccache); } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -70,7 +305,35 @@ cc_result cc_create (apiCB *in_context, cc_uint32 in_flags, ccache_p **out_ccache) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_ccache_t ccache = NULL; + cc_uint32 compat_version; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_remap_version (in_version, &compat_version); + } + + if (!err) { + err = ccapi_context_create_ccache (in_context, in_name, compat_version, + in_principal, &ccache); + } + + if (!err) { + err = cci_ccache_set_compat_version (ccache, compat_version); + } + + if (!err) { + *out_ccache = ccache; + ccache = NULL; + } + + if (ccache) { ccapi_ccache_release (ccache); } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -78,7 +341,20 @@ cc_result cc_create (apiCB *in_context, cc_result cc_close (apiCB *in_context, ccache_p **io_ccache) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_ccache_release (*io_ccache); + } + + if (!err) { + *io_ccache = NULL; + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -86,36 +362,20 @@ cc_result cc_close (apiCB *in_context, cc_result cc_destroy (apiCB *in_context, ccache_p **io_ccache) { - return CC_NOT_SUPP; -} - -/* ------------------------------------------------------------------------ */ - -cc_result cc_seq_fetch_NCs_begin (apiCB *in_context, - ccache_cit **out_iterator) -{ - return CC_NOT_SUPP; -} - -/* ------------------------------------------------------------------------ */ - -// CCache iterators need to return some ccaches twice (when v3 ccache has -// two kinds of credentials). To do that, we use a single v3 iterator, but -// sometimes don't advance it. - -cc_result cc_seq_fetch_NCs_next (apiCB *in_context, - ccache_p **out_ccache, - ccache_cit *in_iterator) -{ - return CC_NOT_SUPP; -} - -/* ------------------------------------------------------------------------ */ - -cc_result cc_seq_fetch_NCs_end (apiCB *in_context, - ccache_cit **io_iterator) -{ - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_ccache_destroy (*io_ccache); + } + + if (!err) { + *io_ccache = NULL; + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -124,7 +384,29 @@ cc_result cc_get_name (apiCB *in_context, ccache_p *in_ccache, char **out_name) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_string_t name = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_ccache_get_name (in_ccache, &name); + } + + if (!err) { + char *string = strdup (name->data); + if (string) { + *out_name = string; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (name) { ccapi_string_release (name); } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -133,7 +415,30 @@ cc_result cc_get_cred_version (apiCB *in_context, ccache_p *in_ccache, cc_int32 *out_version) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_uint32 compat_version; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_version) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ccache_get_compat_version (in_ccache, &compat_version); + } + + if (!err) { + if (compat_version == cc_credentials_v4) { + *out_version = CC_CRED_V4; + + } else if (compat_version == cc_credentials_v5) { + *out_version = CC_CRED_V5; + + } else { + err = ccErrBadCredentialsVersion; + } + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -143,7 +448,22 @@ cc_result cc_set_principal (apiCB *in_context, cc_int32 in_version, char *in_principal) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_uint32 version; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_remap_version (in_version, &version); + } + + if (!err) { + err = ccapi_ccache_set_principal (io_ccache, version, in_principal); + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -152,7 +472,34 @@ cc_result cc_get_principal (apiCB *in_context, ccache_p *in_ccache, char **out_principal) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_uint32 compat_version; + cc_string_t principal = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ccache_get_compat_version (in_ccache, &compat_version); + } + + if (!err) { + err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal); + } + + if (!err) { + char *string = strdup (principal->data); + if (string) { + *out_principal = string; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (principal) { ccapi_string_release (principal); } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -161,7 +508,23 @@ cc_result cc_store (apiCB *in_context, ccache_p *io_ccache, cred_union in_credentials) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_credentials_union *creds_union = NULL; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_cred_union_to_credentials_union (&in_credentials, + &creds_union); + } + + if (!err) { + err = ccapi_ccache_store_credentials (io_ccache, creds_union); + } + + if (creds_union) { cci_credentials_union_release (creds_union); } + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -170,16 +533,207 @@ cc_result cc_remove_cred (apiCB *in_context, ccache_p *in_ccache, cred_union in_credentials) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_credentials_iterator_t iterator = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator); + } + + while (!err) { + cc_credentials_t creds = NULL; + cc_uint32 equal = 0; + + err = ccapi_credentials_iterator_next (iterator, &creds); + + if (!err) { + err = cci_cred_union_compare_to_credentials_union (&in_credentials, + creds->data, + &equal); + } + + if (!err && equal) { + err = ccapi_ccache_remove_credentials (in_ccache, creds); + } + + ccapi_credentials_release (creds); + } + if (err) { err = cci_check_error (ccErrCredentialsNotFound); } + + return cci_remap_error (err); } +#if TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_NCs_begin (apiCB *in_context, + ccache_cit **out_iterator) +{ + cc_result err = ccNoError; + cc_ccache_iterator_t iterator = NULL; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_context_new_ccache_iterator (in_context, &iterator); + } + + if (!err) { + *out_iterator = (ccache_cit *) iterator; + iterator = NULL; /* take ownership */ + } + + if (iterator) { ccapi_ccache_iterator_release (iterator); } + + return cci_remap_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_NCs_next (apiCB *in_context, + ccache_p **out_ccache, + ccache_cit *in_iterator) +{ + cc_result err = ccNoError; + cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator; + cc_ccache_t ccache = NULL; + const char *saved_ccache_name; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_iterator) { err = cci_check_error (ccErrBadParam); } + + /* CCache iterators need to return some ccaches twice (when v3 ccache has + * two kinds of credentials). To do that, we return such ccaches twice + * v4 first, then v5. */ + + if (!err) { + err = cci_ccache_iterator_get_saved_ccache_name (iterator, + &saved_ccache_name); + } + + if (!err) { + if (saved_ccache_name) { + err = ccapi_context_open_ccache (in_context, saved_ccache_name, + &ccache); + + if (!err) { + err = cci_ccache_set_compat_version (ccache, cc_credentials_v5); + } + + if (!err) { + err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL); + } + + } else { + cc_uint32 version = 0; + + err = ccapi_ccache_iterator_next (iterator, &ccache); + + if (!err) { + err = ccapi_ccache_get_credentials_version (ccache, &version); + } + + if (!err) { + if (version == cc_credentials_v4_v5) { + cc_string_t name = NULL; + + err = cci_ccache_set_compat_version (ccache, cc_credentials_v4); + + if (!err) { + err = ccapi_ccache_get_name (ccache, &name); + } + + if (!err) { + err = cci_ccache_iterator_set_saved_ccache_name (iterator, + name->data); + } + + if (name) { ccapi_string_release (name); } + + } else { + err = cci_ccache_set_compat_version (ccache, version); + } + } + } + } + + if (!err) { + *out_ccache = ccache; + ccache = NULL; /* take ownership */ + } + + if (ccache) { ccapi_ccache_release (ccache); } + + return cci_remap_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_result cc_seq_fetch_NCs_end (apiCB *in_context, + ccache_cit **io_iterator) +{ + cc_result err = ccNoError; + cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) io_iterator; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!io_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_ccache_iterator_release (iterator); + } + + return cci_remap_error (err); +} + +#if TARGET_OS_MAC +#pragma mark - +#endif + /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_creds_begin (apiCB *in_context, const ccache_p *in_ccache, ccache_cit **out_iterator) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_credentials_iterator_t iterator = NULL; + cc_uint32 compat_version; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!out_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache, + &compat_version); + } + + if (!err) { + err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache, + &iterator); + } + + if (!err) { + err = cci_credentials_iterator_set_compat_version (iterator, + compat_version); + } + + if (!err) { + *out_iterator = (ccache_cit *) iterator; + iterator = NULL; /* take ownership */ + } + + if (iterator) { ccapi_credentials_iterator_release (iterator); } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -188,7 +742,35 @@ cc_result cc_seq_fetch_creds_next (apiCB *in_context, cred_union **out_creds, ccache_cit *in_iterator) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator; + cc_uint32 compat_version; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!out_creds ) { err = cci_check_error (ccErrBadParam); } + if (!in_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_credentials_iterator_get_compat_version (iterator, + &compat_version); + } + + while (!err) { + cc_credentials_t credentials = NULL; + + err = ccapi_credentials_iterator_next (iterator, &credentials); + + if (!err && (credentials->data->version & compat_version)) { + /* got the next credentials for the correct version */ + err = cci_credentials_union_to_cred_union (credentials->data, + out_creds); + break; + } + + if (credentials) { ccapi_credentials_release (credentials); } + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -196,15 +778,43 @@ cc_result cc_seq_fetch_creds_next (apiCB *in_context, cc_result cc_seq_fetch_creds_end (apiCB *in_context, ccache_cit **io_iterator) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + cc_credentials_iterator_t *iterator = (cc_credentials_iterator_t *) io_iterator; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!io_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccapi_credentials_iterator_release (*iterator); + } + + if (!err) { + *iterator = NULL; + } + + return cci_remap_error (err); } +#if TARGET_OS_MAC +#pragma mark - +#endif + /* ------------------------------------------------------------------------ */ cc_result cc_free_principal (apiCB *in_context, char **io_principal) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!io_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + free (*io_principal); + *io_principal = NULL; + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -212,7 +822,17 @@ cc_result cc_free_principal (apiCB *in_context, cc_result cc_free_name (apiCB *in_context, char **io_name) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!io_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + free (*io_name); + *io_name = NULL; + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -220,7 +840,17 @@ cc_result cc_free_name (apiCB *in_context, cc_result cc_free_creds (apiCB *in_context, cred_union **io_credentials) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context ) { err = cci_check_error (ccErrBadParam); } + if (!io_credentials) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_cred_union_release (*io_credentials); + if (!err) { *io_credentials = NULL; } + } + + return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ @@ -228,5 +858,24 @@ cc_result cc_free_creds (apiCB *in_context, cc_result cc_free_NC_info (apiCB *in_context, infoNC ***io_info) { - return CC_NOT_SUPP; + cc_result err = ccNoError; + + if (!in_context) { err = cci_check_error (ccErrBadParam); } + if (!io_info ) { err = cci_check_error (ccErrBadParam); } + + if (!err && *io_info) { + infoNC **data = *io_info; + int i; + + for (i = 0; data[i] != NULL; i++) { + cc_free_principal (in_context, &data[i]->principal); + cc_free_name (in_context, &data[i]->name); + free (data[i]); + } + free (data); + + *io_info = NULL; + } + + return cci_remap_error (err); } diff --git a/src/ccapi/server/ccs_credentials.c b/src/ccapi/server/ccs_credentials.c index 04c8e21b57..72721e68a1 100644 --- a/src/ccapi/server/ccs_credentials.c +++ b/src/ccapi/server/ccs_credentials.c @@ -56,7 +56,7 @@ cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, } if (!err) { - err = cci_cred_union_read (&credentials->cred_union, in_stream); + err = cci_credentials_union_read (&credentials->cred_union, in_stream); } if (!err && !(credentials->cred_union->version & in_ccache_version)) { @@ -89,7 +89,7 @@ cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials) cc_int32 err = ccNoError; if (!err && io_credentials) { - cci_cred_union_release (io_credentials->cred_union); + cci_credentials_union_release (io_credentials->cred_union); cci_identifier_release (io_credentials->identifier); free (io_credentials); } @@ -112,7 +112,7 @@ cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, } if (!err) { - err = cci_cred_union_write (in_credentials->cred_union, io_stream); + err = cci_credentials_union_write (in_credentials->cred_union, io_stream); } return cci_check_error (err);