From: Tom Yu Date: Wed, 6 Dec 2006 22:57:06 +0000 (+0000) Subject: pull up r18923 from trunk X-Git-Tag: krb5-1.6-beta2~30 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=913f3dfab8f43e71d3d7133984538052ffbc9551;p=krb5.git pull up r18923 from trunk r18923@cathode-dark-space: lxs | 2006-12-05 18:21:56 -0500 ticket: new owner: tlyu target_version: 1.6 subject: krb5_cc_remove should work for the CCAPI tags: pullup Implemented a working krb5_cc_remove for the CCAPI cache type. Added a private support function krb5_creds_compare() which checks if two krb5_creds are identical. This function should be needed by implementations of krb5_cc_remove for other ccache types. ticket: 5003 version_fixed: 1.6 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@18928 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 1935daeeb..3f93efd8a 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1734,6 +1734,11 @@ krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred_default (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); +krb5_boolean +krb5_creds_compare (krb5_context in_context, + krb5_creds *in_creds, + krb5_creds *in_compare_creds); + void krb5int_set_prompt_types (krb5_context, krb5_prompt_type *); diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c index cadd3e5fe..43c9da7d0 100644 --- a/src/lib/krb5/ccache/cc_retr.c +++ b/src/lib/krb5/ccache/cc_retr.c @@ -287,3 +287,102 @@ krb5_cc_retrieve_cred_default (krb5_context context, krb5_ccache id, krb5_flags 0, 0); } } + +/* The following function duplicates some of the functionality above and */ +/* should probably be merged with it at some point. It is used by the */ +/* CCAPI krb5_cc_remove to figure out if the opaque credentials object */ +/* returned by the CCAPI is the same creds as the caller passed in. */ +/* Unlike the code above it requires that all structures be identical. */ + +krb5_boolean KRB5_CALLCONV +krb5_creds_compare (krb5_context in_context, + krb5_creds *in_creds, + krb5_creds *in_compare_creds) +{ + /* Set to 0 when we hit the first mismatch and then fall through */ + int equal = 1; + + if (equal) { + equal = krb5_principal_compare (in_context, in_creds->client, + in_compare_creds->client); + } + + if (equal) { + equal = krb5_principal_compare (in_context, in_creds->server, + in_compare_creds->server); + } + + if (equal) { + equal = (in_creds->keyblock.enctype == in_compare_creds->keyblock.enctype && + in_creds->keyblock.length == in_compare_creds->keyblock.length && + (!in_creds->keyblock.length || + !memcmp (in_creds->keyblock.contents, in_compare_creds->keyblock.contents, + in_creds->keyblock.length))); + } + + if (equal) { + equal = (in_creds->times.authtime == in_compare_creds->times.authtime && + in_creds->times.starttime == in_compare_creds->times.starttime && + in_creds->times.endtime == in_compare_creds->times.endtime && + in_creds->times.renew_till == in_compare_creds->times.renew_till); + } + + if (equal) { + equal = (in_creds->is_skey == in_compare_creds->is_skey); + } + + if (equal) { + equal = (in_creds->ticket_flags == in_compare_creds->ticket_flags); + } + + if (equal) { + krb5_address **addresses = in_creds->addresses; + krb5_address **compare_addresses = in_compare_creds->addresses; + unsigned int i; + + if (addresses && compare_addresses) { + for (i = 0; (equal && addresses[i] && compare_addresses[i]); i++) { + equal = krb5_address_compare (in_context, addresses[i], + compare_addresses[i]); + } + if (equal) { equal = (!addresses[i] && !compare_addresses[i]); } + } else { + if (equal) { equal = (!addresses && !compare_addresses); } + } + } + + if (equal) { + equal = (in_creds->ticket.length == in_compare_creds->ticket.length && + (!in_creds->ticket.length || + !memcmp (in_creds->ticket.data, in_compare_creds->ticket.data, + in_creds->ticket.length))); + } + + if (equal) { + equal = (in_creds->second_ticket.length == in_compare_creds->second_ticket.length && + (!in_creds->second_ticket.length || + !memcmp (in_creds->second_ticket.data, in_compare_creds->second_ticket.data, + in_creds->second_ticket.length))); + } + + if (equal) { + krb5_authdata **authdata = in_creds->authdata; + krb5_authdata **compare_authdata = in_compare_creds->authdata; + unsigned int i; + + if (authdata && compare_authdata) { + for (i = 0; (equal && authdata[i] && compare_authdata[i]); i++) { + equal = (authdata[i]->ad_type == compare_authdata[i]->ad_type && + authdata[i]->length == compare_authdata[i]->length && + (!authdata[i]->length || + !memcmp (authdata[i]->contents, compare_authdata[i]->contents, + authdata[i]->length))); + } + if (equal) { equal = (!authdata[i] && !compare_authdata[i]); } + } else { + if (equal) { equal = (!authdata && !compare_authdata); } + } + } + + return equal; +} diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c index ce54b2895..edbec11f2 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ b/src/lib/krb5/ccache/ccapi/stdcc.c @@ -436,7 +436,7 @@ krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; - cc_credentials_t credentials = NULL; + cc_credentials_union *cred_union = NULL; if (!err) { err = stdccv3_setup (context, ccapi_data); @@ -444,19 +444,18 @@ krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds ) if (!err) { /* copy the fields from the almost identical structures */ - err = copy_krb5_creds_to_cc_credentials (context, creds, &credentials); + err = copy_krb5_creds_to_cc_cred_union (context, creds, &cred_union); } if (!err) { - err = cc_ccache_store_credentials (ccapi_data->NamedCache, - credentials->data); + err = cc_ccache_store_credentials (ccapi_data->NamedCache, cred_union); } if (!err) { cache_changed(); } - if (credentials) { cc_credentials_release (credentials); } + if (cred_union) { cred_union_release (cred_union); } return cc_err_xlate (err); } @@ -519,7 +518,7 @@ krb5_stdccv3_next_cred (krb5_context context, err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { - copy_cc_credentials_to_krb5_creds(context, credentials, creds); + copy_cc_cred_union_to_krb5_creds(context, credentials->data, creds); break; } } @@ -742,36 +741,57 @@ krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context context, krb5_ccache id, krb5_flags flags, - krb5_creds *creds) + krb5_creds *in_creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; - cc_credentials_t credentials = NULL; + cc_credentials_iterator_t iterator = NULL; + int found = 0; if (!err) { err = stdccv3_setup(context, ccapi_data); } - if (!err) { - err = copy_krb5_creds_to_cc_credentials (context, creds, &credentials); - } if (!err) { - err = cc_ccache_remove_credentials (ccapi_data->NamedCache, credentials); + err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache, + &iterator); } - + + /* Note: CCAPI v3 ccaches can contain both v4 and v5 creds */ + while (!err && !found) { + cc_credentials_t credentials = NULL; + + err = cc_credentials_iterator_next (iterator, &credentials); + + if (!err && (credentials->data->version == cc_credentials_v5)) { + krb5_creds creds; + + err = copy_cc_cred_union_to_krb5_creds(context, + credentials->data, &creds); + + if (!err) { + found = krb5_creds_compare (context, in_creds, &creds); + krb5_free_cred_contents (context, &creds); + } + + if (!err && found) { + err = cc_ccache_remove_credentials (ccapi_data->NamedCache, credentials); + } + } + + if (credentials) { cc_credentials_release (credentials); } + } + if (err == ccIteratorEnd) { err = ccErrCredentialsNotFound; } + if (!err) { cache_changed (); - } else if (err == KRB5_FCC_NOFILE) { - err = 0; } - if (credentials) { cc_credentials_release (credentials); } - return cc_err_xlate (err); } -static krb5_error_code KRB5_CALLCONV +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor) { @@ -809,7 +829,7 @@ krb5_stdccv3_ptcursor_new(krb5_context context, return err; } -static krb5_error_code KRB5_CALLCONV +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_next( krb5_context context, krb5_cc_ptcursor cursor, @@ -885,7 +905,7 @@ krb5_stdccv3_ptcursor_next( return err; } -static krb5_error_code KRB5_CALLCONV +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_free( krb5_context context, krb5_cc_ptcursor *cursor) diff --git a/src/lib/krb5/ccache/ccapi/stdcc.h b/src/lib/krb5/ccache/ccapi/stdcc.h index d548c0531..4fe602799 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc.h +++ b/src/lib/krb5/ccache/ccapi/stdcc.h @@ -33,8 +33,9 @@ typedef struct _stdccCacheData { /* function protoypes */ +void krb5_stdcc_shutdown(void); + #ifdef USE_CCAPI_V3 -void krb5_stdccv3_shutdown(void); krb5_error_code KRB5_CALLCONV krb5_stdccv3_close (krb5_context, krb5_ccache id ); @@ -88,18 +89,17 @@ krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds); -static krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new (krb5_context context, krb5_cc_ptcursor *cursor); -static krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_next +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_next (krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *ccache); -static krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_free +krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_free (krb5_context context, krb5_cc_ptcursor *cursor); #else -void krb5_stdcc_shutdown(void); krb5_error_code KRB5_CALLCONV krb5_stdcc_close (krb5_context, krb5_ccache id ); diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c index 2e6538cca..58e72b33a 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.c +++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c @@ -20,9 +20,7 @@ #define fieldSize 255 #ifdef USE_CCAPI_V3 -/* krb5int_cc_credentials_release(cc_credentials_t creds) - * - function used to release internally generated cc_credentials_t objects - */ + static void free_cc_array (cc_data **io_cc_array) @@ -38,47 +36,6 @@ free_cc_array (cc_data **io_cc_array) } } -static cc_int32 -krb5int_cc_credentials_release(cc_credentials_t creds) -{ - if (creds) { - if (creds->data) { - if (creds->data->version == cc_credentials_v5 && - creds->data->credentials.credentials_v5) { - cc_credentials_v5_t *cv5 = creds->data->credentials.credentials_v5; - - /* should use krb5_free_unparsed_name but we have no context */ - if (cv5->client) { free (cv5->client); } - if (cv5->server) { free (cv5->server); } - - if (cv5->keyblock.data) { free (cv5->keyblock.data); } - if (cv5->ticket.data) { free (cv5->ticket.data); } - if (cv5->second_ticket.data) { free (cv5->second_ticket.data); } - - free_cc_array (cv5->addresses); - free_cc_array (cv5->authdata); - - free (cv5); - - } else if (creds->data->version == cc_credentials_v4 && - creds->data->credentials.credentials_v4) { - free (creds->data->credentials.credentials_v4); - } - free ((cc_credentials_union *) creds->data); - } - free(creds); - } - - return ccNoError; -} - -static cc_int32 -krb5int_cc_credentials_compare(cc_credentials_t creds, - cc_credentials_t compare_to, - cc_uint32* equal) { - return ccErrNotImplemented; -} - static krb5_error_code copy_cc_array_to_addresses (krb5_context in_context, cc_data **in_cc_array, @@ -282,12 +239,11 @@ copy_authdata_to_cc_array (krb5_context in_context, */ krb5_error_code -copy_cc_credentials_to_krb5_creds (krb5_context in_context, - cc_credentials_t in_credentials, - krb5_creds *out_creds) +copy_cc_cred_union_to_krb5_creds (krb5_context in_context, + const cc_credentials_union *in_cred_union, + krb5_creds *out_creds) { krb5_error_code err = 0; - const cc_credentials_union *cred_union = in_credentials->data; cc_credentials_v5_t *cv5 = NULL; krb5_int32 offset_seconds = 0, offset_microseconds = 0; krb5_principal client = NULL; @@ -298,10 +254,10 @@ copy_cc_credentials_to_krb5_creds (krb5_context in_context, krb5_address **addresses = NULL; krb5_authdata **authdata = NULL; - if (cred_union->version != cc_credentials_v5) { + if (in_cred_union->version != cc_credentials_v5) { err = KRB5_CC_NOT_KTYPE; } else { - cv5 = cred_union->credentials.credentials_v5; + cv5 = in_cred_union->credentials.credentials_v5; } #if TARGET_OS_MAC @@ -409,14 +365,12 @@ copy_cc_credentials_to_krb5_creds (krb5_context in_context, * - analagous to above but in the reverse direction */ krb5_error_code -copy_krb5_creds_to_cc_credentials (krb5_context in_context, - krb5_creds *in_creds, - cc_credentials_t *out_credentials) +copy_krb5_creds_to_cc_cred_union (krb5_context in_context, + krb5_creds *in_creds, + cc_credentials_union **out_cred_union) { krb5_error_code err = 0; - cc_credentials_t credentials = NULL; cc_credentials_union *cred_union = NULL; - cc_credentials_f *functions = NULL; cc_credentials_v5_t *cv5 = NULL; char *client = NULL; char *server = NULL; @@ -427,7 +381,7 @@ copy_krb5_creds_to_cc_credentials (krb5_context in_context, cc_data **cc_address_array = NULL; cc_data **cc_authdata_array = NULL; - if (out_credentials == NULL) { err = KRB5_CC_NOMEM; } + if (out_cred_union == NULL) { err = KRB5_CC_NOMEM; } #if TARGET_OS_MAC if (!err) { @@ -435,16 +389,6 @@ copy_krb5_creds_to_cc_credentials (krb5_context in_context, } #endif - if (!err) { - credentials = (cc_credentials_t) malloc (sizeof (*credentials)); - if (!credentials) { err = KRB5_CC_NOMEM; } - } - - if (!err) { - functions = (cc_credentials_f *) malloc (sizeof (*functions)); - if (!functions) { err = KRB5_CC_NOMEM; } - } - if (!err) { cred_union = (cc_credentials_union *) malloc (sizeof (*cred_union)); if (!cred_union) { err = KRB5_CC_NOMEM; } @@ -534,19 +478,8 @@ copy_krb5_creds_to_cc_credentials (krb5_context in_context, cred_union->credentials.credentials_v5 = cv5; cv5 = NULL; - credentials->data = cred_union; + *out_cred_union = cred_union; cred_union = NULL; - - functions->release = krb5int_cc_credentials_release; - functions->compare = krb5int_cc_credentials_compare; - credentials->functions = functions; - functions = NULL; -#ifdef TARGET_OS_MAC - credentials->otherFunctions = NULL; -#endif - - *out_credentials = credentials; - credentials = NULL; } if (cc_address_array) { free_cc_array (cc_address_array); } @@ -558,11 +491,41 @@ copy_krb5_creds_to_cc_credentials (krb5_context in_context, if (server) { krb5_free_unparsed_name (in_context, server); } if (cv5) { free (cv5); } if (cred_union) { free (cred_union); } - if (functions) { free (functions); } - if (credentials) { free (credentials); } return err; } + +krb5_error_code +cred_union_release (cc_credentials_union *in_cred_union) +{ + if (in_cred_union) { + if (in_cred_union->version == cc_credentials_v5 && + in_cred_union->credentials.credentials_v5) { + cc_credentials_v5_t *cv5 = in_cred_union->credentials.credentials_v5; + + /* should use krb5_free_unparsed_name but we have no context */ + if (cv5->client) { free (cv5->client); } + if (cv5->server) { free (cv5->server); } + + if (cv5->keyblock.data) { free (cv5->keyblock.data); } + if (cv5->ticket.data) { free (cv5->ticket.data); } + if (cv5->second_ticket.data) { free (cv5->second_ticket.data); } + + free_cc_array (cv5->addresses); + free_cc_array (cv5->authdata); + + free (cv5); + + } else if (in_cred_union->version == cc_credentials_v4 && + in_cred_union->credentials.credentials_v4) { + free (in_cred_union->credentials.credentials_v4); + } + free ((cc_credentials_union *) in_cred_union); + } + + return 0; +} + #else /* !USE_CCAPI_V3 */ /* * CopyCCDataArrayToK5 diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h index 257eb8dcc..c3a5e39cc 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.h +++ b/src/lib/krb5/ccache/ccapi/stdcc_util.h @@ -22,14 +22,16 @@ /* protoypes for private functions declared in stdcc_util.c */ #ifdef USE_CCAPI_V3 krb5_error_code -copy_cc_credentials_to_krb5_creds (krb5_context in_context, - cc_credentials_t in_credentials, - krb5_creds *out_creds); +copy_cc_cred_union_to_krb5_creds (krb5_context in_context, + const cc_credentials_union *in_cred_union, + krb5_creds *out_creds); krb5_error_code -copy_krb5_creds_to_cc_credentials (krb5_context in_context, - krb5_creds *in_creds, - cc_credentials_t *out_credentials); +copy_krb5_creds_to_cc_cred_union (krb5_context in_context, + krb5_creds *in_creds, + cc_credentials_union **out_cred_union); +krb5_error_code +cred_union_release (cc_credentials_union *in_cred_union); #else int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray); int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray);