diff --git a/management/univention-management-console/src/univention/management/console/base.py b/management/univention-management-console/src/univention/management/console/base.py index 96ad0ee..33f2b70 100644 --- a/management/univention-management-console/src/univention/management/console/base.py +++ b/management/univention-management-console/src/univention/management/console/base.py @@ -124,7 +124,7 @@ import univention.admin.uexceptions as udm_errors from univention.management.console.protocol.message import Response, MIMETYPE_JSON from univention.management.console.protocol.definitions import MODULE_ERR, MODULE_ERR_COMMAND_FAILED, SUCCESS -from univention.management.console.ldap import get_user_connection, reset_cache as reset_ldap_connection_cache +from univention.management.console.ldap import get_user_connection, reset_cache as reset_ldap_connection_cache, cleanup_connection from univention.management.console.config import ucr from univention.management.console.log import MODULE, CORE from univention.management.console.error import UMC_Error, NotAcceptable, PasswordRequired, LDAP_ServerDown, LDAP_ConnectionFailed, Unauthorized @@ -161,6 +161,7 @@ class Base(signals.Provider, Translation): self.__acls = None self.__current_language = None self.__requests = {} + self.__user_connections = set() Translation.__init__(self, domain) def update_language(self, locales): @@ -400,6 +401,7 @@ class Base(signals.Provider, Translation): return # local user (probably root) try: lo, po = get_user_connection(bind=self.bind_user_connection, write=False, follow_referral=True) + self.__user_connections.add(lo) return lo except (ldap.LDAPError, udm_errors.base) as exc: CORE.warn('Failed to open LDAP connection for user %s: %s' % (self._user_dn, exc)) @@ -487,3 +489,7 @@ class Base(signals.Provider, Translation): if response.id in self.__requests: self.signal_emit('success', response) del self.__requests[response.id] + + def __del__(self): + for lo in self.__user_connections: + cleanup_connection(lo) diff --git a/management/univention-management-console/src/univention/management/console/ldap.py b/management/univention-management-console/src/univention/management/console/ldap.py index bc5ac54..bc64aff 100644 --- a/management/univention-management-console/src/univention/management/console/ldap.py +++ b/management/univention-management-console/src/univention/management/console/ldap.py @@ -114,6 +114,11 @@ class LDAP(object): def reset_cache(self): self.__ldap_connections.clear() + def cleanup_connection(self, lo): + for key, conn in list(self.__ldap_connections.items()): + if conn[0] is lo: + self.__ldap_connections.pop(key, None) + def _wrapped(self, func, hash_, connection, loarg, poarg): def setter(conn): if conn is None: @@ -162,4 +167,5 @@ get_backup_connection = _LDAP.get_backup_connection user_connection = _LDAP.user_connection get_user_connection = _LDAP.get_user_connection reset_cache = _LDAP.reset_cache +cleanup_connection = _LDAP.cleanup_connection del _LDAP diff --git a/management/univention-management-console/src/univention/management/console/protocol/session.py b/management/univention-management-console/src/univention/management/console/protocol/session.py index fa580d9..578d203 100644 --- a/management/univention-management-console/src/univention/management/console/protocol/session.py +++ b/management/univention-management-console/src/univention/management/console/protocol/session.py @@ -67,7 +67,7 @@ from ..config import MODULE_INACTIVITY_TIMER, MODULE_DEBUG_LEVEL, MODULE_COMMAND from ..locales import I18N, I18N_Manager from ..base import Base from ..error import UMC_Error, Unauthorized, BadRequest, NotFound, Forbidden, ServiceUnavailable -from ..ldap import get_machine_connection, reset_cache +from ..ldap import get_machine_connection, reset_cache, cleanup_connection from ..modules.sanitizers import StringSanitizer, DictSanitizer from ..modules.decorators import sanitize, sanitize_args, simple_response, allow_get_request @@ -353,7 +353,9 @@ class ProcessorBase(Base): def _get_user_favorites(self): if not self._user_dn: # user not authenticated or no LDAP user return set(ucr.get('umc/web/favorites/default', '').split(',')) - favorites = self._get_user_preferences(self.get_user_ldap_connection()).setdefault('favorites', ucr.get('umc/web/favorites/default', '')).strip() + lo = self.get_user_ldap_connection() + favorites = self._get_user_preferences(lo).setdefault('favorites', ucr.get('umc/web/favorites/default', '')).strip() + cleanup_connection(lo) return set(favorites.split(',')) def handle_request_get_categories(self, request): @@ -717,6 +719,7 @@ class ProcessorBase(Base): def __del__(self): CORE.process('Processor: dying') + super(ProcessorBase, self).__del__() for process in list(self.__processes.keys()): self.__processes.pop(process).__del__() @@ -943,6 +946,7 @@ class SessionHandler(ProcessorBase): def __del__(self): CORE.info('The session is shutting down') + super(SessionHandler, self).__del__() if self.processor: self.processor.__del__() self.processor = None