diff options
author | Petr Viktorin <pviktori@redhat.com> | 2013-10-29 17:01:07 +0100 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2014-01-07 09:56:41 +0100 |
commit | 4a64a1f18bd51c65bf34a13fd7541e1d6b4b75fd (patch) | |
tree | 8cc1db4e9b3e1b77f25b36ad5c58a1b37d94fea7 | |
parent | d7f5d58d352f31df144de15976bd06c5aa822210 (diff) | |
download | freeipa-4a64a1f18bd51c65bf34a13fd7541e1d6b4b75fd.tar.gz freeipa-4a64a1f18bd51c65bf34a13fd7541e1d6b4b75fd.tar.xz freeipa-4a64a1f18bd51c65bf34a13fd7541e1d6b4b75fd.zip |
Allow anonymous and all permissions
Disallow adding permissions with non-default bindtype to privileges
Ticket: https://fedorahosted.org/freeipa/ticket/4032
Design: http://www.freeipa.org/page/V3/Anonymous_and_All_permissions
-rw-r--r-- | API.txt | 6 | ||||
-rw-r--r-- | ipalib/plugins/permission.py | 9 | ||||
-rw-r--r-- | ipalib/plugins/privilege.py | 33 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/test_permission_plugin.py | 282 |
4 files changed, 325 insertions, 5 deletions
@@ -2329,7 +2329,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui option: Str('attrs', attribute=False, cli_name='attrs', multivalue=True, required=False) option: Str('filter', attribute=False, cli_name='filter', multivalue=True, required=False) option: Str('ipapermallowedattr', attribute=True, cli_name='attrs', multivalue=True, required=False) -option: StrEnum('ipapermbindruletype', attribute=True, autofill=True, cli_name='bindtype', default=u'permission', multivalue=False, required=True, values=(u'permission',)) +option: StrEnum('ipapermbindruletype', attribute=True, autofill=True, cli_name='bindtype', default=u'permission', multivalue=False, required=True, values=(u'permission', u'all', u'anonymous')) option: DNOrURL('ipapermlocation', alwaysask=True, attribute=True, autofill=False, cli_name='subtree', multivalue=False, query=False, required=False) option: StrEnum('ipapermright', attribute=True, cli_name='permissions', multivalue=True, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, cli_name='target', multivalue=False, required=False) @@ -2385,7 +2385,7 @@ option: Str('attrs', attribute=False, autofill=False, cli_name='attrs', multival option: Str('cn', attribute=True, autofill=False, cli_name='name', multivalue=False, pattern='^[-_ a-zA-Z0-9.]+$', primary_key=True, query=True, required=False) option: Str('filter', attribute=False, autofill=False, cli_name='filter', multivalue=True, query=True, required=False) option: Str('ipapermallowedattr', attribute=True, autofill=False, cli_name='attrs', multivalue=True, query=True, required=False) -option: StrEnum('ipapermbindruletype', attribute=True, autofill=False, cli_name='bindtype', default=u'permission', multivalue=False, query=True, required=False, values=(u'permission',)) +option: StrEnum('ipapermbindruletype', attribute=True, autofill=False, cli_name='bindtype', default=u'permission', multivalue=False, query=True, required=False, values=(u'permission', u'all', u'anonymous')) option: DNOrURL('ipapermlocation', attribute=True, autofill=False, cli_name='subtree', multivalue=False, query=True, required=False) option: StrEnum('ipapermright', attribute=True, autofill=False, cli_name='permissions', multivalue=True, query=True, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, autofill=False, cli_name='target', multivalue=False, query=True, required=False) @@ -2414,7 +2414,7 @@ option: Str('attrs', attribute=False, autofill=False, cli_name='attrs', multival option: Str('delattr*', cli_name='delattr', exclude='webui') option: Str('filter', attribute=False, autofill=False, cli_name='filter', multivalue=True, required=False) option: Str('ipapermallowedattr', attribute=True, autofill=False, cli_name='attrs', multivalue=True, required=False) -option: StrEnum('ipapermbindruletype', attribute=True, autofill=False, cli_name='bindtype', default=u'permission', multivalue=False, required=False, values=(u'permission',)) +option: StrEnum('ipapermbindruletype', attribute=True, autofill=False, cli_name='bindtype', default=u'permission', multivalue=False, required=False, values=(u'permission', u'all', u'anonymous')) option: DNOrURL('ipapermlocation', attribute=True, autofill=False, cli_name='subtree', multivalue=False, required=False) option: StrEnum('ipapermright', attribute=True, autofill=False, cli_name='permissions', multivalue=True, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, autofill=False, cli_name='target', multivalue=False, required=False) diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py index fef640c37..204574697 100644 --- a/ipalib/plugins/permission.py +++ b/ipalib/plugins/permission.py @@ -180,7 +180,7 @@ class permission(baseldap.LDAPObject): label=_('Bind rule type'), doc=_('Bind rule type'), autofill=True, - values=(u'permission',), + values=(u'permission', u'all', u'anonymous'), default=u'permission', ), DNOrURL( @@ -775,6 +775,13 @@ class permission_mod(baseldap.LDAPUpdate): self.obj.reject_system(old_entry) self.obj.upgrade_permission(old_entry) + # Check setting bindtype for an assigned permission + if options.get('ipapermbindruletype') and old_entry.get('member'): + raise errors.ValidationError( + name='ipapermbindruletype', + error=_('cannot set bindtype for a permission that is ' + 'assigned to a privilege')) + # Since `entry` only contains the attributes we are currently changing, # it cannot be used directly to generate an ACI. # First we need to copy the original data into it. diff --git a/ipalib/plugins/privilege.py b/ipalib/plugins/privilege.py index 694e1184f..678eb2416 100644 --- a/ipalib/plugins/privilege.py +++ b/ipalib/plugins/privilege.py @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from ipalib.plugins.baseldap import * -from ipalib import api, _, ngettext +from ipalib import api, _, ngettext, errors from ipalib.plugable import Registry __doc__ = _(""" @@ -152,6 +152,37 @@ class privilege_add_permission(LDAPAddReverseMember): ), ) + def pre_callback(self, ldap, dn, *keys, **options): + if options.get('permission'): + # We can only add permissions with bind rule type set to + # "permission" (or old-style permissions) + ldapfilter = ldap.combine_filters(rules='&', filters=[ + '(objectClass=ipaPermissionV2)', + '(!(ipaPermBindRuleType=permission))', + ldap.make_filter_from_attr('cn', options['permission'], + rules='|'), + ]) + try: + entries, truncated = ldap.find_entries( + filter=ldapfilter, + attrs_list=['cn', 'ipapermbindruletype'], + base_dn=DN(self.api.env.container_permission, + self.api.env.basedn), + size_limit=1) + except errors.NotFound: + pass + else: + entry = entries[0] + message = _('cannot add permission "%(perm)s" with bindtype ' + '"%(bindtype)s" to a privilege') + raise errors.ValidationError( + name='permission', + error=message % { + 'perm': entry.single_value['cn'], + 'bindtype': entry.single_value.get( + 'ipapermbindruletype', 'permission')}) + return dn + @register() class privilege_remove_permission(LDAPRemoveReverseMember): diff --git a/ipatests/test_xmlrpc/test_permission_plugin.py b/ipatests/test_xmlrpc/test_permission_plugin.py index e1a7cd8ee..6564cbc9b 100644 --- a/ipatests/test_xmlrpc/test_permission_plugin.py +++ b/ipatests/test_xmlrpc/test_permission_plugin.py @@ -2140,3 +2140,285 @@ class test_permission_legacy(Declarative): ), ), ] + + +class test_permission_bindtype(Declarative): + cleanup_commands = [ + ('permission_del', [permission1], {'force': True}), + ('permission_del', [permission1_renamed], {'force': True}), + ('privilege_del', [privilege1], {}), + ] + + tests = [ + dict( + desc='Create anonymous %r' % permission1, + command=( + 'permission_add', [permission1], dict( + type=u'user', + ipapermright=u'write', + ipapermbindruletype=u'anonymous', + ) + ), + expected=dict( + value=permission1, + summary=u'Added permission "%s"' % permission1, + result=dict( + dn=permission1_dn, + cn=[permission1], + objectclass=objectclasses.permission, + type=[u'user'], + ipapermright=[u'write'], + ipapermbindruletype=[u'anonymous'], + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ), + ), + + verify_permission_aci( + permission1, users_dn, + '(target = "ldap:///%s")' % DN(('uid', '*'), users_dn) + + '(version 3.0;acl "permission:%s";' % permission1 + + 'allow (write) userdn = "ldap:///anyone";)', + ), + + dict( + desc='Create %r' % privilege1, + command=('privilege_add', [privilege1], + dict(description=u'privilege desc. 1') + ), + expected=dict( + value=privilege1, + summary=u'Added privilege "%s"' % privilege1, + result=dict( + dn=privilege1_dn, + cn=[privilege1], + description=[u'privilege desc. 1'], + objectclass=objectclasses.privilege, + ), + ), + ), + + dict( + desc='Try to add %r to %r' % (permission1, privilege1), + command=( + 'privilege_add_permission', [privilege1], dict( + permission=[permission1], + ) + ), + expected=errors.ValidationError( + name='permission', + error=u'cannot add permission "%s" with bindtype "%s" to a ' + 'privilege' % (permission1, 'anonymous')), + ), + + dict( + desc='Change binddn of %r to all' % permission1, + command=( + 'permission_mod', [permission1], dict( + type=u'user', + ipapermbindruletype=u'all', + ) + ), + expected=dict( + value=permission1, + summary=u'Modified permission "%s"' % permission1, + result=dict( + dn=permission1_dn, + cn=[permission1], + objectclass=objectclasses.permission, + type=[u'user'], + ipapermright=[u'write'], + ipapermbindruletype=[u'all'], + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ), + ), + + verify_permission_aci( + permission1, users_dn, + '(target = "ldap:///%s")' % DN(('uid', '*'), users_dn) + + '(version 3.0;acl "permission:%s";' % permission1 + + 'allow (write) userdn = "ldap:///all";)', + ), + + dict( + desc='Try to add %r to %r' % (permission1, privilege1), + command=( + 'privilege_add_permission', [privilege1], dict( + permission=[permission1], + ) + ), + expected=errors.ValidationError( + name='permission', + error=u'cannot add permission "%s" with bindtype "%s" to a ' + 'privilege' % (permission1, 'all')), + ), + + dict( + desc='Search for %r using --bindtype' % permission1, + command=('permission_find', [], {'ipapermbindruletype': u'all'}), + expected=dict( + count=1, + truncated=False, + summary=u'1 permission matched', + result=[ + dict( + dn=permission1_dn, + cn=[permission1], + type=[u'user'], + ipapermright=[u'write'], + ipapermbindruletype=[u'all'], + objectclass=objectclasses.permission, + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ], + ), + ), + + dict( + desc='Add zero permissions to %r' % (privilege1), + command=('privilege_add_permission', [privilege1], {}), + expected=dict( + completed=0, + failed=dict(member=dict(permission=[])), + result=dict( + dn=privilege1_dn, + cn=[privilege1], + description=[u'privilege desc. 1'], + objectclass=objectclasses.privilege, + ), + ), + ), + + dict( + desc='Rename %r to permission %r' % (permission1, + permission1_renamed), + command=( + 'permission_mod', [permission1], dict(rename=permission1_renamed) + ), + expected=dict( + value=permission1, + summary=u'Modified permission "%s"' % permission1, + result=dict( + dn=permission1_renamed_dn, + cn=[permission1_renamed], + type=[u'user'], + objectclass=objectclasses.permission, + ipapermright=[u'write'], + ipapermbindruletype=[u'all'], + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ), + ), + + verify_permission_aci( + permission1_renamed, users_dn, + '(target = "ldap:///%s")' % DN(('uid', '*'), users_dn) + + '(version 3.0;acl "permission:%s";' % permission1_renamed + + 'allow (write) userdn = "ldap:///all";)', + ), + + dict( + desc='Reset binddn of %r to permission' % permission1_renamed, + command=( + 'permission_mod', [permission1_renamed], dict( + type=u'user', + ipapermbindruletype=u'permission', + ) + ), + expected=dict( + value=permission1_renamed, + summary=u'Modified permission "%s"' % permission1_renamed, + result=dict( + dn=permission1_renamed_dn, + cn=[permission1_renamed], + objectclass=objectclasses.permission, + type=[u'user'], + ipapermright=[u'write'], + ipapermbindruletype=[u'permission'], + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ), + ), + + verify_permission_aci( + permission1_renamed, users_dn, + '(target = "ldap:///%s")' % DN(('uid', '*'), users_dn) + + '(version 3.0;acl "permission:%s";' % permission1_renamed + + 'allow (write) groupdn = "ldap:///%s";)' % permission1_renamed_dn, + ), + + dict( + desc='Rename %r back to %r' % (permission1_renamed, permission1), + command=( + 'permission_mod', [permission1_renamed], + dict(rename=permission1) + ), + expected=dict( + value=permission1_renamed, + summary=u'Modified permission "%s"' % permission1_renamed, + result=dict( + dn=permission1_dn, + cn=[permission1], + type=[u'user'], + objectclass=objectclasses.permission, + ipapermright=[u'write'], + ipapermbindruletype=[u'permission'], + ipapermissiontype=[u'SYSTEM', u'V2'], + ipapermlocation=[users_dn], + ipapermtarget=[DN('uid=*', users_dn)], + ), + ), + ), + + verify_permission_aci( + permission1, users_dn, + '(target = "ldap:///%s")' % DN(('uid', '*'), users_dn) + + '(version 3.0;acl "permission:%s";' % permission1 + + 'allow (write) groupdn = "ldap:///%s";)' % permission1_dn, + ), + + dict( + desc='Add %r to %r' % (permission1, privilege1), + command=( + 'privilege_add_permission', [privilege1], dict( + permission=[permission1], + ) + ), + expected=dict( + completed=1, + failed=dict(member=dict(permission=[])), + result=dict( + dn=privilege1_dn, + cn=[privilege1], + description=[u'privilege desc. 1'], + memberof_permission=[permission1], + objectclass=objectclasses.privilege, + ) + ), + ), + + dict( + desc='Try to change binddn of %r to anonymous' % permission1, + command=( + 'permission_mod', [permission1], dict( + type=u'user', + ipapermbindruletype=u'anonymous', + ) + ), + expected=errors.ValidationError( + name='ipapermbindruletype', + error=u'cannot set bindtype for a permission that is ' + 'assigned to a privilege') + ), + ] |