(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 *);
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;
+}
{
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);
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);
}
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;
}
}
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)
{
return err;
}
-static krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_stdccv3_ptcursor_next(
krb5_context context,
krb5_cc_ptcursor cursor,
return err;
}
-static krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_stdccv3_ptcursor_free(
krb5_context context,
krb5_cc_ptcursor *cursor)
/* 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 );
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 );
#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)
}
}
-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,
*/
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;
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
* - 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;
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) {
}
#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; }
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); }
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
/* 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);