My patch 0580 was wrong; non-POSIX groups obviously lack the posixgroup
objectclass. Actually the only objectclasses that all groups share are
top and ipaobject.
This makes permission plugin & updater join multiple
permission_filter_objectclasses filters with OR, and changes the --type
group filter to (|(objectclass=ipausergroup)(objectclass=posixgroup)).
The first patch has some unrelated test fixes.
--
PetrĀ³
From 4555ed124fc24ad4c84e74795de170c0a0f4eb57 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Thu, 19 Jun 2014 19:06:19 +0200
Subject: [PATCH] Test and docstring fixes
The recent conversions to managed permissions left behind a few
failing tests. Fix them.
Also fix a now incorrect docstring in ipalib.config.
---
ipalib/config.py | 6 +-----
ipatests/test_xmlrpc/test_old_permission_plugin.py | 14 ++++++++------
ipatests/test_xmlrpc/test_permission_plugin.py | 14 ++++++++------
ipatests/test_xmlrpc/test_realmdomains_plugin.py | 2 +-
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/ipalib/config.py b/ipalib/config.py
index b12cfd32184edf964353fda9304dbb5149eb525f..e8958205dbe12e1bae1ac24351d46901a536f3e7 100644
--- a/ipalib/config.py
+++ b/ipalib/config.py
@@ -105,15 +105,11 @@ class Env(object):
u'false'
If an ``str`` value looks like an integer, it's automatically converted to
- the ``int`` type. Likewise, if an ``str`` value looks like a floating-point
- number, it's automatically converted to the ``float`` type. For example:
+ the ``int`` type.
>>> env.lucky = '7'
>>> env.lucky
7
- >>> env.three_halves = '1.5'
- >>> env.three_halves
- 1.5
Leading and trailing white-space is automatically stripped from ``str``
values. For example:
diff --git a/ipatests/test_xmlrpc/test_old_permission_plugin.py b/ipatests/test_xmlrpc/test_old_permission_plugin.py
index 9de397d67979bf54f808b0b61628ee444087af4b..e69c4f824981d5d0f7b3beecdbc5df098e764b3b 100644
--- a/ipatests/test_xmlrpc/test_old_permission_plugin.py
+++ b/ipatests/test_xmlrpc/test_old_permission_plugin.py
@@ -466,9 +466,9 @@ class test_old_permission(Declarative):
summary=u'2 permissions matched',
result=[
{
- 'dn': DN(('cn','Modify Group Password Policy'),
+ 'dn': DN(('cn', 'System: Modify Group Password Policy'),
api.env.container_permission, api.env.basedn),
- 'cn': [u'Modify Group Password Policy'],
+ 'cn': [u'System: Modify Group Password Policy'],
},
{
'dn': DN(('cn', 'System: Read Group Password Policy'),
@@ -796,10 +796,10 @@ class test_old_permission(Declarative):
summary=u'1 permission matched',
result=[
{
- 'dn': DN(('cn','Add user to default group'),
+ 'dn': DN(('cn', 'System: Add User to default group'),
api.env.container_permission, api.env.basedn),
- 'cn': [u'Add user to default group'],
- 'objectclass': objectclasses.system_permission,
+ 'cn': [u'System: Add User to default group'],
+ 'objectclass': objectclasses.permission,
'member_privilege': [u'User Administrators'],
'attrs': [u'member'],
'targetgroup': u'ipausers',
@@ -807,7 +807,9 @@ class test_old_permission(Declarative):
'permissions': [u'write'],
'ipapermbindruletype': [u'permission'],
'ipapermtarget': [DN('cn=ipausers', groups_dn)],
- 'subtree': u'ldap:///%s' % api.env.basedn,
+ 'subtree': u'ldap:///%s' % groups_dn,
+ 'ipapermdefaultattr': [u'member'],
+ 'ipapermissiontype': [u'V2', u'MANAGED', u'SYSTEM'],
}
],
),
diff --git a/ipatests/test_xmlrpc/test_permission_plugin.py b/ipatests/test_xmlrpc/test_permission_plugin.py
index a37876bea5c2d666548f7efa94f32ddbf044c0b4..feffc2eb1285d173d63a07bb42df8e64f816b618 100644
--- a/ipatests/test_xmlrpc/test_permission_plugin.py
+++ b/ipatests/test_xmlrpc/test_permission_plugin.py
@@ -758,9 +758,9 @@ class test_permission(Declarative):
summary=u'2 permissions matched',
result=[
{
- 'dn': DN(('cn','Modify Group Password Policy'),
+ 'dn': DN(('cn', 'System: Modify Group Password Policy'),
api.env.container_permission, api.env.basedn),
- 'cn': [u'Modify Group Password Policy'],
+ 'cn': [u'System: Modify Group Password Policy'],
},
{
'dn': DN(('cn', 'System: Read Group Password Policy'),
@@ -1193,10 +1193,10 @@ class test_permission(Declarative):
summary=u'1 permission matched',
result=[
{
- 'dn': DN(('cn','Add user to default group'),
+ 'dn': DN(('cn', 'System: Add User to default group'),
api.env.container_permission, api.env.basedn),
- 'cn': [u'Add user to default group'],
- 'objectclass': objectclasses.system_permission,
+ 'cn': [u'System: Add User to default group'],
+ 'objectclass': objectclasses.permission,
'member_privilege': [u'User Administrators'],
'attrs': [u'member'],
'targetgroup': [u'ipausers'],
@@ -1206,7 +1206,9 @@ class test_permission(Declarative):
'ipapermtarget': [DN(
'cn=ipausers', api.env.container_group,
api.env.basedn)],
- 'ipapermlocation': [api.env.basedn],
+ 'ipapermlocation': [groups_dn],
+ 'ipapermdefaultattr': [u'member'],
+ 'ipapermissiontype': [u'V2', u'MANAGED', u'SYSTEM'],
}
],
),
diff --git a/ipatests/test_xmlrpc/test_realmdomains_plugin.py b/ipatests/test_xmlrpc/test_realmdomains_plugin.py
index a47fd6b98ed0aed012a49d6f2f6b016e350ef60c..ee8057d1d9aff004e9ed144577e4aed34dc7b8dc 100644
--- a/ipatests/test_xmlrpc/test_realmdomains_plugin.py
+++ b/ipatests/test_xmlrpc/test_realmdomains_plugin.py
@@ -70,7 +70,7 @@ class test_realmdomains(Declarative):
u'(targetfilter = "(objectclass=domainrelatedobject)")'
u'(version 3.0;acl '
u'"permission:System: Read Realm Domains";'
- u'allow (read,compare,search) '
+ u'allow (compare,read,search) '
u'userdn = "ldap:///all";)'
],
),
--
1.9.3
From 9a21b82e07218bff23861185a291298a745ba627 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Thu, 19 Jun 2014 18:14:31 +0200
Subject: [PATCH] permission plugin: Join --type objectclass filters with OR
For groups, we will need to filter on either posixgroup (which UPGs
have but non-posix groups don't) and groupofnames/nestedgroup
(which normal groups have but UPGs don't).
Join permission_filter_objectclasses with `|` and add them as
a single ipapermtargetfilter value.
Part of the work for: https://fedorahosted.org/freeipa/ticket/3566
---
ipalib/plugins/permission.py | 40 +++++++++++++---------
.../install/plugins/update_managed_permissions.py | 5 +--
2 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py
index 3c2127fcc03d2d711ae6e2bfd10407085b7c7c2b..52ab09b14de363e7b34a710ea6af81fac444b5c5 100644
--- a/ipalib/plugins/permission.py
+++ b/ipalib/plugins/permission.py
@@ -363,26 +363,17 @@ def _get_filter_attr_info(self, entry):
# type
if ipapermtargetfilter and ipapermlocation:
for obj in self.api.Object():
- filter_objectclasses = getattr(
- obj, 'permission_filter_objectclasses', None)
- if not filter_objectclasses:
+ filt = self.make_type_filter(obj)
+ if not filt:
continue
+
wantdn = DN(obj.container_dn, self.api.env.basedn)
if DN(ipapermlocation) != wantdn:
continue
- objectclass_targetfilters = set()
- for objclass in filter_objectclasses:
- filter_re = '\(objectclass=%s\)' % re.escape(objclass)
- for tf in ipapermtargetfilter:
- if re.match(filter_re, tf, re.I):
- objectclass_targetfilters.add(tf)
- break
- else:
- break
- else:
+ if filt in ipapermtargetfilter:
result['type'] = [unicode(obj.name)]
- implicit_targetfilters |= objectclass_targetfilters
+ implicit_targetfilters.add(filt)
break
return result
@@ -717,6 +708,17 @@ def upgrade_permission(self, entry, target_entry=None,
raise ValueError('Cannot convert ACI, %r != %r' % (new_acistring,
acistring))
+ def make_type_filter(self, obj):
+ """Make a filter for a --type based permission from an Object"""
+ objectclasses = getattr(obj, 'permission_filter_objectclasses', None)
+ if not objectclasses:
+ return None
+ filters = [u'(objectclass=%s)' % o for o in objectclasses]
+ if len(filters) == 1:
+ return filters[0]
+ else:
+ return '(|%s)' % ''.join(sorted(filters))
+
def preprocess_options(self, options,
return_filter_ops=False,
merge_targetfilter=False):
@@ -808,15 +810,19 @@ def preprocess_options(self, options,
if 'type' in options:
objtype = options.pop('type')
filter_ops['remove'].append(re.compile(r'\(objectclass=.*\)', re.I))
+ filter_ops['remove'].append(re.compile(
+ r'\(\|(\(objectclass=[^(]*\))+\)', re.I))
if objtype:
if 'ipapermlocation' in options:
raise errors.ValidationError(
name='ipapermlocation',
error=_('subtree and type are mutually exclusive'))
obj = self.api.Object[objtype.lower()]
- new_values = [u'(objectclass=%s)' % o
- for o in obj.permission_filter_objectclasses]
- filter_ops['add'].extend(new_values)
+ filt = self.make_type_filter(obj)
+ if not filt:
+ raise errors.ValidationError(
+ _('"%s" is not a valid permission type') % objtype)
+ filter_ops['add'].append(filt)
container_dn = DN(obj.container_dn, self.api.env.basedn)
options['ipapermlocation'] = container_dn
else:
diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py
index 7394e6282a82ab8554c226253e7510acddd91c71..8c83b1ccca5520327e5c8abc9b9a8355a7fd8cd6 100644
--- a/ipaserver/install/plugins/update_managed_permissions.py
+++ b/ipaserver/install/plugins/update_managed_permissions.py
@@ -516,6 +516,8 @@ def update_entry(self, obj, entry, template,
template = dict(template)
template.pop('replaces', None)
template.pop('replaces_system', None)
+ template.pop('replaces_permissions', None)
+ template.pop('replaces_acis', None)
fixup_function = template.pop('fixup_function', None)
if fixup_function:
@@ -536,8 +538,7 @@ def update_entry(self, obj, entry, template,
ldap_filter = template.pop('ipapermtargetfilter', None)
if obj and ldap_filter is None:
- ldap_filter = ['(objectclass=%s)' % oc
- for oc in obj.permission_filter_objectclasses]
+ ldap_filter = [self.api.Object[permission].make_type_filter(obj)]
entry['ipapermtargetfilter'] = list(ldap_filter or [])
ipapermlocation = template.pop('ipapermlocation', None)
--
1.9.3
From c077939b9e6fa05de56c24e04e85539c389f900f Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Thu, 12 Jun 2014 12:01:26 +0200
Subject: [PATCH] Add posixgroup to groups' permission object filter
Private groups don't have the 'ipausergroup' objectclass.
Add posixgroup to the objectclass filters to make
"--type group" permissions apply to all groups.
https://fedorahosted.org/freeipa/ticket/4372
---
ACI.txt | 4 +-
ipalib/plugins/group.py | 2 +-
ipatests/test_xmlrpc/test_permission_plugin.py | 106 ++++++++++++++++++++++++-
3 files changed, 105 insertions(+), 7 deletions(-)
diff --git a/ACI.txt b/ACI.txt
index cd19fb90fdd0ac1947393aabfd667e46a6f015fc..d815eb8bbe37fc67d94ffc679b3d2422b5b804e3 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -29,9 +29,9 @@ aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "p
dn: cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example
aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsrecord || nxtrecord || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || txtrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Update DNS Entries";allow (write) groupdn = "ldap:///cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=System: Read Group Membership,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "member || memberhost || memberof || memberuid || memberuser")(targetfilter = "(objectclass=ipausergroup)")(version 3.0;acl "permission:System: Read Group Membership";allow (compare,read,search) userdn = "ldap:///all";)
+aci: (targetattr = "member || memberhost || memberof || memberuid || memberuser")(targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "permission:System: Read Group Membership";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=System: Read Groups,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "businesscategory || cn || description || gidnumber || ipaexternalmember || ipauniqueid || mepmanagedby || o || objectclass || ou || owner || seealso")(targetfilter = "(objectclass=ipausergroup)")(version 3.0;acl "permission:System: Read Groups";allow (compare,read,search) userdn = "ldap:///anyone";)
+aci: (targetattr = "businesscategory || cn || description || gidnumber || ipaexternalmember || ipauniqueid || mepmanagedby || o || objectclass || ou || owner || seealso")(targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "permission:System: Read Groups";allow (compare,read,search) userdn = "ldap:///anyone";)
dn: cn=System: Read HBAC Rules,cn=permissions,cn=pbac,dc=ipa,dc=example
aci: (targetattr = "accessruletype || accesstime || cn || description || externalhost || hostcategory || ipaenabledflag || ipauniqueid || member || memberhost || memberservice || memberuser || objectclass || servicecategory || sourcehost || sourcehostcategory || usercategory")(targetfilter = "(objectclass=ipahbacrule)")(version 3.0;acl "permission:System: Read HBAC Rules";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=System: Read HBAC Services,cn=permissions,cn=pbac,dc=ipa,dc=example
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 581ee70b635da0f4d85633b7db367229113f9f73..d130f86686e17b8e3cdc5fafabc64fdde4f2dfc4 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -126,7 +126,7 @@ class group(LDAPObject):
object_class = ['ipausergroup']
object_class_config = 'ipagroupobjectclasses'
possible_objectclasses = ['posixGroup', 'mepManagedEntry', 'ipaExternalGroup']
- permission_filter_objectclasses = ['ipausergroup']
+ permission_filter_objectclasses = ['posixgroup', 'ipausergroup']
search_attributes_config = 'ipagroupsearchfields'
default_attributes = [
'cn', 'description', 'gidnumber', 'member', 'memberof',
diff --git a/ipatests/test_xmlrpc/test_permission_plugin.py b/ipatests/test_xmlrpc/test_permission_plugin.py
index feffc2eb1285d173d63a07bb42df8e64f816b618..6ea6c7b1b7a5476afcacc1525145171f995b8b31 100644
--- a/ipatests/test_xmlrpc/test_permission_plugin.py
+++ b/ipatests/test_xmlrpc/test_permission_plugin.py
@@ -102,6 +102,8 @@
nonexistent_dn = DN('cn=does not exist', api.env.basedn)
admin_dn = DN('uid=admin', users_dn)
+group_filter = u'(|(objectclass=ipausergroup)(objectclass=posixgroup))'
+
def verify_permission_aci(name, dn, acistring):
"""Return test dict that verifies the ACI at the given location"""
@@ -1927,7 +1929,7 @@ class test_permission_sync_attributes(Declarative):
verify_permission_aci(
permission1, groups_dn,
'(targetattr = "sn")' +
- '(targetfilter = "(objectclass=ipausergroup)")'
+ '(targetfilter = "%s")' % group_filter +
'(version 3.0;acl "permission:%s";' % permission1 +
'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
),
@@ -1962,7 +1964,103 @@ class test_permission_sync_attributes(Declarative):
permission1, groups_dn,
'(targetattr = "sn")' +
'(target = "ldap:///%s")' % DN(('cn', 'editors'), groups_dn) +
- '(targetfilter = "(objectclass=ipausergroup)")'
+ '(targetfilter = "%s")' % group_filter +
+ '(version 3.0;acl "permission:%s";' % permission1 +
+ 'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
+ ),
+
+ dict(
+ desc='Set extra targetfilter on %r' % permission1,
+ command=(
+ 'permission_mod', [permission1], dict(
+ extratargetfilter=u'(cn=blabla)',
+ )
+ ),
+ expected=dict(
+ value=permission1,
+ summary=u'Modified permission "%s"' % permission1,
+ result=dict(
+ dn=permission1_dn,
+ cn=[permission1],
+ objectclass=objectclasses.permission,
+ type=[u'group'],
+ ipapermright=[u'write'],
+ attrs=[u'sn'],
+ ipapermbindruletype=[u'permission'],
+ ipapermissiontype=[u'SYSTEM', u'V2'],
+ ipapermtarget=[DN('cn=editors', groups_dn)],
+ ipapermlocation=[groups_dn],
+ targetgroup=[u'editors'],
+ extratargetfilter=[u'(cn=blabla)'],
+ ),
+ ),
+ ),
+
+ verify_permission_aci(
+ permission1, groups_dn,
+ '(targetattr = "sn")' +
+ '(target = "ldap:///%s")' % DN(('cn', 'editors'), groups_dn) +
+ '(targetfilter = "(&(cn=blabla)%s)")' % group_filter +
+ '(version 3.0;acl "permission:%s";' % permission1 +
+ 'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
+ ),
+
+ dict(
+ desc='Retreive %r with --all' % permission1,
+ command=(
+ 'permission_show', [permission1], dict(all=True)
+ ),
+ expected=dict(
+ value=permission1,
+ summary=None,
+ result=dict(
+ dn=permission1_dn,
+ cn=[permission1],
+ objectclass=objectclasses.permission,
+ type=[u'group'],
+ ipapermright=[u'write'],
+ attrs=[u'sn'],
+ ipapermincludedattr=[u'sn'],
+ ipapermbindruletype=[u'permission'],
+ ipapermissiontype=[u'SYSTEM', u'V2'],
+ ipapermtarget=[DN('cn=editors', groups_dn)],
+ ipapermlocation=[groups_dn],
+ targetgroup=[u'editors'],
+ extratargetfilter=[u'(cn=blabla)'],
+ ipapermtargetfilter=[u'(cn=blabla)', group_filter],
+ ),
+ ),
+ ),
+
+ dict(
+ desc='Set type of %r back to user' % permission1,
+ command=(
+ 'permission_mod', [permission1], dict(
+ type=u'user', ipapermtarget=None,
+ )
+ ),
+ 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'],
+ attrs=[u'sn'],
+ ipapermbindruletype=[u'permission'],
+ ipapermissiontype=[u'SYSTEM', u'V2'],
+ ipapermlocation=[users_dn],
+ extratargetfilter=[u'(cn=blabla)'],
+ ),
+ ),
+ ),
+
+ verify_permission_aci(
+ permission1, users_dn,
+ '(targetattr = "sn")' +
+ '(targetfilter = "(&(cn=blabla)(objectclass=posixaccount))")' +
'(version 3.0;acl "permission:%s";' % permission1 +
'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
),
@@ -2102,7 +2200,7 @@ class test_permission_sync_nice(Declarative):
verify_permission_aci(
permission1, groups_dn,
'(targetattr = "sn")' +
- '(targetfilter = "(objectclass=ipausergroup)")' +
+ '(targetfilter = "%s")' % group_filter +
'(version 3.0;acl "permission:%s";' % permission1 +
'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
),
@@ -2137,7 +2235,7 @@ class test_permission_sync_nice(Declarative):
permission1, groups_dn,
'(targetattr = "sn")' +
'(target = "ldap:///%s")' % DN(('cn', 'editors'), groups_dn) +
- '(targetfilter = "(objectclass=ipausergroup)")' +
+ '(targetfilter = "%s")' % group_filter +
'(version 3.0;acl "permission:%s";' % permission1 +
'allow (write) groupdn = "ldap:///%s";)' % permission1_dn,
),
--
1.9.3
_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel