kim_error kim_ui_handle_kim_error (kim_ui_context *in_context, kim_identity in_identity, enum kim_ui_error_type in_type, kim_error in_error) { kim_error err = KIM_NO_ERROR; kim_string message = NULL; kim_string description = NULL; if (!err) { /* Do this first so last error doesn't get overwritten */ err = kim_string_create_for_last_error (&description, in_error); } if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err) { kim_string key = NULL; switch (in_type) { case kim_ui_error_type_authentication: key = "Kerberos Login Failed:"; break; case kim_ui_error_type_change_password: key = "Kerberos Change Password Failed:"; break; case kim_ui_error_type_selection: case kim_ui_error_type_generic: default: key = "Kerberos Operation Failed:"; break; } err = kim_os_string_create_localized (&message, key); } if (!err) { err = kim_ui_handle_error (in_context, in_identity, in_error, message, description); } kim_string_free (&description); kim_string_free (&message); return check_error (err); }
kim_error kim_identity_change_password_common (kim_identity in_identity, kim_boolean in_old_password_expired, kim_ui_context *in_ui_context, kim_string *out_new_password) { kim_error err = KIM_NO_ERROR; kim_boolean done = 0; if (!err && !in_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_ui_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } while (!err && !done) { char *old_password = NULL; char *new_password = NULL; char *verify_password = NULL; kim_error rejected_err = KIM_NO_ERROR; kim_string rejected_message = NULL; kim_string rejected_description = NULL; kim_boolean was_prompted = 0; /* ignore because we always prompt */ err = kim_ui_change_password (in_ui_context, in_identity, in_old_password_expired, &old_password, &new_password, &verify_password); if (!err) { kim_comparison comparison; err = kim_string_compare (new_password, verify_password, &comparison); if (!err && !kim_comparison_is_equal_to (comparison)) { err = check_error (KIM_PASSWORD_MISMATCH_ERR); } } if (!err) { kim_credential credential = NULL; if (in_ui_context->type == kim_ui_type_cli && in_ui_context->tcontext) { /* command line has already gotten the credentials for us */ credential = (kim_credential) in_ui_context->tcontext; } else { err = kim_credential_create_for_change_password (&credential, in_identity, old_password, in_ui_context, &was_prompted); } if (!err) { err = kim_identity_change_password_with_credential (in_identity, credential, new_password, in_ui_context, &rejected_err, &rejected_message, &rejected_description); } kim_credential_free (&credential); if (in_ui_context->type == kim_ui_type_cli) { in_ui_context->tcontext = NULL; /* just freed our creds */ } } if (!err && rejected_err) { /* Password rejected, report it to the user */ err = kim_ui_handle_error (in_ui_context, in_identity, rejected_err, rejected_message, rejected_description); } else if (err && err != KIM_USER_CANCELED_ERR && err != KIM_DUPLICATE_UI_REQUEST_ERR) { /* New creds failed, report error to user. * Overwrite error so we loop and let the user try again. * The user always gets prompted so we always loop. */ err = kim_ui_handle_kim_error (in_ui_context, in_identity, kim_ui_error_type_change_password, err); } else { /* password change succeeded or the user gave up */ done = 1; if (!err && out_new_password) { err = kim_string_copy (out_new_password, new_password); } if (!err) { kim_error terr = KIM_NO_ERROR; kim_string saved_password = NULL; terr = kim_os_identity_get_saved_password (in_identity, &saved_password); if (!terr) { /* We changed the password and the user had their * old password saved. Update it. */ terr = kim_os_identity_set_saved_password (in_identity, new_password); } kim_string_free (&saved_password); } if (err == KIM_DUPLICATE_UI_REQUEST_ERR) { err = KIM_NO_ERROR; } } kim_string_free (&rejected_message); kim_string_free (&rejected_description); kim_ui_free_string (in_ui_context, &old_password); kim_ui_free_string (in_ui_context, &new_password); kim_ui_free_string (in_ui_context, &verify_password); } return check_error (err); }