kim_error kim_identity_copy (kim_identity *out_identity, kim_identity in_identity) { kim_error err = KIM_NO_ERROR; kim_identity identity = KIM_IDENTITY_ANY; if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && in_identity != KIM_IDENTITY_ANY) { err = kim_identity_allocate (&identity); if (!err) { err = krb5_error (in_identity->context, krb5_copy_context (in_identity->context, &identity->context)); } if (!err) { err = krb5_error (identity->context, krb5_copy_principal (identity->context, in_identity->principal, &identity->principal)); } } if (!err) { *out_identity = identity; identity = NULL; } kim_identity_free (&identity); return check_error (err); }
kim_error kim_identity_create_from_components (kim_identity *out_identity, kim_string in_realm, kim_string in_1st_component, ...) { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; if (!err && !out_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_realm ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_1st_component) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { err = kim_identity_allocate (&identity); } if (!err) { err = krb5_error (NULL, krb5_init_context (&identity->context)); } if (!err) { va_list args; va_start (args, in_1st_component); err = krb5_error (identity->context, krb5int_build_principal_alloc_va (identity->context, &identity->principal, strlen(in_realm), in_realm, in_1st_component, args)); va_end (args); } if (!err) { *out_identity = identity; identity = NULL; } kim_identity_free (&identity); return check_error (err); }
kim_error kim_identity_create_from_krb5_principal (kim_identity *out_identity, krb5_context in_krb5_context, krb5_principal in_krb5_principal) { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; if (!err && !out_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_krb5_principal) { err = check_error (KIM_NULL_PARAMETER_ERR); } /* KLCreatePrincipalFromKerberos5Principal passes NULL in_krb5_context */ if (!err) { err = kim_identity_allocate (&identity); } if (!err) { if (in_krb5_context) { err = krb5_error (in_krb5_context, krb5_copy_context (in_krb5_context, &identity->context)); } else { err = krb5_error (NULL, krb5_init_context (&identity->context)); } } if (!err) { err = krb5_error (identity->context, krb5_copy_principal (identity->context, in_krb5_principal, &identity->principal)); } if (!err) { *out_identity = identity; identity = NULL; } kim_identity_free (&identity); return check_error (err); }
static inline kim_error kim_identity_allocate (kim_identity *out_identity) { kim_error err = kim_library_init (); kim_identity identity = NULL; if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { identity = malloc (sizeof (*identity)); if (!identity) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { *identity = kim_identity_initializer; *out_identity = identity; identity = NULL; } kim_identity_free (&identity); return check_error (err); }
kim_error kim_identity_create_from_string (kim_identity *out_identity, kim_string in_string) { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_string ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { err = kim_identity_allocate (&identity); } if (!err) { err = krb5_error (NULL, krb5_init_context (&identity->context)); } if (!err) { krb5_error_code code = krb5_parse_name (identity->context, in_string, &identity->principal); if (code == KRB5_PARSE_MALFORMED) { err = kim_error_set_message_for_code (KIM_BAD_PRINCIPAL_STRING_ERR, in_string); } else if (code) { err = krb5_error (identity->context, code); } } if (!err) { *out_identity = identity; identity = NULL; } if (identity) { kim_identity_free (&identity); } return check_error (err); }
int print_ccache (kim_ccache in_ccache, int *out_found_valid_tgt) { kim_error err = 0; kim_credential_iterator iterator = NULL; kim_identity ccache_identity = NULL; kim_string type = NULL; kim_string name = NULL; kim_string ccache_identity_string = NULL; int found_tickets = 0; *out_found_valid_tgt = 0; if (!err) { err = kim_ccache_get_type (in_ccache, &type); printiferr (err, "while getting the ccache type"); } if (!err) { err = kim_ccache_get_name (in_ccache, &name); printiferr (err, "while getting the ccache name"); } if (!err) { err = kim_ccache_get_client_identity (in_ccache, &ccache_identity); printiferr (err, "while getting the ccache principal"); } if (!err) { err = kim_identity_get_display_string (ccache_identity, &ccache_identity_string); printiferr (err, "while unparsing the ccache principal name"); } if (!err) { printmsg ("Kerberos 5 ticket cache: '%s:%s'\nDefault principal: %s\n\n", type, name, ccache_identity_string); printmsg ("Valid Starting"); printfiller (' ', get_timestamp_width () - sizeof ("Valid Starting") + 3); printmsg ("Expires"); printfiller (' ', get_timestamp_width () - sizeof ("Expires") + 3); printmsg ("Service Principal\n"); err = kim_credential_iterator_create (&iterator, in_ccache); } while (!err) { kim_credential credential = NULL; kim_identity client = NULL; kim_identity service = NULL; kim_string client_string = NULL; kim_string service_string = NULL; krb5_creds *creds = NULL; int extra_field = 0; err = kim_credential_iterator_next (iterator, &credential); if (!err && !credential) { break; } if (!err) { err = kim_credential_get_client_identity (credential, &client); printiferr (err, "while getting the client principal"); } if (!err) { err = kim_identity_get_display_string (client, &client_string); printiferr (err, "while unparsing the client principal name"); } if (!err) { err = kim_credential_get_service_identity (credential, &service); printiferr (err, "while getting the service principal"); } if (!err) { err = kim_identity_get_display_string (service, &service_string); printiferr (err, "while unparsing the service principal name"); } if (!err) { err = kim_credential_get_krb5_creds (credential, kcontext, &creds); printiferr (err, "while getting krb5 creds"); } if (!err && krb5_is_config_principal(kcontext, creds->server)) goto next; if (!err) { found_tickets = 1; printtime (creds->times.starttime ? creds->times.starttime : creds->times.authtime); printmsg (" "); printtime (creds->times.endtime); printmsg (" "); printmsg ("%s\n", service_string); if (strcmp (ccache_identity_string, client_string)) { if (!extra_field) { printmsg ("\t"); } printmsg ("for client %s", client_string); extra_field++; } if (creds->ticket_flags & TKT_FLG_RENEWABLE) { printmsg (extra_field ? ", " : "\t"); printmsg ("renew until "); printtime (creds->times.renew_till); extra_field += 2; } if (extra_field > 2) { printmsg ("\n"); extra_field = 0; } if (show_flags) { printmsg (extra_field ? ", " : "\t"); printflags (creds->ticket_flags); extra_field++; } if (extra_field > 2) { printmsg ("\n"); extra_field = 0; } if (show_enctypes) { krb5_ticket *ticket_rep; if (krb5_decode_ticket (&creds->ticket, &ticket_rep) == 0) { if (!extra_field) { printmsg ("\t"); } else { printmsg (", "); } printmsg ("Etype (skey, tkt): %s, ", enctype_to_string (creds->keyblock.enctype)); printmsg ("%s ", enctype_to_string (ticket_rep->enc_part.enctype)); extra_field++; krb5_free_ticket (kcontext, ticket_rep); } } if (extra_field) { printmsg ("\n"); } if (show_address_list) { printmsg ("\tAddresses: "); if (!creds->addresses || !creds->addresses[0]) { printmsg ("(none)\n"); } else { int i; for (i = 0; creds->addresses[i]; i++) { if (i > 0) { printmsg (", "); } printaddress (*creds->addresses[i]); } printmsg ("\n"); } } if (extra_field) { printmsg ("\n"); } } if (!err) { kim_boolean is_tgt = 0; kim_credential_state state; err = kim_credential_is_tgt (credential, &is_tgt); printiferr (err, "while checking if creds are valid"); if (!err) { err = kim_credential_get_state (credential, &state); } if (!err && is_tgt && state == kim_credentials_state_valid) { *out_found_valid_tgt = 1; } } next: if (creds) { krb5_free_creds (kcontext, creds); } kim_string_free (&client_string); kim_string_free (&service_string); kim_identity_free (&client); kim_identity_free (&service); kim_credential_free (&credential); } kim_string_free (&type); kim_string_free (&name); kim_string_free (&ccache_identity_string); kim_identity_free (&ccache_identity); kim_credential_iterator_free (&iterator); if (!err) { if (!found_tickets) { printerr ("No Kerberos 5 tickets in credentials cache\n"); } else { printmsg ("\n"); } } return err; }
static int destroy_tickets (void) { krb5_error_code err = 0; if (cache_name) { kim_ccache ccache = NULL; err = kim_ccache_create_from_display_name (&ccache, cache_name); printiferr (err, "while locating credentials cache '%s'", cache_name); if (!err) { err = kim_ccache_destroy (&ccache); printiferr (err, "while destroying credentials cache '%s'", cache_name); } } else if (all) { /* Destroy all ticket caches */ kim_ccache_iterator iterator = NULL; err = kim_ccache_iterator_create (&iterator); while (!err) { kim_ccache ccache = NULL; err = kim_ccache_iterator_next (iterator, &ccache); if (!err) { if (ccache) { err = kim_ccache_destroy (&ccache); } else { break; /* no more ccaches */ } } } kim_ccache_iterator_free (&iterator); } else { /* Destroy the tickets by the principal or the default tickets */ kim_identity identity = KIM_IDENTITY_ANY; kim_ccache ccache = NULL; if (principal_name) { err = kim_identity_create_from_string (&identity, principal_name); printiferr (err, "while creating identity for '%s'", principal_name); } if (!err) { kim_ccache_create_from_client_identity (&ccache, identity); if (identity) { printiferr (err, "while getting ccache for '%s'", principal_name); } else { printiferr (err, "while getting default ccache"); } } if (!err) { err = kim_ccache_destroy (&ccache); printiferr (err, "while destroying tickets"); } kim_identity_free (&identity); } return err ? 1 : 0; }
kim_error kim_os_selection_hints_remember_identity (kim_selection_hints in_selection_hints, kim_identity in_identity) { kim_error err = KIM_NO_ERROR; CFArrayRef old_hints_array = NULL; CFMutableArrayRef new_hints_array = NULL; CFIndex count = 0; CFIndex i = 0; kim_boolean hint_already_exists = 0; kim_boolean hints_array_changed = 0; if (!err && !in_selection_hints) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { err = kim_os_selection_hints_get_selection_hints_array (&old_hints_array); } if (!err) { if (old_hints_array) { new_hints_array = CFArrayCreateMutableCopy (kCFAllocatorDefault, 0, old_hints_array); } else { new_hints_array = CFArrayCreateMutable (kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); } if (!new_hints_array) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { count = CFArrayGetCount (new_hints_array); } for (i = 0; !err && i < count; i++) { CFDictionaryRef dictionary = NULL; kim_identity identity = NULL; kim_boolean hints_equal = 0; dictionary = CFArrayGetValueAtIndex (new_hints_array, i); if (!dictionary) { err = KIM_OUT_OF_MEMORY_ERR; } if (!err && CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) { kim_debug_printf ("%s: Malformed entry in hints array.", __FUNCTION__); continue; /* skip entries which aren't dictionaries */ } if (!err) { err = kim_os_selection_hints_compare_to_dictionary (in_selection_hints, dictionary, &hints_equal); } if (!err && hints_equal) { kim_comparison comparison; err = kim_os_selection_hints_get_dictionary_identity (dictionary, &identity); if (!err) { err = kim_identity_compare (in_identity, identity, &comparison); } if (!err) { if (kim_comparison_is_equal_to (comparison) && !hint_already_exists) { hint_already_exists = 1; } else { CFArrayRemoveValueAtIndex (new_hints_array, i); i--; /* back up one index so we don't skip */ count = CFArrayGetCount (new_hints_array); /* count changed */ hints_array_changed = 1; } } kim_identity_free (&identity); } } if (!err && !hint_already_exists) { CFDictionaryRef new_hint_dictionary = NULL; err = kim_os_selection_hints_create_dictionary (in_selection_hints, in_identity, &new_hint_dictionary); if (!err) { CFArrayInsertValueAtIndex (new_hints_array, 0, new_hint_dictionary); hints_array_changed = 1; } if (new_hint_dictionary) { CFRelease (new_hint_dictionary); } } if (!err && hints_array_changed) { err = kim_os_selection_hints_set_selection_hints_array (new_hints_array); } if (new_hints_array ) { CFRelease (new_hints_array); } if (old_hints_array ) { CFRelease (old_hints_array); } return check_error (err); }
/* ------------------------------------------------------------------------ */ kim_error kim_os_preferences_set_favorites_for_key (kim_preference_key in_key, kim_favorites in_favorites) { kim_error err = KIM_NO_ERROR; kim_count count = 0; CFMutableArrayRef array = NULL; if (!err && !in_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { err = kim_favorites_get_number_of_identities (in_favorites, &count); } if (!err) { array = CFArrayCreateMutable (kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); if (!array) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { kim_count i; for (i = 0; !err && i < count; i++) { kim_identity identity = NULL; kim_options options = NULL; kim_string string = NULL; CFStringRef cfstring = NULL; CFMutableDictionaryRef dictionary = NULL; err = kim_favorites_get_identity_at_index (in_favorites, i, &identity, &options); if (!err) { err = kim_identity_get_string (identity, &string); } if (!err) { err = kim_os_string_get_cfstring (string, &cfstring); } if (!err) { dictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dictionary) { err = check_error (KIM_OUT_OF_MEMORY_ERR); } } if (!err) { err = kim_os_preferences_set_value_for_dict_key (dictionary, kim_preference_key_client_identity, cfstring); } if (!err && options) { err = kim_os_preferences_options_to_dictionary (options, dictionary); } if (!err) { CFArrayAppendValue (array, dictionary); } if (dictionary) { CFRelease (dictionary); } if (cfstring ) { CFRelease (cfstring); } kim_string_free (&string); kim_options_free (&options); kim_identity_free (&identity); } } if (!err) { err = kim_os_preferences_set_value (in_key, array); } if (array) { CFRelease (array); } return check_error (err); }
kim_error kim_os_preferences_get_favorites_for_key (kim_preference_key in_key, kim_favorites io_favorites) { kim_error err = KIM_NO_ERROR; CFArrayRef value = NULL; if (!err && !io_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { err = kim_os_preferences_copy_value (in_key, CFArrayGetTypeID (), (CFPropertyListRef *) &value); } if (!err && value) { if (!value || CFArrayGetCount (value) < 1) { err = kim_favorites_remove_all_identities (io_favorites); } else { CFIndex count = CFArrayGetCount (value); CFIndex i; for (i = 0; !err && i < count; i++) { CFDictionaryRef dictionary = NULL; CFStringRef cfstring = NULL; dictionary = (CFDictionaryRef) CFArrayGetValueAtIndex (value, i); if (!dictionary || CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) { err = check_error (KIM_PREFERENCES_READ_ERR); } if (!err) { err = kim_os_preferences_copy_value_for_dict_key (dictionary, kim_preference_key_client_identity, CFStringGetTypeID (), (CFPropertyListRef *) &cfstring); } if (!err && cfstring) { kim_string string = NULL; kim_identity identity = NULL; kim_options options = KIM_OPTIONS_DEFAULT; err = kim_os_string_create_from_cfstring (&string, cfstring); if (!err) { err = kim_identity_create_from_string (&identity, string); } if (!err && (CFDictionaryGetCount (dictionary) > 1)) { err = kim_os_preferences_dictionary_to_options (dictionary, &options); } if (!err) { err = kim_favorites_add_identity (io_favorites, identity, options); } kim_string_free (&string); kim_options_free (&options); kim_identity_free (&identity); } } if (err) { kim_favorites_remove_all_identities (io_favorites); } } } if (value) { CFRelease (value); } return check_error (err); }