From 682edbf2152aa2dce2f6350226bffc6ebc2526c1 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Tue, 25 Sep 2012 08:14:57 -0400 Subject: Restrict admins group modifications Group-mod command no longer allows --rename and/or --external changes made to the admins group. In such cases, ProtectedEntryError is being raised. https://fedorahosted.org/freeipa/ticket/3098 --- ipalib/errors.py | 6 +++--- ipalib/plugins/group.py | 20 ++++++++++++++++--- tests/test_xmlrpc/test_group_plugin.py | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/ipalib/errors.py b/ipalib/errors.py index 31fc14ea4..7bf267290 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -1659,18 +1659,18 @@ class LastMemberError(ExecutionError): class ProtectedEntryError(ExecutionError): """ - **4309** Raised when an entry being deleted is protected + **4309** Raised when an entry being deleted or modified in a forbidden way is protected For example: >>> raise ProtectedEntryError(label=u'group', key=u'admins', reason=_(u'privileged group')) Traceback (most recent call last): ... - ProtectedEntryError: group admins cannot be deleted: privileged group + ProtectedEntryError: group admins cannot be deleted/modified: privileged group """ errno = 4309 - format = _('%(label)s %(key)s cannot be deleted: %(reason)s') + format = _('%(label)s %(key)s cannot be deleted/modified: %(reason)s') ############################################################################## diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py index f1e34bd56..45758d320 100644 --- a/ipalib/plugins/group.py +++ b/ipalib/plugins/group.py @@ -107,7 +107,7 @@ Example: ipa group-add-member ad_admins --groups ad_admins_external """) -protected_group_name = u'admins' +PROTECTED_GROUPS = (u'admins', u'trust admins') class group(LDAPObject): """ @@ -222,7 +222,7 @@ class group_del(LDAPDelete): group_attrs = self.obj.methods.show( self.obj.get_primary_key_from_dn(dn), all=True )['result'] - if keys[0] == protected_group_name: + if keys[0] in PROTECTED_GROUPS: raise errors.ProtectedEntryError(label=_(u'group'), key=keys[0], reason=_(u'privileged group')) if 'mepmanagedby' in group_attrs: @@ -260,6 +260,14 @@ class group_mod(LDAPUpdate): def pre_callback(self, ldap, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) + + is_protected_group = keys[-1] in PROTECTED_GROUPS + + if 'rename' in options: + if is_protected_group: + raise errors.ProtectedEntryError(label=u'group', key=keys[-1], + reason=u'Cannot be renamed') + if ('posix' in options and options['posix']) or 'gidnumber' in options: (dn, old_entry_attrs) = ldap.get_entry(dn, ['objectclass']) if 'ipaexternalgroup' in old_entry_attrs['objectclass']: @@ -272,7 +280,11 @@ class group_mod(LDAPUpdate): entry_attrs['objectclass'] = old_entry_attrs['objectclass'] if not 'gidnumber' in options: entry_attrs['gidnumber'] = 999 + if options['external']: + if is_protected_group: + raise errors.ProtectedEntryError(label=u'group', key=keys[-1], + reason=u'Cannot support external non-IPA members') (dn, old_entry_attrs) = ldap.get_entry(dn, ['objectclass']) if 'posixgroup' in old_entry_attrs['objectclass']: raise errors.PosixGroupViolation() @@ -281,6 +293,7 @@ class group_mod(LDAPUpdate): else: old_entry_attrs['objectclass'].append('ipaexternalgroup') entry_attrs['objectclass'] = old_entry_attrs['objectclass'] + # Can't check for this in a validator because we lack context if 'gidnumber' in options and options['gidnumber'] is None: raise errors.RequirementError(name='gid') @@ -393,7 +406,8 @@ class group_remove_member(LDAPRemoveMember): def pre_callback(self, ldap, dn, found, not_found, *keys, **options): assert isinstance(dn, DN) - if keys[0] == protected_group_name: + if keys[0] in PROTECTED_GROUPS: + protected_group_name = keys[0] result = api.Command.group_show(protected_group_name) users_left = set(result['result'].get('member_user', [])) users_deleted = set(options['user']) diff --git a/tests/test_xmlrpc/test_group_plugin.py b/tests/test_xmlrpc/test_group_plugin.py index 77a419b0c..a74a5e4c3 100644 --- a/tests/test_xmlrpc/test_group_plugin.py +++ b/tests/test_xmlrpc/test_group_plugin.py @@ -870,6 +870,42 @@ class test_group(Declarative): key='admins', reason='privileged group'), ), + + dict( + desc='Try to rename the admins group', + command=('group_mod', [u'admins'], dict(rename=u'loosers')), + expected=errors.ProtectedEntryError(label=u'group', + key='admins', reason='Cannot be renamed'), + ), + + dict( + desc='Try to modify the admins group to support external membership', + command=('group_mod', [u'admins'], dict(external=True)), + expected=errors.ProtectedEntryError(label=u'group', + key='admins', reason='Cannot support external non-IPA members'), + ), + + dict( + desc='Try to delete the trust admins group', + command=('group_del', [u'trust admins'], {}), + expected=errors.ProtectedEntryError(label=u'group', + key='trust admins', reason='privileged group'), + ), + + dict( + desc='Try to rename the trust admins group', + command=('group_mod', [u'trust admins'], dict(rename=u'loosers')), + expected=errors.ProtectedEntryError(label=u'group', + key='trust admins', reason='Cannot be renamed'), + ), + + dict( + desc='Try to modify the trust admins group to support external membership', + command=('group_mod', [u'trust admins'], dict(external=True)), + expected=errors.ProtectedEntryError(label=u'group', + key='trust admins', reason='Cannot support external non-IPA members'), + ), + dict( desc='Delete %r' % user1, command=('user_del', [user1], {}), -- cgit