]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Let SPNEGO display mechanism errors
authorSimo Sorce <simo@redhat.com>
Tue, 17 Dec 2013 21:15:14 +0000 (16:15 -0500)
committerTom Yu <tlyu@mit.edu>
Thu, 16 Jan 2014 19:43:34 +0000 (14:43 -0500)
To avoid potential recursion we use a thread local variable that tells
us whether the ancestor was called via spnego_gss_display_name().  If
we detect recursion, we assume that we returned a com_err code like
ENOMEM and call error_message(); in the worst case that will result in
an "Unknown error" message.

[ghudson@mit.edu: Edited comments and commit message; removed an
unneeded line of code.]

(cherry picked from commit d160bc733a3dbeb6d84f4e175234ff18738d9f66)

ticket: 7823 (new)

src/include/k5-thread.h
src/lib/gssapi/spnego/spnego_mech.c

index 17ef69ee786b32650190d60b0a889ea0b7a8ad32..52f9fbfb5e187958056c52d4497dca106e84ded2 100644 (file)
@@ -406,6 +406,7 @@ typedef enum {
     K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME,
     K5_KEY_GSS_KRB5_CCACHE_NAME,
     K5_KEY_GSS_KRB5_ERROR_MESSAGE,
+    K5_KEY_GSS_SPNEGO_STATUS,
 #if defined(__MACH__) && defined(__APPLE__)
     K5_KEY_IPC_CONNECTION_INFO,
 #endif
index 696f42df5a0673ff4d51a7b5404170a2bca48ca6..b294e268d765d431aa76e46221cf89a0a7d56a55 100644 (file)
@@ -84,8 +84,8 @@ extern int gssint_put_der_length(OM_uint32, unsigned char **, unsigned int);
 
 
 /* private routines for spnego_mechanism */
-static spnego_token_t make_spnego_token(char *);
-static gss_buffer_desc make_err_msg(char *);
+static spnego_token_t make_spnego_token(const char *);
+static gss_buffer_desc make_err_msg(const char *);
 static int g_token_size(gss_OID_const, unsigned int);
 static int g_make_token_header(gss_OID_const, unsigned int,
                               unsigned char **, unsigned int);
@@ -309,6 +309,12 @@ int gss_krb5int_lib_init(void);
 
 int gss_spnegoint_lib_init(void)
 {
+       int err;
+
+       err = k5_key_register(K5_KEY_GSS_SPNEGO_STATUS, NULL);
+       if (err)
+               return err;
+
 #ifdef _GSS_STATIC_LINK
        return gss_spnegomechglue_init();
 #else
@@ -1790,7 +1796,6 @@ cleanup:
 }
 #endif /*  LEAN_CLIENT */
 
-
 /*ARGSUSED*/
 OM_uint32 KRB5_CALLCONV
 spnego_gss_display_status(
@@ -1801,6 +1806,9 @@ spnego_gss_display_status(
                OM_uint32 *message_context,
                gss_buffer_t status_string)
 {
+       OM_uint32 maj = GSS_S_COMPLETE;
+       int ret;
+
        dsyslog("Entering display_status\n");
 
        *message_context = 0;
@@ -1831,13 +1839,31 @@ spnego_gss_display_status(
                                                "return a valid token"));
                break;
            default:
-               status_string->length = 0;
-               status_string->value = "";
+               /* Not one of our minor codes; might be from a mech.  Call back
+                * to gss_display_status, but first check for recursion. */
+               if (k5_getspecific(K5_KEY_GSS_SPNEGO_STATUS) != NULL) {
+                       /* Perhaps we returned a com_err code like ENOMEM. */
+                       const char *err = error_message(status_value);
+                       *status_string = make_err_msg(err);
+                       break;
+               }
+               /* Set a non-null pointer value; doesn't matter which one. */
+               ret = k5_setspecific(K5_KEY_GSS_SPNEGO_STATUS, &ret);
+               if (ret != 0) {
+                       *minor_status = ret;
+                       maj = GSS_S_FAILURE;
+                       break;
+               }
+               maj = gss_display_status(minor_status, status_value,
+                                        status_type, mech_type,
+                                        message_context, status_string);
+               /* This is unlikely to fail; not much we can do if it does. */
+               (void)k5_setspecific(K5_KEY_GSS_SPNEGO_STATUS, NULL);
                break;
        }
 
        dsyslog("Leaving display_status\n");
-       return (GSS_S_COMPLETE);
+       return maj;
 }
 
 
@@ -3519,13 +3545,13 @@ negotiate_mech(gss_OID_set supported, gss_OID_set received,
  * these routines will be changes to return the error string.
  */
 static spnego_token_t
-make_spnego_token(char *name)
+make_spnego_token(const char *name)
 {
        return (spnego_token_t)strdup(name);
 }
 
 static gss_buffer_desc
-make_err_msg(char *name)
+make_err_msg(const char *name)
 {
        gss_buffer_desc buffer;