summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2013-10-29 17:01:07 +0100
committerMartin Kosek <mkosek@redhat.com>2014-01-07 09:56:41 +0100
commit4a64a1f18bd51c65bf34a13fd7541e1d6b4b75fd (patch)
tree8cc1db4e9b3e1b77f25b36ad5c58a1b37d94fea7
parentd7f5d58d352f31df144de15976bd06c5aa822210 (diff)
downloadfreeipa-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.txt6
-rw-r--r--ipalib/plugins/permission.py9
-rw-r--r--ipalib/plugins/privilege.py33
-rw-r--r--ipatests/test_xmlrpc/test_permission_plugin.py282
4 files changed, 325 insertions, 5 deletions
diff --git a/API.txt b/API.txt
index 3bb1b76a..a6c3aed8 100644
--- a/API.txt
+++ b/API.txt
@@ -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 fef640c3..20457469 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 694e1184..678eb241 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 e1a7cd8e..6564cbc9 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')
+ ),
+ ]