From: Michael R Sweet Date: Fri, 15 Feb 2019 22:07:10 +0000 (-0500) Subject: Non-Kerberized IPP printing to Windows was broken (Issue #5515) X-Git-Tag: v2.2.11~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bafbb263f8096db27b345cdac71a967409d574de;p=thirdparty%2Fcups.git Non-Kerberized IPP printing to Windows was broken (Issue #5515) --- diff --git a/CHANGES.md b/CHANGES.md index fefebe0d88..9d0aa5aeb0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -CHANGES - 2.2.11 - 2019-02-05 +CHANGES - 2.2.11 - 2019-02-15 ============================= @@ -20,6 +20,7 @@ Changes in CUPS v2.2.11 (Issue #5506) - The `ippValidateAttribute` function did not catch all instances of invalid UTF-8 strings (Issue #5509) +- Non-Kerberized printing to Windows via IPP was broken (Issue #5515) - Fixed a potential crash bug in cups-driverd (rdar://46625579) - Fixed a performance regression with large PPDs (rdar://47040759) diff --git a/cups/auth.c b/cups/auth.c index e4328e025b..a91b0dbe4a 100644 --- a/cups/auth.c +++ b/cups/auth.c @@ -52,6 +52,9 @@ static const char *cups_auth_param(const char *scheme, const char *name, char *v static const char *cups_auth_scheme(const char *www_authenticate, char *scheme, size_t schemesize); #ifdef HAVE_GSSAPI +# define CUPS_GSS_OK 0 /* Successfully set credentials */ +# define CUPS_GSS_NONE -1 /* No credentials */ +# define CUPS_GSS_FAIL -2 /* Failed credentials/authentication */ # ifdef HAVE_GSS_ACQUIRE_CRED_EX_F # ifdef HAVE_GSS_GSSAPI_SPI_H # include @@ -178,6 +181,8 @@ cupsDoAuthentication( * Check the scheme name... */ + DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme)); + #ifdef HAVE_GSSAPI if (!_cups_strcasecmp(scheme, "Negotiate")) { @@ -185,18 +190,36 @@ cupsDoAuthentication( * Kerberos authentication... */ - if (_cupsSetNegotiateAuthString(http, method, resource)) + int gss_status; /* Auth status */ + + if ((gss_status = _cupsSetNegotiateAuthString(http, method, resource)) == CUPS_GSS_FAIL) { + DEBUG_puts("1cupsDoAuthentication: Negotiate failed."); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } - - break; + else if (gss_status == CUPS_GSS_NONE) + { + DEBUG_puts("2cupsDoAuthentication: No credentials for Negotiate."); + continue; + } + else + { + DEBUG_puts("2cupsDoAuthentication: Using Negotiate."); + break; + } } else #endif /* HAVE_GSSAPI */ if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest")) - continue; /* Not supported (yet) */ + { + /* + * Other schemes not yet supported... + */ + + DEBUG_printf(("2cupsDoAuthentication: Scheme \"%s\" not yet supported.", scheme)); + continue; + } /* * See if we should retry the current username:password... @@ -226,6 +249,7 @@ cupsDoAuthentication( if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) { + DEBUG_puts("1cupsDoAuthentication: User canceled password request."); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } @@ -255,6 +279,7 @@ cupsDoAuthentication( char encode[256]; /* Base64 buffer */ + DEBUG_puts("2cupsDoAuthentication: Using Basic."); httpEncode64_2(encode, sizeof(encode), http->userpass, (int)strlen(http->userpass)); httpSetAuthString(http, "Basic", encode); break; @@ -273,19 +298,22 @@ cupsDoAuthentication( cups_auth_param(schemedata, "realm", http->realm, sizeof(http->realm)); if (_httpSetDigestAuthString(http, nonce, method, resource)) + { + DEBUG_puts("2cupsDoAuthentication: Using Basic."); break; + } } } if (http->authstring) { - DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring)); + DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\".", http->authstring)); return (0); } else { - DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", www_auth)); + DEBUG_puts("1cupsDoAuthentication: No supported schemes."); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); @@ -298,7 +326,7 @@ cupsDoAuthentication( * '_cupsSetNegotiateAuthString()' - Set the Kerberos authentication string. */ -int /* O - 0 on success, -1 on error */ +int /* O - 0 on success, negative on error */ _cupsSetNegotiateAuthString( http_t *http, /* I - Connection to server */ const char *method, /* I - Request method ("GET", "POST", "PUT") */ @@ -323,10 +351,16 @@ _cupsSetNegotiateAuthString( { DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos " "framework is not present"); - return (-1); + return (CUPS_GSS_NONE); } # endif /* __APPLE__ */ + if (!strcmp(http->hostname, "localhost") || http->hostname[0] == '/' || isdigit(http->hostname[0] & 255) || !strchr(http->hostname, '.')) + { + DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos not available for host \"%s\".", http->hostname)); + return (CUPS_GSS_NONE); + } + if (http->gssname == GSS_C_NO_NAME) { http->gssname = cups_gss_getname(http, _cupsGSSServiceName()); @@ -371,7 +405,7 @@ _cupsSetNegotiateAuthString( cupsUser(), http->gsshost); if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) - return (-1); + return (CUPS_GSS_FAIL); /* * Try to acquire credentials... @@ -425,18 +459,20 @@ _cupsSetNegotiateAuthString( } # endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */ - if (GSS_ERROR(major_status)) + if (major_status == GSS_S_NO_CRED) { - cups_gss_printf(major_status, minor_status, - "_cupsSetNegotiateAuthString: Unable to initialize " - "security context"); - return (-1); + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: No credentials"); + return (CUPS_GSS_NONE); + } + else if (GSS_ERROR(major_status)) + { + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Unable to initialize security context"); + return (CUPS_GSS_FAIL); } # ifdef DEBUG else if (major_status == GSS_S_CONTINUE_NEEDED) - cups_gss_printf(major_status, minor_status, - "_cupsSetNegotiateAuthString: Continuation needed!"); + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Continuation needed"); # endif /* DEBUG */ if (output_token.length > 0 && output_token.length <= 65536) @@ -470,10 +506,10 @@ _cupsSetNegotiateAuthString( "large - %d bytes!", (int)output_token.length)); gss_release_buffer(&minor_status, &output_token); - return (-1); + return (CUPS_GSS_FAIL); } - return (0); + return (CUPS_GSS_OK); } #endif /* HAVE_GSSAPI */