/* * Deletion from credentials file */ int KRB5_CALLCONV krb_delete_cred ( char* sname, char* sinstance, char* srealm) { cc_credentials_t theCreds = NULL; cc_credentials_iterator_t iterator = NULL; cc_int32 cc_err = ccNoError; cc_context_t cc_context = NULL; cc_int32 cc_version; cc_ccache_t ccache = NULL; cc_err = cc_initialize (&cc_context, ccapi_version_3, &cc_version, NULL); if (cc_err == ccNoError) { cc_err = cc_context_open_ccache (cc_context, TKT_FILE, &ccache); } if (cc_err == ccNoError) { cc_err = cc_ccache_new_credentials_iterator (ccache, &iterator); } if (cc_err == ccNoError) { for (;;) { /* get next creds */ cc_err = cc_credentials_iterator_next (iterator, &theCreds); if (cc_err != ccNoError) { break; } if ((theCreds -> data -> version == cc_credentials_v4) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> service, sname) == 0) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> service_instance, sinstance) == 0) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> realm, srealm) == 0)) { cc_ccache_remove_credentials (ccache, theCreds); cc_credentials_release (theCreds); break; } cc_credentials_release (theCreds); } } if (iterator != NULL) cc_credentials_iterator_release (iterator); if (ccache != NULL) cc_ccache_release (ccache); if (cc_context != NULL) cc_context_release (cc_context); if (cc_err != ccNoError) return KFAILURE; else return KSUCCESS; }
/* * next cred * * - get the next credential in the cache as part of an iterator call * - this maps to call to cc_seq_fetch_creds */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_t credentials = NULL; cc_credentials_iterator_t iterator = *cursor; if (!iterator) { err = KRB5_CC_END; } if (!err) { err = stdccv3_setup (context, ccapi_data); } /* Note: CCAPI v3 ccaches can contain both v4 and v5 creds */ while (!err) { err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { copy_cc_cred_union_to_krb5_creds(context, credentials->data, creds); break; } } if (credentials) { cc_credentials_release (credentials); } if (err == ccIteratorEnd) { cc_credentials_iterator_release (iterator); *cursor = 0; } return cc_err_xlate (err); }
/* * remove * * - remove the specified credentials from the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *in_creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = NULL; int found = 0; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { 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 = krb5int_cc_creds_match_request(context, whichfields, 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 (iterator) { err = cc_credentials_iterator_release(iterator); } if (!err) { cache_changed (); } return cc_err_xlate (err); }
/* * Number of credentials in credentials cache */ int KRB5_CALLCONV krb_get_num_cred (void) { cc_credentials_t theCreds = NULL; int count = 0; cc_credentials_iterator_t iterator = NULL; cc_int32 cc_err = ccNoError; cc_context_t cc_context = NULL; cc_int32 cc_version; cc_ccache_t ccache = NULL; cc_err = cc_initialize (&cc_context, ccapi_version_3, &cc_version, NULL); if (cc_err == ccNoError) { cc_err = cc_context_open_ccache (cc_context, TKT_FILE, &ccache); } if (cc_err == ccNoError) { cc_err = cc_ccache_new_credentials_iterator (ccache, &iterator); } if (cc_err == ccNoError) { for (;;) { /* get next creds */ cc_err = cc_credentials_iterator_next (iterator, &theCreds); if (cc_err != ccNoError) break; if (theCreds -> data -> version == cc_credentials_v4) count++; cc_credentials_release (theCreds); } } if (iterator != NULL) cc_credentials_iterator_release (iterator); if (ccache != NULL) cc_ccache_release (ccache); if (cc_context != NULL) cc_context_release (cc_context); if (cc_err != ccNoError) return 0; else return count; }
cc_int32 check_once_cc_credentials_iterator_next(cc_credentials_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_credentials_t creds = NULL; cc_uint32 actual_count = 0; cc_int32 possible_return_values[5] = { ccNoError, ccIteratorEnd, ccErrBadParam, ccErrNoMem, ccErrInvalidCredentialsIterator, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) while (!err) { err = cc_credentials_iterator_next(iterator, &creds); if (creds) { actual_count++; cc_credentials_release(creds); creds = NULL; } } if (err == ccIteratorEnd) { err = ccNoError; } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); END_CHECK_ONCE; return err; }
/* * Retrieval from credentials file * This function is _not_!! well-defined under CCache API, because * there is no guarantee about order of credentials remaining the same. */ int KRB5_CALLCONV krb_get_nth_cred ( char* sname, char* sinstance, char* srealm, int n) { cc_credentials_t theCreds = NULL; int count = 0; cc_credentials_iterator_t iterator = NULL; cc_int32 cc_err = ccNoError; cc_context_t cc_context = NULL; cc_int32 cc_version; cc_ccache_t ccache = NULL; if (n < 1) return KFAILURE; cc_err = cc_initialize (&cc_context, ccapi_version_3, &cc_version, NULL); if (cc_err == ccNoError) { cc_err = cc_context_open_ccache (cc_context, TKT_FILE, &ccache); } if (cc_err == ccNoError) { cc_err = cc_ccache_new_credentials_iterator (ccache, &iterator); } if (cc_err == ccNoError) { for (count = 0; count < n;) { /* get next creds */ cc_err = cc_credentials_iterator_next (iterator, &theCreds); if (cc_err != ccNoError) break; if (theCreds -> data -> version == cc_credentials_v4) count++; if (count < n - 1) cc_credentials_release (theCreds); } } if (cc_err == ccNoError) { strcpy (sname, theCreds -> data -> credentials.credentials_v4 -> service); strcpy (sinstance, theCreds -> data -> credentials.credentials_v4 -> service_instance); strcpy (srealm, theCreds -> data -> credentials.credentials_v4 -> realm); } if (theCreds != NULL) cc_credentials_release (theCreds); if (iterator != NULL) cc_credentials_iterator_release (iterator); if (ccache != NULL) cc_ccache_release (ccache); if (cc_context != NULL) cc_context_release (cc_context); if (cc_err != ccNoError) return KFAILURE; else return KSUCCESS; }
/* * Retrieval from credentials cache */ int KRB5_CALLCONV krb_get_cred ( char* service, char* instance, char* realm, CREDENTIALS* creds) { int kerr = KSUCCESS; cc_int32 cc_err = ccNoError; cc_credentials_t theCreds = NULL; cc_credentials_iterator_t iterator = NULL; cc_context_t cc_context = NULL; cc_int32 cc_version; cc_ccache_t ccache = NULL; #ifdef USE_LOGIN_LIBRARY // If we are requesting a tgt, prompt for it if (strncmp (service, KRB_TICKET_GRANTING_TICKET, ANAME_SZ) == 0) { OSStatus err; char *cacheName; KLPrincipal outPrincipal; err = __KLInternalAcquireInitialTicketsForCache (TKT_FILE, kerberosVersion_V4, NULL, &outPrincipal, &cacheName); if (err == klNoErr) { krb_set_tkt_string (cacheName); // Tickets for the krb4 principal went here KLDisposeString (cacheName); KLDisposePrincipal (outPrincipal); } else { return GC_NOTKT; } } #endif /* USE_LOGIN_LIBRARY */ cc_err = cc_initialize (&cc_context, ccapi_version_3, &cc_version, NULL); if (cc_err == ccNoError) { cc_err = cc_context_open_ccache (cc_context, TKT_FILE, &ccache); } if (cc_err == ccNoError) { cc_err = cc_ccache_new_credentials_iterator (ccache, &iterator); } if (cc_err == ccNoError) { for (;;) { /* get next creds */ cc_err = cc_credentials_iterator_next (iterator, &theCreds); if (cc_err == ccIteratorEnd) { kerr = GC_NOTKT; break; } if (cc_err != ccNoError) { kerr = KFAILURE; break; } /* version, service, instance, realm check */ if ((theCreds -> data -> version == cc_credentials_v4) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> service, service) == 0) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> service_instance, instance) == 0) && (strcmp (theCreds -> data -> credentials.credentials_v4 -> realm, realm) == 0)) { /* Match! */ strcpy (creds -> service, service); strcpy (creds -> instance, instance); strcpy (creds -> realm, realm); memmove (creds -> session, theCreds -> data -> credentials.credentials_v4 -> session_key, sizeof (C_Block)); creds -> lifetime = theCreds -> data -> credentials.credentials_v4 -> lifetime; creds -> kvno = theCreds -> data -> credentials.credentials_v4 -> kvno; creds -> ticket_st.length = theCreds -> data -> credentials.credentials_v4 -> ticket_size; memmove (creds -> ticket_st.dat, theCreds -> data -> credentials.credentials_v4 -> ticket, creds -> ticket_st.length); creds -> issue_date = theCreds -> data -> credentials.credentials_v4 -> issue_date; strcpy (creds -> pname, theCreds -> data -> credentials.credentials_v4 -> principal); strcpy (creds -> pinst, theCreds -> data -> credentials.credentials_v4 -> principal_instance); creds -> stk_type = theCreds -> data -> credentials.credentials_v4 -> string_to_key_type; cc_credentials_release (theCreds); kerr = KSUCCESS; break; } else { cc_credentials_release (theCreds); } } } if (iterator != NULL) cc_credentials_iterator_release (iterator); if (ccache != NULL) cc_ccache_release (ccache); if (cc_context != NULL) cc_context_release (cc_context); if (kerr != KSUCCESS) return kerr; if (cc_err != ccNoError) return GC_NOTKT; else return KSUCCESS; }