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