Project

General

Profile

Bug #70439

ldap: crash sur une erreur de mot de passe

Added by Benjamin Dauvergne 3 months ago. Updated 3 months ago.

Status:
Nouveau
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
Start date:
18 October 2022
Due date:
% Done:

0%

Estimated time:
Patch proposed:
No
Planning:
No

Description

https://sentry.entrouvert.org/entrouvert/publik/issues/96073/

INVALID_CREDENTIALS: {'desc': 'Invalid credentials'}
  File "authentic2/backends/ldap_backend.py", line 726, in authenticate_block
    results = conn.simple_bind_s(authz_id, password, serverctrls=serverctrls)
  File "ldap/ldapobject.py", line 1222, in simple_bind_s
    res = self._apply_method_s(SimpleLDAPObject.simple_bind_s,*args,**kwargs)
  File "ldap/ldapobject.py", line 1204, in _apply_method_s
    return func(self,*args,**kwargs)
  File "ldap/ldapobject.py", line 446, in simple_bind_s
    resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout)
  File "ldap/ldapobject.py", line 748, in result3
    resp_type, resp_data, resp_msgid, decoded_resp_ctrls, retoid, retval = self.result4(
  File "authentic2/backends/ldap_backend.py", line 184, in result4
    ) = NativeLDAPObject.result4(
  File "ldap/ldapobject.py", line 758, in result4
    ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
  File "ldap/ldapobject.py", line 331, in _ldap_call
    reraise(exc_type, exc_value, exc_traceback)
  File "ldap/compat.py", line 44, in reraise
    raise exc_value
  File "ldap/ldapobject.py", line 315, in _ldap_call
    result = func(*args,**kwargs)

TransactionManagementError: select_for_update cannot be used outside of a transaction.
  File "django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/decorators/clickjacking.py", line 15, in wrapped_view
    resp = view_func(*args, **kwargs)
  File "django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "django/utils/decorators.py", line 142, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "authentic2/views.py", line 400, in login
    auth_blocks.append(utils_misc.get_authenticator_method(authenticator, 'login', parameters))
  File "authentic2/utils/misc.py", line 196, in get_authenticator_method
    content = response = getattr(authenticator, method)(**parameters)
  File "authentic2/apps/authenticators/models.py", line 206, in login
    return views.login_password_login(request, self, *args, **kwargs)
  File "authentic2/views.py", line 719, in login_password_login
    csrf_token_check(request, form)
  File "authentic2/utils/views.py", line 48, in csrf_token_check
    if form.is_valid() and not getattr(request, 'csrf_processing_done', False):
  File "django/forms/forms.py", line 185, in is_valid
    return self.is_bound and not self.errors
  File "django/forms/forms.py", line 180, in errors
    self.full_clean()
  File "django/forms/forms.py", line 382, in full_clean
    self._clean_form()
  File "django/forms/forms.py", line 409, in _clean_form
    cleaned_data = self.clean()
  File "authentic2/forms/authentication.py", line 105, in clean
    self.clean_authenticate()
  File "authentic2/forms/authentication.py", line 122, in clean_authenticate
    self.user_cache = utils_misc.authenticate(
  File "authentic2/utils/misc.py", line 1310, in authenticate
    return dj_authenticate(request=request, **kwargs)
  File "django/contrib/auth/__init__.py", line 73, in authenticate
    user = backend.authenticate(request, **credentials)
  File "authentic2/backends/ldap_backend.py", line 652, in authenticate
    user = self.authenticate_block(request, block, uid, password)
  File "authentic2/backends/ldap_backend.py", line 744, in authenticate_block
    user = self._lookup_existing_user(authz_id, block, attributes)
  File "authentic2/backends/ldap_backend.py", line 1485, in _lookup_existing_user
    user = self._lookup_by_email(ou=ou, block=block, attributes=attributes)
  File "authentic2/backends/ldap_backend.py", line 1396, in _lookup_by_email
    Lock.lock_email(email)
  File "authentic2/models.py", line 626, in lock_email
    cls.lock('email:%s' % email, nowait=nowait)
  File "authentic2/models.py", line 615, in lock
    cls.objects.select_for_update(nowait=nowait).get(name=name)
  File "django/db/models/query.py", line 402, in get
    num = len(clone)
  File "django/db/models/query.py", line 256, in __len__
    self._fetch_all()
  File "django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "django/db/models/sql/compiler.py", line 1129, in execute_sql
    sql, params = self.as_sql()
  File "django/db/models/sql/compiler.py", line 518, in as_sql
    raise TransactionManagementError('select_for_update cannot be used outside of a transaction.')

_lookup_existing_user() fait en dehors d'une transaction, mais dans ce cas précis aucun lock ne devrait être pris, le fix le plus simple reste de faire ça dans un scope atomic().


Related issues

Related to Authentic 2 - Bug #70437: sur un login, avec du LDAP, TransactionManagementError: select_for_update cannot be used outside of a transaction.Fermé18 October 2022

Actions

History

#1

Updated by Frédéric Péters 3 months ago

  • Related to Bug #70437: sur un login, avec du LDAP, TransactionManagementError: select_for_update cannot be used outside of a transaction. added

Also available in: Atom PDF