On 05/22/2014 03:07 PM, Petr Viktorin wrote:
Hello,
Here I start upgrading  the existing default permissions to the new
Managed style.

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

The patches rely on my patch 0551
(https://fedorahosted.org/freeipa/ticket/4349)
You may run into what seems to be a 389 bug. If you get a "Midair
Collision" (NO_SUCH_ATTRIBUTE) error, restart the DS and try running
ipa-ldap-updater again. I'm working with Ludwig on this one.



The operation is now described at
http://www.freeipa.org/page/V4/Managed_Read_permissions#Replacing_legacy_default_permissions


If there user has modified an old default permission, a warning is
logged the replacement permission is not added/updated. The user needs
to evaluate the situation: either update the old permission to match the
original default, or remove the old permission, and then run
ipa-ldap-updater will create the new one.
Is bailing out the right thing to do if the old entry was modified?
It could be possible to parse the permission, figure out the changes the
user made, and apply them to the new one, but that seems like too much
guesswork to me.
On the other hand, my approach has a downside as well: if the
'memberallowcmd' attribute was removed from 'Modify Sudo rule', there's
now no way to upgrade while allowing access but keeping that attribute
off-limits, short of writing deny a ACI by hand. How big a problem is
this? It might be worth it to create a special tool that upgrades a
single permission and allows setting the excluded/included attributes
explicitly.



There are some interesting scenarios to think about with respect to
upgrades and user changes:

* Upgrade to old version, e.g.
   - have IPA 3.2 master, IPA 3.2 replica
   - upgrade master to 4.0 (old permissions are updated)
   - then upgrade replica to 3.3 (old permissions are added again!)

This is AFAIK not supported but it does happen.
We can't change old IPA versions, so any upgrade to a pre-4.0 IPA will
always add the old permissions, but with this patch, a subsequent
upgrade to 4.0+, or running a 4.0+ ipa-ldap-update, will remove the old
permissions again.

Tied to that is another scenario:

* Re-create permissions with old names
   - have IPA 4.0 master
   - Create a permission named 'Modify Sudo rule'
   - Upgrade to IPA 4.1

Here we need to make sure the new permission is *not* removed, because a
new 'Modify Sudo rule' permission is no longer special in any way. To
ensure this the updater only removes old-style permissions.

One thing that can happen when 4.0 masters are still mixed with 3.x is
that an old permission named 'Modify Sudo rule' is added on the old
server. Any update to 4.0+ will remove that.
Old-style default permissions were sorta-kinda managed by IPA itself
anyway, so users should expect this. We should still point it out in the
docs though, since I expect some users to start messing with the
permissions before upgrading all of the infrastructure to 4.0.


The second patch upgrades sudorule permissions, this server as an
example of how the  will work.
The third patch fixes https://fedorahosted.org/freeipa/ticket/4344

The user read permissions patches had a conflict with these; attaching rebased version.


--
Petr³
From 5daa5638fad0161966bb2437a73aba6cec286236 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Wed, 14 May 2014 16:08:28 +0200
Subject: [PATCH] Add mechanism for updating permissions to managed

Part of the work for: https://fedorahosted.org/freeipa/ticket/4346
---
 .../install/plugins/update_managed_permissions.py  | 69 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py
index c9994c77d390a85bfa954231dc8114aeb19709d6..33c892895ef840ce4daafc7e6f4384aef7654577 100644
--- a/ipaserver/install/plugins/update_managed_permissions.py
+++ b/ipaserver/install/plugins/update_managed_permissions.py
@@ -64,6 +64,9 @@
 * non_object
   - If true, no object-specific defaults are used (e.g. for
     ipapermtargetfilter, ipapermlocation).
+* replaces
+  - A list of ACIs corresponding to legacy default permissions replaced
+    by this permission.
 * fixup_function
   - A callable that may modify the template in-place before it is applied.
   - Called with the permission name, template dict, and keyword arguments:
@@ -77,11 +80,13 @@
 """
 
 from ipalib import api, errors
-from ipapython.dn import DN
+from ipalib.aci import ACI
 from ipalib.plugable import Registry
 from ipalib.plugins import aci
-from ipalib.plugins.permission import permission
+from ipalib.plugins.permission import permission, permission_del
 from ipalib.aci import ACI
+from ipapython import ipautil
+from ipapython.dn import DN
 from ipaserver.plugins.ldap2 import ldap2
 from ipaserver.install.plugins import LAST
 from ipaserver.install.plugins.baseupdate import PostUpdate
@@ -228,6 +233,17 @@
 }
 
 
+def get_aci_names(acistrs):
+    names = []
+    for acistr in acistrs:
+        aci = ACI(acistr)
+        prefix, sep, name = aci.name.partition(':')
+        assert prefix == 'permission'
+        assert sep
+        names.append(name)
+    return names
+
+
 @register()
 class update_managed_permissions(PostUpdate):
     """Update managed permissions after an update.
@@ -302,9 +318,10 @@ def update_permission(self, ldap, obj, name, template, anonymous_read_aci):
         assert name.startswith('System:')
 
         dn = self.api.Object[permission].get_dn(name)
+        permission_plugin = self.api.Object[permission]
 
         try:
-            attrs_list = list(self.api.Object[permission].default_attributes)
+            attrs_list = list(permission_plugin.default_attributes)
             attrs_list.remove('memberindirect')
             entry = ldap.get_entry(dn, attrs_list)
             is_new = False
@@ -312,10 +329,42 @@ def update_permission(self, ldap, obj, name, template, anonymous_read_aci):
             entry = ldap.make_entry(dn)
             is_new = True
 
-        self.log.debug('Updating managed permission: %s', name)
         self.update_entry(obj, entry, template,
                           anonymous_read_aci, is_new=is_new)
 
+        remove_legacy = False
+        if 'replaces' in template:
+            sub_dict = {
+                'SUFFIX': str(self.api.env.basedn),
+            }
+            legacy_acistrs = [ipautil.template_str(r, sub_dict)
+                              for r in template['replaces']]
+
+            legacy_names = get_aci_names(legacy_acistrs)
+            legacy_name = legacy_names[0]
+            assert all(legacy_name == n for n in legacy_names[1:])
+
+            legacy_dn = permission_plugin.get_dn(legacy_name)
+            try:
+                legacy_entry = ldap.get_entry(legacy_dn,
+                                              ['ipapermissiontype', 'cn'])
+            except errors.NotFound:
+                pass
+            else:
+                if 'ipapermissiontype' not in legacy_entry:
+                    acientry, acistr = permission_plugin._get_aci_entry_and_string(
+                        legacy_entry, notfound_ok=True)
+                    if acistr is None or any(acistr == s for s in legacy_acistrs):
+                        remove_legacy = True
+                    else:
+                        self.log.warning(
+                            "Permission '%s' has been modified; "
+                            "not replacing it by '%s'.",
+                            legacy_name, name)
+                        return
+
+        update_aci = True
+        self.log.debug('Updating managed permission: %s', name)
         if is_new:
             ldap.add_entry(entry)
         else:
@@ -323,11 +372,16 @@ def update_permission(self, ldap, obj, name, template, anonymous_read_aci):
                 ldap.update_entry(entry)
             except errors.EmptyModlist:
                 self.log.debug('No changes to permission: %s', name)
-                return
+                update_aci = False
 
-        self.log.debug('Updating ACI for managed permission: %s', name)
+        if update_aci:
+            self.log.debug('Updating ACI for managed permission: %s', name)
+            permission_plugin.update_aci(entry)
+
+        if remove_legacy:
+            self.log.info("Removing legacy permission '%s'", legacy_name)
+            self.api.Command[permission_del](unicode(legacy_name))
 
-        self.api.Object[permission].update_aci(entry)
 
     def update_entry(self, obj, entry, template,
                      anonymous_read_aci, is_new):
@@ -339,6 +393,7 @@ def update_entry(self, obj, entry, template,
         entry.single_value['cn'] = name
 
         template = dict(template)
+        template.pop('replaces', None)
 
         fixup_function = template.pop('fixup_function', None)
         if fixup_function:
-- 
1.9.0

From d8cc918345fd0c21ae16bd305e6499180286cfd4 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Wed, 14 May 2014 14:57:35 +0200
Subject: [PATCH] Convert Sudo rule default permissions to managed

Part of the work for: https://fedorahosted.org/freeipa/ticket/4346
---
 install/updates/40-delegation.update | 25 ---------------------
 ipalib/plugins/sudorule.py           | 43 +++++++++++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
index 7f0f85124686fde97f35cca6dbb80614faf431d0..3f3b98799acfc7c5ae7218c3de682db35b815d2e 100644
--- a/install/updates/40-delegation.update
+++ b/install/updates/40-delegation.update
@@ -108,27 +108,6 @@ dn: cn=Sudo Administrator,cn=privileges,cn=pbac,$SUFFIX
 default:cn: Sudo Administrator
 default:description: Sudo Administrator
 
-dn: cn=Add Sudo rule,cn=permissions,cn=pbac,$SUFFIX
-default:objectClass: groupofnames
-default:objectClass: ipapermission
-default:objectClass: top
-default:cn: Add Sudo rule
-default:member: cn=Sudo Administrator,cn=privileges,cn=pbac,$SUFFIX
-
-dn: cn=Delete Sudo rule,cn=permissions,cn=pbac,$SUFFIX
-default:objectClass: groupofnames
-default:objectClass: ipapermission
-default:objectClass: top
-default:cn: Delete Sudo rule
-default:member: cn=Sudo Administrator,cn=privileges,cn=pbac,$SUFFIX
-
-dn: cn=Modify Sudo rule,cn=permissions,cn=pbac,$SUFFIX
-default:objectClass: groupofnames
-default:objectClass: ipapermission
-default:objectClass: top
-default:cn: Modify Sudo rule
-default:member: cn=Sudo Administrator,cn=privileges,cn=pbac,$SUFFIX
-
 dn: cn=Add Sudo command,cn=permissions,cn=pbac,$SUFFIX
 default:objectClass: groupofnames
 default:objectClass: ipapermission
@@ -172,10 +151,6 @@ dn: cn=Manage Sudo command group membership,cn=permissions,cn=pbac,$SUFFIX
 default:member: cn=Sudo Administrator,cn=privileges,cn=pbac,$SUFFIX
 
 dn: $SUFFIX
-add:aci: '(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Add Sudo rule";allow (add) groupdn = "ldap:///cn=Add Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)'
-add:aci: '(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Delete Sudo rule";allow (delete) groupdn = "ldap:///cn=Delete Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)'
-add:aci: '(targetattr = "description || ipaenabledflag || usercategory || hostcategory || cmdcategory || ipasudorunasusercategory || ipasudorunasgroupcategory || externaluser || ipasudorunasextuser || ipasudorunasextgroup || memberdenycmd || memberallowcmd || memberuser")(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Modify Sudo rule";allow (write) groupdn = "ldap:///cn=Modify Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)'
-
 remove:aci: '(targetattr = "description")(target = "ldap:///sudocmd=*,cn=sudocmds,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Modify Sudo command";allow (write) groupdn = "ldap:///cn=Modify Sudo command,cn=permissions,cn=pbac,$SUFFIX";)'
 remove:aci: '(target = "ldap:///sudocmd=*,cn=sudocmds,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Delete Sudo command";allow (delete) groupdn = "ldap:///cn=Delete Sudo command,cn=permissions,cn=pbac,$SUFFIX";)'
 remove:aci: '(target = "ldap:///sudocmd=*,cn=sudocmds,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Add Sudo command";allow (add) groupdn = "ldap:///cn=Add Sudo command,cn=permissions,cn=pbac,$SUFFIX";)'
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index 627b4b975f6336658eb74d37b4c15d803511c5d4..b5f97cca83a5a52e2be0e66f5fc76e097a64e369 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -144,7 +144,48 @@ class sudorule(LDAPObject):
                 'sudorunasuser', 'sudorunasgroup', 'sudooption',
                 'sudonotbefore', 'sudonotafter', 'sudoorder', 'description',
             },
-        }
+        },
+        'System: Add Sudo rule': {
+            'ipapermbindruletype': 'permission',
+            'ipapermright': {'add'},
+            'ipapermdefaultattr': {
+                'cmdcategory', 'cn', 'description', 'externalhost',
+                'externaluser', 'hostcategory', 'hostmask', 'ipaenabledflag',
+                'ipasudoopt', 'ipasudorunas', 'ipasudorunasextgroup',
+                'ipasudorunasextuser', 'ipasudorunasgroup',
+                'ipasudorunasgroupcategory', 'ipasudorunasusercategory',
+                'ipauniqueid', 'memberallowcmd', 'memberdenycmd',
+                'memberhost', 'memberuser', 'sudonotafter', 'sudonotbefore',
+                'sudoorder', 'usercategory', 'objectclass',
+            },
+            'replaces': [
+                '(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Add Sudo rule";allow (add) groupdn = "ldap:///cn=Add Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)',
+            ],
+            'default_privileges': {'Sudo Administrator'},
+        },
+        'System: Delete Sudo rule': {
+            'ipapermbindruletype': 'permission',
+            'ipapermright': {'delete'},
+            'replaces': [
+                '(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Delete Sudo rule";allow (delete) groupdn = "ldap:///cn=Delete Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)',
+            ],
+            'default_privileges': {'Sudo Administrator'},
+        },
+        'System: Modify Sudo rule': {
+            'ipapermbindruletype': 'permission',
+            'ipapermright': {'add'},
+            'ipapermdefaultattr': {
+                'description', 'ipaenabledflag', 'usercategory',
+                'hostcategory', 'cmdcategory', 'ipasudorunasusercategory',
+                'ipasudorunasgroupcategory', 'externaluser',
+                'ipasudorunasextuser', 'ipasudorunasextgroup', 'memberdenycmd',
+                'memberallowcmd', 'memberuser',
+            },
+            'replaces': [
+                '(targetattr = "description || ipaenabledflag || usercategory || hostcategory || cmdcategory || ipasudorunasusercategory || ipasudorunasgroupcategory || externaluser || ipasudorunasextuser || ipasudorunasextgroup || memberdenycmd || memberallowcmd || memberuser")(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Modify Sudo rule";allow (write) groupdn = "ldap:///cn=Modify Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)',
+            ],
+            'default_privileges': {'Sudo Administrator'},
+        },
     }
 
     label = _('Sudo Rules')
