Allow permissions with 'self' bindruletype

Make it possible to create a managed permission with
ipapermbindruletype="self". The ACI will have bind rule
'(userdn = "ldap:///self")'.

Example
-------

Allow users to modify their own fasTimezone and fasIRCNick attributes:

```
managed_permissions = {
    "System: Self-Modify FAS user attributes": {
        "ipapermright": {"write"},
        "ipapermtargetfilter": ["(objectclass=fasuser)"],
        "ipapermbindruletype": "self",
        "ipapermdefaultattr": ["fasTimezone", "fasIRCNick"],
    }
}
```

See: https://github.com/fedora-infra/freeipa-fas/pull/107
Fixes: https://pagure.io/freeipa/issue/8348
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Christian Heimes 2020-06-02 15:08:16 +02:00 committed by Alexander Bokovoy
parent 373f8cdce7
commit 9dda004f27
6 changed files with 60 additions and 9 deletions

View File

@ -3678,7 +3678,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('attrs*')
option: Str('extratargetfilter*', cli_name='filter')
option: Str('filter*')
option: StrEnum('ipapermbindruletype', autofill=True, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous'])
option: StrEnum('ipapermbindruletype', autofill=True, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous', u'self'])
option: DNOrURL('ipapermlocation?', alwaysask=True, autofill=False, cli_name='subtree')
option: StrEnum('ipapermright*', alwaysask=True, autofill=False, cli_name='right', values=[u'read', u'search', u'compare', u'write', u'add', u'delete', u'all'])
option: DNParam('ipapermtarget?', cli_name='target')
@ -3736,7 +3736,7 @@ option: Str('attrs*', autofill=False)
option: Str('cn?', autofill=False, cli_name='name')
option: Str('extratargetfilter*', autofill=False, cli_name='filter')
option: Str('filter*', autofill=False)
option: StrEnum('ipapermbindruletype?', autofill=False, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous'])
option: StrEnum('ipapermbindruletype?', autofill=False, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous', u'self'])
option: Str('ipapermdefaultattr*', autofill=False, cli_name='defaultattrs')
option: Str('ipapermexcludedattr*', autofill=False, cli_name='excludedattrs')
option: Str('ipapermincludedattr*', autofill=False, cli_name='includedattrs')
@ -3770,7 +3770,7 @@ option: Str('attrs*', autofill=False)
option: Str('delattr*', cli_name='delattr')
option: Str('extratargetfilter*', autofill=False, cli_name='filter')
option: Str('filter*', autofill=False)
option: StrEnum('ipapermbindruletype?', autofill=False, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous'])
option: StrEnum('ipapermbindruletype?', autofill=False, cli_name='bindtype', default=u'permission', values=[u'permission', u'all', u'anonymous', u'self'])
option: Str('ipapermexcludedattr*', autofill=False, cli_name='excludedattrs')
option: Str('ipapermincludedattr*', autofill=False, cli_name='includedattrs')
option: DNOrURL('ipapermlocation?', autofill=False, cli_name='subtree')

View File

@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
# #
########################################################
define(IPA_API_VERSION_MAJOR, 2)
define(IPA_API_VERSION_MINOR, 237)
# Last change: allow rename a hostgroup
define(IPA_API_VERSION_MINOR, 238)
# Last change: permission ipapermbindruletype=self
########################################################

View File

@ -159,7 +159,7 @@ return {
{
$type: 'radio',
name: 'ipapermbindruletype',
options: ['permission', 'all', 'anonymous']
options: ['permission', 'all', 'anonymous', 'self']
},
{
$type: 'rights',
@ -280,7 +280,7 @@ return {
{
$type: 'radio',
name: 'ipapermbindruletype',
options: ['permission', 'all', 'anonymous'],
options: ['permission', 'all', 'anonymous', 'self'],
default_value: 'permission'
},
{

View File

@ -635,6 +635,10 @@ class update_managed_permissions(Updater):
# Attributes from template
bindruletype = template.pop('ipapermbindruletype', 'permission')
if bindruletype not in {"all", "anonymous", "self", "permission"}:
raise ValueError(
f"Invalid ipapermbindruletype '{bindruletype}'"
)
if is_new:
entry.single_value['ipapermbindruletype'] = bindruletype

View File

@ -279,8 +279,8 @@ class permission(baseldap.LDAPObject):
label=_('Bind rule type'),
doc=_('Bind rule type'),
autofill=True,
values=(u'permission', u'all', u'anonymous'),
default=u'permission',
values=('permission', 'all', 'anonymous', 'self'),
default='permission',
flags={'allow_mod_for_managed_permission'},
),
DNOrURL(
@ -600,6 +600,8 @@ class permission(baseldap.LDAPObject):
bindrule = 'userdn = "ldap:///all"'
elif ipapermbindruletype == 'anonymous':
bindrule = 'userdn = "ldap:///anyone"'
elif ipapermbindruletype == 'self':
bindrule = 'userdn = "ldap:///self"'
else:
raise ValueError(ipapermbindruletype)

View File

@ -4345,3 +4345,48 @@ class test_autoadd_operational_attrs(Declarative):
'allow (read) groupdn = "ldap:///%s";)' % permission1_dn,
),
]
class test_self_bindrule(Declarative):
"""Test creation of permission with bindrule self
"""
cleanup_commands = [
('permission_del', [permission1], {'force': True}),
]
tests = [
dict(
desc='Create %r' % permission1,
command=(
'permission_add', [permission1], dict(
ipapermlocation=DN('cn=accounts', api.env.basedn),
ipapermright=u'read',
ipapermbindruletype='self',
attrs=[u'objectclass'],
)
),
expected=dict(
value=permission1,
summary=u'Added permission "%s"' % permission1,
result=dict(
dn=permission1_dn,
cn=[permission1],
objectclass=objectclasses.permission,
attrs=[u'objectclass', u'entryusn', u'createtimestamp',
u'modifytimestamp'],
ipapermright=[u'read'],
ipapermbindruletype=[u'self'],
ipapermissiontype=[u'SYSTEM', u'V2'],
ipapermlocation=[DN('cn=accounts', api.env.basedn)],
),
),
),
verify_permission_aci(
permission1, DN('cn=accounts', api.env.basedn),
'(targetattr = "createtimestamp || entryusn || modifytimestamp '
+ '|| objectclass")'
+ '(version 3.0;acl "permission:%s";' % permission1
+ 'allow (read) userdn = "ldap:///self";)',
),
]