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

The first two patches are rebased from what I sent back in March; the third fixes ACIs using targetfilter.

--
PetrĀ³

From 2abc32b6fecd4836f529a213857b8146e86e6ca8 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Thu, 8 Mar 2012 07:55:00 -0500
Subject: [PATCH] Use ipauniqueid for the RDN of sudo commands

Since sudo commands are case-sensitive, we can't use the CN
as the RDN.

Tests for case-sensitive behavior included

https://fedorahosted.org/freeipa/ticket/2482
---
 ipalib/plugins/sudocmd.py                     |    1 +
 tests/test_xmlrpc/test_sudocmd_plugin.py      |   79 ++++++++++++++++++++---
 tests/test_xmlrpc/test_sudocmdgroup_plugin.py |   85 +++++++++++++++++++++----
 tests/test_xmlrpc/xmlrpc_test.py              |   13 +++-
 4 files changed, 152 insertions(+), 26 deletions(-)

diff --git a/ipalib/plugins/sudocmd.py b/ipalib/plugins/sudocmd.py
index 42068edea3c51804be9ee5919934462afbee578f..f27a58cadd6e6abc16611621387f26125737bf78 100644
--- a/ipalib/plugins/sudocmd.py
+++ b/ipalib/plugins/sudocmd.py
@@ -62,6 +62,7 @@ class sudocmd(LDAPObject):
         'memberof': ['sudocmdgroup'],
     }
     uuid_attribute = 'ipauniqueid'
+    rdn_attribute = 'ipauniqueid'
     label = _('Sudo Commands')
     label_singular = _('Sudo Command')
 
