freeipa/ipatests/test_integration/test_legacy_clients.py
Stanislav Levin d86b57c057 Make use of the single configuration point for the default shells
For now all the default shells of users and admin are hardcoded in
different parts of the project. This makes it impossible to run the
test suite against the setup, which has the default shell differed
from '/bin/sh'.

The single configuration point for the shell of users and admin is
added to overcome this limitation.

Fixes: https://pagure.io/freeipa/issue/7978
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2019-06-19 11:39:51 +02:00

579 lines
21 KiB
Python

# Authors:
# Tomas Babej <tbabej@redhat.com>
#
# Copyright (C) 2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# FIXME: Pylint errors
# pylint: disable=no-member
from __future__ import absolute_import
import os
import re
import unittest
from ipaplatform.constants import constants as platformconstants
from ipaplatform.paths import paths
from ipatests.pytest_ipa.integration import tasks
# importing test_trust under different name to avoid nose executing the test
# base class imported from this module
from ipatests.test_integration import test_trust as trust_tests
class BaseTestLegacyClient:
"""
Tests legacy client support.
"""
advice_id = None
backup_files = ['/etc/sysconfig/authconfig',
'/etc/pam.d',
'/etc/openldap/cacerts',
'/etc/openldap/ldap.conf',
'/etc/nsswitch.conf',
paths.SSSD_CONF]
homedir_template = "/home/{domain}/{username}"
default_shell = platformconstants.DEFAULT_SHELL
required_extra_roles = ()
optional_extra_roles = ()
# Actual test classes need to override these attributes to set the expected
# values on the UID and GID results, since this varies with the usage of the
# POSIX and non-POSIX ID ranges
testuser_uid_regex = None
testuser_gid_regex = None
subdomain_testuser_uid_regex = None
subdomain_testuser_gid_regex = None
treedomain_testuser_uid_regex = None
treedomain_testuser_gid_regex = None
# To allow custom validation dependent on the trust type
posix_trust = False
def test_apply_advice(self):
# Obtain the advice from the server
tasks.kinit_admin(self.master)
result = self.master.run_command(['ipa-advise', self.advice_id])
advice = result.stdout_text
# Apply the advice on the legacy client
advice_path = os.path.join(self.legacy_client.config.test_dir,
'advice.sh')
self.legacy_client.put_file_contents(advice_path, advice)
result = self.legacy_client.run_command(['bash', '-x', '-e',
advice_path])
# Restart SSHD to load new PAM configuration
self.legacy_client.run_command([paths.SBIN_SERVICE, 'sshd', 'restart'])
def clear_sssd_caches(self):
tasks.clear_sssd_cache(self.master)
tasks.clear_sssd_cache(self.legacy_client)
def test_getent_ipa_user(self):
self.clear_sssd_caches()
result = self.legacy_client.run_command(['getent', 'passwd', 'admin'])
admin_regex = r"admin:\*:(\d+):(\d+):"\
r"Administrator:/home/admin:{}".format(
platformconstants.DEFAULT_ADMIN_SHELL,
)
assert re.search(admin_regex, result.stdout_text)
def test_getent_ipa_group(self):
self.clear_sssd_caches()
result = self.legacy_client.run_command(['getent', 'group', 'admins'])
admin_group_regex = r"admins:\*:(\d+):admin"
assert re.search(admin_group_regex, result.stdout_text)
def test_id_ipa_user(self):
self.clear_sssd_caches()
result = self.legacy_client.run_command(['id', 'admin'])
uid_regex = r"uid=(\d+)\(admin\)"
gid_regex = r"gid=(\d+)\(admins\)"
groups_regex = r"groups=(\d+)\(admins\)"
assert re.search(uid_regex, result.stdout_text)
assert re.search(gid_regex, result.stdout_text)
assert re.search(groups_regex, result.stdout_text)
def test_getent_ad_user(self):
self.clear_sssd_caches()
testuser = 'testuser@%s' % self.ad.domain.name
result = self.legacy_client.run_command(['getent', 'passwd', testuser])
testuser_regex = r"testuser@%s:\*:%s:%s:"\
r"Test User:%s:%s"\
% (re.escape(self.ad.domain.name),
self.testuser_uid_regex,
self.testuser_gid_regex,
self.homedir_template.format(
username='testuser',
domain=re.escape(self.ad.domain.name)),
self.default_shell,
)
assert re.search(testuser_regex, result.stdout_text)
def test_getent_ad_group(self):
self.clear_sssd_caches()
testgroup = 'testgroup@%s' % self.ad.domain.name
result = self.legacy_client.run_command(['getent', 'group', testgroup])
testgroup_regex = r"%s:\*:%s:" % (testgroup, self.testuser_gid_regex)
assert re.search(testgroup_regex, result.stdout_text)
def test_id_ad_user(self):
self.clear_sssd_caches()
testuser = 'testuser@%s' % self.ad.domain.name
testgroup = 'testgroup@%s' % self.ad.domain.name
result = self.legacy_client.run_command(['id', testuser])
# Only for POSIX trust testing does the testuser belong to the
# testgroup
group_name = '\(%s\)' % testgroup if self.posix_trust else ''
uid_regex = "uid=%s\(%s\)" % (self.testuser_uid_regex, testuser)
gid_regex = "gid=%s%s" % (self.testuser_gid_regex, group_name)
groups_regex = "groups=%s%s" % (self.testuser_gid_regex, group_name)
assert re.search(uid_regex, result.stdout_text)
assert re.search(gid_regex, result.stdout_text)
assert re.search(groups_regex, result.stdout_text)
def test_login_ipa_user(self):
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
result = self.master.run_command(
'sshpass -p %s '
'ssh '
'-o StrictHostKeyChecking=no '
'-l admin '
'%s '
'"echo test"' %
(self.legacy_client.config.admin_password,
self.legacy_client.hostname))
assert "test" in result.stdout_text
def test_login_ad_user(self):
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
testuser = 'testuser@%s' % self.ad.domain.name
result = self.master.run_command(
'sshpass -p Secret123 '
'ssh '
'-o StrictHostKeyChecking=no '
'-l %s '
'%s '
'"echo test"' %
(testuser, self.legacy_client.hostname))
assert "test" in result.stdout_text
def test_login_disabled_ipa_user(self):
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
self.clear_sssd_caches()
result = self.master.run_command(
'sshpass -p %s '
'ssh '
'-o StrictHostKeyChecking=no '
'-l disabledipauser '
'%s '
'"echo test"'
% (self.legacy_client.config.admin_password,
self.legacy_client.external_hostname),
raiseonerr=False)
assert result.returncode != 0
def test_login_disabled_ad_user(self):
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
testuser = 'disabledaduser@%s' % self.ad.domain.name
result = self.master.run_command(
'sshpass -p Secret123 '
'ssh '
'-o StrictHostKeyChecking=no '
'-l %s '
'%s '
'"echo test"' %
(testuser, self.legacy_client.external_hostname),
raiseonerr=False)
assert result.returncode != 0
def test_getent_subdomain_ad_user(self):
if not self.ad_subdomain:
raise unittest.SkipTest('AD for the subdomain is not available.')
self.clear_sssd_caches()
testuser = 'subdomaintestuser@%s' % self.ad_subdomain
result = self.legacy_client.run_command(['getent', 'passwd', testuser])
testuser_regex = r"subdomaintestuser@%s:\*:%s:%s:"\
r"Subdomaintest User:%s:"\
r"%s"\
% (re.escape(self.ad_subdomain),
self.subdomain_testuser_uid_regex,
self.subdomain_testuser_gid_regex,
self.homedir_template.format(
username='subdomaintestuser',
domain=re.escape(self.ad_subdomain)),
self.default_shell,
)
assert re.search(testuser_regex, result.stdout_text)
def test_getent_subdomain_ad_group(self):
if not self.ad_subdomain:
raise unittest.SkipTest('AD for the subdomain is not available.')
self.clear_sssd_caches()
testgroup = 'subdomaintestgroup@%s' % self.ad_subdomain
result = self.legacy_client.run_command(['getent', 'group', testgroup])
testgroup_stdout = r"%s:\*:%s:" % (testgroup,
self.subdomain_testuser_gid_regex)
assert re.search(testgroup_stdout, result.stdout_text)
def test_id_subdomain_ad_user(self):
if not self.ad_subdomain:
raise unittest.SkipTest('AD for the subdomain is not available.')
self.clear_sssd_caches()
testuser = 'subdomaintestuser@%s' % self.ad_subdomain
testgroup = 'subdomaintestgroup@%s' % self.ad_subdomain
result = self.legacy_client.run_command(['id', testuser])
# Only for POSIX trust testing does the testuser belong to the
# testgroup
group_name = '\(%s\)' % testgroup if self.posix_trust else ''
uid_regex = "uid=%s\(%s\)" % (self.subdomain_testuser_uid_regex,
testuser)
gid_regex = "gid=%s%s" % (self.subdomain_testuser_gid_regex,
group_name)
groups_regex = "groups=%s%s" % (self.subdomain_testuser_gid_regex,
group_name)
assert re.search(uid_regex, result.stdout_text)
assert re.search(gid_regex, result.stdout_text)
assert re.search(groups_regex, result.stdout_text)
def test_login_subdomain_ad_user(self):
if not self.ad_subdomain:
raise unittest.SkipTest('AD for the subdomain is not available.')
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
testuser = 'subdomaintestuser@%s' % self.ad_subdomain
result = self.master.run_command(
'sshpass -p Secret123 '
'ssh '
'-o StrictHostKeyChecking=no '
'-l %s '
'%s '
'"echo test"' %
(testuser, self.legacy_client.external_hostname))
assert "test" in result.stdout_text
def test_login_disabled_subdomain_ad_user(self):
if not self.ad_subdomain:
raise unittest.SkipTest('AD for the subdomain is not available.')
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest('Package sshpass not available on %s'
% self.master.hostname)
testuser = 'subdomaindisabledaduser@%s' % self.ad_subdomain
result = self.master.run_command(
'sshpass -p Secret123 '
'ssh '
'-o StrictHostKeyChecking=no '
'-l %s '
'%s '
'"echo test"' %
(testuser, self.legacy_client.external_hostname),
raiseonerr=False)
assert result.returncode != 0
def test_getent_treedomain_ad_user(self):
if not self.ad_treedomain:
raise unittest.SkipTest('AD tree root domain is not available.')
self.clear_sssd_caches()
testuser = 'treetestuser@{0}'.format(self.ad_treedomain)
result = self.legacy_client.run_command(['getent', 'passwd', testuser])
testuser_regex = (r"treetestuser@{0}:\*:{1}:{2}:TreeTest User:"
r"/home/{0}/treetestuser:{3}".format(
re.escape(self.ad_treedomain),
self.treedomain_testuser_uid_regex,
self.treedomain_testuser_gid_regex,
self.default_shell,
))
assert re.search(testuser_regex, result.stdout_text)
def test_getent_treedomain_ad_group(self):
if not self.ad_treedomain:
raise unittest.SkipTest('AD tree root domain is not available')
self.clear_sssd_caches()
testgroup = 'treetestgroup@{0}'.format(self.ad_treedomain)
result = self.legacy_client.run_command(['getent', 'group', testgroup])
testgroup_stdout = r"{0}:\*:{1}:".format(
testgroup, self.treedomain_testuser_gid_regex)
assert re.search(testgroup_stdout, result.stdout_text)
def test_id_treedomain_ad_user(self):
if not self.ad_treedomain:
raise unittest.SkipTest('AD tree root domain is not available')
self.clear_sssd_caches()
testuser = 'treetestuser@{0}'.format(self.ad_treedomain)
testgroup = 'treetestgroup@{0}'.format(self.ad_treedomain)
result = self.legacy_client.run_command(['id', testuser])
# Only for POSIX trust testing does the testuser belong to the
# testgroup
group_name = '\({}\)'.format(testgroup) if self.posix_trust else ''
uid_regex = "uid={0}\({1}\)".format(
self.treedomain_testuser_uid_regex, testuser)
gid_regex = "gid={0}{1}".format(
self.treedomain_testuser_gid_regex, group_name)
group_regex = "groups={0}{1}".format(
self.treedomain_testuser_gid_regex, group_name)
assert re.search(uid_regex, result.stdout_text)
assert re.search(gid_regex, result.stdout_text)
assert re.search(group_regex, result.stdout_text)
def test_login_treedomain_ad_user(self):
if not self.ad_treedomain:
raise unittest.SkipTest('AD tree root domain is not available.')
if not self.master.transport.file_exists('/usr/bin/sshpass'):
raise unittest.SkipTest(
'Package sshpass not available on {}'.format(
self.master.hostname)
)
result = self.master.run_command(
'sshpass -p {0} ssh -o StrictHostKeyChecking=no '
'-l admin {1} "echo test"'.format(
self.legacy_client.config.admin_password,
self.legacy_client.external_hostname))
assert "test" in result.stdout_text
@classmethod
def install(cls, mh):
super(BaseTestLegacyClient, cls).install(mh)
tasks.kinit_admin(cls.master)
password_confirmation = (
cls.master.config.admin_password +
'\n' +
cls.master.config.admin_password
)
cls.master.run_command(['ipa', 'user-add', 'disabledipauser',
'--first', 'disabled',
'--last', 'ipauser',
'--password'],
stdin_text=password_confirmation)
cls.master.run_command(['ipa', 'user-disable', 'disabledipauser'])
cls.ad = cls.ad_domains[0].ads[0]
cls.legacy_client = cls.host_by_role(cls.required_extra_roles[0])
# Determine whether the subdomain AD is available
try:
child_ad = cls.host_by_role(cls.optional_extra_roles[0])
cls.ad_subdomain = '.'.join(
child_ad.hostname.split('.')[1:])
except LookupError:
cls.ad_subdomain = None
# Determine whether the tree domain AD is available
try:
cls.tree_ad = cls.host_by_role(cls.optional_extra_roles[1])
cls.ad_treedomain = '.'.join(
cls.tree_ad.hostname.split('.')[1:])
except LookupError:
cls.ad_treedomain = None
tasks.apply_common_fixes(cls.legacy_client)
for f in cls.backup_files:
tasks.backup_file(cls.legacy_client, f)
@classmethod
def uninstall(cls, mh):
cls.master.run_command(['ipa', 'user-del', 'disabledipauser'],
raiseonerr=False)
# Remove information about trust from AD, if domain was defined
if hasattr(cls, 'ad_domain'):
tasks.remove_trust_info_from_ad(cls.master, cls.ad_domain)
# Also unapply fixes on the legacy client, if defined
if hasattr(cls, 'legacy_client'):
tasks.unapply_fixes(cls.legacy_client)
super(BaseTestLegacyClient, cls).uninstall(mh)
# Base classes with attributes that are specific for each legacy client test
class BaseTestLegacySSSDBefore19RedHat:
advice_id = 'config-redhat-sssd-before-1-9'
required_extra_roles = ['legacy_client_sssd_redhat']
optional_extra_roles = ['ad_subdomain', 'ad_treedomain']
class BaseTestLegacyNssPamLdapdRedHat:
advice_id = 'config-redhat-nss-pam-ldapd'
required_extra_roles = ['legacy_client_nss_pam_ldapd_redhat']
optional_extra_roles = ['ad_subdomain', 'ad_treedomain']
def clear_sssd_caches(self):
tasks.clear_sssd_cache(self.master)
class BaseTestLegacyNssLdapRedHat:
advice_id = 'config-redhat-nss-ldap'
required_extra_roles = ['legacy_client_nss_ldap_redhat']
optional_extra_roles = ['ad_subdomain', 'ad_treedomain']
def clear_sssd_caches(self):
tasks.clear_sssd_cache(self.master)
# Base classes that join legacy client specific steps with steps required
# to setup IPA with trust (both with and without using the POSIX attributes)
class BaseTestLegacyClientPosix(trust_tests.BaseTestTrust,
BaseTestLegacyClient):
testuser_uid_regex = '10042'
testuser_gid_regex = '10047'
subdomain_testuser_uid_regex = '10142'
subdomain_testuser_gid_regex = '10147'
treedomain_testuser_uid_regex = '10242'
treedomain_testuser_gid_regex = '10247'
posix_trust = True
def test_remove_trust_with_posix_attributes(self):
pass
class BaseTestLegacyClientNonPosix(trust_tests.BaseTestTrust,
BaseTestLegacyClient):
testuser_uid_regex = r'(?!10042)(\d+)'
testuser_gid_regex = r'(?!10047)(\d+)'
subdomain_testuser_uid_regex = r'(?!10142)(\d+)'
subdomain_testuser_gid_regex = r'(?!10147)(\d+)'
treedomain_testuser_uid_regex = r'(?!10242)(\d+)'
treedomain_testuser_gid_regex = r'(?!10247)(\d+)'
def test_remove_nonposix_trust(self):
pass
class BaseTestSSSDMixin:
def test_apply_advice(self):
super(BaseTestSSSDMixin, self).test_apply_advice()
tasks.setup_sssd_debugging(self.legacy_client)
# Tests definitions themselves. Beauty. Just pure beauty.
class TestLegacySSSDBefore19RedHatNonPosix(BaseTestSSSDMixin,
BaseTestLegacySSSDBefore19RedHat,
BaseTestLegacyClientNonPosix):
pass
class TestLegacyNssPamLdapdRedHatNonPosix(BaseTestLegacyNssPamLdapdRedHat,
BaseTestLegacyClientNonPosix):
pass
class TestLegacyNssLdapRedHatNonPosix(BaseTestLegacyNssLdapRedHat,
BaseTestLegacyClientNonPosix):
pass
class TestLegacySSSDBefore19RedHatPosix(BaseTestSSSDMixin,
BaseTestLegacySSSDBefore19RedHat,
BaseTestLegacyClientPosix):
pass
class TestLegacyNssPamLdapdRedHatPosix(BaseTestLegacyNssPamLdapdRedHat,
BaseTestLegacyClientPosix):
pass
class TestLegacyNssLdapRedHatPosix(BaseTestLegacyNssLdapRedHat,
BaseTestLegacyClientPosix):
pass