aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2006-12-05 23:21:56 +0000
committerAlexandra Ellwood <lxs@mit.edu>2006-12-05 23:21:56 +0000
commit3d22bd77a212fc75d49495476f5d08d76be2f313 (patch)
treee02fb8062f31af0c31ad2be42794a294fdecbd0b
parent1526e420455d51bc0eceb24452f398858b585bc7 (diff)
downloadkrb5-3d22bd77a212fc75d49495476f5d08d76be2f313.zip
krb5-3d22bd77a212fc75d49495476f5d08d76be2f313.tar.gz
krb5-3d22bd77a212fc75d49495476f5d08d76be2f313.tar.bz2
krb5_cc_remove should work for the CCAPI
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: new owner: tlyu target_version: 1.6 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18923 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/k5-int.h5
-rw-r--r--src/lib/krb5/ccache/cc_retr.c99
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.c60
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.h10
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.c123
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.h14
6 files changed, 200 insertions, 111 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 73527c9..0ceee4d 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -1732,6 +1732,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 cadd3e5..43c9da7 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 ce54b28..edbec11 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 d548c05..4fe6027 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 2e6538c..58e72b3 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) {
@@ -436,16 +390,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 257eb8d..c3a5e39 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);