From 27862be469db71abf2bcdf64837143a56a6bcd10 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Sat, 27 Sep 2008 21:31:06 +0000 Subject: [PATCH] Renamed kim_identity_get_components to kim_identity_get_components_string to better reflect what it does (a string of everything but the realm, not an array of components like the old name might imply). Added private functions which will be used by KLL to shim on top of KIM. Private functions also reduce memory allocations inside of KIM. ticket: 6055 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20766 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/kim/kim_identity.h | 4 +- src/kim/lib/kim-lite.exports | 2 +- src/kim/lib/kim.exports | 2 +- src/kim/lib/kim_credential.c | 160 ++++++++++------------------- src/kim/lib/kim_identity.c | 30 ++++-- src/kim/lib/kim_identity_private.h | 4 + src/kim/lib/kim_options.c | 118 ++++++++++++--------- src/kim/lib/kim_options_private.h | 9 +- src/kim/lib/kim_string_private.h | 8 +- src/kim/lib/mac/kim_os_identity.c | 56 +++++++++- 10 files changed, 210 insertions(+), 183 deletions(-) diff --git a/src/include/kim/kim_identity.h b/src/include/kim/kim_identity.h index c627758d1..8f10168f9 100644 --- a/src/include/kim/kim_identity.h +++ b/src/include/kim/kim_identity.h @@ -248,8 +248,8 @@ kim_error kim_identity_get_component_at_index (kim_identity in_identity, * \return On success, #KIM_NO_ERROR. On failure, an error code representing the failure. * \brief Get a display string of the non-realm components of an identity. */ -kim_error kim_identity_get_components (kim_identity in_identity, - kim_string *out_components); +kim_error kim_identity_get_components_string (kim_identity in_identity, + kim_string *out_components); /*! * \param in_identity an identity object. diff --git a/src/kim/lib/kim-lite.exports b/src/kim/lib/kim-lite.exports index a89be7c11..816b8bb56 100644 --- a/src/kim/lib/kim-lite.exports +++ b/src/kim/lib/kim-lite.exports @@ -12,7 +12,7 @@ kim_identity_get_string kim_identity_get_display_string kim_identity_get_realm kim_identity_get_number_of_components -kim_identity_get_components +kim_identity_get_components_string kim_identity_get_component_at_index kim_identity_get_krb5_principal kim_identity_change_password diff --git a/src/kim/lib/kim.exports b/src/kim/lib/kim.exports index ac4d123db..fea6bf813 100644 --- a/src/kim/lib/kim.exports +++ b/src/kim/lib/kim.exports @@ -13,7 +13,7 @@ kim_identity_get_display_string kim_identity_get_realm kim_identity_get_number_of_components kim_identity_get_component_at_index -kim_identity_get_components +kim_identity_get_components_string kim_identity_get_krb5_principal kim_identity_change_password kim_identity_free diff --git a/src/kim/lib/kim_credential.c b/src/kim/lib/kim_credential.c index 8a8b6cd0b..c1d48e1b7 100644 --- a/src/kim/lib/kim_credential.c +++ b/src/kim/lib/kim_credential.c @@ -209,9 +209,6 @@ kim_error kim_credential_create_new (kim_credential *out_credential, kim_credential credential = NULL; kim_options options = NULL; kim_ui_context context; - kim_string service = NULL; - krb5_principal principal = NULL; - krb5_get_init_creds_opt *init_cred_options = NULL; kim_boolean ui_inited = 0; kim_boolean done = 0; @@ -233,22 +230,6 @@ kim_error kim_credential_create_new (kim_credential *out_credential, } } - if (!err) { - err = kim_options_get_init_cred_options (options, - credential->context, - &init_cred_options); - } - - if (!err) { - kim_options_get_service_name (options, &service); - } - - if (!err) { - err = kim_identity_get_krb5_principal (in_identity, - credential->context, - &principal); - } - if (!err) { err = kim_ui_init (&context); if (!err) { @@ -261,6 +242,10 @@ kim_error kim_credential_create_new (kim_credential *out_credential, krb5_creds creds; kim_boolean free_creds = 0; kim_count prompt_count; + krb5_principal principal = kim_identity_krb5_principal (in_identity); + krb5_get_init_creds_opt *opts = kim_options_init_cred_options (options); + char *service = kim_options_service_name (options); + kim_time start_time = kim_options_start_time (options); /* set counter to zero so we can tell if we got prompted */ context.prompt_count = 0; @@ -271,9 +256,10 @@ kim_error kim_credential_create_new (kim_credential *out_credential, principal, NULL, kim_ui_prompter, - &context, 0, - (char *) service, - init_cred_options)); + &context, + start_time, + service, + opts)); prompt_count = context.prompt_count; /* remember if we got prompts */ if (!err) { free_creds = 1; } @@ -316,20 +302,12 @@ kim_error kim_credential_create_new (kim_credential *out_credential, if (!err) { err = check_error (fini_err); } } - /* free before credential is passed back to caller */ - if (credential && init_cred_options) { - kim_options_free_init_cred_options (credential->context, &init_cred_options); - } - - if (credential && principal) { krb5_free_principal (credential->context, principal); } - if (!err) { *out_credential = credential; credential = NULL; } - if (!in_options) { kim_options_free (&options); } - kim_string_free (&service); + if (options != in_options) { kim_options_free (&options); } kim_credential_free (&credential); return check_error (err); @@ -350,9 +328,7 @@ kim_error kim_credential_create_from_keytab (kim_credential *out_credential, krb5_creds creds; kim_boolean free_creds = FALSE; krb5_principal principal = NULL; - kim_time start_time = 0; - kim_string service_name = NULL; - krb5_get_init_creds_opt *init_cred_options = NULL; + kim_options options = in_options; if (!err && !out_credential) { err = check_error (KIM_NULL_PARAMETER_ERR); } @@ -364,28 +340,8 @@ kim_error kim_credential_create_from_keytab (kim_credential *out_credential, err = krb5_error (NULL, krb5_init_context (&credential->context)); } - if (!err) { - kim_options options = in_options; - - if (!options) { - err = kim_options_create (&options); - } - - if (!err) { - err = kim_options_get_start_time (options, &start_time); - } - - if (!err) { - err = kim_options_get_service_name (options, &service_name); - } - - if (!err) { - err = kim_options_get_init_cred_options (options, - credential->context, - &init_cred_options); - } - - if (options != in_options) { kim_options_free (&options); } + if (!err && !options) { + err = kim_options_create (&options); } if (!err) { @@ -436,14 +392,18 @@ kim_error kim_credential_create_from_keytab (kim_credential *out_credential, } if (!err) { + krb5_get_init_creds_opt *opts = kim_options_init_cred_options (options); + char *service = kim_options_service_name (options); + kim_time start_time = kim_options_start_time (options); + err = krb5_error (credential->context, krb5_get_init_creds_keytab (credential->context, &creds, principal, keytab, start_time, - (char *) service_name, - init_cred_options)); + service, + opts)); if (!err) { free_creds = TRUE; } } @@ -454,15 +414,15 @@ kim_error kim_credential_create_from_keytab (kim_credential *out_credential, &credential->creds)); } + if (principal ) { krb5_free_principal (credential->context, principal); } + if (!err) { *out_credential = credential; credential = NULL; } - if (principal ) { krb5_free_principal (credential->context, principal); } + if (options != in_options) { kim_options_free (&options); } if (free_creds) { krb5_free_cred_contents (credential->context, &creds); } - kim_options_free_init_cred_options (credential->context, &init_cred_options); - kim_string_free (&service_name); kim_credential_free (&credential); return check_error (err); @@ -519,7 +479,6 @@ kim_error kim_credential_create_for_change_password (kim_credential *out_creden kim_credential credential = NULL; kim_string realm = NULL; kim_string service = NULL; - krb5_principal principal = NULL; kim_string service_format = "kadmin/changepw@%s"; if (!err && !out_credential ) { err = check_error (KIM_NULL_PARAMETER_ERR); } @@ -535,12 +494,6 @@ kim_error kim_credential_create_for_change_password (kim_credential *out_creden err = krb5_error (NULL, krb5_init_context (&credential->context)); } - if (!err) { - err = kim_identity_get_krb5_principal (in_identity, - credential->context, - &principal); - } - if (!err) { err = kim_identity_get_realm (in_identity, &realm); } @@ -552,6 +505,7 @@ kim_error kim_credential_create_for_change_password (kim_credential *out_creden if (!err) { krb5_creds creds; kim_boolean free_creds = 0; + krb5_principal principal = kim_identity_krb5_principal (in_identity); krb5_get_init_creds_opt opts; krb5_get_init_creds_opt_init (&opts); @@ -585,8 +539,6 @@ kim_error kim_credential_create_for_change_password (kim_credential *out_creden if (free_creds) { krb5_free_cred_contents (credential->context, &creds); } } - if (principal) { krb5_free_principal (credential->context, principal); } - if (!err) { *out_user_was_prompted = (in_ui_context->prompt_count > 0); *out_credential = credential; @@ -952,50 +904,41 @@ kim_error kim_credential_get_options (kim_credential in_credential, /* ------------------------------------------------------------------------ */ kim_error kim_credential_store (kim_credential in_credential, - kim_identity in_client_identity, + kim_identity in_identity, kim_ccache *out_ccache) { kim_error err = KIM_NO_ERROR; - krb5_context context = NULL; krb5_ccache k5ccache = NULL; - kim_string type = NULL; - krb5_principal client_principal = NULL; kim_boolean destroy_ccache_on_error = FALSE; - if (!err && !in_credential ) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err && !in_client_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } - - if (!err) { - err = krb5_error (NULL, krb5_init_context (&context)); - } - - if (!err) { - err = kim_identity_get_krb5_principal (in_client_identity, context, - &client_principal); - } + if (!err && !in_credential) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err && !in_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { char *environment_ccache = getenv ("KRB5CCNAME"); if (environment_ccache) { - err = krb5_error (context, - krb5_cc_resolve (context, environment_ccache, + err = krb5_error (in_credential->context, + krb5_cc_resolve (in_credential->context, + environment_ccache, &k5ccache)); } else { kim_ccache ccache = NULL; err = kim_ccache_create_from_client_identity (&ccache, - in_client_identity); + in_identity); if (!err) { - err = kim_ccache_get_krb5_ccache (ccache, context, &k5ccache); + err = kim_ccache_get_krb5_ccache (ccache, + in_credential->context, + &k5ccache); } else if (err == KIM_NO_SUCH_PRINCIPAL_ERR) { /* Nothing to replace, create a new ccache */ - err = krb5_error (context, - krb5_cc_new_unique (context, "API", NULL, - &k5ccache)); + err = krb5_error (in_credential->context, + krb5_cc_new_unique (in_credential->context, + "API", NULL, &k5ccache)); if (!err) { destroy_ccache_on_error = TRUE; } } @@ -1004,9 +947,11 @@ kim_error kim_credential_store (kim_credential in_credential, } if (!err) { + krb5_principal principal = kim_identity_krb5_principal (in_identity); + err = krb5_error (in_credential->context, krb5_cc_initialize (in_credential->context, - k5ccache, client_principal)); + k5ccache, principal)); } if (!err) { @@ -1016,7 +961,9 @@ kim_error kim_credential_store (kim_credential in_credential, } if (!err && out_ccache) { - err = kim_ccache_create_from_krb5_ccache (out_ccache, context, k5ccache); + err = kim_ccache_create_from_krb5_ccache (out_ccache, + in_credential->context, + k5ccache); } if (k5ccache) { @@ -1026,9 +973,6 @@ kim_error kim_credential_store (kim_credential in_credential, krb5_cc_close (in_credential->context, k5ccache); } } - if (client_principal) { krb5_free_principal (context, client_principal); } - if (context ) { krb5_free_context (context); } - kim_string_free (&type); return check_error (err); } @@ -1044,7 +988,6 @@ kim_error kim_credential_verify (kim_credential in_credential, { kim_error err = KIM_NO_ERROR; krb5_context scontext = NULL; - krb5_principal service_principal = NULL; krb5_keytab keytab = NULL; if (!err && !in_credential) { err = check_error (KIM_NULL_PARAMETER_ERR); } @@ -1053,30 +996,32 @@ kim_error kim_credential_verify (kim_credential in_credential, err = krb5_error (NULL, krb5_init_secure_context (&scontext)); } - if (!err && in_service_identity) { - err = kim_identity_get_krb5_principal (in_service_identity, scontext, &service_principal); - } - if (in_keytab) { err = krb5_error (scontext, krb5_kt_resolve (scontext, in_keytab, &keytab)); } if (!err) { + krb5_principal sprincipal = NULL; krb5_verify_init_creds_opt options; /* That's "no key == fail" not "no fail" >.< */ krb5_verify_init_creds_opt_init (&options); krb5_verify_init_creds_opt_set_ap_req_nofail (&options, in_fail_if_no_service_key); + if (in_service_identity) { + sprincipal = kim_identity_krb5_principal (in_service_identity); + } + err = krb5_error (scontext, - krb5_verify_init_creds (scontext, in_credential->creds, - service_principal, + krb5_verify_init_creds (scontext, + in_credential->creds, + sprincipal, keytab, NULL /* don't store creds in ccache */, &options)); - if (err && !service_principal && in_fail_if_no_service_key) { + if (err && !in_service_identity && in_fail_if_no_service_key) { /* If the service principal wasn't specified but we are supposed to * fail without a key we should walk the keytab trying to find one * that succeeds. */ @@ -1124,9 +1069,8 @@ kim_error kim_credential_verify (kim_credential in_credential, } } - if (keytab ) { krb5_kt_close (scontext, keytab); } - if (service_principal) { krb5_free_principal (scontext, service_principal); } - if (scontext ) { krb5_free_context (scontext); } + if (keytab ) { krb5_kt_close (scontext, keytab); } + if (scontext) { krb5_free_context (scontext); } return check_error (err); } diff --git a/src/kim/lib/kim_identity.c b/src/kim/lib/kim_identity.c index 333067bc5..b431ae8b8 100644 --- a/src/kim/lib/kim_identity.c +++ b/src/kim/lib/kim_identity.c @@ -200,14 +200,21 @@ kim_error kim_identity_create_from_krb5_principal (kim_identity *out_identity, if (!err && !out_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_krb5_principal) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err && !in_krb5_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); } + /* KLCreatePrincipalFromKerberos5Principal passes NULL in_krb5_context */ if (!err) { err = kim_identity_allocate (&identity); } if (!err) { - err = krb5_error (NULL, krb5_init_context (&identity->context)); + 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) { @@ -440,8 +447,8 @@ kim_error kim_identity_get_component_at_index (kim_identity in_identity, /* ------------------------------------------------------------------------ */ -kim_error kim_identity_get_components (kim_identity in_identity, - kim_string *out_components) +kim_error kim_identity_get_components_string (kim_identity in_identity, + kim_string *out_components) { kim_error err = KIM_NO_ERROR; kim_string components = NULL; @@ -502,8 +509,8 @@ kim_error kim_identity_get_krb5_principal (kim_identity in_identity, if (!err && !out_krb5_principal) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { - err = krb5_error (in_identity->context, - krb5_copy_principal (in_identity->context, + err = krb5_error (in_krb5_context, + krb5_copy_principal (in_krb5_context, in_identity->principal, out_krb5_principal)); } @@ -513,6 +520,17 @@ kim_error kim_identity_get_krb5_principal (kim_identity in_identity, /* ------------------------------------------------------------------------ */ +krb5_principal kim_identity_krb5_principal (kim_identity in_identity) +{ + if (in_identity) { + return in_identity->principal; + } + check_error (KIM_NULL_PARAMETER_ERR); /* log error */ + return NULL; +} + +/* ------------------------------------------------------------------------ */ + kim_error kim_identity_is_tgt_service (kim_identity in_identity, kim_boolean *out_is_tgt_service) { diff --git a/src/kim/lib/kim_identity_private.h b/src/kim/lib/kim_identity_private.h index 4b1adeb48..f8ef4d629 100644 --- a/src/kim/lib/kim_identity_private.h +++ b/src/kim/lib/kim_identity_private.h @@ -31,6 +31,8 @@ #include "kim_library_private.h" #include "kim_ui_private.h" +krb5_principal kim_identity_krb5_principal (kim_identity in_identity); + kim_error kim_identity_is_tgt_service (kim_identity in_identity, kim_boolean *out_is_tgt_service); @@ -47,4 +49,6 @@ kim_error kim_identity_change_password_common (kim_identity in_identity, kim_boolean in_old_password_expired, kim_ui_context *in_ui_context); +kim_error kim_os_identity_remove_saved_password (kim_identity in_identity); + #endif /* KIM_IDENTITY_PRIVATE_H */ diff --git a/src/kim/lib/kim_options.c b/src/kim/lib/kim_options.c index 84a77f6cd..a5470f413 100644 --- a/src/kim/lib/kim_options.c +++ b/src/kim/lib/kim_options.c @@ -37,6 +37,8 @@ struct kim_options_opaque { kim_boolean proxiable; kim_boolean addressless; kim_string service_name; + krb5_context init_cred_context; + krb5_get_init_creds_opt *init_cred_options; }; struct kim_options_opaque kim_options_initializer = { @@ -47,6 +49,8 @@ kim_default_renewal_lifetime, kim_default_forwardable, kim_default_proxiable, kim_default_addressless, +NULL, +NULL, NULL }; /* ------------------------------------------------------------------------ */ @@ -417,70 +421,74 @@ kim_error kim_options_get_service_name (kim_options in_options, return check_error (err); } +#pragma mark - + /* ------------------------------------------------------------------------ */ -kim_error kim_options_get_init_cred_options (kim_options in_options, - krb5_context in_context, - krb5_get_init_creds_opt **out_init_cred_options) +char *kim_options_service_name (kim_options in_options) { - kim_error err = KIM_NO_ERROR; - krb5_get_init_creds_opt *init_cred_options; - krb5_address **addresses = NULL; - - if (!err && !in_options ) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err && !out_init_cred_options) { err = check_error (KIM_NULL_PARAMETER_ERR); } - - if (!err) { - krb5_get_init_creds_opt_alloc (in_context, &init_cred_options); - } - - if (!err && in_options) { - if (!in_options->addressless) { - err = krb5_error (in_context, - krb5_os_localaddr (in_context, &addresses)); - } - - if (!err) { - krb5_get_init_creds_opt_set_tkt_life (init_cred_options, in_options->lifetime); - krb5_get_init_creds_opt_set_renew_life (init_cred_options, in_options->renewable ? in_options->renewal_lifetime : 0); - krb5_get_init_creds_opt_set_forwardable (init_cred_options, in_options->forwardable); - krb5_get_init_creds_opt_set_proxiable (init_cred_options, in_options->proxiable); - krb5_get_init_creds_opt_set_address_list (init_cred_options, addresses); - addresses = NULL; - } + if (in_options) { + return (char *) in_options->service_name; } - - if (!err) { - *out_init_cred_options = init_cred_options; - init_cred_options = NULL; + check_error (KIM_NULL_PARAMETER_ERR); /* log bad options input */ + return NULL; +} + +/* ------------------------------------------------------------------------ */ + +kim_time kim_options_start_time (kim_options in_options) +{ + if (in_options) { + return in_options->start_time; } - - if (init_cred_options) { krb5_get_init_creds_opt_free (in_context, init_cred_options); } - if (addresses ) { krb5_free_addresses (in_context, addresses); } - - return check_error (err); + check_error (KIM_NULL_PARAMETER_ERR); /* log bad options input */ + return 0; } /* ------------------------------------------------------------------------ */ -kim_error kim_options_free_init_cred_options (krb5_context in_context, - krb5_get_init_creds_opt **io_init_cred_options) +krb5_get_init_creds_opt *kim_options_init_cred_options (kim_options in_options) { kim_error err = KIM_NO_ERROR; + krb5_address **addresses = NULL; - if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err && !in_options) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err && io_init_cred_options && *io_init_cred_options) { - if ((*io_init_cred_options)->address_list) { - krb5_free_addresses (in_context, (*io_init_cred_options)->address_list); - (*io_init_cred_options)->address_list = NULL; - } - krb5_get_init_creds_opt_free (in_context, *io_init_cred_options); - *io_init_cred_options = NULL; + if (!err && !in_options->addressless) { + err = krb5_error (in_options->init_cred_context, + krb5_os_localaddr (in_options->init_cred_context, + &addresses)); } - return check_error (err); + if (!err && !in_options->init_cred_context) { + err = krb5_error (NULL, + krb5_init_context (&in_options->init_cred_context)); + } + + if (!err && !in_options->init_cred_options) { + err = krb5_error (in_options->init_cred_context, + krb5_get_init_creds_opt_alloc (in_options->init_cred_context, + &in_options->init_cred_options)); + } + + if (!err) { + krb5_get_init_creds_opt_set_tkt_life (in_options->init_cred_options, + in_options->lifetime); + krb5_get_init_creds_opt_set_renew_life (in_options->init_cred_options, + in_options->renewable ? in_options->renewal_lifetime : 0); + krb5_get_init_creds_opt_set_forwardable (in_options->init_cred_options, + in_options->forwardable); + krb5_get_init_creds_opt_set_proxiable (in_options->init_cred_options, + in_options->proxiable); + krb5_get_init_creds_opt_set_address_list (in_options->init_cred_options, + addresses); + addresses = NULL; + } + + if (addresses) { krb5_free_addresses (in_options->init_cred_context, + addresses); } + + return !check_error (err) ? in_options->init_cred_options : NULL; } /* ------------------------------------------------------------------------ */ @@ -489,6 +497,18 @@ void kim_options_free (kim_options *io_options) { if (io_options && *io_options) { kim_string_free (&(*io_options)->service_name); + if ((*io_options)->init_cred_context) { + if ((*io_options)->init_cred_options) { + if ((*io_options)->init_cred_options->address_list) { + krb5_free_addresses ((*io_options)->init_cred_context, + (*io_options)->init_cred_options->address_list); + } + krb5_get_init_creds_opt_free ((*io_options)->init_cred_context, + (*io_options)->init_cred_options); + } + krb5_free_context ((*io_options)->init_cred_context); + } + free (*io_options); *io_options = NULL; } diff --git a/src/kim/lib/kim_options_private.h b/src/kim/lib/kim_options_private.h index f11d414ef..5c49e41f2 100644 --- a/src/kim/lib/kim_options_private.h +++ b/src/kim/lib/kim_options_private.h @@ -31,11 +31,10 @@ kim_error kim_options_create_empty (kim_options *out_options); -kim_error kim_options_get_init_cred_options (kim_options in_options, - krb5_context in_context, - krb5_get_init_creds_opt **out_init_cred_options); +krb5_get_init_creds_opt *kim_options_init_cred_options (kim_options in_options); -kim_error kim_options_free_init_cred_options (krb5_context in_context, - krb5_get_init_creds_opt **io_init_cred_options); +char *kim_options_service_name (kim_options in_options); + +kim_time kim_options_start_time (kim_options in_options); #endif /* KIM_OPTIONS_PRIVATE_H */ diff --git a/src/kim/lib/kim_string_private.h b/src/kim/lib/kim_string_private.h index 9ee4846c2..48d7bae13 100644 --- a/src/kim/lib/kim_string_private.h +++ b/src/kim/lib/kim_string_private.h @@ -48,18 +48,12 @@ kim_error kim_string_create_from_format_va_retcode (kim_string *out_string, kim_error kim_string_create_from_format_va (kim_string *out_string, kim_string in_format, - va_list in_args); + va_list in_args); kim_error kim_string_create_from_buffer (kim_string *out_string, const char *in_buffer, kim_count in_length); -kim_error kim_string_prepend (kim_string *io_string, - kim_string in_prefix); - -kim_error kim_string_append (kim_string *io_string, - kim_string in_suffix); - /* OS-specific because it should use UTF8-safe sorting where possible */ kim_error kim_os_string_compare (kim_string in_string, kim_string in_compare_to_string, diff --git a/src/kim/lib/mac/kim_os_identity.c b/src/kim/lib/mac/kim_os_identity.c index c25729b75..690a2f252 100644 --- a/src/kim/lib/mac/kim_os_identity.c +++ b/src/kim/lib/mac/kim_os_identity.c @@ -45,7 +45,7 @@ kim_error kim_os_identity_get_saved_password (kim_identity in_identity, if (!err && !out_password) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { - err = kim_identity_get_components (in_identity, &name); + err = kim_identity_get_components_string (in_identity, &name); } if (!err) { @@ -86,7 +86,7 @@ kim_error kim_os_identity_set_saved_password (kim_identity in_identity, if (!err && !in_password) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { - err = kim_identity_get_components (in_identity, &name); + err = kim_identity_get_components_string (in_identity, &name); } if (!err) { @@ -142,8 +142,9 @@ kim_error kim_os_identity_set_saved_password (kim_identity in_identity, attrInfo.tag = &tag; attrInfo.format = &format; - err = SecKeychainItemCopyAttributesAndData (itemRef, &attrInfo, NULL, - &copiedAttrs, 0, NULL); + err = SecKeychainItemCopyAttributesAndData (itemRef, &attrInfo, + NULL, &copiedAttrs, + 0, NULL); if (!err) { /* Label format used by Apple patches */ @@ -183,6 +184,53 @@ kim_error kim_os_identity_set_saved_password (kim_identity in_identity, /* ------------------------------------------------------------------------ */ +kim_error kim_os_identity_remove_saved_password (kim_identity in_identity) +{ + kim_error err = KIM_NO_ERROR; + kim_string realm = NULL; + kim_string name = NULL; + + if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } + + if (!err) { + err = kim_identity_get_components_string (in_identity, &name); + } + + if (!err) { + err = kim_identity_get_realm (in_identity, &realm); + } + + if (!err) { + SecKeychainItemRef itemRef = NULL; + UInt32 namelen = strlen (name); + UInt32 realmlen = strlen (realm); + void *buffer = NULL; + UInt32 length = 0; + + err = SecKeychainFindGenericPassword (nil, + realmlen, realm, + namelen, name, + &length, &buffer, + &itemRef); + + if (!err) { + err = SecKeychainItemDelete (itemRef); + + } else if (err == errSecItemNotFound) { + err = KIM_NO_ERROR; /* No password not an error */ + } + + if (itemRef) { CFRelease (itemRef); } + } + + if (name ) { kim_string_free (&name); } + if (realm) { kim_string_free (&realm); } + + return check_error (err); +} + +/* ------------------------------------------------------------------------ */ + kim_error kim_os_identity_create_for_username (kim_identity *out_identity) { kim_error err = KIM_NO_ERROR; -- 2.26.2