--- /usr/share/pyshared/univention/management/console/modules/udm/udm_ldap.py.orig 2012-10-24 13:50:15.000000000 +0200 +++ /usr/share/pyshared/univention/management/console/modules/udm/udm_ldap.py 2012-10-24 18:00:25.000000000 +0200 @@ -33,6 +33,7 @@ import operator import threading +import gc from univention.management.console import Translation from univention.management.console.modules import Base, UMC_OptionTypeError, UMC_OptionMissing, UMC_CommandError @@ -131,6 +132,8 @@ _ldap_connection = lo _ldap_position = po return ret + except (udm_errors.ldapSizelimitExceeded, udm_errors.ldapTimeout), e: + raise e except ( LDAPError, udm_errors.base ), e: MODULE.info( 'LDAP operation for user %s has failed' % _user_dn ) try: @@ -149,6 +152,8 @@ _ldap_connection = lo _ldap_position = po return ret + except (udm_errors.ldapSizelimitExceeded, udm_errors.ldapTimeout), e: + raise e except udm_errors.base, e: raise LDAP_ConnectionError( str( e ) ) @@ -390,14 +395,26 @@ filter_s = '%s=%s' % ( attribute, value ) MODULE.info( 'Searching for LDAP objects: container = %s, filter = %s, superordinate = %s' % ( container, filter_s, superordinate ) ) + result = None try: - return self.module.lookup( None, ldap_connection, filter_s, base = container, superordinate = superordinate, scope = scope ) + result = self.module.lookup( None, ldap_connection, filter_s, base = container, superordinate = superordinate, scope = scope, sizelimit = int(ucr.get('directory/manager/web/sizelimit', '2000')) ) except udm_errors.insufficientInformation, e: return [] + except udm_errors.ldapTimeout, e: + raise udm_errors.ldapTimeout( _('The query you have entered timed out. Please narrow down your search by specifiying more query parameters') ) + except udm_errors.ldapSizelimitExceeded, e: + raise udm_errors.ldapSizelimitExceeded( _('The query you have entered yields too many matching entries. Please narrow down your search by specifiying more query parameters. The current size limit of %s can be configured with the UCR variable directory/manager/web/sizelimit.') % ucr.get('directory/manager/web/sizelimit', '2000') ) except ( LDAPError, udm_errors.ldapError ), e: raise e except udm_errors.base, e: raise UDM_Error( str( e ) ) + + # call the garbage collector manually as many parallel request may cause the + # process to use too much memory + MODULE.info('Triggering garbage collection') + gc.collect() + + return result @LDAP_Connection def get( self, ldap_dn = None, superordinate = None, attributes = [], ldap_connection = None, ldap_position = None ): --- /usr/share/pyshared/univention/admin/uexceptions.py.orig 2012-10-24 14:15:30.000000000 +0200 +++ /usr/share/pyshared/univention/admin/uexceptions.py 2012-10-24 15:03:27.000000000 +0200 @@ -52,6 +52,12 @@ class ldapError(base): message=_('LDAP Error') +class ldapTimeout(base): + message=_('The specified timeout for the LDAP search has been exceeded.') + +class ldapSizelimitExceeded(base): + message=_('The specified size limit for the LDAP search has been exceeded.') + class insufficientInformation(base): message=_('Information provided is not sufficient.') --- /usr/share/pyshared/univention/admin/uldap.py.orig 2012-10-24 14:46:02.000000000 +0200 +++ /usr/share/pyshared/univention/admin/uldap.py 2012-10-24 15:03:10.000000000 +0200 @@ -321,6 +321,10 @@ raise univention.admin.uexceptions.noObject, _err2str(msg) except ldap.INAPPROPRIATE_MATCHING, msg: raise univention.admin.uexceptions.insufficientInformation, _err2str(msg) + except (ldap.TIMEOUT, ldap.TIMELIMIT_EXCEEDED), msg: + raise univention.admin.uexceptions.ldapTimeout, _err2str(msg) + except ldap.SIZELIMIT_EXCEEDED, msg: + raise univention.admin.uexceptions.ldapSizelimitExceeded, _err2str(msg) except ldap.LDAPError, msg: raise univention.admin.uexceptions.ldapError, _err2str(msg)