summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/errors.py6
-rw-r--r--ipalib/plugins/group.py20
-rw-r--r--tests/test_xmlrpc/test_group_plugin.py36
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], {}),