mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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
This commit is contained in:
committed by
Martin Kosek
parent
d7f5d58d35
commit
4a64a1f18b
6
API.txt
6
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('attrs', attribute=False, cli_name='attrs', multivalue=True, required=False)
|
||||||
option: Str('filter', attribute=False, cli_name='filter', 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: 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: 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: 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)
|
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('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('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: 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: 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: 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)
|
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('delattr*', cli_name='delattr', exclude='webui')
|
||||||
option: Str('filter', attribute=False, autofill=False, cli_name='filter', multivalue=True, required=False)
|
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: 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: 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: 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)
|
option: DNParam('ipapermtarget', attribute=True, autofill=False, cli_name='target', multivalue=False, required=False)
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ class permission(baseldap.LDAPObject):
|
|||||||
label=_('Bind rule type'),
|
label=_('Bind rule type'),
|
||||||
doc=_('Bind rule type'),
|
doc=_('Bind rule type'),
|
||||||
autofill=True,
|
autofill=True,
|
||||||
values=(u'permission',),
|
values=(u'permission', u'all', u'anonymous'),
|
||||||
default=u'permission',
|
default=u'permission',
|
||||||
),
|
),
|
||||||
DNOrURL(
|
DNOrURL(
|
||||||
@@ -775,6 +775,13 @@ class permission_mod(baseldap.LDAPUpdate):
|
|||||||
self.obj.reject_system(old_entry)
|
self.obj.reject_system(old_entry)
|
||||||
self.obj.upgrade_permission(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,
|
# Since `entry` only contains the attributes we are currently changing,
|
||||||
# it cannot be used directly to generate an ACI.
|
# it cannot be used directly to generate an ACI.
|
||||||
# First we need to copy the original data into it.
|
# First we need to copy the original data into it.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from ipalib.plugins.baseldap import *
|
from ipalib.plugins.baseldap import *
|
||||||
from ipalib import api, _, ngettext
|
from ipalib import api, _, ngettext, errors
|
||||||
from ipalib.plugable import Registry
|
from ipalib.plugable import Registry
|
||||||
|
|
||||||
__doc__ = _("""
|
__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()
|
@register()
|
||||||
class privilege_remove_permission(LDAPRemoveReverseMember):
|
class privilege_remove_permission(LDAPRemoveReverseMember):
|
||||||
|
|||||||
@@ -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')
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user