Bug 1317019

Summary: Installing mod_auth_mellon causes working Kerberos authentication to start failing
Product: Red Hat Enterprise Linux 6 Reporter: Jan Pazdziora <jpazdziora>
Component: mod_auth_mellonAssignee: John Dennis <jdennis>
Status: CLOSED WONTFIX QA Contact: Kaleem <ksiddiqu>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.8CC: arubin, jdennis, jpazdziora, nkinder
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1324536 (view as bug list) Environment:
Last Closed: 2016-10-20 17:28:51 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1324536    

Description Jan Pazdziora 2016-03-11 17:28:59 UTC
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:

Comment 1 Jan Pazdziora 2016-03-11 17:36:48 UTC
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.

Comment 2 Jan Pazdziora 2016-03-11 17:38:49 UTC
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.

Comment 3 Jan Pazdziora 2016-03-11 17:41:01 UTC
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.

Comment 4 Simo Sorce 2016-03-14 14:00:02 UTC
John,
do you think you have b/w to look at this ?

Comment 5 John Dennis 2016-04-08 15:14:43 UTC
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.

Comment 6 Nathan Kinder 2016-10-20 17:28:51 UTC
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.