34b659
From 32b222610532b543d713d4d4b5ce02eed15a66d5 Mon Sep 17 00:00:00 2001
34b659
From: Martin Babinsky <mbabinsk@redhat.com>
34b659
Date: Tue, 6 Dec 2016 18:07:50 +0100
34b659
Subject: [PATCH] gracefully handle setting replica bind dn group on old
34b659
 masters
34b659
34b659
Pre-3.3 masters do not support setting 'nsds5replicabinddngroup'
34b659
attribute on existing replica entry during setup of initial replication.
34b659
In this case UNWILLING_TO_PERFORM is returned. The code can interpret
34b659
this error as an indication of old master and fall back to just adding
34b659
its LDAP principal to entry's 'nsds5replicabinddn' attribute.
34b659
34b659
https://fedorahosted.org/freeipa/ticket/6532
34b659
34b659
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
34b659
---
34b659
 ipaserver/install/replication.py | 48 ++++++++++++++++++++++++++--------------
34b659
 1 file changed, 32 insertions(+), 16 deletions(-)
34b659
34b659
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
34b659
index e9624894d7d1e745be8072268fa76d51a8c117e3..5f03ddeadfc515255509a1f49d3b38687e561b9f 100644
34b659
--- a/ipaserver/install/replication.py
34b659
+++ b/ipaserver/install/replication.py
34b659
@@ -429,6 +429,34 @@ class ReplicationManager(object):
34b659
         return DN(('cn', 'replica'), ('cn', self.db_suffix),
34b659
                   ('cn', 'mapping tree'), ('cn', 'config'))
34b659
 
34b659
+    def set_replica_binddngroup(self, r_conn, entry, replica_groupdn):
34b659
+        """
34b659
+        Set nsds5replicabinddngroup attribute on remote master's replica entry.
34b659
+        Older masters (ipa < 3.3) may not support setting this attribute. In
34b659
+        this case log the error and fall back to setting replica's binddn
34b659
+        directly.
34b659
+        """
34b659
+        binddn_groups = {
34b659
+            DN(p) for p in entry.get('nsds5replicabinddngroup', [])}
34b659
+
34b659
+        mod = []
34b659
+        if replica_groupdn not in binddn_groups:
34b659
+            mod.append((ldap.MOD_ADD, 'nsds5replicabinddngroup',
34b659
+                        replica_groupdn))
34b659
+
34b659
+        if 'nsds5replicabinddngroupcheckinterval' not in entry:
34b659
+            mod.append(
34b659
+                (ldap.MOD_ADD,
34b659
+                 'nsds5replicabinddngroupcheckinterval',
34b659
+                 '60'))
34b659
+        if mod:
34b659
+            try:
34b659
+                r_conn.modify_s(entry.dn, mod)
34b659
+            except ldap.UNWILLING_TO_PERFORM:
34b659
+                root_logger.debug(
34b659
+                    "nsds5replicabinddngroup attribute not supported on "
34b659
+                    "remote master.")
34b659
+
34b659
     def replica_config(self, conn, replica_id, replica_binddn):
34b659
         assert isinstance(replica_binddn, DN)
34b659
         dn = self.replica_dn()
34b659
@@ -440,27 +468,15 @@ class ReplicationManager(object):
34b659
         try:
34b659
             entry = conn.get_entry(dn)
34b659
             managers = {DN(m) for m in entry.get('nsDS5ReplicaBindDN', [])}
34b659
-            binddn_groups = {
34b659
-                DN(p) for p in entry.get('nsds5replicabinddngroup', [])}
34b659
 
34b659
-            mod = []
34b659
             if replica_binddn not in managers:
34b659
                 # Add the new replication manager
34b659
-                mod.append((ldap.MOD_ADD, 'nsDS5ReplicaBindDN',
34b659
-                            replica_binddn))
34b659
-
34b659
-            if replica_groupdn not in binddn_groups:
34b659
-                mod.append((ldap.MOD_ADD, 'nsds5replicabinddngroup',
34b659
-                            replica_groupdn))
34b659
-
34b659
-            if 'nsds5replicabinddngroupcheckinterval' not in entry:
34b659
-                mod.append(
34b659
-                    (ldap.MOD_ADD,
34b659
-                     'nsds5replicabinddngroupcheckinterval',
34b659
-                     '60'))
34b659
-            if mod:
34b659
+                mod = [(ldap.MOD_ADD, 'nsDS5ReplicaBindDN',
34b659
+                        replica_binddn)]
34b659
                 conn.modify_s(dn, mod)
34b659
 
34b659
+            self.set_replica_binddngroup(conn, entry, replica_groupdn)
34b659
+
34b659
             # replication is already configured
34b659
             return
34b659
         except errors.NotFound:
34b659
-- 
34b659
2.7.4
34b659