On 24.02.2016 13:36, Jan Cholasta wrote:
On 24.2.2016 13:07, Martin Basti wrote:


On 24.02.2016 10:45, Jan Cholasta wrote:
On 23.2.2016 17:20, Martin Basti wrote:


On 22.02.2016 09:00, Jan Cholasta wrote:
Hi,

On 17.2.2016 14:49, Martin Basti wrote:
https://fedorahosted.org/freeipa/ticket/5631

Patch attached (for master, 4.3, 4.2)

1) All the replication agreement permission ACIs should be located in
the same entry. Currently "Read Replication Agreements" is in
"cn=config" and everything else in "cn=mapping tree,cn=config", so I
guess "cn=mapping tree,cn=config" makes more sense.


2) Instead of literal DN('cn=permissions,cn=pbac'), use
api.env.container_permissions.


3) IMO the removal of managed permission attributes could be a little
bit more robust. You should check that the original entry contains all
the required values before touching it (objectclass=ipapermissionv2,
ipapermissiontype=V2, ipapermissiontype=MANAGED) and remove only the
values that need to be removed, instead of just overwriting everything.


Honza

Updated patch attached.

The patch does not apply on ipa-4-2.

I will send it later.

Also this bit in replica-acis.ldif is redundant:

+
+dn: cn=mapping tree,cn=config
+changetype: modify
+add: aci
All related ACIs to replication are in both replica-acis.ldif and
20-aci.update.
I just do not want to mess it more than it is.

What I'm trying to say is that:

    dn: cn=mapping tree,cn=config
    changetype: modify
    add: aci
    aci: $ACI1

    dn: cn=mapping tree,cn=config
    changetype: modify
    add: aci
    aci: $ACI2

is the same as:

    dn: cn=mapping tree,cn=config
    changetype: modify
    add: aci
    aci: $ACI1
    aci: $ACI2

. You actually have it right in 20-aci.update, but not in replica-acis.ldif.

I made it in that way to keep consistency in the replica-acis.ldif file.

Patch for 4-2 added


From bf05a9b458c82e4be4273f00610cdaa7569a5036 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                      |   7 +-
 install/updates/90-post_upgrade_plugins.update     |   1 +
 .../install/plugins/update_managed_permissions.py  | 133 +++++++++++----------
 6 files changed, 93 insertions(+), 64 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..7596ca8e7b24ed54e19f78e772df81953f5441e7 100644
--- a/install/share/replica-acis.ldif
+++ b/install/share/replica-acis.ldif
@@ -3,6 +3,11 @@
 dn: cn="$SUFFIX",cn=mapping tree,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
 aci: (targetattr=*)(version 3.0;acl "permission:Add Replication Agreements";allow (add) groupdn = "ldap:///cn=Add Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 
 dn: cn="$SUFFIX",cn=mapping tree,cn=config
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
index cba1897e1fd1136fbcbd7c6ccaf03bfa4b696a44..403ef65aa8d905b80c751225f4221b41fbea5f15 100644
--- a/install/updates/20-aci.update
+++ b/install/updates/20-aci.update
@@ -54,10 +54,15 @@ add:aci:(targetattr="ipaUniqueId || memberOf || enrolledBy || krbExtraData || kr
 dn: cn=tasks,cn=config
 add:aci:(targetattr="*")(version 3.0; acl "Admin can read all tasks"; allow (read, compare, search) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";;)
 
+# replication ACIs should reside in cn=mapping tree,cn=config and be common for both suffixes
+dn: cn=mapping tree,cn=config
+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";)
+
 # Removal of obsolete ACIs
 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
+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";)
 
 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 f0d77138520f41376d71478d3633ea4c19f66195..871472fd9b7e6c3bd79d128f60fc8ac702f7bd38 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -18,6 +18,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..508fd59dc62a57b0dac89cb5cf7f7fbc54c94c2d 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,75 @@ 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'),
+            self.api.env.container_permission,
+            self.api.env.basedn
+        )
+
+        new_perm_dn = DN(
+            ('cn', 'Read Replication Agreements'),
+            self.api.env.container_permission,
+            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, ()
+
+        # values are case insensitive
+        for t in list(perm_entry['ipapermissiontype']):
+            if t.lower() in ['managed', 'v2']:
+                perm_entry['ipapermissiontype'].remove(t)
+
+        for o in list(perm_entry['objectclass']):
+            if o.lower() == 'ipapermissionv2':
+                # remove permission V2 objectclass and related attributes
+                perm_entry['objectclass'].remove(o)
+                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)
+        try:
+            ldap.update_entry(perm_entry)
+        except errors.EmptyModlist:
+            pass
+
+        # 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 4332e5d4b52d13b0d08d57691b77bc892999303b 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                      |   4 +-
 install/updates/90-post_upgrade_plugins.update     |   1 +
 .../install/plugins/update_managed_permissions.py  | 133 +++++++++++----------
 6 files changed, 90 insertions(+), 64 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..fcfe7bd4ab9c362c81108a5c817f956e513ab111 100644
--- a/install/share/replica-acis.ldif
+++ b/install/share/replica-acis.ldif
@@ -3,6 +3,11 @@
 dn: cn=mapping tree,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
 aci: (targetattr=*)(version 3.0;acl "permission:Add Replication Agreements";allow (add) groupdn = "ldap:///cn=Add Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 
 dn: cn=mapping tree,cn=config
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
index 7da48cfd1e2454843beea9fe1d9b18c3cdf1a113..4802ae0458e8b870bf3127764ebabac1a48f7cf2 100644
--- a/install/updates/20-aci.update
+++ b/install/updates/20-aci.update
@@ -72,6 +72,7 @@ dn: cn=mapping tree,cn=config
 add: aci: (targetattr=*)(version 3.0;acl "permission:Add Replication Agreements";allow (add) groupdn = "ldap:///cn=Add Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 add: aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "permission:Modify Replication Agreements"; allow (read, write, search) groupdn = "ldap:///cn=Modify Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
 add: aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "permission:Remove Replication Agreements";allow (delete) groupdn = "ldap:///cn=Remove 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: cn="$SUFFIX",cn=mapping tree,cn=config
 remove:aci: (targetattr=*)(version 3.0;acl "permission:Add Replication Agreements";allow (add) groupdn = "ldap:///cn=Add Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
@@ -86,8 +87,9 @@ remove:aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreemen
 
 # Removal of obsolete ACIs
 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
+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";)
 
 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..36ac5cca891e3307845a3c03df0e239265a5f5f5 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,75 @@ 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'),
+            self.api.env.container_permission,
+            self.api.env.basedn
+        )
+
+        new_perm_dn = DN(
+            ('cn', 'Read Replication Agreements'),
+            self.api.env.container_permission,
+            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, ()
+
+        # values are case insensitive
+        for t in list(perm_entry['ipapermissiontype']):
+            if t.lower() in ['managed', 'v2']:
+                perm_entry['ipapermissiontype'].remove(t)
+
+        for o in list(perm_entry['objectclass']):
+            if o.lower() == 'ipapermissionv2':
+                # remove permission V2 objectclass and related attributes
+                perm_entry['objectclass'].remove(o)
+                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)
+        try:
+            ldap.update_entry(perm_entry)
+        except errors.EmptyModlist:
+            pass
+
+        # 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