Hide Forgot
Description of problem: When mod_auth_mellon package is installed to a working Apache HTTP Server with Kerberos authentication, the Kerberos authentication stops working even if mod_auth_mellon was not configured in any way. Version-Release number of selected component (if applicable): mod_auth_mellon-0.8.0-4.el6.x86_64 How reproducible: Deterministic. Steps to Reproduce: 1. Have Apache HTTP Server configured with mod_auth_kerb. 2. Verify that kinit as some user and curl -Lksi --negotiate -u : returns 401 and then 200, something like # curl -Lksi --negotiate -u : https://$(hostname)/application/login HTTP/1.1 401 Authorization Required Date: Fri, 11 Mar 2016 17:23:37 GMT Server: Apache/2.2.15 (Red Hat) WWW-Authenticate: Negotiate Content-Length: 127 Connection: close Content-Type: text/html; charset=iso-8859-1 HTTP/1.1 200 OK Date: Fri, 11 Mar 2016 17:23:37 GMT Server: Apache/2.2.15 (Red Hat) Pragma: no-cache Refresh: 3; URL=/application Set-Cookie: the-test-cookie=ok:Robert Chase (bob23557: bob23557); path=/application Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 3. Run yum install -y mod_auth_mellon 4. Run service httpd restart 5. Rerun that curl --negotiate -u : command. Actual results: # curl -Lksi --negotiate -u : https://$(hostname)/application/login HTTP/1.1 401 Authorization Required Date: Fri, 11 Mar 2016 17:23:57 GMT Server: Apache/2.2.15 (Red Hat) Content-Length: 127 Connection: close Content-Type: text/html; charset=iso-8859-1 <html><meta http-equiv="refresh" content="0; URL=/application/login2"><body>Kerberos authentication did not pass.</body></html> Expected results: As before mod_auth_mellon was installed -- 401 with WWW-Authenticate: Negotiate and then 200. Additional info:
My estimate is that the problem is caused by mod_auth_mellon's am_check_uid function. It does not check at all whether MellonEnable is enabled on that location. Normally it does not matter because ap_run_check_user_id in httpd-2.2's ap_process_request_internal is not run unless if (ap_some_auth_required(r)) { is true. Which normally is not but on locations where Kerberos (or Basic) HTTP Auth is enabled, this condition is met even if we did not configure/enable mod_auth_mellon in any way.
RFC 2616 says 10.4.2 401 Unauthorized The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. mod_auth_mellon's use of HTTP_UNAUTHORIZED is a violation of the RFC all by itself because it does not implement HTTP Auth.
The problem is present on RHEL 7 as well. On RHEL 6 it's just a little bit more obvious because of the naming of the configuration files -- mod_auth_mellon is loaded before mod_auth_kerb on RHEL 6, triggering the issue more easily.
John, do you think you have b/w to look at this ?
Re comment #2 with regards to returning HTTP_UNAUTHORIZED. [Modifying the result code should be the subject of a new and different bug report, please keep independent problems in independent bug reports, but let's talk about it anyway here.] Clearly it was wrong to return HTTP_UNAUTHORIZED if mellon was not enabled for that location but we've fixed that. However, for the cases where mellon is enabled it's not clear to me it's wrong except for the case where mellon determines the user is not authorized, in which case I think it should return HTTP_FORBIDDEN. Arguing the use of HTTP_UNAUTHORIZED is inappropriate because it's restricted to HTTP Auth (Basic or Digest) seems spurious because the HTTP spec was written prior to the adoption of other authentication methods. Kerberos Negotiate utilizes HTTP_UNAUTHORIZED to request resubmission with credentials and it's not HTTP Auth and I don't think anyone feels that is a violation of the HTTP spec. Also I'm reluctant to change the behavior of a RHEL component for 2 reasons. First we generally do not introduce behavioral changes into our enterprise distributions because we don't know if it might break an existing deployment. Secondly I think such a change should have the blessing of upstream, thus we should coordinate with them prior to making this change. Here are the cases where am_check_uid() return HTTP_UNAUTHORIZED and my interpretation of each situation. Note, in many cases the existing behavior does not perfectly match the HTTP spec but many of these cases are grey area and it's a matter of interpretation when the spec is silent. You make the best judgment call you can. 1) Missing session Theoretically this shouldn't happen, it would most likely be the result of a race condition. The session should have been established earlier in am_auth_mellon_user(), if the session becomes invalid in between operations I'm not sure what else one should do other than indicate one should attempt to reauthenticate. The other possibility is the missing session is the result of some fault in mellon, but returning SERVER_ERROR doesn't seem quite right either if in fact all that occurred was a race condidtion. 2) Session exists but user is not logged in. This is essentially the same case as #1, the best option here is to indicate one should reauthenticate. 3) There is a valid session and the user is logged in but authorization checks fail. Once again this should have been caught earlier in am_auth_mellon_user() which also calls am_check_permissions() and if the authorization check fails am_check_permissions() returns HTTP_FORBIDDEN which is then returned for the request. However when am_check_permissions() is later called in am_check_uid() it returns HTTP_UNAUTHORIZED. This is the one place where the return code is definitely wrong, it should be HTTP_FORBIDDEN.
We do not plan to fix this for RHEL 6.x. It has been addressed for RHEL 7.x, so the recommendation would be to upgrade if you want to use SAML and GSSAPI in the same httpd instance.