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.
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