summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-12-17 16:15:14 -0500
committerGreg Hudson <ghudson@mit.edu>2013-12-18 15:58:55 -0500
commitd160bc733a3dbeb6d84f4e175234ff18738d9f66 (patch)
tree207a2bfdd3ec89bb2557604b4cb41b0a34bc94ef
parentc91f2a285e77e71bd283483d583c68e76eb3a0dd (diff)
downloadkrb5-d160bc733a3dbeb6d84f4e175234ff18738d9f66.tar.gz
krb5-d160bc733a3dbeb6d84f4e175234ff18738d9f66.tar.xz
krb5-d160bc733a3dbeb6d84f4e175234ff18738d9f66.zip
Let SPNEGO display mechanism errors
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.] ticket: 7045 target_version: 1.12.1 tags: pullup
-rw-r--r--src/include/k5-thread.h1
-rw-r--r--src/lib/gssapi/spnego/spnego_mech.c42
2 files changed, 35 insertions, 8 deletions
diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h
index 1b7fa6981d..ab46ec328d 100644
--- a/src/include/k5-thread.h
+++ b/src/include/k5-thread.h
@@ -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
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 06cfab00f8..7e4bf901b4 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -85,8 +85,8 @@ extern int gssint_put_der_length(unsigned int, 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);
@@ -316,6 +316,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
@@ -1791,7 +1797,6 @@ cleanup:
}
#endif /* LEAN_CLIENT */
-
/*ARGSUSED*/
OM_uint32 KRB5_CALLCONV
spnego_gss_display_status(
@@ -1802,6 +1807,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;
@@ -1832,13 +1840,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;
}
@@ -3550,13 +3576,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;