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 <cheimes@redhat.com>
This commit is contained in:
Florence Blanc-Renaud 2018-12-13 14:54:07 +01:00 committed by Christian Heimes
parent a34d92d25c
commit faa122a8b8

View File

@ -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:
"""Manage replication agreements
@ -527,8 +543,16 @@ class ReplicationManager:
# 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:
# 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