diff --git a/lc_ldap.py b/lc_ldap.py index 234b203..49e11e7 100644 --- a/lc_ldap.py +++ b/lc_ldap.py @@ -36,6 +36,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## import de la lib standard +import os import sys import re @@ -388,9 +389,28 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object): def _find_id(self, attr, realm=None): '''Trouve un id libre. Si une plage est fournie, cherche l'id dans celle-ci, sinon, prend le plus élevé possible.''' - res = self.search_s(variables.base_dn, ldap.SCOPE_SUBTREE, '%s=*' % attr, attrlist = [attr]) + # On essaye de récupérer le dernier id si on l'a déjà vu passé + try: + last_id = open('/tmp/lc_ldap_lastid_%s_%s' % (attr, os.getuid())).read().strip() + except IOError: + last_id = 0 + # On récupère tous les id plus grand que le dernier que l'on connait + res = self.search_s(variables.base_dn, ldap.SCOPE_SUBTREE, '%s>=%s' % (attr, last_id), attrlist = [attr]) + # Si jamais id n'a pas de methode ORDERING, on récupère une liste vide et on fallback en récupérant tous les id (c'est lent) + if res == []: + res = self.search_s(variables.base_dn, ldap.SCOPE_SUBTREE, '%s=*' % attr, attrlist = [attr]) + # On extrait seulement les valeurs des id qui nous intêressent nonfree = [ int(r[1].get(attr)[0]) for r in res if r[1].get(attr) ] + # On trie pour récupérer le dernier nonfree.sort() + try: + last_id = nonfree[-1] + except IndexError: + last_id = 0 + # On écrit le nouveau dernier id connu + f=os.open('/tmp/lc_ldap_lastid_%s_%s' % (attr, os.getuid()), os.O_WRONLY | os.O_CREAT, 0600) + os.write(f, str(last_id)) + os.close(f) plage = None # On récupère la plage des mids @@ -417,10 +437,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object): raise EnvironmentError('Aucun %s libre dans la plage [%d, %d]' % (attr, plage[0], i)) else: - try: - i = nonfree[-1] + 1 - except IndexError: - i = 1 + i = last_id + 1 while True: try: self.lockholder.addlock(attr, str(i))