def authenticate_bind_request(self, request):
"""
Given a LDAP bind request:
* Check if it is contained in the bind cache.
If yes: Return success and bind the service account.
* If not: resolve the DN and redirect the request to privacyIDEA.
:param request: An `pureldap.LDAPBindRequest` instance.
:return: Deferred that fires a tuple ``(success, message)``, whereas ``success`` denotes whether privacyIDEA
successfully validated the given password. If ``success`` is ``False``, ``message`` contains an error message.
"""
#: This 2-tuple has the following semantics:
#: If the first element is True, authentication has succeeded! The second element then
#: contains the app marker as a string.
#: If the first element is False, authentication has failed. The second element then contains
#: the error message.
result = (False, '')
try:
app_marker, realm = yield self.factory.resolve_realm(request.dn)
user = yield self.factory.resolve_user(request.dn)
except UserMappingError:
# User could not be found
log.info('Could not resolve {dn!r} to user', dn=request.dn)
result = (False, 'Invalid user.')
except RealmMappingError, e:
# Realm could not be mapped
log.info('Could not resolve {dn!r} to realm: {message!r}', dn=request.dn, message=e.message)
# TODO: too much information revealed?
result = (False, 'Could not determine realm.')
else:
log.info('Resolved {dn!r} to {user!r}@{realm!r} ({marker!r})',
dn=request.dn, user=user, realm=realm, marker=app_marker)
password = request.auth
if self.factory.is_bind_cached(request.dn, app_marker, request.auth):
log.info('Combination found in bind cache!')
result = (True, app_marker)
else:
response = yield self.request_validate(self.factory.validate_url,
user,
realm,
password)
json_body = yield readBody(response)
if response.code == 200:
body = json.loads(json_body)
if body['result']['status']:
if body['result']['value']:
result = (True, app_marker)
else:
result = (False, 'Failed to authenticate.')
else:
result = (False, 'Failed to authenticate. privacyIDEA error.')
else:
result = (False, 'Failed to authenticate. Wrong HTTP response ({})'.format(response.code))
# TODO: Is this the right place to bind the service user?
# (check that result[0] is actually True and not just truthy)
if result[0] is True and self.factory.bind_service_account:
log.info('Successful authentication, authenticating as service user ...')
# Reset value in case the connection is re-used
self.forwarded_passthrough_bind = False
yield self.bind_service_account()
defer.returnValue(result)
评论列表
文章目录