This has been spawned off bug #4003; summary follows. There are two types of error code we can get back from the GSSAPI: a "major status" from the GSS layer[1], and a "minor status" from the underlying authentication mechanism itself[2] (in our case, this means kerberos). In a perfect world, we would only ever need to look at the major status, since this covers most error conditions and is mechanism independent. However, most GSSAPI implementations just seem to return the generic code "GSS_S_FAILURE" on error, and leave the caller to check the minor status for details instead. The problem with this is that different kerberos implementations return different minor statuses for any given error condition; this includes the risk that any given implementation may return the same minor status code for two completely different error conditions. This makes it very difficult to create any kind of reliable mapping to interpret error codes correctly. One example of this can be seen in bug #4003, comment 13 - if we define "Expired ticket" as one of our common error scenarios, only OSX 10.8 returns our preferred GSS major status code. Linux and OSX 10.4 return relatively sensible KRB5 minor statuses, while Solaris returns something totally useless for determining what the problem actually is, simply telling us that it can't find a valid ticket for the realm. However, providing just a generic message to the user for kerberos errors is not optimal. If we can figure out some kind of sensible approach, then we should try to improve this. [1] http://www.gnu.org/software/gss/manual/html_node/Error-Handling.html [2] http://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-admin/Kerberos-V5-Library-Error-Codes.html
On Windows we also have the issue of not properly reporting the underlying system error code. I failed to find a decent way to get strings for these codes, but this patch at least gives the number for lookup: Index: openssh/openbsd-compat/win32-sspi.c =================================================================== --- openssh/openbsd-compat/win32-sspi.c (revision 33497) +++ openssh/openbsd-compat/win32-sspi.c (working copy) @@ -180,15 +182,15 @@ } else if (status_type == GSS_C_MECH_CODE) { + static char msg[256]; + // Minor status if (*message_context) return GSS_S_FAILURE; - switch (status_value) { - // FIXME: We don't set a minor code on Windows - default: - msg = "No minor code available"; - } + // FIXME: Can strings for these be fetched somewhere? + snprintf(msg, sizeof(msg), "Windows error: 0x%08x", status_value); + status_string->length = strlen(msg); status_string->value = msg; @@ -234,6 +240,7 @@ int ret; ret = DeleteSecurityContext((*context_handle)->ctxt_handle); + *minor_status = ret; if (ret == SEC_E_OK) { if ((*context_handle)->cred_handle) @@ -328,6 +341,7 @@ NULL, (*context_handle)->cred_handle, &ptsExpiry); + *minor_status = ret; if (ret != SEC_E_OK) { free((*context_handle)->cred_handle); @@ -404,6 +418,7 @@ &pOutput, &pfContextAttr, NULL); + *minor_status = ret; if (ret_flags != NULL) if (pfContextAttr & ISC_RET_INTEGRITY)