Projet

Général

Profil

Bug #70439

ldap: crash sur une erreur de mot de passe

Ajouté par Benjamin Dauvergne il y a plus d'un an. Mis à jour il y a 2 mois.

Statut:
Solution déployée
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
18 octobre 2022
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Non
Planning:
Non

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().


Demandes liées

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

Actions

Révisions associées

Révision 0c77d676 (diff)
Ajouté par Benjamin Dauvergne il y a 2 mois

ldap: prevent use of lock_email outside of a transaction (#70439)

Historique

#1

Mis à jour par Frédéric Péters il y a plus d'un an

  • Lié à Bug #70437: sur un login, avec du LDAP, TransactionManagementError: select_for_update cannot be used outside of a transaction. ajouté
#3

Mis à jour par Benjamin Dauvergne il y a 5 mois

  • Assigné à mis à Benjamin Dauvergne
#4

Mis à jour par Robot Gitea il y a 5 mois

  • Statut changé de Nouveau à Solution proposée

Benjamin Dauvergne (bdauvergne) a ouvert une pull request sur Gitea concernant cette demande :

#5

Mis à jour par Robot Gitea il y a 2 mois

  • Statut changé de Solution proposée à Solution validée

Nicolas Roche (nroche) a approuvé une pull request sur Gitea concernant cette demande :

#6

Mis à jour par Robot Gitea il y a 2 mois

  • Statut changé de Solution validée à Résolu (à déployer)

Benjamin Dauvergne (bdauvergne) a mergé une pull request sur Gitea concernant cette demande :

#7

Mis à jour par Transition automatique il y a 2 mois

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF