https://fedorahosted.org/freeipa/ticket/5631

Patch attached (for master, 4.3, 4.2)
From 9528695d172a3127f146904a4b0695bb0eb06065 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Thu, 4 Feb 2016 16:23:40 +0100
Subject: [PATCH] fix permission: Read Replication Agreements

This permission cannot be MANAGED permission because it is located in
nonreplicating part of the LDAP tree.

As side effect, the particular ACI has not been created on all replicas.

This commit makes Read Replication Agreements non managed permission and
also fix missing ACI on replicas.

https://fedorahosted.org/freeipa/ticket/5631
---
 ACI.txt                                            |   2 -
 install/share/delegation.ldif                      |   9 ++
 install/share/replica-acis.ldif                    |   5 +
 install/updates/20-aci.update                      |   3 +
 install/updates/90-post_upgrade_plugins.update     |   1 +
 .../install/plugins/update_managed_permissions.py  | 126 +++++++++++----------
 6 files changed, 83 insertions(+), 63 deletions(-)

diff --git a/ACI.txt b/ACI.txt
index 40fa822217eaee8d0966491b10cdf7e0739a87ce..fd1ba6725f2377a2506284c9477f99424e9d1e0a 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -388,8 +388,6 @@ dn: cn=Domain Level,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "createtimestamp || entryusn || ipadomainlevel || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipadomainlevelconfig)")(version 3.0;acl "permission:System: Read Domain Level";allow (compare,read,search) userdn = "ldap:///all";;)
 dn: cn=masters,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || ipaconfigstring || modifytimestamp || objectclass")(targetfilter = "(objectclass=nscontainer)")(version 3.0;acl "permission:System: Read IPA Masters";allow (compare,read,search) groupdn = "ldap:///cn=System: Read IPA Masters,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-dn: cn=config
-aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:System: Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Replication Agreements,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=replication,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || modifytimestamp || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicachangecount || nsds5replicacleanruv || nsds5replicaid || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicatombstonepurgeinterval || nsds5replicatype || nsds5task || nsstate || objectclass")(targetfilter = "(objectclass=nsds5replica)")(version 3.0;acl "permission:System: Read Replication Information";allow (compare,read,search) userdn = "ldap:///all";;)
 dn: cn=certificates,cn=ipa,cn=etc,dc=ipa,dc=example
diff --git a/install/share/delegation.ldif b/install/share/delegation.ldif
index bacd9e68af0a17770a00a0809d05e884d523f9b7..067b4d26a8be8f4d1b699c15b027ed7f260ddb5b 100644
--- a/install/share/delegation.ldif
+++ b/install/share/delegation.ldif
@@ -173,6 +173,15 @@ cn: Modify Replication Agreements
 ipapermissiontype: SYSTEM
 member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
 
+dn: cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX
+changetype: add
+objectClass: top
+objectClass: groupofnames
+objectClass: ipapermission
+cn: Read Replication Agreements
+ipapermissiontype: SYSTEM
+member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
+
 dn: cn=Remove Replication Agreements,cn=permissions,cn=pbac,$SUFFIX
 changetype: add
 objectClass: top
diff --git a/install/share/replica-acis.ldif b/install/share/replica-acis.ldif
index 8c0bc8ec3826a57ee531726cfeec2789484a3032..bf01036d6261971f89c11d5f7daa085f5392d832 100644
--- a/install/share/replica-acis.ldif
+++ b/install/share/replica-acis.ldif
@@ -1,5 +1,10 @@
 # Replica administration
 
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+
 dn: cn="$SUFFIX",cn=mapping tree,cn=config
 changetype: modify
 add: aci
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
index cba1897e1fd1136fbcbd7c6ccaf03bfa4b696a44..06be89ae24800f2b215974e03a6dc22de78a2bc9 100644
--- a/install/updates/20-aci.update
+++ b/install/updates/20-aci.update
@@ -58,6 +58,9 @@ add:aci:(targetattr="*")(version 3.0; acl "Admin can read all tasks"; allow (rea
 dn: cn=config
 # Replaced by 'System: Read Replication Agreements'
 remove:aci: (targetattr != aci)(version 3.0; aci "replica admins read access"; allow (read, search, compare) groupdn = "ldap:///cn=Modify Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+# ticket 5631: this ACI cannot be a managed ACI, because it is located in nonreplicated container, must be added here
+remove:aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:System: Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+add:aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 
 dn: $SUFFIX
 remove:aci: (targetattr = "*")(target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX";)(version 3.0; acl "No anonymous access to roles"; deny (read,search,compare) userdn != "ldap:///all";;)
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
index 3df3a4574705dbd8df8f25149c13877898afb66b..7751029d8be36a4ca8e84d6db767434eff56e803 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -16,6 +16,7 @@ plugin: update_upload_cacrt
 plugin: update_master_to_dnsforwardzones
 plugin: update_managed_post
 plugin: update_managed_permissions
+plugin: update_read_replication_agreements_permission
 plugin: update_idrange_baserid
 plugin: update_passync_privilege_update
 plugin: update_oddjobd_for_adtrust
diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py
index 563dbb0d6ad9d81d757af257a2f8e5c39cd94575..a3fb4dca4889ae26f4ea2b1d8301c11ca78e7831 100644
--- a/ipaserver/install/plugins/update_managed_permissions.py
+++ b/ipaserver/install/plugins/update_managed_permissions.py
@@ -257,67 +257,6 @@ NONOBJECT_PERMISSIONS = {
             'ipantdomainguid', 'ipantfallbackprimarygroup',
         },
     },
-    'System: Read Replication Agreements': {
-        'ipapermlocation': DN('cn=config'),
-        'ipapermtargetfilter': {
-            '(|'
-                '(objectclass=nsds5Replica)'
-                '(objectclass=nsds5replicationagreement)'
-                '(objectclass=nsDSWindowsReplicationAgreement)'
-                '(objectClass=nsMappingTree)'
-            ')'
-        },
-        'ipapermbindruletype': 'permission',
-        'ipapermright': {'read', 'search', 'compare'},
-        'ipapermdefaultattr': {
-            'cn', 'objectclass',
-            # nsds5Replica
-            'nsds5replicaroot', 'nsds5replicaid', 'nsds5replicacleanruv',
-            'nsds5replicaabortcleanruv', 'nsds5replicatype',
-            'nsds5replicabinddn', 'nsstate', 'nsds5replicaname',
-            'nsds5flags', 'nsds5task', 'nsds5replicareferral',
-            'nsds5replicaautoreferral', 'nsds5replicapurgedelay',
-            'nsds5replicatombstonepurgeinterval', 'nsds5replicachangecount',
-            'nsds5replicalegacyconsumer', 'nsds5replicaprotocoltimeout',
-            'nsds5replicabackoffmin', 'nsds5replicabackoffmax',
-            # nsds5replicationagreement
-            'nsds5replicacleanruvnotified', 'nsds5replicahost',
-            'nsds5replicaport', 'nsds5replicatransportinfo',
-            'nsds5replicabinddn', 'nsds5replicacredentials',
-            'nsds5replicabindmethod', 'nsds5replicaroot',
-            'nsds5replicatedattributelist',
-            'nsds5replicatedattributelisttotal', 'nsds5replicaupdateschedule',
-            'nsds5beginreplicarefresh', 'description', 'nsds50ruv',
-            'nsruvreplicalastmodified', 'nsds5replicatimeout',
-            'nsds5replicachangessentsincestartup', 'nsds5replicalastupdateend',
-            'nsds5replicalastupdatestart', 'nsds5replicalastupdatestatus',
-            'nsds5replicaupdateinprogress', 'nsds5replicalastinitend',
-            'nsds5replicaenabled', 'nsds5replicalastinitstart',
-            'nsds5replicalastinitstatus', 'nsds5debugreplicatimeout',
-            'nsds5replicabusywaittime', 'nsds5replicastripattrs',
-            'nsds5replicasessionpausetime', 'nsds5replicaprotocoltimeout',
-            # nsDSWindowsReplicationAgreement
-            'nsds5replicahost', 'nsds5replicaport',
-            'nsds5replicatransportinfo', 'nsds5replicabinddn',
-            'nsds5replicacredentials', 'nsds5replicabindmethod',
-            'nsds5replicaroot', 'nsds5replicatedattributelist',
-            'nsds5replicaupdateschedule', 'nsds5beginreplicarefresh',
-            'description', 'nsds50ruv', 'nsruvreplicalastmodified',
-            'nsds5replicatimeout', 'nsds5replicachangessentsincestartup',
-            'nsds5replicalastupdateend', 'nsds5replicalastupdatestart',
-            'nsds5replicalastupdatestatus', 'nsds5replicaupdateinprogress',
-            'nsds5replicalastinitend', 'nsds5replicalastinitstart',
-            'nsds5replicalastinitstatus', 'nsds5debugreplicatimeout',
-            'nsds5replicabusywaittime', 'nsds5replicasessionpausetime',
-            'nsds7windowsreplicasubtree', 'nsds7directoryreplicasubtree',
-            'nsds7newwinusersyncenabled', 'nsds7newwingroupsyncenabled',
-            'nsds7windowsdomain', 'nsds7dirsynccookie', 'winsyncinterval',
-            'onewaysync', 'winsyncmoveaction', 'nsds5replicaenabled',
-            'winsyncdirectoryfilter', 'winsyncwindowsfilter',
-            'winsyncsubtreepair',
-        },
-        'default_privileges': {'Replication Administrators'},
-    },
     'System: Read DUA Profile': {
         'ipapermlocation': DN('ou=profile', api.env.basedn),
         'ipapermtargetfilter': {
@@ -724,3 +663,68 @@ class update_managed_permissions(Updater):
             raise ValueError(
                 'Unknown key(s) in managed permission template %s: %s' % (
                     name, ', '.join(template.keys())))
+
+
+@register()
+class update_read_replication_agreements_permission(Updater):
+    """'Read replication agreements' permission must not be managed permission
+
+    https://fedorahosted.org/freeipa/ticket/5631
+
+    Existing permission "cn=System: Read Replication Agreements" must be moved
+    to non-managed permission "cn=Read Replication Agreements" using modrdn
+    ldap operation to keep current membership of the permission set by user.
+
+    ACI is updated via update files
+    """
+
+    def execute(self, **options):
+        ldap = self.api.Backend.ldap2
+        old_perm_dn = DN(
+            ('cn', 'System: Read Replication Agreements'),
+            ('cn', 'permissions'),
+            ('cn', 'pbac'),
+            self.api.env.basedn
+        )
+
+        new_perm_dn = DN(
+            ('cn', 'Read Replication Agreements'),
+            ('cn', 'permissions'),
+            ('cn', 'pbac'),
+            self.api.env.basedn
+        )
+
+        try:
+            perm_entry = ldap.get_entry(old_perm_dn)
+        except errors.NotFound:
+            self.log.debug("Old permission not found")
+            return False, ()
+
+        try:
+            ldap.get_entry(new_perm_dn)
+        except errors.NotFound:
+            # we can happily upgrade
+            pass
+        else:
+            self.log.error("Permission '{}' cannot be upgraded. "
+                           "Permission with target name '{}' already "
+                           "exists".format(old_perm_dn, new_perm_dn))
+            return False, ()
+
+        # remove MANAGED permissions related attributes
+        perm_entry['objectclass'] = ['top', 'groupofnames', 'ipapermission']
+        perm_entry['ipapermissiontype'] = ['SYSTEM']
+        perm_entry['ipapermdefaultattr'] = []
+        perm_entry['ipapermright'] = []
+        perm_entry['ipapermbindruletype'] = []
+        perm_entry['ipapermlocation'] = []
+        perm_entry['ipapermtargetfilter'] = []
+
+        self.log.debug("Removing MANAGED attributes from permission %s",
+                       old_perm_dn)
+        ldap.update_entry(perm_entry)
+
+        # do modrdn on permission
+        self.log.debug("modrdn: %s -> %s", old_perm_dn, new_perm_dn)
+        ldap.move_entry(old_perm_dn, new_perm_dn)
+        return False, ()
-- 
2.5.0

From efad8e5c0df03d3dacc06eb46ba39145bc9401c1 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Thu, 4 Feb 2016 16:23:40 +0100
Subject: [PATCH] fix permission: Read Replication Agreements

This permission cannot be MANAGED permission because it is located in
nonreplicating part of the LDAP tree.

As side effect, the particular ACI has not been created on all replicas.

This commit makes Read Replication Agreements non managed permission and
also fix missing ACI on replicas.

https://fedorahosted.org/freeipa/ticket/5631
---
 ACI.txt                                            |   2 -
 install/share/delegation.ldif                      |   9 ++
 install/share/replica-acis.ldif                    |   5 +
 install/updates/20-aci.update                      |   3 +
 install/updates/90-post_upgrade_plugins.update     |   1 +
 .../install/plugins/update_managed_permissions.py  | 126 +++++++++++----------
 6 files changed, 83 insertions(+), 63 deletions(-)

diff --git a/ACI.txt b/ACI.txt
index bbc2e660cc0a549421069f2f569f8b1dbf42c724..24cb332ce6e10c82a5bfab76d084fb6c0277800d 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -388,8 +388,6 @@ dn: cn=Domain Level,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "createtimestamp || entryusn || ipadomainlevel || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipadomainlevelconfig)")(version 3.0;acl "permission:System: Read Domain Level";allow (compare,read,search) userdn = "ldap:///all";;)
 dn: cn=masters,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || ipaconfigstring || modifytimestamp || objectclass")(targetfilter = "(objectclass=nscontainer)")(version 3.0;acl "permission:System: Read IPA Masters";allow (compare,read,search) groupdn = "ldap:///cn=System: Read IPA Masters,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-dn: cn=config
-aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:System: Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Replication Agreements,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=replication,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || modifytimestamp || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicachangecount || nsds5replicacleanruv || nsds5replicaid || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicatombstonepurgeinterval || nsds5replicatype || nsds5task || nsstate || objectclass")(targetfilter = "(objectclass=nsds5replica)")(version 3.0;acl "permission:System: Read Replication Information";allow (compare,read,search) userdn = "ldap:///all";;)
 dn: cn=certificates,cn=ipa,cn=etc,dc=ipa,dc=example
diff --git a/install/share/delegation.ldif b/install/share/delegation.ldif
index bacd9e68af0a17770a00a0809d05e884d523f9b7..067b4d26a8be8f4d1b699c15b027ed7f260ddb5b 100644
--- a/install/share/delegation.ldif
+++ b/install/share/delegation.ldif
@@ -173,6 +173,15 @@ cn: Modify Replication Agreements
 ipapermissiontype: SYSTEM
 member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
 
+dn: cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX
+changetype: add
+objectClass: top
+objectClass: groupofnames
+objectClass: ipapermission
+cn: Read Replication Agreements
+ipapermissiontype: SYSTEM
+member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
+
 dn: cn=Remove Replication Agreements,cn=permissions,cn=pbac,$SUFFIX
 changetype: add
 objectClass: top
diff --git a/install/share/replica-acis.ldif b/install/share/replica-acis.ldif
index 673513087fc99f8c95b9d9ea30e2db51eb6260f9..870a1644f85b4104f42388c3e87df8d65a2e3866 100644
--- a/install/share/replica-acis.ldif
+++ b/install/share/replica-acis.ldif
@@ -1,5 +1,10 @@
 # Replica administration
 
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+
 dn: cn=mapping tree,cn=config
 changetype: modify
 add: aci
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
index 7da48cfd1e2454843beea9fe1d9b18c3cdf1a113..22e95b6200040b75684b912f4a4bc93a04b8f3ce 100644
--- a/install/updates/20-aci.update
+++ b/install/updates/20-aci.update
@@ -88,6 +88,9 @@ remove:aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreemen
 dn: cn=config
 # Replaced by 'System: Read Replication Agreements'
 remove:aci: (targetattr != aci)(version 3.0; aci "replica admins read access"; allow (read, search, compare) groupdn = "ldap:///cn=Modify Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+# ticket 5631: this ACI cannot be a managed ACI, because it is located in nonreplicated container, must be added here
+remove:aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:System: Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+add:aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || nsds50ruv || nsds5beginreplicarefresh || nsds5debugreplicatimeout || nsds5flags || nsds5replicaabortcleanruv || nsds5replicaautoreferral || nsds5replicabackoffmax || nsds5replicabackoffmin || nsds5replicabinddn || nsds5replicabindmethod || nsds5replicabusywaittime || nsds5replicachangecount || nsds5replicachangessentsincestartup || nsds5replicacleanruv || nsds5replicacleanruvnotified || nsds5replicacredentials || nsds5replicaenabled || nsds5replicahost || nsds5replicaid || nsds5replicalastinitend || nsds5replicalastinitstart || nsds5replicalastinitstatus || nsds5replicalastupdateend || nsds5replicalastupdatestart || nsds5replicalastupdatestatus || nsds5replicalegacyconsumer || nsds5replicaname || nsds5replicaport || nsds5replicaprotocoltimeout || nsds5replicapurgedelay || nsds5replicareferral || nsds5replicaroot || nsds5replicasessionpausetime || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || nsds5replicatimeout || nsds5replicatombstonepurgeinterval || nsds5replicatransportinfo || nsds5replicatype || nsds5replicaupdateinprogress || nsds5replicaupdateschedule || nsds5task || nsds7directoryreplicasubtree || nsds7dirsynccookie || nsds7newwingroupsyncenabled || nsds7newwinusersyncenabled || nsds7windowsdomain || nsds7windowsreplicasubtree || nsruvreplicalastmodified || nsstate || objectclass || onewaysync || winsyncdirectoryfilter || winsyncinterval || winsyncmoveaction || winsyncsubtreepair || winsyncwindowsfilter")(targetfilter = "(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0;acl "permission:Read Replication Agreements";allow (compare,read,search) groupdn = "ldap:///cn=Read Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 
 dn: $SUFFIX
 remove:aci: (targetattr = "*")(target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX";)(version 3.0; acl "No anonymous access to roles"; deny (read,search,compare) userdn != "ldap:///all";;)
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
index 626255af7ade0d405f802f7330a65b0e0f03ed6b..5642021ad93cf336db2d872bf3ef6db99b5ffa46 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -17,5 +17,6 @@ plugin: update_upload_cacrt
 plugin: update_master_to_dnsforwardzones
 plugin: update_managed_post
 plugin: update_managed_permissions
+plugin: update_read_replication_agreements_permission
 plugin: update_idrange_baserid
 plugin: update_passync_privilege_update
diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py
index d68e24302edfcb5674c0cc654ba202eb8f650cc4..6459f4fecddba6755345c0f16a0b1a99d528b5aa 100644
--- a/ipaserver/install/plugins/update_managed_permissions.py
+++ b/ipaserver/install/plugins/update_managed_permissions.py
@@ -262,67 +262,6 @@ NONOBJECT_PERMISSIONS = {
             'ipantdomainguid', 'ipantfallbackprimarygroup',
         },
     },
-    'System: Read Replication Agreements': {
-        'ipapermlocation': DN('cn=config'),
-        'ipapermtargetfilter': {
-            '(|'
-                '(objectclass=nsds5Replica)'
-                '(objectclass=nsds5replicationagreement)'
-                '(objectclass=nsDSWindowsReplicationAgreement)'
-                '(objectClass=nsMappingTree)'
-            ')'
-        },
-        'ipapermbindruletype': 'permission',
-        'ipapermright': {'read', 'search', 'compare'},
-        'ipapermdefaultattr': {
-            'cn', 'objectclass',
-            # nsds5Replica
-            'nsds5replicaroot', 'nsds5replicaid', 'nsds5replicacleanruv',
-            'nsds5replicaabortcleanruv', 'nsds5replicatype',
-            'nsds5replicabinddn', 'nsstate', 'nsds5replicaname',
-            'nsds5flags', 'nsds5task', 'nsds5replicareferral',
-            'nsds5replicaautoreferral', 'nsds5replicapurgedelay',
-            'nsds5replicatombstonepurgeinterval', 'nsds5replicachangecount',
-            'nsds5replicalegacyconsumer', 'nsds5replicaprotocoltimeout',
-            'nsds5replicabackoffmin', 'nsds5replicabackoffmax',
-            # nsds5replicationagreement
-            'nsds5replicacleanruvnotified', 'nsds5replicahost',
-            'nsds5replicaport', 'nsds5replicatransportinfo',
-            'nsds5replicabinddn', 'nsds5replicacredentials',
-            'nsds5replicabindmethod', 'nsds5replicaroot',
-            'nsds5replicatedattributelist',
-            'nsds5replicatedattributelisttotal', 'nsds5replicaupdateschedule',
-            'nsds5beginreplicarefresh', 'description', 'nsds50ruv',
-            'nsruvreplicalastmodified', 'nsds5replicatimeout',
-            'nsds5replicachangessentsincestartup', 'nsds5replicalastupdateend',
-            'nsds5replicalastupdatestart', 'nsds5replicalastupdatestatus',
-            'nsds5replicaupdateinprogress', 'nsds5replicalastinitend',
-            'nsds5replicaenabled', 'nsds5replicalastinitstart',
-            'nsds5replicalastinitstatus', 'nsds5debugreplicatimeout',
-            'nsds5replicabusywaittime', 'nsds5replicastripattrs',
-            'nsds5replicasessionpausetime', 'nsds5replicaprotocoltimeout',
-            # nsDSWindowsReplicationAgreement
-            'nsds5replicahost', 'nsds5replicaport',
-            'nsds5replicatransportinfo', 'nsds5replicabinddn',
-            'nsds5replicacredentials', 'nsds5replicabindmethod',
-            'nsds5replicaroot', 'nsds5replicatedattributelist',
-            'nsds5replicaupdateschedule', 'nsds5beginreplicarefresh',
-            'description', 'nsds50ruv', 'nsruvreplicalastmodified',
-            'nsds5replicatimeout', 'nsds5replicachangessentsincestartup',
-            'nsds5replicalastupdateend', 'nsds5replicalastupdatestart',
-            'nsds5replicalastupdatestatus', 'nsds5replicaupdateinprogress',
-            'nsds5replicalastinitend', 'nsds5replicalastinitstart',
-            'nsds5replicalastinitstatus', 'nsds5debugreplicatimeout',
-            'nsds5replicabusywaittime', 'nsds5replicasessionpausetime',
-            'nsds7windowsreplicasubtree', 'nsds7directoryreplicasubtree',
-            'nsds7newwinusersyncenabled', 'nsds7newwingroupsyncenabled',
-            'nsds7windowsdomain', 'nsds7dirsynccookie', 'winsyncinterval',
-            'onewaysync', 'winsyncmoveaction', 'nsds5replicaenabled',
-            'winsyncdirectoryfilter', 'winsyncwindowsfilter',
-            'winsyncsubtreepair',
-        },
-        'default_privileges': {'Replication Administrators'},
-    },
     'System: Read DUA Profile': {
         'ipapermlocation': DN('ou=profile', api.env.basedn),
         'ipapermtargetfilter': {
@@ -729,3 +668,68 @@ class update_managed_permissions(Updater):
             raise ValueError(
                 'Unknown key(s) in managed permission template %s: %s' % (
                     name, ', '.join(template.keys())))
+
+
+@register()
+class update_read_replication_agreements_permission(Updater):
+    """'Read replication agreements' permission must not be managed permission
+
+    https://fedorahosted.org/freeipa/ticket/5631
+
+    Existing permission "cn=System: Read Replication Agreements" must be moved
+    to non-managed permission "cn=Read Replication Agreements" using modrdn
+    ldap operation to keep current membership of the permission set by user.
+
+    ACI is updated via update files
+    """
+
+    def execute(self, **options):
+        ldap = self.api.Backend.ldap2
+        old_perm_dn = DN(
+            ('cn', 'System: Read Replication Agreements'),
+            ('cn', 'permissions'),
+            ('cn', 'pbac'),
+            self.api.env.basedn
+        )
+
+        new_perm_dn = DN(
+            ('cn', 'Read Replication Agreements'),
+            ('cn', 'permissions'),
+            ('cn', 'pbac'),
+            self.api.env.basedn
+        )
+
+        try:
+            perm_entry = ldap.get_entry(old_perm_dn)
+        except errors.NotFound:
+            self.log.debug("Old permission not found")
+            return False, ()
+
+        try:
+            ldap.get_entry(new_perm_dn)
+        except errors.NotFound:
+            # we can happily upgrade
+            pass
+        else:
+            self.log.error("Permission '{}' cannot be upgraded. "
+                           "Permission with target name '{}' already "
+                           "exists".format(old_perm_dn, new_perm_dn))
+            return False, ()
+
+        # remove MANAGED permissions related attributes
+        perm_entry['objectclass'] = ['top', 'groupofnames', 'ipapermission']
+        perm_entry['ipapermissiontype'] = ['SYSTEM']
+        perm_entry['ipapermdefaultattr'] = []
+        perm_entry['ipapermright'] = []
+        perm_entry['ipapermbindruletype'] = []
+        perm_entry['ipapermlocation'] = []
+        perm_entry['ipapermtargetfilter'] = []
+
+        self.log.debug("Removing MANAGED attributes from permission %s",
+                       old_perm_dn)
+        ldap.update_entry(perm_entry)
+
+        # do modrdn on permission
+        self.log.debug("modrdn: %s -> %s", old_perm_dn, new_perm_dn)
+        ldap.move_entry(old_perm_dn, new_perm_dn)
+        return False, ()
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to