Allow the admin user to be disabled

A previous change made it not possible to remove the admin
user. This also included disabling the admin user. The user can
be disabled, just not deleted because it is required.

Move the test test_ipa_cacert_manage_prune to the end of the
class because it changes time which can break replication.

Fixes: https://pagure.io/freeipa/issue/9489

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Rob Crittenden 2024-04-04 13:41:20 -04:00 committed by Florence Blanc-Renaud
parent 182dca38c2
commit 6b0f6ff19e
3 changed files with 61 additions and 30 deletions

View File

@ -146,8 +146,7 @@ PROTECTED_USERS = ('admin',)
def check_protected_member(user, protected_group_name=u'admins'):
'''
Ensure admin and the last enabled member of a protected group cannot
be deleted or disabled by raising ProtectedEntryError or
LastMemberError as appropriate.
be deleted.
'''
if user in PROTECTED_USERS:
@ -157,6 +156,12 @@ def check_protected_member(user, protected_group_name=u'admins'):
reason=_("privileged user"),
)
def check_last_member(user, protected_group_name=u'admins'):
'''
Ensure the last enabled member of a protected group cannot
be disabled.
'''
# Get all users in the protected group
result = api.Command.user_find(in_group=protected_group_name)
@ -807,6 +812,7 @@ class user_del(baseuser_del):
# If the target entry is a Delete entry, skip the orphaning/removal
# of OTP tokens.
check_protected_member(keys[-1])
check_last_member(keys[-1])
preserve = options.get('preserve', False)
@ -1147,7 +1153,7 @@ class user_disable(LDAPQuery):
def execute(self, *keys, **options):
ldap = self.obj.backend
check_protected_member(keys[-1])
check_last_member(keys[-1])
dn, _oc = self.obj.get_either_dn(*keys, **options)
ldap.deactivate_entry(dn)

View File

@ -1498,29 +1498,6 @@ class TestIPACommand(IntegrationTest):
assert 'This account is currently not available' in \
result.stdout_text
def test_ipa_cacert_manage_prune(self):
"""Test for ipa-cacert-manage prune"""
certfile = os.path.join(self.master.config.test_dir, 'cert.pem')
self.master.put_file_contents(certfile, isrgrootx1)
result = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'install', certfile])
certs_before_prune = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'list'], raiseonerr=False
).stdout_text
assert isrgrootx1_nick in certs_before_prune
# Jump in time to make sure the cert is expired
self.master.run_command(['date', '-s', '+15Years'])
result = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'prune'], raiseonerr=False
).stdout_text
self.master.run_command(['date', '-s', '-15Years'])
assert isrgrootx1_nick in result
def test_ipa_getkeytab_server(self):
"""
Exercise the ipa-getkeytab server options
@ -1618,6 +1595,54 @@ class TestIPACommand(IntegrationTest):
result = host.run_command([paths.KLIST])
assert host_princ in result.stdout_text
def test_delete_last_enabled_admin(self):
"""
The admin user may be disabled. Don't allow all other
members of admins to be removed if the admin user is
disabled which would leave the install with no
usable admins users
"""
user = 'adminuser2'
passwd = 'Secret123'
tasks.create_active_user(self.master, user, passwd)
tasks.kinit_admin(self.master)
self.master.run_command(['ipa', 'group-add-member', 'admins',
'--users', user])
tasks.kinit_user(self.master, user, passwd)
self.master.run_command(['ipa', 'user-disable', 'admin'])
result = self.master.run_command(
['ipa', 'user-del', user],
raiseonerr=False
)
self.master.run_command(['ipa', 'user-enable', 'admin'])
tasks.kdestroy_all(self.master)
assert result.returncode == 1
assert 'cannot be deleted or disabled' in result.stderr_text
def test_ipa_cacert_manage_prune(self):
"""Test for ipa-cacert-manage prune"""
certfile = os.path.join(self.master.config.test_dir, 'cert.pem')
self.master.put_file_contents(certfile, isrgrootx1)
result = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'install', certfile])
certs_before_prune = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'list'], raiseonerr=False
).stdout_text
assert isrgrootx1_nick in certs_before_prune
# Jump in time to make sure the cert is expired
self.master.run_command(['date', '-s', '+15Years'])
result = self.master.run_command(
[paths.IPA_CACERT_MANAGE, 'prune'], raiseonerr=False
).stdout_text
self.master.run_command(['date', '-s', '-15Years'])
assert isrgrootx1_nick in result
class TestIPACommandWithoutReplica(IntegrationTest):
"""

View File

@ -1046,8 +1046,8 @@ class TestAdmins(XMLRPC_test):
tracker = Tracker()
command = tracker.make_command('user_disable', admin1)
with raises_exact(errors.ProtectedEntryError(label=u'user',
key=admin1, reason='privileged user')):
with raises_exact(errors.LastMemberError(label=u'group',
key=admin1, container=admin_group)):
command()
def test_create_admin2(self, admin2):
@ -1065,8 +1065,8 @@ class TestAdmins(XMLRPC_test):
admin2.disable()
tracker = Tracker()
with raises_exact(errors.ProtectedEntryError(label=u'user',
key=admin1, reason='privileged user')):
with raises_exact(errors.LastMemberError(label=u'group',
key=admin1, container=admin_group)):
tracker.run_command('user_disable', admin1)
admin2.delete()