Ugly hack to disconnect ldap right after action processing is done

This commit is contained in:
Alexandre Aubin 2019-05-16 20:32:52 +02:00
parent ff6343c53a
commit 322a60b306
2 changed files with 20 additions and 1 deletions

View file

@ -526,6 +526,18 @@ class ActionsMap(object):
logger.debug('action [%s] executed in %.3fs', logger.debug('action [%s] executed in %.3fs',
log_id, stop - start) log_id, stop - start)
# For some reason we need to do this now before the
# garbage collector kicks in ...
# ... because sometimes the ldap library is already half
# gone when trying to properly close the ldap object
# which leads to :
# TypeError: "'NoneType' object is not callable" in <bound method Authenticator.__del__ of <moulinette.authenticators.ldap.Authenticator object at 0xabcdef123456>> ignored
# (here the NoneType stuff refers to RequestControlTuples in ldapobject.py ...)
# I got this when running `yunohost user list` (but not when running `yunohost domain list` for some reason)
from moulinette.authenticators.ldap import Authenticator
for i in Authenticator.instances:
i().freecon()
@staticmethod @staticmethod
def get_namespaces(): def get_namespaces():
""" """

View file

@ -9,6 +9,7 @@ import crypt
import ldap import ldap
import ldap.sasl import ldap.sasl
import ldap.modlist as modlist import ldap.modlist as modlist
import weakref
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.authenticators import BaseAuthenticator from moulinette.authenticators import BaseAuthenticator
@ -33,11 +34,13 @@ class Authenticator(BaseAuthenticator):
""" """
instances = []
def __init__(self, name, uri, base_dn, user_rdn=None): def __init__(self, name, uri, base_dn, user_rdn=None):
logger.debug("initialize authenticator '%s' with: uri='%s', " logger.debug("initialize authenticator '%s' with: uri='%s', "
"base_dn='%s', user_rdn='%s'", name, uri, base_dn, user_rdn) "base_dn='%s', user_rdn='%s'", name, uri, base_dn, user_rdn)
super(Authenticator, self).__init__(name) super(Authenticator, self).__init__(name)
self.__class__.instances.append(weakref.proxy(self))
self.uri = uri self.uri = uri
self.basedn = base_dn self.basedn = base_dn
if user_rdn: if user_rdn:
@ -52,10 +55,14 @@ class Authenticator(BaseAuthenticator):
self.authenticate(None) self.authenticate(None)
def __del__(self): def __del__(self):
self.freecon()
def freecon(self):
"""Disconnect and free ressources""" """Disconnect and free ressources"""
if self.con: if self.con and hasattr(self.con, "_l"):
self.con.unbind_s() self.con.unbind_s()
# Implement virtual properties # Implement virtual properties
vendor = 'ldap' vendor = 'ldap'