-- 
1.9.0

From 962d930caa52024427928f0509a162f1f8cf72db Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Wed, 14 May 2014 15:10:10 +0200
Subject: [PATCH] Add missing attributes to 'Modify Sudo rule' permission

https://fedorahosted.org/freeipa/ticket/4344
---
 ipalib/plugins/sudorule.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index b5f97cca83a5a52e2be0e66f5fc76e097a64e369..17fe915c383810cf05e94bfb0d7765d9c5c0785e 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -179,7 +179,10 @@ class sudorule(LDAPObject):
                 'hostcategory', 'cmdcategory', 'ipasudorunasusercategory',
                 'ipasudorunasgroupcategory', 'externaluser',
                 'ipasudorunasextuser', 'ipasudorunasextgroup', 'memberdenycmd',
-                'memberallowcmd', 'memberuser',
+                'memberallowcmd', 'memberuser', 'memberhost', 'externalhost',
+                'sudonotafter', 'hostmask', 'sudoorder', 'sudonotbefore',
+                'ipasudorunas', 'externalhost', 'ipasudorunasgroup',
+                'ipasudoopt', 'memberhost',
             },
             'replaces': [
                 '(targetattr = "description || ipaenabledflag || usercategory || hostcategory || cmdcategory || ipasudorunasusercategory || ipasudorunasgroupcategory || externaluser || ipasudorunasextuser || ipasudorunasextgroup || memberdenycmd || memberallowcmd || memberuser")(target = "ldap:///ipauniqueid=*,cn=sudorules,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Modify Sudo rule";allow (write) groupdn = "ldap:///cn=Modify Sudo rule,cn=permissions,cn=pbac,$SUFFIX";)',
-- 
1.9.0

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to