Newer 389ds servers have a new option to have a different set of filtered attributes from normal replication.
This has been added in order to allow DS to replicate memberof attributes only during a total update so that we do not need to run a fixup memberof task on a replica at install time. This task is quite inefficient for big database and can take a long time. By replicating memberof while the DB is locked we are guaranteed the memberof list is consistent so we do not need a fixup. This patch allows to enable this feature dynamically. If the server does not yet support the new option it falls back to the previous behavior. Fixes: https://fedorahosted.org/freeipa/ticket/1794 I am sending the patch but it has been jointly developed at various stages by Nathan, JR, and me. Simo. -- Simo Sorce * Red Hat, Inc * New York
>From 1ce9bd802d0cc59057d89ef2a2a7f0605c582308 Mon Sep 17 00:00:00 2001 From: JR Aquino <jr.aqu...@citrix.com> Date: Fri, 16 Sep 2011 10:23:02 -0700 Subject: [PATCH] Replication: Adjust replica installation to omit processing memberof computations https://fedorahosted.org/freeipa/ticket/1794 If the master does not yet support the total update list feature we still run the memberof fixup task and not fail to replicate due to the new attribute not being settable. Jointly-developed-with: Simo Sorce <sso...@redhat.com> Jointly-developed-with: Nathank Kinder <nkin...@redhat.com> --- install/tools/ipa-replica-install | 1 - install/ui/test/data/json_metadata.json | 1 + ipaserver/install/dsinstance.py | 6 ++++++ ipaserver/install/replication.py | 28 +++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install index af317cde5bfbcfccde8d768b35c369207221e636..c77c21327b22326230c1587b932da5dd1bab3a76 100755 --- a/install/tools/ipa-replica-install +++ b/install/tools/ipa-replica-install @@ -466,7 +466,6 @@ def main(): raise RuntimeError("Failed to configure the client") ds.replica_populate() - ds.init_memberof() #Everything installed properly, activate ipa service. ipaservices.knownservices.ipa.enable() diff --git a/install/ui/test/data/json_metadata.json b/install/ui/test/data/json_metadata.json index 482eb6c3b8e502ee81714fe611822f2593bfd8f9..f87ab114c48330d6af791214d462fc9fc6562ffa 100644 --- a/install/ui/test/data/json_metadata.json +++ b/install/ui/test/data/json_metadata.json @@ -3273,6 +3273,7 @@ "nsds5replicaroot", "nsds5replicasessionpausetime", "nsds5replicatedattributelist", + "nsds5replicatedattributelisttotal", "nsds5replicatimeout", "nsds5replicatombstonepurgeinterval", "nsds5replicatransportinfo", diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 790b560b92a28897a8f7e4ad076669241b168c3f..858bb892cb39fc36c7512cfb5e6c74b68fafb37f 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -169,6 +169,7 @@ class DsInstance(service.Service): self.idmax = None self.subject_base = None self.open_ports = [] + self.run_init_memberof = True if realm_name: self.suffix = util.realm_to_suffix(self.realm_name) self.__setup_sub_dict() @@ -295,6 +296,7 @@ class DsInstance(service.Service): repl.setup_replication(self.master_fqdn, r_binddn="cn=Directory Manager", r_bindpw=self.dm_password) + self.run_init_memberof = repl.needs_memberof_fixup() def __enable(self): self.backup_state("enabled", self.is_enabled()) @@ -433,6 +435,10 @@ class DsInstance(service.Service): self._ldap_mod("memberof-conf.ldif") def init_memberof(self): + + if not self.run_init_memberof: + return + self._ldap_mod("memberof-task.ldif", self.sub_dict) # Note, keep dn in sync with dn in install/share/memberof-task.ldif dn = "cn=IPA install %s,cn=memberof task,cn=tasks,cn=config" % self.sub_dict["TIME"] diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index 986fb5e83e9296ad415f54fa106170391904b3c0..a048cac4d070110b2071ec04b3880f812eb129c4 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -107,6 +107,7 @@ class ReplicationManager(object): self.starttls = starttls tmp = util.realm_to_suffix(realm) self.suffix = str(DN(tmp)).lower() + self.need_memberof_fixup = False # If we are passed a password we'll use it as the DM password # otherwise we'll do a GSSAPI bind. @@ -433,6 +434,7 @@ class ReplicationManager(object): which use a different name on each side. If master is None then isn't a dogtag replication agreement. """ + cn, dn = self.agreement_dn(b_hostname, master=master) try: a_conn.getEntry(dn, ldap.SCOPE_BASE) @@ -440,11 +442,14 @@ class ReplicationManager(object): except errors.NotFound: pass - # List of attributes that need to be excluded from replication. - excludes = ('memberof', 'entryusn', - 'krblastsuccessfulauth', - 'krblastfailedauth', - 'krbloginfailedcount') + # List of attributes that need to be excluded from replication initialization. + totalexcludes = ('entryusn', + 'krblastsuccessfulauth', + 'krblastfailedauth', + 'krbloginfailedcount') + + # List of attributes that need to be excluded from normal replication. + excludes = ('memberof', ) + totalexcludes entry = ipaldap.Entry(dn) entry.setValues('objectclass', "nsds5replicationagreement") @@ -472,8 +477,21 @@ class ReplicationManager(object): a_conn.add_s(entry) + try: + mod = [(ldap.MOD_ADD, 'nsDS5ReplicatedAttributeListTotal', + '(objectclass=*) $ EXCLUDE %s' % " ".join(totalexcludes))] + a_conn.modify_s(dn, mod) + except ldap.LDAPError, e: + # Apparently there are problems set the total list + # Probably the master is an old 389-ds server, tell the caller + # that we will have to set the memberof fixup task + self.need_memberof_fixup = True + entry = a_conn.waitForEntry(entry) + def needs_memberof_fixup(self): + return self.need_memberof_fixup + def setup_krb_princs_as_replica_binddns(self, a, b): """ Search the appropriate principal names so we can get -- 1.7.6.4
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel