Renamed error handling files to reflect what they do now.
authorAlexandra Ellwood <lxs@mit.edu>
Tue, 23 Sep 2008 21:46:12 +0000 (21:46 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Tue, 23 Sep 2008 21:46:12 +0000 (21:46 +0000)
Moved GUI code into OS-specific directory.
Fixed bugs in cache collection iterator routines where it was mishandling
the magic empty ccache created when the cache collection is empty.

ticket: 6055

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20747 dc483132-0cff-0310-8789-dd5450dbe970

16 files changed:
src/include/kim/kim.h
src/include/kim/kim_credential.h
src/include/kim/kim_error.h [deleted file]
src/include/kim/kim_string.h
src/include/kim/kim_types.h
src/kim/lib/kim-lite.exports
src/kim/lib/kim.exports
src/kim/lib/kim_ccache.c
src/kim/lib/kim_credential.c
src/kim/lib/kim_error_message.c [moved from src/kim/lib/kim_error.c with 95% similarity]
src/kim/lib/kim_errors.et [moved from src/kim/lib/kim_error_code.et with 100% similarity]
src/kim/lib/kim_string.c
src/kim/lib/kim_ui.c
src/kim/lib/kim_ui_gui_private.h
src/kim/lib/kim_ui_private.h
src/kim/lib/mac/kim_os_ui_gui.c [moved from src/kim/lib/kim_ui_gui.c with 68% similarity]

index 893891defdafbf31fddc4eef054138d375068809..19e82ecb6c726e00ea67f8e159e937530089aba4 100644 (file)
@@ -30,8 +30,8 @@ extern "C" {
 #endif
 
 #include <kim/kim_types.h>
+#include <kim/kim_errors.h>
 #include <kim/kim_string.h>
-#include <kim/kim_error.h>
 #include <kim/kim_identity.h>
 #include <kim/kim_options.h>
 #include <kim/kim_selection_hints.h>
index 88ccc5dce0190ad837d23fab460ed7f3153f0624..c25b02e9061cb107db19821c7e35c879f1372cb6 100644 (file)
@@ -451,7 +451,8 @@ kim_error kim_credential_get_expiration_time (kim_credential  in_credential,
 /*!
  * \param in_credential               a credential object. 
  * \param out_renewal_expiration_time on exit, the time when \a in_credential will no longer 
- *                                    be renewable. May be in the past or future.
+ *                                    be renewable. May be in the past or future.  If 
+ *                                    credentials are not renewable at all, returns 0.
  * \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
  * \brief Get the time when the credentials will no longer be renewable.
  * \sa kim_ccache_get_renewal_expiration_time
@@ -459,7 +460,17 @@ kim_error kim_credential_get_expiration_time (kim_credential  in_credential,
 kim_error kim_credential_get_renewal_expiration_time (kim_credential  in_credential,
                                                       kim_time       *out_renewal_expiration_time);
 
+/*!
+ * \param in_credential       a credential object. 
+ * \param out_ticket_flags    on exit, the krb5 ticket flags for \a in_credential.
+ *                            See krb5 API documentation for the meaning of these flags.
+ * \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
+ * \brief Get the krb5 ticket_flags for a credential.
+ */
+kim_error kim_credential_get_krb5_ticket_flags (kim_credential  in_credential,
+                                                krb5_flags     *out_ticket_flags);
 
+    
 /*!
  * \param in_credential       a credential object. 
  * \param in_client_identity  a client identity.
@@ -521,7 +532,7 @@ kim_error kim_credential_validate (kim_credential *io_credential,
 /*!
  * \param in_credential            a credential object containing a change
  *                                 password credential.  Use 
- *                                 #kim_credential_change_password to obtain
+ *                                 #kim_credential_create_for_change_password to obtain
  *                                 a change password credential.
  * \param in_identity              an identity to change the password for.  May
  *                                 be different than the identity the credential
diff --git a/src/include/kim/kim_error.h b/src/include/kim/kim_error.h
deleted file mode 100644 (file)
index 07c6d17..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2005-2006 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- * 
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef KIM_ERROR_H
-#define KIM_ERROR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <kim/kim_types.h>
-#include <kim/kim_error_code.h>
-
-/*!
- * \ingroup kim_types_reference
- * The kim_error_t returned when no error occurred. 
- */
-#define KIM_NO_ERROR                  ((kim_error) 0)
-    
-/*!
- * \page kim_error_overview KIM Error Overview
- *
- * Like most C APIs, the KIM API returns numeric error codes.  These error
- * codes may come from KIM, krb5 or GSS APIs.  In most cases the caller will
- * want to handle these error programmatically.  However, in some circumstances 
- * the caller may wish to print an error string to the user.  
- *
- * One problem with just printing the error code to the user is that frequently
- * the context behind the error has been lost.  For example if KIM is trying to 
- * obtain credentials via referrals, it may fail partway through the process.
- * In this case the error code will be KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, which
- * maps to "Client not found in Kerberos database".  Unfortunately this error
- * isn't terribly helpful because it doesn't tell the user whether they typoed
- * their principal name or if referrals failed.  
- *
- * To avoid this problem, KIM maintains an explanatory string for the last 
- * error seen in each thread calling into KIM.  If a caller wishes to display
- * an error to the user, immediately after getting the error the caller should
- * call #kim_string_get_last_error_message() to obtain a copy of the  
- * descriptive error message.
- * 
- * Note that because this string is stored in thread-specific data, callers 
- * must call #kim_string_get_last_error_message() before calling any KIM APIs
- * or any other APIs which might call into KIM.  Callers who are not going
- * to display this error string immediately should also make a copy of it
- * so that it is not overwritten by the next call into KIM.
- *
- * See \ref kim_error_reference for information on specific APIs.
- */
-
-/*!
- * \defgroup kim_error_reference KIM Error Reference Documentation
- * @{
- */
-
-/*!
- * \param out_string On success, a human-readable UTF-8 string describing the 
- *                   error representedby \a in_error.  Must be freed with
- *                   kim_string_free().
- * \param in_error   an error code.  Used to verify that the correct error
- *                   string will be returned (see note below).
- * \return On success, KIM_NO_ERROR.  
- * \note This API is implemented using thread local storage.  It should be 
- * called immediately after a KIM API returns an error code so that the correct
- * string is returned.  The returned copy may then be held by the caller until 
- * needed.  If \a in_error does not match the last saved error KIM may return
- * a less descriptive string.
- * \brief Get a text description of an error suitable for display to the user.
- */
-kim_error kim_string_get_last_error_message (kim_string *out_string,
-                                             kim_error   in_error);
-
-/*!@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* KIM_ERROR_H */
index 79cd0ee2477201e52c23500a83d0f512c9058894..bc4f647e86a2864620f62222be73e3dac336f0e5 100644 (file)
@@ -39,6 +39,27 @@ extern "C" {
  * Memory management routines are provided for runtime consistency on
  * operating systems with shared libraries and multiple runtimes.
  *
+ * \section kim_string_error_messages KIM Error Messages
+ *
+ * Like most C APIs, the KIM API returns numeric error codes.  These error
+ * codes may come from KIM, krb5 or GSS APIs.  In most cases the caller will
+ * want to handle these error programmatically.  However, in some circumstances 
+ * the caller may wish to print an error string to the user.  
+ *
+ * One problem with just printing the error code to the user is that frequently
+ * the context behind the error has been lost.  For example if KIM is trying to 
+ * obtain credentials via referrals, it may fail partway through the process.
+ * In this case the error code will be KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, which
+ * maps to "Client not found in Kerberos database".  Unfortunately this error
+ * isn't terribly helpful because it doesn't tell the user whether they typoed
+ * their principal name or if referrals failed.  
+ *
+ * To avoid this problem, KIM maintains an explanatory string for the last 
+ * error seen in each thread calling into KIM.  If a caller wishes to display
+ * an error to the user, immediately after getting the error the caller should
+ * call #kim_string_create_for_error() to obtain a copy of the  
+ * descriptive error message.
+ *
  * See \ref kim_string_reference for information on specific APIs.
  */
 
@@ -60,6 +81,22 @@ extern "C" {
 kim_error kim_string_create_for_error (kim_string *out_string,
                                        kim_error   in_error);
 
+/*!
+ * \param out_string On success, a human-readable UTF-8 string describing the 
+ *                   error representedby \a in_error.  Must be freed with
+ *                   kim_string_free().
+ * \param in_error   an error code.  Used to verify that the correct error
+ *                   string will be returned (see note below).
+ * \return On success, KIM_NO_ERROR.  
+ * \note This API is implemented using thread local storage.  It should be 
+ * called immediately after a KIM API returns an error code so that the correct
+ * string is returned.  The returned copy may then be held by the caller until 
+ * needed.  If \a in_error does not match the last saved error KIM may return
+ * a less descriptive string.
+ * \brief Get a text description of an error suitable for display to the user.
+ */
+kim_error kim_string_create_for_last_error (kim_string *out_string,
+                                            kim_error   in_error);
     
 /*!
  * \param out_string on exit, a new string object which is a copy of \a in_string.  
index 545d7479c00f4d3974ebd8c6b9010556077671de..8cf97246e382ca4ead61062112938c1d6eecf261 100644 (file)
@@ -41,6 +41,8 @@ extern "C" {
  */
 typedef int32_t     kim_error;
 
+#define KIM_NO_ERROR ((kim_error) 0)
+
 /*!
  * A time value represented in seconds since January 1, 1970.
  */
index 1b8466a561d8a43dc5f1fdf688f6f6a1ac3599d3..708d2753c42a8a8168809a9375a25486c10e9b95 100644 (file)
@@ -1,5 +1,4 @@
-kim_string_get_last_error_message
-
+kim_string_create_for_last_error
 kim_string_copy
 kim_string_compare
 kim_string_free
@@ -91,6 +90,7 @@ kim_credential_get_state
 kim_credential_get_start_time
 kim_credential_get_expiration_time
 kim_credential_get_renewal_expiration_time
+kim_credential_get_krb5_ticket_flags
 kim_credential_store
 kim_credential_renew
 kim_credential_validate
index d2f2e27e7ed5d8d2de4b0be2d7286074e9f9c0fc..bdacd6299da69a93f27027c428da8c471fe2c13c 100644 (file)
@@ -1,5 +1,4 @@
-kim_string_get_last_error_message
-
+kim_string_create_for_last_error
 kim_string_copy
 kim_string_compare
 kim_string_free
@@ -92,6 +91,7 @@ kim_credential_get_state
 kim_credential_get_start_time
 kim_credential_get_expiration_time
 kim_credential_get_renewal_expiration_time
+kim_credential_get_krb5_ticket_flags
 kim_credential_store
 kim_credential_verify
 kim_credential_renew
index dd6bdf77dc45ea4d19c7333b1d8a5060ecda940c..713a15bf421af8b588d021795b84e019f3c69d51 100644 (file)
 struct kim_ccache_iterator_opaque {
     krb5_context context;
     krb5_cccol_cursor cursor;
+    kim_boolean first;
 };
 
-struct kim_ccache_iterator_opaque kim_ccache_iterator_initializer = { NULL, NULL };
+struct kim_ccache_iterator_opaque kim_ccache_iterator_initializer = { NULL, NULL, 1 };
 
 /* ------------------------------------------------------------------------ */
 
@@ -83,9 +84,34 @@ kim_error kim_ccache_iterator_next (kim_ccache_iterator  in_ccache_iterator,
     if (!err && !out_ccache        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
-        krb5_error_code terr = krb5_cccol_cursor_next (in_ccache_iterator->context, 
-                                                       in_ccache_iterator->cursor,
-                                                       &ccache);
+        err = krb5_cccol_cursor_next (in_ccache_iterator->context, 
+                                      in_ccache_iterator->cursor,
+                                      &ccache);
+        if (err == KRB5_CC_END) {
+            ccache = NULL; /* out of ccaches */
+            err = KIM_NO_ERROR;
+        }        
+    }
+    
+    if (!err && ccache && in_ccache_iterator->first) {
+        krb5_principal principal = NULL;
+        
+        /* krb5 API is sneaky and returns a single empty ccache if the
+         * cache collection is empty.  Check for it: */
+        err = krb5_error (in_ccache_iterator->context,
+                           krb5_cc_get_principal (in_ccache_iterator->context, 
+                                                  ccache, 
+                                                  &principal));
+        
+        if (err) {
+            krb5_cc_close (in_ccache_iterator->context, ccache);
+            ccache = NULL;
+            err = KIM_NO_ERROR;
+        }
+    }
+    
+    if (!err) {
+        in_ccache_iterator->first = 0;
         
         if (ccache) {
             err = kim_ccache_create_from_krb5_ccache (out_ccache,
@@ -93,10 +119,7 @@ kim_error kim_ccache_iterator_next (kim_ccache_iterator  in_ccache_iterator,
                                                       ccache);
         } else {
             *out_ccache = NULL; /* no more ccaches */
-        }
-        if (terr && terr != KRB5_CC_END) {
-            err = krb5_error (in_ccache_iterator->context, terr);
-        }
+        }        
     }
     
     if (ccache) { krb5_cc_close (in_ccache_iterator->context, ccache); }
@@ -275,6 +298,7 @@ kim_error kim_ccache_create_from_client_identity (kim_ccache   *out_ccache,
     while (!err && !found) {
         kim_ccache ccache = NULL;
         kim_identity identity = NULL;
+        kim_comparison comparison;
         
         err = kim_ccache_iterator_next (iterator, &ccache);
         
@@ -296,10 +320,11 @@ kim_error kim_ccache_create_from_client_identity (kim_ccache   *out_ccache,
         }
         
         if (!err) {
-            err = kim_identity_compare (in_client_identity, identity, &found);
+            err = kim_identity_compare (in_client_identity, identity, &comparison);
         }
         
-        if (!err && found) {
+        if (!err && kim_comparison_is_equal_to (comparison)) {
+            found = 1;
             *out_ccache = ccache;
             ccache = NULL;
         }
index f81b50f12e35cd620c5679c742b0167a43234d21..36c6ca1b6e26e10d05f3e8d8bd8c9e1a243afcbb 100644 (file)
@@ -281,12 +281,13 @@ kim_error kim_credential_create_new (kim_credential *out_credential,
         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 (principal ) { krb5_free_principal (credential->context, principal); }
     if (!in_options) { kim_options_free (&options); }
     kim_string_free (&service);
     kim_credential_free (&credential);
@@ -781,7 +782,8 @@ kim_error kim_credential_get_start_time (kim_credential  in_credential,
 {
     kim_error err = KIM_NO_ERROR;
     
-    if (!err && !in_credential) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_credential ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_start_time) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
         *out_start_time = (in_credential->creds->times.starttime ? 
@@ -815,10 +817,32 @@ kim_error kim_credential_get_renewal_expiration_time (kim_credential  in_credent
 {
     kim_error err = KIM_NO_ERROR;
     
-    if (!err && !in_credential) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_credential              ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_renewal_expiration_time) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_credential->creds->ticket_flags & TKT_FLG_RENEWABLE) {
+            *out_renewal_expiration_time = in_credential->creds->times.renew_till;
+        } else {
+            *out_renewal_expiration_time = 0;
+        }
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_credential_get_krb5_ticket_flags (kim_credential  in_credential,
+                                                krb5_flags     *out_ticket_flags)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_credential   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_ticket_flags) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
-        *out_renewal_expiration_time = in_credential->creds->times.renew_till;
+        *out_ticket_flags = in_credential->creds->ticket_flags;
     }
     
     return check_error (err);
similarity index 95%
rename from src/kim/lib/kim_error.c
rename to src/kim/lib/kim_error_message.c
index c481e2fb2cdc72013af801cfad2bb62da2b89cc4..b292505c4cc8592fdcd5429db75bf79975661d9a 100644 (file)
@@ -211,13 +211,3 @@ void kim_error_terminate (void)
     k5_mutex_destroy (&kim_error_lock);
 }
 
-#pragma mark -- Public API --
-
-
-/* ------------------------------------------------------------------------ */
-
-kim_error kim_string_get_last_error_message (kim_string *out_string,
-                                             kim_error   in_error)
-{
-    return kim_string_copy (out_string, kim_error_message (in_error));
-}
index 6968f19d9d0dbc988bb6ee22b616878066ff8417..2dc284c932fbbbcc71891506e3b2f0d31802da6e 100644 (file)
@@ -114,6 +114,14 @@ kim_error kim_string_create_from_buffer (kim_string *out_string,
 
 /* ------------------------------------------------------------------------ */
 
+kim_error kim_string_create_for_last_error (kim_string *out_string,
+                                            kim_error   in_error)
+{
+    return kim_string_copy (out_string, kim_error_message (in_error));
+}
+
+/* ------------------------------------------------------------------------ */
+
 kim_error kim_string_copy (kim_string *out_string, 
                            kim_string  in_string)
 {
index 36920144e407d04ad71cc38e6bbb5a3f1b14ff84..a87e150ba0dd043367fb433fe93cb8efbd5706af 100644 (file)
 
 static kim_prompt_type kim_ui_ptype2ktype (krb5_prompt_type type)
 {
-    switch (type) {
-        case KRB5_PROMPT_TYPE_PASSWORD:
-            return kim_prompt_type_password;
-            
-        case KRB5_PROMPT_TYPE_PREAUTH:
-            return kim_prompt_type_preauth;
+    if (type == KRB5_PROMPT_TYPE_PASSWORD) {
+        return kim_prompt_type_password;
+        
+    } else if (type == KRB5_PROMPT_TYPE_PREAUTH) {
+        return kim_prompt_type_preauth;
     }
     return kim_prompt_type_preauth;
 }
 
-/* ------------------------------------------------------------------------ */
-/* Set the identity field in your context and pass the context as the data */
-
-krb5_error_code kim_ui_prompter (krb5_context  in_krb5_context,
-                                 void         *in_context,
-                                 const char   *in_name,
-                                 const char   *in_banner,
-                                 int           in_num_prompts,
-                                 krb5_prompt   in_prompts[])
-{
-    kim_error err = KIM_NO_ERROR;
-    krb5_prompt_type *types = NULL;
-    kim_ui_context *context = (kim_ui_context *) in_context;
-    int i;
-
-    if (!err && !in_krb5_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    if (!err && !in_context     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    if (!err && !in_prompts     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-
-    if (!err) {
-        types = krb5_get_prompt_types (in_krb5_context);
-        if (!types) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    }
-    
-    for (i = 0; !err && i < in_num_prompts; i++) {
-        char *reply = NULL;
-        
-        err = kim_ui_auth_prompt (context,
-                                  context->identity,
-                                  kim_ui_ptype2ktype (types[i]),
-                                  in_prompts[i].hidden, 
-                                  in_name,
-                                  in_banner,
-                                  in_prompts[i].prompt,
-                                  &reply);
-        
-        if (!err) {
-            uint32_t reply_len = strlen (reply);
-            
-            if ((reply_len + 1) > in_prompts[i].reply->length) {
-                kim_debug_printf ("%s(): reply %d is too long (is %d, should be %d)\n",
-                                  __FUNCTION__, i, 
-                                  reply_len, in_prompts[i].reply->length);
-                reply_len = in_prompts[i].reply->length;
-            }
-            
-            memmove (in_prompts[i].reply->data, reply, reply_len + 1);
-            in_prompts[i].reply->length = reply_len;
-        }
-        
-        kim_ui_free_string (context, &reply);
-    }
-    
-    return check_error (err);
-}
 
 #pragma mark -
 
@@ -110,7 +54,7 @@ kim_error kim_ui_init (kim_ui_context *io_context)
     if (!err) {
 #ifndef LEAN_CLIENT
         kim_ui_environment environment = kim_library_ui_environment ();
-
+        
         if (environment == KIM_UI_ENVIRONMENT_GUI) {
 #endif /* LEAN_CLIENT */
             io_context->type = kim_ui_type_gui_plugin;
@@ -120,9 +64,9 @@ kim_error kim_ui_init (kim_ui_context *io_context)
             if (err) { 
                 io_context->type = kim_ui_type_gui_builtin;
                 
-                err = kim_ui_gui_init ((kim_ui_gui_context *) &io_context->tcontext);
+                err = kim_os_ui_gui_init ((kim_ui_gui_context *) &io_context->tcontext);
             }
-
+            
         } else if (environment == KIM_UI_ENVIRONMENT_CLI) {
             io_context->type = kim_ui_type_cli;
             
@@ -134,7 +78,11 @@ kim_error kim_ui_init (kim_ui_context *io_context)
             err = check_error (KIM_NO_UI_ERR);
         }
 #endif /* LEAN_CLIENT */
-    }    
+    }
+    
+    if (!err) {
+        io_context->identity = NULL;
+    }
     
     return check_error (err);
 }
@@ -156,8 +104,8 @@ kim_error kim_ui_enter_identity (kim_ui_context      *in_context,
             
 #ifndef LEAN_CLIENT
         } else if (in_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_enter_identity ((kim_ui_gui_context) in_context->tcontext, 
-                                             out_identity);
+            err = kim_os_ui_gui_enter_identity ((kim_ui_gui_context) in_context->tcontext, 
+                                                out_identity);
             
         } else if (in_context->type == kim_ui_type_cli) {
             err = kim_ui_cli_enter_identity ((kim_ui_cli_context) in_context->tcontext, 
@@ -193,9 +141,9 @@ kim_error kim_ui_select_identity (kim_ui_context      *in_context,
             
 #ifndef LEAN_CLIENT
         } else if (in_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_select_identity ((kim_ui_gui_context) in_context->tcontext, 
-                                              in_hints,
-                                              out_identity);
+            err = kim_os_ui_gui_select_identity ((kim_ui_gui_context) in_context->tcontext, 
+                                                 in_hints,
+                                                 out_identity);
             
         } else if (in_context->type == kim_ui_type_cli) {
             err = kim_ui_cli_select_identity ((kim_ui_cli_context) in_context->tcontext, 
@@ -213,58 +161,103 @@ kim_error kim_ui_select_identity (kim_ui_context      *in_context,
 }
 
 /* ------------------------------------------------------------------------ */
+/* Set the identity field in your context and pass the context as the data */
 
-kim_error kim_ui_auth_prompt (kim_ui_context    *in_context,
-                              kim_identity       in_identity,
-                              kim_prompt_type    in_type,
-                              kim_boolean        in_hide_reply, 
-                              kim_string         in_title,
-                              kim_string         in_message,
-                              kim_string         in_description,
-                              char             **out_reply)
+krb5_error_code kim_ui_prompter (krb5_context  in_krb5_context,
+                                 void         *in_context,
+                                 const char   *in_name,
+                                 const char   *in_banner,
+                                 int           in_num_prompts,
+                                 krb5_prompt   in_prompts[])
 {
     kim_error err = KIM_NO_ERROR;
+    krb5_prompt_type *types = NULL;
+    kim_ui_context *context = (kim_ui_context *) in_context;
+    int i;
     
-    if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-    /* in_title, in_message or in_description may be NULL */
+    if (!err && !in_krb5_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_context     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_prompts     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
-        if (in_context->type == kim_ui_type_gui_plugin) {
-            err = kim_ui_plugin_auth_prompt ((kim_ui_plugin_context) in_context->tcontext, 
-                                             in_identity, 
-                                             in_type,
-                                             in_hide_reply,
-                                             in_title,
-                                             in_message,
-                                             in_description,
-                                             out_reply);
-
-#ifndef LEAN_CLIENT
-        } else if (in_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_auth_prompt ((kim_ui_gui_context) in_context->tcontext, 
-                                          in_identity, 
-                                          in_type,
-                                          in_hide_reply,
-                                          in_title,
-                                          in_message,
-                                          in_description,
-                                          out_reply);
+        types = krb5_get_prompt_types (in_krb5_context);
+        if (!types) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    }
+    
+    for (i = 0; !err && i < in_num_prompts; i++) {
+        char *reply = NULL;
+        kim_prompt_type type = kim_ui_ptype2ktype (types[i]);
+        kim_boolean got_saved_password = 0;
+                
+        if (type == kim_prompt_type_password) {
+            /* Check for saved password on OSes that support it */
+            kim_error terr = KIM_NO_ERROR;
             
-        } else if (in_context->type == kim_ui_type_cli) {
-            err = kim_ui_cli_auth_prompt ((kim_ui_cli_context) in_context->tcontext, 
-                                          in_identity, 
-                                          in_type,
-                                          in_hide_reply,
-                                          in_title,
-                                          in_message,
-                                          in_description,
-                                          out_reply);
+            terr = kim_os_identity_get_saved_password (context->identity, 
+                                                       (kim_string *) &reply);
+            if (!terr) { got_saved_password = 1; }
+        }
+        
+        if (!got_saved_password) {
+            if (context->type == kim_ui_type_gui_plugin) {
+                err = kim_ui_plugin_auth_prompt ((kim_ui_plugin_context) context->tcontext, 
+                                                 context->identity, 
+                                                 type,
+                                                 in_prompts[i].hidden,
+                                                 in_name,
+                                                 in_banner,
+                                                 in_prompts[i].prompt,
+                                                 &reply);
+                
+#ifndef LEAN_CLIENT
+            } else if (context->type == kim_ui_type_gui_builtin) {
+                err = kim_os_ui_gui_auth_prompt ((kim_ui_gui_context) context->tcontext, 
+                                                 context->identity, 
+                                                 type,
+                                                 in_prompts[i].hidden,
+                                                 in_name,
+                                                 in_banner,
+                                                 in_prompts[i].prompt,
+                                                 &reply);
+                
+            } else if (context->type == kim_ui_type_cli) {
+                err = kim_ui_cli_auth_prompt ((kim_ui_cli_context) context->tcontext, 
+                                              context->identity, 
+                                              type,
+                                              in_prompts[i].hidden,
+                                              in_name,
+                                              in_banner,
+                                              in_prompts[i].prompt,
+                                              &reply);
 #endif /* LEAN_CLIENT */
+                
+            } else {
+                err = check_error (KIM_NO_UI_ERR);
+            }
+        }
+
+        if (!err) {
+            uint32_t reply_len = strlen (reply);
             
-        } else {
-            err = check_error (KIM_NO_UI_ERR);
+            if ((reply_len + 1) > in_prompts[i].reply->length) {
+                kim_debug_printf ("%s(): reply %d is too long (is %d, should be %d)\n",
+                                  __FUNCTION__, i, 
+                                  reply_len, in_prompts[i].reply->length);
+                reply_len = in_prompts[i].reply->length;
+            }
+            
+            memmove (in_prompts[i].reply->data, reply, reply_len + 1);
+            in_prompts[i].reply->length = reply_len;
+        }
+        
+        /* Clean up reply buffer.  Saved passwords are allocated by KIM. */
+        if (reply) {
+            memset (reply, '\0', strlen (reply));
+            if (got_saved_password) {
+                kim_string_free ((kim_string *) &reply);
+             } else {
+                kim_ui_free_string (context, &reply);
+            }
         }
     }
     
@@ -299,12 +292,12 @@ kim_error kim_ui_change_password (kim_ui_context  *in_context,
             
 #ifndef LEAN_CLIENT
         } else if (in_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_change_password ((kim_ui_gui_context) in_context->tcontext, 
-                                              in_identity, 
-                                              in_old_password_expired,
-                                              out_old_password,
-                                              out_new_password,
-                                              out_verify_password);
+            err = kim_os_ui_gui_change_password ((kim_ui_gui_context) in_context->tcontext, 
+                                                 in_identity, 
+                                                 in_old_password_expired,
+                                                 out_old_password,
+                                                 out_new_password,
+                                                 out_verify_password);
             
         } else if (in_context->type == kim_ui_type_cli) {
             err = kim_ui_cli_change_password ((kim_ui_cli_context) in_context->tcontext, 
@@ -313,14 +306,13 @@ kim_error kim_ui_change_password (kim_ui_context  *in_context,
                                               out_old_password,
                                               out_new_password,
                                               out_verify_password);
-            
 #endif /* LEAN_CLIENT */
             
         } else {
             err = check_error (KIM_NO_UI_ERR);
         }
     }
-        
+    
     return check_error (err);
 }
 
@@ -338,14 +330,14 @@ kim_error kim_ui_handle_kim_error (kim_ui_context         *in_context,
     
     if (!err) {
         /* Do this first so last error doesn't get overwritten */
-        err = kim_string_get_last_error_message (&description, in_error);
+        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 = "KLStringLoginFailed";
@@ -361,7 +353,7 @@ kim_error kim_ui_handle_kim_error (kim_ui_context         *in_context,
                 key = "KLStringKerberosOperationFailed";
                 break;
         }
-
+        
         err = kim_os_string_create_localized (&message, key);
     }
     
@@ -393,25 +385,25 @@ kim_error kim_ui_handle_error (kim_ui_context *in_context,
     if (!err) {
         if (in_context->type == kim_ui_type_gui_plugin) {
             err = kim_ui_plugin_handle_error ((kim_ui_plugin_context) in_context->tcontext, 
-                                               in_identity, 
-                                               in_error,
-                                               in_error_message,
-                                               in_error_description);
+                                              in_identity, 
+                                              in_error,
+                                              in_error_message,
+                                              in_error_description);
             
 #ifndef LEAN_CLIENT
         } else if (in_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_handle_error ((kim_ui_gui_context) in_context->tcontext, 
-                                            in_identity, 
-                                            in_error,
-                                            in_error_message,
-                                            in_error_description);
+            err = kim_os_ui_gui_handle_error ((kim_ui_gui_context) in_context->tcontext, 
+                                              in_identity, 
+                                              in_error,
+                                              in_error_message,
+                                              in_error_description);
             
         } else if (in_context->type == kim_ui_type_cli) {
             err = kim_ui_cli_handle_error ((kim_ui_cli_context) in_context->tcontext, 
-                                            in_identity, 
-                                            in_error,
-                                            in_error_message,
-                                            in_error_description);
+                                           in_identity, 
+                                           in_error,
+                                           in_error_message,
+                                           in_error_description);
 #endif /* LEAN_CLIENT */  
             
         } else {
@@ -434,8 +426,8 @@ void kim_ui_free_string (kim_ui_context  *in_context,
             
 #ifndef LEAN_CLIENT
         } else if (in_context->type == kim_ui_type_gui_builtin) {
-            kim_ui_gui_free_string ((kim_ui_gui_context) in_context->tcontext, 
-                                    io_string);
+            kim_os_ui_gui_free_string ((kim_ui_gui_context) in_context->tcontext, 
+                                       io_string);
             
         } else if (in_context->type == kim_ui_type_cli) {
             kim_ui_cli_free_string ((kim_ui_cli_context) in_context->tcontext, 
@@ -455,14 +447,12 @@ kim_error kim_ui_fini (kim_ui_context *io_context)
     if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
-        kim_identity_free (&io_context->identity);
-
         if (io_context->type == kim_ui_type_gui_plugin) {
             err = kim_ui_plugin_fini ((kim_ui_plugin_context *) &io_context->tcontext);
             
 #ifndef LEAN_CLIENT
         } else if (io_context->type == kim_ui_type_gui_builtin) {
-            err = kim_ui_gui_fini ((kim_ui_gui_context *) &io_context->tcontext);
+            err = kim_os_ui_gui_fini ((kim_ui_gui_context *) &io_context->tcontext);
             
         } else if (io_context->type == kim_ui_type_cli) {
             err = kim_ui_cli_fini ((kim_ui_cli_context *) &io_context->tcontext);
index b6d2ebd52ebed3ee7704941f9a2db8fb03c39c0a..9792f53d545b6b68cd761b265be199f576c72a6e 100644 (file)
@@ -35,41 +35,41 @@ struct kim_ui_gui_context;
 typedef struct kim_ui_gui_context *kim_ui_gui_context;
 
 
-kim_error kim_ui_gui_init (kim_ui_gui_context *out_context);
+kim_error kim_os_ui_gui_init (kim_ui_gui_context *out_context);
 
-kim_error kim_ui_gui_enter_identity (kim_ui_gui_context  in_context,
-                                     kim_identity       *out_identity);
+kim_error kim_os_ui_gui_enter_identity (kim_ui_gui_context  in_context,
+                                        kim_identity       *out_identity);
 
-kim_error kim_ui_gui_select_identity (kim_ui_gui_context   in_context,
-                                      kim_selection_hints  in_hints,
-                                      kim_identity        *out_identity);
+kim_error kim_os_ui_gui_select_identity (kim_ui_gui_context   in_context,
+                                         kim_selection_hints  in_hints,
+                                         kim_identity        *out_identity);
 
-kim_error kim_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
-                                  kim_identity         in_identity,
-                                  kim_prompt_type      in_type,
-                                  kim_boolean          in_hide_reply, 
-                                  kim_string           in_title,
-                                  kim_string           in_message,
-                                  kim_string           in_description,
-                                  char               **out_reply);
+kim_error kim_os_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
+                                     kim_identity         in_identity,
+                                     kim_prompt_type      in_type,
+                                     kim_boolean          in_hide_reply, 
+                                     kim_string           in_title,
+                                     kim_string           in_message,
+                                     kim_string           in_description,
+                                     char               **out_reply);
 
-kim_error kim_ui_gui_change_password (kim_ui_gui_context    in_context,
-                                      kim_identity          in_identity,
-                                      kim_boolean           in_old_password_expired,
-                                      char                **out_old_password,
-                                      char                **out_new_password,
-                                      char                **out_verify_password);
+kim_error kim_os_ui_gui_change_password (kim_ui_gui_context    in_context,
+                                         kim_identity          in_identity,
+                                         kim_boolean           in_old_password_expired,
+                                         char                **out_old_password,
+                                         char                **out_new_password,
+                                         char                **out_verify_password);
 
-kim_error kim_ui_gui_handle_error (kim_ui_gui_context   in_context,
-                                    kim_identity         in_identity,
-                                    kim_error            in_error,
-                                    kim_string           in_error_message,
-                                    kim_string           in_error_description);
+kim_error kim_os_ui_gui_handle_error (kim_ui_gui_context   in_context,
+                                      kim_identity         in_identity,
+                                      kim_error            in_error,
+                                      kim_string           in_error_message,
+                                      kim_string           in_error_description);
 
-void kim_ui_gui_free_string (kim_ui_gui_context   in_context,
-                             char               **io_string);
+void kim_os_ui_gui_free_string (kim_ui_gui_context   in_context,
+                                char               **io_string);
 
-kim_error kim_ui_gui_fini (kim_ui_gui_context *io_context);
+kim_error kim_os_ui_gui_fini (kim_ui_gui_context *io_context);
 
 #endif /* LEAN_CLIENT */
 
index 817a4b29ff909b7ce76a1e463c749c30694d558f..abaffcf0424bbb047ce42d9ce945eddcfa0dea56 100644 (file)
@@ -50,12 +50,6 @@ typedef struct kim_ui_context {
     kim_identity identity;
 } kim_ui_context;
 
-krb5_error_code kim_ui_prompter (krb5_context  in_krb5_context,
-                                 void         *in_context,
-                                 const char   *in_name,
-                                 const char   *in_banner,
-                                 int           in_num_prompts,
-                                 krb5_prompt   in_prompts[]);
 
 
 kim_error kim_ui_init (kim_ui_context *io_context);
@@ -67,14 +61,12 @@ kim_error kim_ui_select_identity (kim_ui_context       *in_context,
                                   kim_selection_hints   in_hints,
                                   kim_identity         *out_identity);
 
-kim_error kim_ui_auth_prompt (kim_ui_context    *in_context,
-                              kim_identity       in_identity,
-                              kim_prompt_type    in_type,
-                              kim_boolean        in_hide_reply, 
-                              kim_string         in_title,
-                              kim_string         in_message,
-                              kim_string         in_description,
-                              char             **out_reply);
+krb5_error_code kim_ui_prompter (krb5_context  in_krb5_context,
+                                 void         *in_context,
+                                 const char   *in_name,
+                                 const char   *in_banner,
+                                 int           in_num_prompts,
+                                 krb5_prompt   in_prompts[]);
 
 kim_error kim_ui_change_password (kim_ui_context  *in_context,
                                   kim_identity     in_identity,
similarity index 68%
rename from src/kim/lib/kim_ui_gui.c
rename to src/kim/lib/mac/kim_os_ui_gui.c
index 9eb41e457aa6d0947ab9469a4e339aa1795a8f7c..c755a7894b32b663cc4abcfe3a36b590f3af8ebf 100644 (file)
@@ -35,7 +35,7 @@ struct kim_ui_gui_context {
 
 /* ------------------------------------------------------------------------ */
 
-static void kim_ui_gui_context_free (kim_ui_gui_context *io_context)
+static void kim_os_ui_gui_context_free (kim_ui_gui_context *io_context)
 {
     if (io_context && *io_context) { 
         free (*io_context);
@@ -45,7 +45,7 @@ static void kim_ui_gui_context_free (kim_ui_gui_context *io_context)
 
 /* ------------------------------------------------------------------------ */
 
-static kim_error kim_ui_gui_context_allocate (kim_ui_gui_context *out_context)
+static kim_error kim_os_ui_gui_context_allocate (kim_ui_gui_context *out_context)
 {
     kim_error err = KIM_NO_ERROR;
     kim_ui_gui_context context = NULL;
@@ -62,7 +62,7 @@ static kim_error kim_ui_gui_context_allocate (kim_ui_gui_context *out_context)
         context = NULL;
     }
     
-    kim_ui_gui_context_free (&context);
+    kim_os_ui_gui_context_free (&context);
     
     return check_error (err);    
 }
@@ -71,7 +71,7 @@ static kim_error kim_ui_gui_context_allocate (kim_ui_gui_context *out_context)
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_init (kim_ui_gui_context *out_context)
+kim_error kim_os_ui_gui_init (kim_ui_gui_context *out_context)
 {
     kim_error err = KIM_NO_ERROR;
     kim_ui_gui_context context = NULL;
@@ -79,7 +79,7 @@ kim_error kim_ui_gui_init (kim_ui_gui_context *out_context)
     if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
-        err = kim_ui_gui_context_allocate (&context);
+        err = kim_os_ui_gui_context_allocate (&context);
     }
     
     if (!err) {
@@ -90,15 +90,15 @@ kim_error kim_ui_gui_init (kim_ui_gui_context *out_context)
         context = NULL;
     }
     
-    kim_ui_gui_context_free (&context);
+    kim_os_ui_gui_context_free (&context);
     
     return check_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_enter_identity (kim_ui_gui_context   in_context,
-                                     kim_identity        *out_identity)
+kim_error kim_os_ui_gui_enter_identity (kim_ui_gui_context   in_context,
+                                        kim_identity        *out_identity)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -113,9 +113,9 @@ kim_error kim_ui_gui_enter_identity (kim_ui_gui_context   in_context,
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_select_identity (kim_ui_gui_context   in_context,
-                                      kim_selection_hints  in_hints,
-                                      kim_identity        *out_identity)
+kim_error kim_os_ui_gui_select_identity (kim_ui_gui_context   in_context,
+                                         kim_selection_hints  in_hints,
+                                         kim_identity        *out_identity)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -131,14 +131,14 @@ kim_error kim_ui_gui_select_identity (kim_ui_gui_context   in_context,
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
-                                  kim_identity         in_identity,
-                                  kim_prompt_type      in_type,
-                                  kim_boolean          in_hide_reply, 
-                                  kim_string           in_title,
-                                  kim_string           in_message,
-                                  kim_string           in_description,
-                                  char               **out_reply)
+kim_error kim_os_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
+                                     kim_identity         in_identity,
+                                     kim_prompt_type      in_type,
+                                     kim_boolean          in_hide_reply, 
+                                     kim_string           in_title,
+                                     kim_string           in_message,
+                                     kim_string           in_description,
+                                     char               **out_reply)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -155,12 +155,12 @@ kim_error kim_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_change_password (kim_ui_gui_context   in_context,
-                                      kim_identity         in_identity,
-                                      kim_boolean          in_old_password_expired,
-                                      char               **out_old_password,
-                                      char               **out_new_password,
-                                      char               **out_verify_password)
+kim_error kim_os_ui_gui_change_password (kim_ui_gui_context   in_context,
+                                         kim_identity         in_identity,
+                                         kim_boolean          in_old_password_expired,
+                                         char               **out_old_password,
+                                         char               **out_new_password,
+                                         char               **out_verify_password)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -178,11 +178,11 @@ kim_error kim_ui_gui_change_password (kim_ui_gui_context   in_context,
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_handle_error (kim_ui_gui_context in_context,
-                                   kim_identity       in_identity,
-                                   kim_error          in_error,
-                                   kim_string         in_error_message,
-                                   kim_string         in_error_description)
+kim_error kim_os_ui_gui_handle_error (kim_ui_gui_context in_context,
+                                      kim_identity       in_identity,
+                                      kim_error          in_error,
+                                      kim_string         in_error_message,
+                                      kim_string         in_error_description)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -198,15 +198,15 @@ kim_error kim_ui_gui_handle_error (kim_ui_gui_context in_context,
 
 /* ------------------------------------------------------------------------ */
 
-void kim_ui_gui_free_string (kim_ui_gui_context   in_context,
-                             char               **io_string)
+void kim_os_ui_gui_free_string (kim_ui_gui_context   in_context,
+                                char               **io_string)
 {
     kim_string_free ((kim_string *) io_string);
 }
 
 /* ------------------------------------------------------------------------ */
 
-kim_error kim_ui_gui_fini (kim_ui_gui_context *io_context)
+kim_error kim_os_ui_gui_fini (kim_ui_gui_context *io_context)
 {
     kim_error err = KIM_NO_ERROR;
     
@@ -216,7 +216,7 @@ kim_error kim_ui_gui_fini (kim_ui_gui_context *io_context)
     }
     
     if (!err) {
-        kim_ui_gui_context_free (io_context);
+        kim_os_ui_gui_context_free (io_context);
     }