[Freeipa-devel] [PATCH] 0064 Rework task naming in LDAP updates to avoid conflicts

Alexander Bokovoy abokovoy at redhat.com
Tue Jul 24 10:01:47 UTC 2012


Hi,

There are two problems in task naming in LDAP updates:

1. Randomness may be scarce in virtual machines
2. Random number is added to the time value rounded to a second

The second issue leads to values that may repeat themselves as time
only grows and random number is non-negative as well, so
t2+r2 can be equal to t1+t2 generated earlier.

Since task name is a DN, there is no strict requirement to use an
integer value.  Instead, we can take time and attribute name. To get
reasonable 'randomness' these values are then hashed with sha1 and use
the resulting string as task name.

SHA1 may technically be an overkill here as we could simply use

   indextask_$date_$attribute

where $date is a value of time.time() but SHA1 gives a resonable
'randomness' into the string.

I was hit by this issue today, see https://fedorahosted.org/freeipa/ticket/2942

-- 
/ Alexander Bokovoy
-------------- next part --------------
>From 60ec577e92ac9d2eabb78b27a877fa2dbd96741d Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue, 24 Jul 2012 12:07:23 +0300
Subject: [PATCH 3/3] Rework task naming in LDAP updates to avoid conflicting
 names in certain cases

There are two problems in task naming in LDAP updates:

1. Randomness may be scarce in virtual machines
2. Random number is added to the time value rounded to a second

The second issue leads to values that may repeat themselves as time
only grows and random number is non-negative as well, so
t2+r2 can be equal to t1+t2 generated earlier.

Since task name is a DN, there is no strict requirement to use an integer value.
Instead, we can take time and attribute name. To get reasonable 'randomness'
these values are then hashed with sha1 and use the resulting string as task name.

https://fedorahosted.org/freeipa/ticket/2942
---
 ipaserver/install/ldapupdate.py |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index c64139889d9f84866ac0cd358ed3a3a7d95af7dc..a28ffb8c8fa86d4989db282ea60721db6d0a7c9a 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -29,9 +29,11 @@ from ipaserver.install import installutils
 from ipaserver.install import service
 from ipaserver import ipaldap
 from ipapython import entity, ipautil
+from ipapython.compat import sha1
 from ipalib import util
 from ipalib import errors
 from ipalib import api
+from ipalib.dn import DN
 import ldap
 from ldap.dn import escape_dn_chars
 from ipapython.ipa_log_manager import *
@@ -328,16 +330,14 @@ class LDAPUpdate:
         if self.live_run:
             time.sleep(5)
 
-        r = random.SystemRandom()
+        tasktime = str(time.time())
+        self.sub_dict['IDXHASH'] = sha1('_'.join(
+                      [tasktime, attribute, tasktime, attribute ])).hexdigest()
 
-        # Refresh the time to make uniqueness more probable. Add on some
-        # randomness for good measure.
-        self.sub_dict['TIME'] = int(time.time()) + r.randint(0,10000)
+        cn = self._template_str("indextask_$IDXHASH")
+        dn = DN(('cn', cn), ('cn', 'index'), ('cn', 'tasks'), ('cn', 'config'))
 
-        cn = self._template_str("indextask_$TIME")
-        dn = "cn=%s, cn=index, cn=tasks, cn=config" % cn
-
-        e = ipaldap.Entry(dn)
+        e = ipaldap.Entry(str(dn))
 
         e.setValues('objectClass', ['top', 'extensibleObject'])
         e.setValue('cn', cn)
@@ -345,7 +345,7 @@ class LDAPUpdate:
         e.setValues('nsIndexAttribute', attribute)
 
         root_logger.info("Creating task to index attribute: %s", attribute)
-        root_logger.debug("Task id: %s", dn)
+        root_logger.debug("Task id: %s", str(dn))
 
         if self.live_run:
             self.conn.addEntry(e)
-- 
1.7.10.4



More information about the Freeipa-devel mailing list