From 02b5074d84ad42cb6ffc2abd7a84fbff62747470 Mon Sep 17 00:00:00 2001 From: Petr Viktorin 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 Reviewed-By: Martin Kosek --- ipalib/plugins/permission.py | 40 +++++++++++-------- .../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 3c2127fcc..52ab09b14 100644 --- a/ipalib/plugins/permission.py +++ b/ipalib/plugins/permission.py @@ -363,26 +363,17 @@ class permission(baseldap.LDAPObject): # 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 @@ class permission(baseldap.LDAPObject): 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 @@ class permission(baseldap.LDAPObject): 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 7394e6282..8c83b1ccc 100644 --- a/ipaserver/install/plugins/update_managed_permissions.py +++ b/ipaserver/install/plugins/update_managed_permissions.py @@ -516,6 +516,8 @@ class update_managed_permissions(PostUpdate): 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 @@ class update_managed_permissions(PostUpdate): 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)