pull up r20572 from trunk
authorTom Yu <tlyu@mit.edu>
Mon, 11 Aug 2008 15:08:37 +0000 (15:08 +0000)
committerTom Yu <tlyu@mit.edu>
Mon, 11 Aug 2008 15:08:37 +0000 (15:08 +0000)
 r20572@cathode-dark-space:  jaltman | 2008-07-23 11:04:26 -0400
 ticket: 5745
 tags: pullup

 This patch modifies the NIM Kerberos v5 plug-in to use the
 krb5_get_error_message() function to look up the error string
 if the call to krb5_get_init_creds_password() fails. If the call
 to krb5_get_error_message() fails, the caller will failover to
 the previous method of looking up a suitable error message based
 on the error code.

ticket: 5745
version_fixed: 1.6.4
status: resolved

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@20640 dc483132-0cff-0310-8789-dd5450dbe970

src/windows/identity/plugins/krb5/krb5funcs.c
src/windows/identity/plugins/krb5/krb5funcs.h
src/windows/identity/plugins/krb5/krb5newcreds.c
src/windows/identity/plugins/krb5/krbcred.h

index 8d0de1293957cf3915aeae71ed5581c8254b8997..efab36e5ea4b54380274d53270e40d907fb55e61 100644 (file)
@@ -1357,7 +1357,8 @@ khm_krb5_kinit(krb5_context       alt_ctx,
                DWORD              addressless,
                DWORD              publicIP,
                krb5_prompter_fct  prompter,
-               void *             p_data)
+               void *             p_data,
+               char **            pp_error_message)
 {
     krb5_error_code                    code = 0;
     krb5_context                       ctx = NULL;
@@ -1387,6 +1388,8 @@ khm_krb5_kinit(krb5_context       alt_ctx,
             goto cleanup;
     }
 
+    pkrb5_clear_error_message(ctx);
+
     if (ccache) {
         _reportf(L"Using supplied ccache name %S", ccache);
         code = pkrb5_cc_resolve(ctx, ccache, &cc);
@@ -1523,6 +1526,18 @@ khm_krb5_kinit(krb5_context       alt_ctx,
     if (code) goto cleanup;
 
 cleanup:
+    if (pp_error_message) {
+        const char * em;
+
+        em = pkrb5_get_error_message(ctx, code);
+        if (em == NULL) {
+            *pp_error_message = NULL;
+        } else {
+            *pp_error_message = _strdup(em);
+            pkrb5_free_error_message(ctx, em);
+        }
+    }
+
     if ( addrs ) {
         for ( i=0;i<addr_count;i++ ) {
             if ( addrs[i] ) {
index 990db269db39950d8480c45999bfaac4b8b2223e..62e4bd5362e2bb87b9f95c99d139d93137117c62 100644 (file)
@@ -123,7 +123,8 @@ khm_krb5_kinit(krb5_context       alt_ctx,
                DWORD              addressless,
                DWORD              publicIP,
                krb5_prompter_fct  prompter,
-               void *             p_data);
+               void *             p_data,
+               char **            pp_error_message);
 
 long
 khm_krb5_changepwd(char * principal,
index 6b64302c37f5e2699bf45e93070c085826694b46..48c10a4d7870119b5727a15b9c89490ed3677e42 100644 (file)
@@ -633,8 +633,15 @@ k5_kinit_fiber_proc(PVOID lpParameter)
     while(TRUE)
     {
         if(g_fjob.command == FIBER_CMD_KINIT) {
+            char * error_msg = NULL;
+
             g_fjob.state = FIBER_STATE_KINIT;
 
+            if (g_fjob.error_message) {
+                PFREE(g_fjob.error_message);
+                g_fjob.error_message = NULL;
+            }
+
             g_fjob.prompt_set = 0;
 
             if (k5_cached_kinit_prompter()) {
@@ -670,6 +677,11 @@ k5_kinit_fiber_proc(PVOID lpParameter)
                                                g_fjob.renewable);
 
         retry_kinit:
+            if (error_msg) {
+                free(error_msg);
+                error_msg = NULL;
+            }
+
             g_fjob.code =
                 khm_krb5_kinit(0,
                                g_fjob.principal,
@@ -682,7 +694,8 @@ k5_kinit_fiber_proc(PVOID lpParameter)
                                g_fjob.addressless,
                                g_fjob.publicIP,
                                k5_kinit_prompter,
-                               &g_fjob);
+                               &g_fjob,
+                               &error_msg);
 
             /* If the principal was found to be valid, and if we
                restricted the options that were being passed to kinit,
@@ -695,6 +708,17 @@ k5_kinit_fiber_proc(PVOID lpParameter)
                 g_fjob.state = FIBER_STATE_KINIT;
                 goto retry_kinit;
             }
+
+            if (error_msg) {
+                wchar_t tmp[1024];
+
+                if (AnsiStrToUnicode(tmp, sizeof(tmp), error_msg)) {
+                    g_fjob.error_message = PWCSDUP(tmp);
+                }
+
+                free(error_msg);
+                error_msg = NULL;
+            }
         }
 
     _switch_to_main:
@@ -1489,6 +1513,9 @@ k5_free_kinit_job(void)
     if (g_fjob.ccache)
         PFREE(g_fjob.ccache);
 
+    if (g_fjob.error_message)
+        PFREE(g_fjob.error_message);
+
     ZeroMemory(&g_fjob, sizeof(g_fjob));
 }
 
@@ -1625,7 +1652,7 @@ k5_find_tgt_filter(khm_handle cred,
     khm_int32 rv;
 
     if (KHM_SUCCEEDED(kcdb_cred_get_identity(cred,
-                                           &cident)) &&
+                                             &cident)) &&
         cident == ident &&
         KHM_SUCCEEDED(kcdb_cred_get_flags(cred, &f)) &&
         (f & KCDB_CRED_FLAG_INITIAL) &&
@@ -2108,6 +2135,11 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                         d->cred_message = NULL;
                     }
 
+                    if (g_fjob.error_message) {
+                        StringCbCopy(msg, sizeof(msg), g_fjob.error_message);
+                        goto have_message;
+                    }
+
                     msg[0] = L'\0';
 
                     switch(g_fjob.code) {
@@ -2151,6 +2183,8 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                         }
                     }
 
+                have_message:
+
                     if (msg[0]) {
                         StringCbLength(msg, sizeof(msg), &cb);
                         cb += sizeof(wchar_t);
@@ -2312,11 +2346,15 @@ k5_msg_cred_dialog(khm_int32 msg_type,
 
                 if(g_fjob.code != 0) {
                     wchar_t tbuf[1024];
-                    DWORD suggestion;
+                    DWORD suggestion = 0;
                     kherr_suggestion suggest_code;
 
-                    khm_err_describe(g_fjob.code, tbuf, sizeof(tbuf),
-                                     &suggestion, &suggest_code);
+                    if (g_fjob.error_message) {
+                        StringCbCopy(tbuf, sizeof(tbuf), g_fjob.error_message);
+                    } else {
+                        khm_err_describe(g_fjob.code, tbuf, sizeof(tbuf),
+                                         &suggestion, &suggest_code);
+                    }
 
                     _report_cs0(KHERR_ERROR, tbuf);
                     if (suggestion != 0)
@@ -2691,7 +2729,8 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                                               d->addressless, /* addressless */
                                               d->publicIP, /* public IP */
                                               NULL, /* prompter */
-                                              NULL /* prompter data */);
+                                              NULL, /* prompter data */
+                                              NULL  /* error message */);
 
                         if (code) {
                             rv = KHM_ERROR_UNKNOWN;
index a194343accf523f006c80791917092cc9b8c11ce..ddc745c935b1e49c110f35ecabd6265c5e46ff0e 100644 (file)
@@ -171,6 +171,7 @@ typedef struct _fiber_job_t {
     int     code;
     int     state;
     int     prompt_set;
+    wchar_t *error_message;
 
     BOOL    null_password;
     BOOL    valid_principal;