Skip to content

Commit

Permalink
Handle DatabaseError in RPC-Server connect()
Browse files Browse the repository at this point in the history
DatabaseError exceptions with 'account inactivated' message are turned
into 401 Unauthorized errors. The problem occurs when a user is disabled
but has a valid cookie.

Other DatabaseErrors are turned into 503 Service Unavailable. They
usually occur when LDAP server is not available or broken.

Fixes: https://pagure.io/freeipa/issue/8352
Signed-off-by: Christian Heimes <[email protected]>
Reviewed-By: Alexander Bokovoy <[email protected]>
  • Loading branch information
tiran authored and abbra committed Jun 7, 2020
1 parent 894b3f1 commit d79a7a9
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions ipaserver/rpcserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@

HTTP_STATUS_SUCCESS = '200 Success'
HTTP_STATUS_SERVER_ERROR = '500 Internal Server Error'
HTTP_STATUS_SERVICE_UNAVAILABLE = "503 Service Unavailable"

_not_found_template = """<html>
<head>
Expand Down Expand Up @@ -122,6 +123,18 @@
</body>
</html>"""

_service_unavailable_template = """<html>
<head>
<title>503 Service Unavailable</title>
</head>
<body>
<h1>Service Unavailable</h1>
<p>
<strong>%(message)s</strong>
</p>
</body>
</html>"""

_success_template = """<html>
<head>
<title>200 Success</title>
Expand Down Expand Up @@ -188,6 +201,20 @@ def unauthorized(self, environ, start_response, message, reason):
output = _unauthorized_template % dict(message=escape(message))
return [output.encode('utf-8')]

def service_unavailable(self, environ, start_response, message):
"""
Return a 503 Service Unavailable
"""
status = HTTP_STATUS_SERVICE_UNAVAILABLE
response_headers = [('Content-Type', 'text/html; charset=utf-8')]

logger.error('%s: %s', status, message)

start_response(status, response_headers)
output = _service_unavailable_template % dict(message=escape(message))
return [output.encode('utf-8')]


def read_input(environ):
"""
Read the request body from environ['wsgi.input'].
Expand Down Expand Up @@ -858,6 +885,15 @@ def __call__(self, environ, start_response):
self.create_context(ccache=ccache_name)
except ACIError as e:
return self.unauthorized(environ, start_response, str(e), 'denied')
except errors.DatabaseError as e:
# account is disable but user has a valid ticket
msg = str(e)
if "account inactivated" in msg.lower():
return self.unauthorized(
environ, start_response, str(e), "account disabled"
)
else:
return self.service_unavailable(environ, start_response, msg)

try:
response = super(jsonserver_session, self).__call__(environ, start_response)
Expand Down

0 comments on commit d79a7a9

Please sign in to comment.