diff --git a/tests/test_xmlrpc/test_sudocmd_plugin.py b/tests/test_xmlrpc/test_sudocmd_plugin.py
index 75b6bbccbb47cc03f4408b791c687f3880bb934a..dc69d17a200c9a8f9dafbaf65508826f5eb0b62b 100644
--- a/tests/test_xmlrpc/test_sudocmd_plugin.py
+++ b/tests/test_xmlrpc/test_sudocmd_plugin.py
@@ -22,17 +22,20 @@ Test the `ipalib/plugins/sudocmd.py` module.
 """
 
 from ipalib import api, errors
-from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid
+from tests.test_xmlrpc.xmlrpc_test import (Declarative, fuzzy_sudocmddn,
+    fuzzy_uuid)
 from tests.test_xmlrpc import objectclasses
 from ipapython.dn import DN
 
 sudocmd1 = u'/usr/bin/sudotestcmd1'
+sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1'
 
 
 class test_sudocmd(Declarative):
 
     cleanup_commands = [
         ('sudocmd_del', [sudocmd1], {}),
+        ('sudocmd_del', [sudocmd1_camelcase], {}),
     ]
 
     tests = [
@@ -72,16 +75,35 @@ class test_sudocmd(Declarative):
                 value=sudocmd1,
                 summary=u'Added Sudo Command "%s"' % sudocmd1,
                 result=dict(
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                     sudocmd=[sudocmd1],
                     description=[u'Test sudo command 1'],
                     objectclass=objectclasses.sudocmd,
                     ipauniqueid=[fuzzy_uuid],
                 ),
             ),
         ),
 
+        dict(
+            desc='Create %r' % sudocmd1_camelcase,
+            command=('sudocmd_add', [sudocmd1_camelcase],
+                dict(
+                    description=u'Test sudo command 2',
+                ),
+            ),
+            expected=dict(
+                value=sudocmd1_camelcase,
+                summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase,
+                result=dict(
+                    dn=fuzzy_sudocmddn,
+                    sudocmd=[sudocmd1_camelcase],
+                    description=[u'Test sudo command 2'],
+                    objectclass=objectclasses.sudocmd,
+                    ipauniqueid=[fuzzy_uuid],
+                ),
+            ),
+        ),
+
 
         dict(
             desc='Try to create duplicate %r' % sudocmd1,
@@ -94,16 +116,26 @@ class test_sudocmd(Declarative):
                 u'name "%s" already exists' % sudocmd1),
         ),
 
+        dict(
+            desc='Try to create duplicate %r' % sudocmd1_camelcase,
+            command=('sudocmd_add', [sudocmd1_camelcase],
+                dict(
+                    description=u'Test sudo command 2',
+                ),
+            ),
+            expected=errors.DuplicateEntry(message=u'sudo command with ' +
+                u'name "%s" already exists' % sudocmd1_camelcase),
+        ),
+
 
         dict(
             desc='Retrieve %r' % sudocmd1,
             command=('sudocmd_show', [sudocmd1], {}),
             expected=dict(
                 value=sudocmd1,
                 summary=None,
                 result=dict(
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                     sudocmd=[sudocmd1],
                     description=[u'Test sudo command 1'],
                 ),
@@ -120,15 +152,31 @@ class test_sudocmd(Declarative):
                 summary=u'1 Sudo Command matched',
                 result=[
                     dict(
-                        dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),
-                              ('cn','sudo'),api.env.basedn),
+                        dn=fuzzy_sudocmddn,
                         sudocmd=[sudocmd1],
                         description=[u'Test sudo command 1'],
                     ),
                 ],
             ),
         ),
 
+        dict(
+            desc='Search for %r' % sudocmd1_camelcase,
+            command=('sudocmd_find', [sudocmd1_camelcase], {}),
+            expected=dict(
+                count=1,
+                truncated=False,
+                summary=u'1 Sudo Command matched',
+                result=[
+                    dict(
+                        dn=fuzzy_sudocmddn,
+                        sudocmd=[sudocmd1_camelcase],
+                        description=[u'Test sudo command 2'],
+                    ),
+                ],
+            ),
+        ),
+
 
         dict(
             desc='Update %r' % sudocmd1,
@@ -152,8 +200,7 @@ class test_sudocmd(Declarative):
                 value=sudocmd1,
                 summary=None,
                 result=dict(
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                     sudocmd=[sudocmd1],
                     description=[u'Updated sudo command 1'],
                 ),
@@ -194,4 +241,18 @@ class test_sudocmd(Declarative):
             expected=errors.NotFound(
                 reason=u'%s: sudo command not found' % sudocmd1),
         ),
+
+        dict(
+            desc='Retrieve %r' % sudocmd1_camelcase,
+            command=('sudocmd_show', [sudocmd1_camelcase], {}),
+            expected=dict(
+                value=sudocmd1_camelcase,
+                summary=None,
+                result=dict(
+                    dn=fuzzy_sudocmddn,
+                    sudocmd=[sudocmd1_camelcase],
+                    description=[u'Test sudo command 2'],
+                ),
+            ),
+        ),
     ]
diff --git a/tests/test_xmlrpc/test_sudocmdgroup_plugin.py b/tests/test_xmlrpc/test_sudocmdgroup_plugin.py
index b8c15737d5bc486219749b632ed7bae408048b61..7d688dc3281b535dec419889e38c9ae8af688876 100644
--- a/tests/test_xmlrpc/test_sudocmdgroup_plugin.py
+++ b/tests/test_xmlrpc/test_sudocmdgroup_plugin.py
@@ -22,12 +22,13 @@ Test the `ipalib/plugins/sudocmdgroup.py` module.
 
 from ipalib import api, errors
 from tests.test_xmlrpc import objectclasses
-from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
+from xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_sudocmddn
 from ipapython.dn import DN
 
 sudocmdgroup1 = u'testsudocmdgroup1'
 sudocmdgroup2 = u'testsudocmdgroup2'
 sudocmd1 = u'/usr/bin/sudotestcmd1'
+sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1'
 sudocmd_plus = u'/bin/ls -l /lost+found/*'
 
 def create_command(sudocmd):
@@ -43,19 +44,18 @@ def create_command(sudocmd):
             result=dict(
                 objectclass=objectclasses.sudocmd,
                 sudocmd=[sudocmd],
-                ipauniqueid=[fuzzy_uuid],
-                description=[u'Test sudo command'],
-                dn=DN(('sudocmd',sudocmd),('cn','sudocmds'),('cn','sudo'),
-                      api.env.basedn),
+                ipauniqueid=[fuzzy_uuid], description=[u'Test sudo command'],
+                dn=fuzzy_sudocmddn,
             ),
         ),
     )
 
 class test_sudocmdgroup(Declarative):
     cleanup_commands = [
         ('sudocmdgroup_del', [sudocmdgroup1], {}),
         ('sudocmdgroup_del', [sudocmdgroup2], {}),
         ('sudocmd_del', [sudocmd1], {}),
+        ('sudocmd_del', [sudocmd1_camelcase], {}),
         ('sudocmd_del', [sudocmd_plus], {}),
     ]
 
@@ -76,12 +76,28 @@ class test_sudocmdgroup(Declarative):
                     sudocmd=[u'/usr/bin/sudotestcmd1'],
                     ipauniqueid=[fuzzy_uuid],
                     description=[u'Test sudo command 1'],
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                 ),
             ),
         ),
 
+        dict(
+            desc='Create %r' % sudocmd1_camelcase,
+            command=(
+                'sudocmd_add', [], dict(sudocmd=sudocmd1_camelcase, description=u'Test sudo command 2')
+            ),
+            expected=dict(
+                value=sudocmd1_camelcase,
+                summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase,
+                result=dict(
+                    objectclass=objectclasses.sudocmd,
+                    sudocmd=[u'/usr/bin/sudoTestCmd1'],
+                    ipauniqueid=[fuzzy_uuid],
+                    description=[u'Test sudo command 2'],
+                    dn=fuzzy_sudocmddn,
+                ),
+            ),
+        ),
 
         dict(
             desc='Verify the managed sudo command %r was created' % sudocmd1,
@@ -92,8 +108,7 @@ class test_sudocmdgroup(Declarative):
                 result=dict(
                     sudocmd=[sudocmd1],
                     description=[u'Test sudo command 1'],
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                 ),
             ),
         ),
@@ -413,11 +428,10 @@ class test_sudocmdgroup(Declarative):
                 value=sudocmd1,
                 summary=None,
                 result=dict(
-                    dn=DN(('sudocmd',sudocmd1),('cn','sudocmds'),('cn','sudo'),
-                          api.env.basedn),
+                    dn=fuzzy_sudocmddn,
                     sudocmd=[sudocmd1],
                     description=[u'Test sudo command 1'],
-                    memberof_sudocmdgroup = [u'testsudocmdgroup1'],
+                    memberof_sudocmdgroup=[u'testsudocmdgroup1'],
                 ),
             ),
         ),
@@ -446,6 +460,29 @@ class test_sudocmdgroup(Declarative):
         ),
 
         dict(
+            desc='Add member %r to %r' % (sudocmd1_camelcase, sudocmdgroup1),
+            command=(
+                'sudocmdgroup_add_member', [sudocmdgroup1],
+                dict(sudocmd=sudocmd1_camelcase)
+            ),
+            expected=dict(
+                completed=1,
+                failed=dict(
+                    member=dict(
+                        sudocmd=tuple(),
+                    ),
+                ),
+                result={
+                        'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'),
+                               ('cn','sudo'),api.env.basedn),
+                        'member_sudocmd': (sudocmd1, sudocmd1_camelcase),
+                        'cn': [sudocmdgroup1],
+                        'description': [u'New desc 1'],
+                },
+            ),
+        ),
+
+        dict(
             desc='Remove member %r from %r' % (sudocmd1, sudocmdgroup1),
             command=('sudocmdgroup_remove_member',
                 [sudocmdgroup1], dict(sudocmd=sudocmd1)
@@ -459,7 +496,29 @@ class test_sudocmdgroup(Declarative):
                 ),
                 result={
                     'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'),
-                             ('cn','sudo'),api.env.basedn),
+                           ('cn','sudo'),api.env.basedn),
+                    'member_sudocmd': (sudocmd1_camelcase,),
+                    'cn': [sudocmdgroup1],
+                    'description': [u'New desc 1'],
+                },
+            ),
+        ),
+
+        dict(
+            desc='Remove member %r from %r' % (sudocmd1_camelcase, sudocmdgroup1),
+            command=('sudocmdgroup_remove_member',
+                [sudocmdgroup1], dict(sudocmd=sudocmd1_camelcase)
+            ),
+            expected=dict(
+                completed=1,
+                failed=dict(
+                    member=dict(
+                        sudocmd=tuple(),
+                    ),
+                ),
+                result={
+                    'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'),
+                           ('cn','sudo'),api.env.basedn),
                     'cn': [sudocmdgroup1],
                     'description': [u'New desc 1'],
                 },
diff --git a/tests/test_xmlrpc/xmlrpc_test.py b/tests/test_xmlrpc/xmlrpc_test.py
index 7c32be0db31d69373f988a2bb1ec7171679b36ae..03596e85ad1b1fc81e3b8980bdeed17475815ce0 100644
--- a/tests/test_xmlrpc/xmlrpc_test.py
+++ b/tests/test_xmlrpc/xmlrpc_test.py
@@ -35,14 +35,19 @@ from ipalib.x509 import valid_issuer
 # or `long`?  If not, we still need to return them as `unicode` instead of `str`.
 fuzzy_digits = Fuzzy('^\d+$', type=basestring)
 
+uuid_re = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
+
 # Matches an ipauniqueid like u'784d85fd-eae7-11de-9d01-54520012478b'
-fuzzy_uuid = Fuzzy(
-    '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
-)
+fuzzy_uuid = Fuzzy('^%s$' % uuid_re)
 
 # Matches netgroup dn. Note (?i) at the beginning of the regexp is the ingnore case flag
 fuzzy_netgroupdn = Fuzzy(
-    '(?i)ipauniqueid=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12},cn=ng,cn=alt,%s' % api.env.basedn
+    '(?i)ipauniqueid=%s,cn=ng,cn=alt,%s' % (uuid_re, api.env.basedn)
+)
+
+# Matches sudocmd dn
+fuzzy_sudocmddn = Fuzzy(
+    '(?i)ipauniqueid=%s,cn=sudocmds,cn=sudo,%s' % (uuid_re, api.env.basedn)
 )
 
 # Matches a hash signature, not enforcing length
-- 
1.7.7.6

From 3a6912e767bd7534e5d3ecc791dd2754c8d3474d Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 13 Mar 2012 08:37:24 -0400
Subject: [PATCH] Prevent a sudo command from being deleted if it is a member
 of a sudo rule.

Tests included.
---
 ipalib/plugins/sudocmd.py                 |   19 ++++++++
 tests/test_xmlrpc/test_sudocmd_plugin.py  |   70 +++++++++++++++++++++++++++++
 tests/test_xmlrpc/test_sudorule_plugin.py |    2 +
 3 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/ipalib/plugins/sudocmd.py b/ipalib/plugins/sudocmd.py
index f27a58cadd6e6abc16611621387f26125737bf78..3e00d16f5fe29a3549bd966f62ac7e41f669be7d 100644
--- a/ipalib/plugins/sudocmd.py
+++ b/ipalib/plugins/sudocmd.py
@@ -109,6 +109,25 @@ class sudocmd_del(LDAPDelete):
 
     msg_summary = _('Deleted Sudo Command "%(value)s"')
 
+    def pre_callback(self, ldap, dn, *keys, **options):
+        dependent_sudorules = []
+        for attr in ('memberallowcmd', 'memberdenycmd'):
+            search_kw = {attr: dn, 'objectClass': 'ipasudorule'}
+            filter = ldap.make_filter(search_kw, rules=ldap.MATCH_ALL)
+            try:
+                entries, truncated = ldap.find_entries(filter, ['cn'])
+            except errors.NotFound:
+                pass
+            else:
+                for entry_dn, entry_attrs in entries:
+                    [cn] = entry_attrs['cn']
+                    dependent_sudorules.append(cn)
+
+        if dependent_sudorules:
+            raise errors.DependentEntry(key=keys[0], label='sudorule',
+                dependent=', '.join(dependent_sudorules))
+        return dn
+
 api.register(sudocmd_del)
 
 class sudocmd_mod(LDAPUpdate):
diff --git a/tests/test_xmlrpc/test_sudocmd_plugin.py b/tests/test_xmlrpc/test_sudocmd_plugin.py
index dc69d17a200c9a8f9dafbaf65508826f5eb0b62b..b2b23cb9cb220f8a0e6cd60a68f852ef5002a2f9 100644
--- a/tests/test_xmlrpc/test_sudocmd_plugin.py
+++ b/tests/test_xmlrpc/test_sudocmd_plugin.py
@@ -30,12 +30,15 @@ from ipapython.dn import DN
 sudocmd1 = u'/usr/bin/sudotestcmd1'
 sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1'
 
+sudorule1 = u'test_sudorule1'
+
 
 class test_sudocmd(Declarative):
 
     cleanup_commands = [
         ('sudocmd_del', [sudocmd1], {}),
         ('sudocmd_del', [sudocmd1_camelcase], {}),
+        ('sudorule_del', [sudorule1], {}),
     ]
 
     tests = [
@@ -207,6 +210,73 @@ class test_sudocmd(Declarative):
             ),
         ),
 
+        dict(
+            desc='Create %r' % sudorule1,
+            command=('sudorule_add', [sudorule1], {}),
+            expected=lambda e, result: True,
+        ),
+
+        dict(
+            desc='Add %r to %r allow list' % (sudocmd1, sudorule1),
+            command=('sudorule_add_allow_command', [sudorule1],
+                dict(sudocmd=sudocmd1)),
+            expected=dict(
+                    completed=1,
+                    failed=dict(
+                        memberallowcmd=dict(sudocmdgroup=(), sudocmd=())),
+                    result=lambda result: True,
+                ),
+        ),
+
+        dict(
+            desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1),
+            command=('sudocmd_del', [sudocmd1], {}),
+            expected=errors.DependentEntry(key=sudocmd1, label='sudorule',
+                dependent=sudorule1),
+        ),
+
+        dict(
+            desc='Remove %r from %r' % (sudocmd1, sudorule1),
+            command=('sudorule_remove_allow_command', [sudorule1],
+                dict(sudocmd=sudocmd1)),
+            expected=dict(
+                    completed=1,
+                    failed=dict(
+                        memberallowcmd=dict(sudocmdgroup=(), sudocmd=())),
+                    result=lambda result: True,
+                ),
+        ),
+
+        dict(
+            desc='Add %r to %r deny list' % (sudocmd1, sudorule1),
+            command=('sudorule_add_deny_command', [sudorule1],
+                dict(sudocmd=sudocmd1)),
+            expected=dict(
+                    completed=1,
+                    failed=dict(
+                        memberdenycmd=dict(sudocmdgroup=(), sudocmd=())),
+                    result=lambda result: True,
+                ),
+        ),
+
+        dict(
+            desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1),
+            command=('sudocmd_del', [sudocmd1], {}),
+            expected=errors.DependentEntry(key=sudocmd1, label='sudorule',
+                dependent=sudorule1),
+        ),
+
+        dict(
+            desc='Remove %r from %r' % (sudocmd1, sudorule1),
+            command=('sudorule_remove_deny_command', [sudorule1],
+                dict(sudocmd=sudocmd1)),
+            expected=dict(
+                    completed=1,
+                    failed=dict(
+                        memberdenycmd=dict(sudocmdgroup=(), sudocmd=())),
+                    result=lambda result: True,
+                ),
+        ),
 
         dict(
             desc='Delete %r' % sudocmd1,
diff --git a/tests/test_xmlrpc/test_sudorule_plugin.py b/tests/test_xmlrpc/test_sudorule_plugin.py
index 9b44065af22fd49a64e30adc73836b4c5a6f931d..ec5d16d62cc38b0d9ef439de96267dda88525fa8 100644
--- a/tests/test_xmlrpc/test_sudorule_plugin.py
+++ b/tests/test_xmlrpc/test_sudorule_plugin.py
@@ -718,6 +718,8 @@ class test_sudorule(XMLRPC_test):
         api.Command['group_del'](self.test_group)
         api.Command['host_del'](self.test_host)
         api.Command['hostgroup_del'](self.test_hostgroup)
+        api.Command['sudorule_remove_allow_command'](self.rule_name,
+                                                     sudocmd=self.test_command)
         api.Command['sudocmd_del'](self.test_command)
         api.Command['sudocmdgroup_del'](self.test_sudoallowcmdgroup)
         api.Command['sudocmdgroup_del'](self.test_sudodenycmdgroup)
-- 
1.7.7.6

From d98fe0fde533a95d5917f1921093250e0eb1c93f Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 13 Mar 2012 08:37:24 -0400
Subject: [PATCH] Update sudocmd ACIs to use targetfilter

Sudo commands created in the past have the CN in their RDN, while the new
case-sensitive ones have ipaUniqueID. In order for permissions to apply
to both of these, use a targetfilter for objectclass=ipasudocmd instead
of sudocmd=* in the target.
---
 install/updates/40-delegation.update |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
index 1e512d0f7ce085f9d16e03b091b6ea5b2b28b453..5c14a703655e5de0c3b6a13e5b1a69a40ebfc13b 100644
--- a/install/updates/40-delegation.update
+++ b/install/updates/40-delegation.update
@@ -175,9 +175,14 @@ 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";)'
-add: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";)'
-add: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";)'
-add: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";)'
+
+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";)'
+add:aci: '(targetfilter = "(objectclass=ipasudocmd)")(targetattr = "description")(target = "ldap:///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";)'
+add:aci: '(targetfilter = "(objectclass=ipasudocmd)")(target = "ldap:///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";)'
+add:aci: '(targetfilter = "(objectclass=ipasudocmd)")(target = "ldap:///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";)'
+
 add:aci: '(target = "ldap:///cn=*,cn=sudocmdgroups,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Add Sudo command group";allow (add) groupdn = "ldap:///cn=Add Sudo command group,cn=permissions,cn=pbac,$SUFFIX";)'
 add:aci: '(target = "ldap:///cn=*,cn=sudocmdgroups,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Delete Sudo command group";allow (delete) groupdn = "ldap:///cn=Delete Sudo command group,cn=permissions,cn=pbac,$SUFFIX";)'
 add:aci: '(targetattr = "member")(target = "ldap:///cn=*,cn=sudocmdgroups,cn=sudo,$SUFFIX";)(version 3.0;acl "permission:Manage Sudo command group membership";allow (write) groupdn = "ldap:///cn=Manage Sudo command group membership,cn=permissions,cn=pbac,$SUFFIX";)'
-- 
1.7.7.6

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

Reply via email to