From e879ca9b693a10f456f03d3c471afa49321516f9 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Thu, 13 Dec 2018 14:54:07 +0100 Subject: [PATCH] replication: check remote ds version before editing attributes When the remote server has an old DS version, update of the replication attributes nsds5ReplicaReleaseTimeout nsds5ReplicaBackoffMax and nsDS5ReplicaBindDnGroupCheckInterval fails even if the remote schema has been updated. Check first the remote server version and update the attributes only if the version is high enough. A previous fix was already performing this check (commit 02f4a7a), but not in all the cases. This fix also handles when the remote server already has a cn=replica entry (for instance because it has already established replication with another host). Fixes https://pagure.io/freeipa/issue/7796 Reviewed-By: Christian Heimes Reviewed-By: Christian Heimes --- ipaserver/install/replication.py | 33 ++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index 92a99cd9482f86d6820230479bf94c871669572e..70629b4528f033908c584bfaf0793cfa4ce259d4 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -215,6 +215,22 @@ def wait_for_entry(connection, dn, timeout, attr=None, attrvalue='*', time.sleep(1) +def get_ds_version(conn): + """Returns the DS version + + Retrieves the DS version from the vendorVersion attribute stored in LDAP. + :param conn: LDAP connection established and authenticated to the server + for which we need the version + :return: a tuple containing the DS version + """ + # Find which 389-ds is installed + rootdse = conn.get_entry(DN(''), ['vendorVersion']) + version = rootdse.single_value.get('vendorVersion') + mo = re.search(r'(\d+)\.(\d+)\.(\d+)[\.\d]*', version) + vendor_version = tuple(int(v) for v in mo.groups()) + return vendor_version + + class ReplicationManager(object): """Manage replication agreements @@ -527,8 +543,16 @@ class ReplicationManager(object): # Add the new replication manager binddns.append(replica_binddn) - for key, value in REPLICA_CREATION_SETTINGS.items(): - entry[key] = value + # If the remote server has 389-ds < 1.3, it does not + # support the attributes we are trying to set. + # Find which 389-ds is installed + vendor_version = get_ds_version(conn) + if vendor_version >= (1, 3, 0): + for key, value in REPLICA_CREATION_SETTINGS.items(): + entry[key] = value + else: + logger.debug("replication attributes not supported " + "on remote master, skipping update.") try: conn.update_entry(entry) @@ -604,10 +628,7 @@ class ReplicationManager(object): # If the remote server has 389-ds < 1.3, it does not # support the attributes we are trying to set. # Find which 389-ds is installed - rootdse = r_conn.get_entry(DN(''), ['vendorVersion']) - version = rootdse.single_value.get('vendorVersion') - mo = re.search(r'(\d+)\.(\d+)\.(\d+)[\.\d]*', version) - vendor_version = tuple(int(v) for v in mo.groups()) + vendor_version = get_ds_version(r_conn) if vendor_version >= (1, 3, 0): # 389-ds understands the replication attributes, # we can safely modify them -- 2.17.2