summaryrefslogtreecommitdiffstats
path: root/src/tests/multihost/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/multihost/basic')
-rw-r--r--src/tests/multihost/basic/mhc.yaml8
-rw-r--r--src/tests/multihost/basic/test_basic.py88
-rw-r--r--src/tests/multihost/basic/test_config.py114
-rw-r--r--src/tests/multihost/basic/test_files.py78
-rw-r--r--src/tests/multihost/basic/test_ifp.py37
-rw-r--r--src/tests/multihost/basic/test_kcm.py340
-rw-r--r--src/tests/multihost/basic/test_sssctl_config_check.py107
-rw-r--r--src/tests/multihost/basic/test_sudo.py66
-rw-r--r--src/tests/multihost/basic/utils_config.py32
9 files changed, 870 insertions, 0 deletions
diff --git a/src/tests/multihost/basic/mhc.yaml b/src/tests/multihost/basic/mhc.yaml
new file mode 100644
index 0000000..24d5054
--- /dev/null
+++ b/src/tests/multihost/basic/mhc.yaml
@@ -0,0 +1,8 @@
+root_password: 'vagrant'
+domains:
+- name: tier0.tests
+ type: sssd
+ hosts:
+ - name: client
+ external_hostname: client.test
+ role: master
diff --git a/src/tests/multihost/basic/test_basic.py b/src/tests/multihost/basic/test_basic.py
new file mode 100644
index 0000000..72f092e
--- /dev/null
+++ b/src/tests/multihost/basic/test_basic.py
@@ -0,0 +1,88 @@
+""" SSSD Sanity Test Cases
+
+:requirement: IDM-SSSD-REQ : KRB5 Provider
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+import pytest
+import time
+import configparser as ConfigParser
+from sssd.testlib.common.utils import sssdTools
+
+
+class TestSanitySSSD(object):
+ """ Basic Sanity Test cases """
+ @pytest.mark.converted('test_authentication.py', 'test_authentication__login')
+ @staticmethod
+ def test_ssh_user_login(multihost):
+ """
+ :title: Login: Check ssh login as LDAP user with Kerberos credentials
+ :id: b7600a46-1827-486a-ae2e-cbedad6ddf41
+ """
+ client = sssdTools(multihost.master[0])
+ ssh0 = client.auth_from_client("foo1", 'Secret123') == 3
+ assert ssh0, "Authentication Failed as user foo1"
+
+ @pytest.mark.converted('test_kcm.py', 'test_kcm__simple_kinit')
+ @staticmethod
+ def test_kinit(multihost):
+ """
+ :title: Login: Verify kinit is successfull after user login
+ :id: 5e15e9e9-c559-49b8-a164-abe13d82d0fd
+ """
+ user = 'foo2'
+ cmd = multihost.master[0].run_command(
+ f'su - {user} -c "kinit"', stdin_text='Secret123',
+ raiseonerr=False)
+ assert cmd.returncode == 0, "kinit failed!"
+
+ cmd2 = multihost.master[0].run_command(
+ f'su - {user} -c "klist"', raiseonerr=False)
+ assert cmd2.returncode == 0, "klist failed!"
+
+ @pytest.mark.converted('test_authentication.py', 'test_authentication__offline_login')
+ @staticmethod
+ def test_offline_ssh_login(multihost):
+ """
+ :title: Login: Verify offline ssh login
+ :id: 90e9a834-a1f9-4bef-bdae-57a7b411cce4
+ """
+ multihost.master[0].transport.get_file('/etc/sssd/sssd.conf',
+ '/tmp/sssd.conf')
+ sssdconfig = ConfigParser.RawConfigParser()
+ sssdconfig.read('/tmp/sssd.conf')
+ domain_section = "%s/%s" % ('domain', 'EXAMPLE.TEST')
+ if domain_section in sssdconfig.sections():
+ sssdconfig.set(domain_section, 'cache_credentials', 'True')
+ sssdconfig.set(domain_section, 'krb5_store_password_if_offline',
+ 'True')
+ sssdconfig.set('pam', 'offline_credentials_expiration', '0')
+ with open('/tmp/sssd.conf', "w") as file_d:
+ sssdconfig.write(file_d)
+ else:
+ print("Could not fetch sssd.conf")
+ assert False
+ multihost.master[0].transport.put_file('/tmp/sssd.conf',
+ '/etc/sssd/sssd.conf')
+ multihost.master[0].service_sssd('restart')
+ time.sleep(5)
+ client = sssdTools(multihost.master[0])
+ user = 'foo4'
+ ssh0 = client.auth_from_client(user, password='Secret123') == 3
+ assert ssh0, f"Initial ssh login as {user} failed."
+
+ stop_dirsrv = 'systemctl stop dirsrv@example1'
+ stop_krb5kdc = 'systemctl stop krb5kdc'
+ multihost.master[0].run_command(stop_dirsrv)
+ multihost.master[0].run_command(stop_krb5kdc)
+
+ ssh1 = client.auth_from_client(user, password='Secret123') == 3
+
+ start_dirsrv = 'systemctl start dirsrv@example1'
+ start_krb5kdc = 'systemctl start krb5kdc'
+ multihost.master[0].run_command(start_dirsrv)
+ multihost.master[0].run_command(start_krb5kdc)
+
+ assert ssh1, f"Offline ssh login as {user} failed."
diff --git a/src/tests/multihost/basic/test_config.py b/src/tests/multihost/basic/test_config.py
new file mode 100644
index 0000000..8d4847b
--- /dev/null
+++ b/src/tests/multihost/basic/test_config.py
@@ -0,0 +1,114 @@
+""" SSSD Configuration-related Test Cases
+
+:requirement: IDM-SSSD-REQ: Configuration merging
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+
+import pytest
+from utils_config import remove_section, set_param
+
+
+class TestSSSDConfig(object):
+ """
+ Test cases around SSSD config management
+ """
+ def _assert_config_value(self, multihost, section, key, value):
+ # This would really be much, much nicer to implement using python-ldb
+ # but at the moment, the multihost tests rely on a virtual environment
+ # where everything is pip-installed..and python-ldb is not present in
+ # pip
+ confdb_dn = 'cn=%s,cn=config' % (section)
+ ldb_cmd = 'ldbsearch -H /var/lib/sss/db/config.ldb -b %s' % (confdb_dn)
+ cmd = multihost.master[0].run_command(ldb_cmd)
+ check_str = '%s: %s' % (key, value)
+ assert check_str in cmd.stdout_text
+
+ @pytest.mark.converted('test_config.py', 'test_config__change_config_while_sssd_running')
+ def test_sssd_genconf_sssd_running(self, multihost):
+ """
+ :title: config: sssd --genconf is able to re-generate
+ the configuration even while SSSD is running
+ :id: 078721e9-536b-4fd8-a36d-bd94673228fc
+ """
+ multihost.master[0].service_sssd('restart')
+
+ self._assert_config_value(multihost, 'pam', 'debug_level', '9')
+
+ set_param(multihost, 'pam', 'debug_level', '1')
+ multihost.master[0].run_command('/usr/sbin/sssd --genconf')
+ self._assert_config_value(multihost, 'pam', 'debug_level', '1')
+
+ set_param(multihost, 'pam', 'debug_level', '9')
+
+ @pytest.mark.converted('test_config.py', 'test_config__genconf_particular_section')
+ def test_sssd_genconf_section_only(self, multihost):
+ """
+ :title: config: sssd --genconf-section only
+ refreshes those sections given on the command line
+ :id: 011bf2ad-4a2a-4350-adfa-7826349e262f
+ """
+ multihost.master[0].service_sssd('restart')
+
+ self._assert_config_value(multihost, 'pam', 'debug_level', '9')
+ self._assert_config_value(multihost, 'nss', 'debug_level', '9')
+
+ set_param(multihost, 'pam', 'debug_level', '1')
+ set_param(multihost, 'nss', 'debug_level', '1')
+ multihost.master[0].run_command(
+ '/usr/sbin/sssd --genconf-section=pam')
+
+ # We only told genconf to touch the pam section..
+ self._assert_config_value(multihost, 'pam', 'debug_level', '1')
+ # ..so the NSS section shouldn't be updated at all
+ self._assert_config_value(multihost, 'nss', 'debug_level', '9')
+
+ set_param(multihost, 'nss', 'debug_level', '9')
+ set_param(multihost, 'pam', 'debug_level', '9')
+
+ @pytest.mark.converted('test_config.py', 'test_config__add_remove_section')
+ def test_sssd_genconf_add_remove_section(self, multihost):
+ """
+ :title: config: sssd --genconf-section can not only modify
+ existing configuration sections, but also add a new section
+ :id: 8df66b51-aadc-456e-8f27-a1a787e61769
+ """
+ # Establish a baseline
+ multihost.master[0].service_sssd('restart')
+ self._assert_config_value(multihost, 'pam', 'debug_level', '9')
+ self._assert_config_value(multihost, 'nss', 'debug_level', '9')
+
+ set_param(multihost, 'foo', 'bar', 'baz')
+
+ multihost.master[0].run_command(
+ '/usr/sbin/sssd --genconf-section=foo')
+
+ ldb_cmd = 'ldbsearch -H /var/lib/sss/db/config.ldb -b cn=foo,cn=config'
+ cmd = multihost.master[0].run_command(ldb_cmd)
+ assert 'bar: baz' in cmd.stdout_text
+
+ remove_section(multihost, 'foo')
+ multihost.master[0].run_command(
+ '/usr/sbin/sssd --genconf-section=foo')
+
+ ldb_cmd = 'ldbsearch -H /var/lib/sss/db/config.ldb -b cn=foo,cn=config'
+ cmd = multihost.master[0].run_command(ldb_cmd)
+ assert 'foo' not in cmd.stdout_text
+ # Also make sure the existing sections were intact
+ self._assert_config_value(multihost, 'pam', 'debug_level', '9')
+ self._assert_config_value(multihost, 'nss', 'debug_level', '9')
+
+ @pytest.mark.converted('test_config.py', 'test_config__genconf_no_such_section')
+ def test_sssd_genconf_no_such_section(self, multihost):
+ """
+ :title: config: Referencing a non-existant section must not fail
+ :id: 4e160dcc-9789-4f3f-b8d4-c67d27ef4a1c
+ :description: Referencing a non-existant section must not fail,
+ because we want to call this command from the systemd unit files
+ and by default the sections don't have to be present
+ """
+ multihost.master[0].service_sssd('restart')
+ multihost.master[0].run_command(
+ '/usr/sbin/sssd --genconf-section=xyz')
diff --git a/src/tests/multihost/basic/test_files.py b/src/tests/multihost/basic/test_files.py
new file mode 100644
index 0000000..5a1c8c2
--- /dev/null
+++ b/src/tests/multihost/basic/test_files.py
@@ -0,0 +1,78 @@
+"""Files test provider cases
+
+:requirement: IDM-SSSD-REQ :: SSSD is default for local resolution
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+import pytest
+
+
+def have_files_provider(multihost):
+ cmd = multihost.master[0].run_command('man sssd-files | grep files', raiseonerr=False)
+ return cmd.returncode == 0
+
+
+def get_sss_entry(multihost, db, ent_name):
+ cmd = multihost.master[0].run_command('getent %s -s sss %s' % (db, ent_name), raiseonerr=False)
+ return cmd.returncode, cmd.stdout_text
+
+
+def get_sss_user(multihost, username):
+ return get_sss_entry(multihost, 'passwd', username)
+
+
+@pytest.mark.usefixtures('enable_files_domain', 'files_domain_users_class')
+class TestImplicitFilesProvider(object):
+ """
+ Test the files provider. This test runs the implicit files provider
+ together with another domain to stick close to what users use in Fedora
+ """
+ @pytest.mark.converted('test_files.py', 'test_files__getent_does_not_handle_root')
+ def test_files_does_not_handle_root(self, multihost):
+ """
+ :title: files: files provider does not handle root
+ :id: 5aa5165d-379f-4fc6-b4ed-b32b66406d4f
+ """
+ if not have_files_provider(multihost):
+ pytest.skip("Files Provider support isn't available, skipping")
+ exit_status, _ = get_sss_user(multihost, 'root')
+ assert exit_status == 2
+
+ @pytest.mark.converted('test_files.py', 'test_files__simple_getent')
+ def test_files_sanity(self, multihost):
+ """
+ :title: files: Test that the files provider can resolve a user
+ :id: 242cd094-b04d-4857-981a-8624573dde84
+ """
+ if not have_files_provider(multihost):
+ pytest.skip("Files Provider support isn't available, skipping")
+ exit_status, _ = get_sss_user(multihost, 'lcl1')
+ assert exit_status == 0
+
+ @pytest.mark.converted('test_files.py', 'test_files__enumeration')
+ def test_files_enumeration(self, multihost):
+ """
+ :title: files: Verify files provider do not enumerate
+ :id: e6d922bf-3af2-4cea-8570-6dd9233da624
+ :description: Since nss_files enumerates and libc would
+ concatenate the results, the files provider of SSSD should
+ not enumerate
+ """
+ if not have_files_provider(multihost):
+ pytest.skip("Files Provider support isn't available, skipping")
+ cmd = multihost.master[0].run_command('getent passwd -s sss')
+ assert len(cmd.stdout_text) == 0
+
+ @pytest.mark.converted('test_files.py', 'test_files__user_modify')
+ def test_updated_homedir(self, multihost):
+ """
+ :title: files: Test that homedir is updated
+ :id: a9a0a911-1818-40d1-b897-0397ef107fd4
+ """
+ if not have_files_provider(multihost):
+ pytest.skip("Files Provider support isn't available, skipping")
+ exit_status, output = get_sss_user(multihost, 'no_home_user')
+ assert exit_status == 0
+ assert ":/tmp:" in output
diff --git a/src/tests/multihost/basic/test_ifp.py b/src/tests/multihost/basic/test_ifp.py
new file mode 100644
index 0000000..a8cf24b
--- /dev/null
+++ b/src/tests/multihost/basic/test_ifp.py
@@ -0,0 +1,37 @@
+"""InfoPipe test cases
+
+:requirement: IDM-SSSD-REQ : Configuration and Service Management
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+import pytest
+
+
+class TestInfoPipe(object):
+ """
+ Test the InfoPipe responder
+ """
+ def test_ifp_extra_attributes_property(self, multihost):
+ """
+ :title: ifp: requesting the extraAttributes property works
+ :id: 23b8c7e8-df4b-47ef-b38e-0503040e1d67
+ see e.g. https://github.com/SSSD/sssd/issues/4891
+ """
+ # Note that this test needs dbus-tools package that
+ # is not implicitly installed here.
+ check_ifp = "libsss_simpleifp" in multihost.master[0].run_command("rpm -qa").stdout_text
+ if not check_ifp:
+ pytest.skip("libsss_simpleifp is not present, skipping test.")
+ dbus_send_cmd = \
+ """
+ dbus-send --print-reply --system \
+ --dest=org.freedesktop.sssd.infopipe \
+ /org/freedesktop/sssd/infopipe/Users/LDAP_2eTEST/123 \
+ org.freedesktop.DBus.Properties.Get \
+ string:"org.freedesktop.sssd.infopipe.Users.User" \
+ string:"extraAttributes"
+ """
+ cmd = multihost.master[0].run_command(dbus_send_cmd)
+ assert cmd.returncode == 0
diff --git a/src/tests/multihost/basic/test_kcm.py b/src/tests/multihost/basic/test_kcm.py
new file mode 100644
index 0000000..8f527f6
--- /dev/null
+++ b/src/tests/multihost/basic/test_kcm.py
@@ -0,0 +1,340 @@
+""" KCM Responder Sanity Test Cases
+
+:requirement: IDM-SSSD-REQ :: SSSD KCM as default Kerberos CCACHE provider
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+import os
+import re
+import pytest
+from pexpect import pxssh
+from utils_config import set_param
+from sssd.testlib.common.utils import sssdTools
+
+
+class TestSanityKCM(object):
+ """ KCM Sanity Test cases """
+ def _kcm_service_op(self, multihost, svc_op):
+ systemd_kcm_op = 'systemctl %s sssd-kcm' % (svc_op)
+ multihost.master[0].run_command(systemd_kcm_op)
+
+ def _start_kcm(self, multihost):
+ self._kcm_service_op(multihost, 'start')
+
+ def _stop_kcm(self, multihost):
+ self._kcm_service_op(multihost, 'stop')
+
+ def _restart_kcm(self, multihost):
+ self._kcm_service_op(multihost, 'restart')
+
+ def _remove_kcm_log_file(self, multihost):
+ multihost.master[0].run_command('rm -f /var/log/sssd/sssd_kcm.log')
+
+ def _kcm_log_length(self, multihost):
+ basename = 'sssd_kcm.log'
+ kcm_log_file = '/var/log/sssd/' + basename
+ local_kcm_log_file = '/tmp/kcm.log'
+ try:
+ multihost.master[0].transport.get_file(kcm_log_file,
+ local_kcm_log_file)
+ except FileNotFoundError:
+ return 0
+
+ nlines = sum(1 for line in open(local_kcm_log_file))
+ os.remove(local_kcm_log_file)
+ return nlines
+
+ def _remove_secret_db(self, multihost):
+ multihost.master[0].run_command(
+ 'rm -f /var/lib/sss/secrets/secrets.ldb')
+ self._restart_kcm(multihost)
+
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_kinit_kcm(self, multihost):
+ """
+ :title: kcm: Run kinit with KRB5CCNAME=KCM
+ :id: 245eecf6-04b9-4c9f-8685-681d184fbbcf
+ """
+ self._start_kcm(multihost)
+
+ user = 'foo3'
+ cmd = multihost.master[0].run_command(
+ f'su - {user} -c "KRB5CCNAME=KCM:; kinit"', stdin_text='Secret123',
+ raiseonerr=False)
+ assert cmd.returncode == 0, "kinit failed!"
+
+ cmd2 = multihost.master[0].run_command(
+ f'su - {user} -c "KRB5CCNAME=KCM:; klist"', raiseonerr=False)
+ assert cmd2.returncode == 0, "klist failed!"
+ assert 'Ticket cache: KCM:14583103' in cmd2.stdout_text
+
+ @staticmethod
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_ssh_login_kcm(multihost):
+ """
+ :title: kcm: Verify ssh logins are successuful with kcm as default
+ :id: 458ed1e4-b908-40d3-b2fd-392e8d2dcf4b
+ """
+ # pylint: disable=unused-argument
+ client = sssdTools(multihost.master[0])
+ ssh0 = client.auth_from_client("foo4", 'Secret123') == 3
+ if not ssh0:
+ multihost.master[0].run_command(
+ 'journalctl -u sssd -n 50 --no-pager')
+ assert ssh0, "Authentication Failed as user foo4"
+
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_kcm_debug_level_set(self, multihost):
+ """
+ :title: kcm: After kcm section with debug
+ level set restaring sssd-kcm service enables kcm debugging
+ :id: 31c74bfc-69d5-46bd-aef8-a5581970832e
+ :description: Test that just adding a [kcm] section and restarting
+ the kcm service enables debugging without having to restart the
+ whole sssd
+ """
+ # Start from a known-good state where the configuration is refreshed
+ # by the monitor and logging is completely disabled
+ multihost.master[0].service_sssd('stop')
+ self._stop_kcm(multihost)
+ self._remove_kcm_log_file(multihost)
+ set_param(multihost, 'kcm', 'debug_level', '0')
+ multihost.master[0].service_sssd('start')
+ self._start_kcm(multihost)
+
+ log_lines_pre = self._kcm_log_length(multihost)
+
+ # Debugging is disabled, kinit and make sure that no debug messages
+ # were produced
+ user = 'foo3'
+ client = sssdTools(multihost.master[0])
+ ssh0 = client.auth_from_client(user, 'Secret123') == 3
+ assert ssh0, f"Authentication Failed as user {user}."
+
+ multihost.master[0].run_command(
+ f'su - {user} -c "kdestroy"', raiseonerr=False)
+
+ log_lines_nodebug = self._kcm_log_length(multihost)
+ assert log_lines_nodebug == log_lines_pre
+
+ # Enable debugging, restart only the kcm service, make sure some
+ # debug messages were produced
+ set_param(multihost, 'kcm', 'debug_level', '9')
+ self._restart_kcm(multihost)
+
+ ssh1 = client.auth_from_client(user, 'Secret123') == 3
+ assert ssh1, f"Authentication Failed as user {user}."
+
+ multihost.master[0].run_command(
+ f'su - {user} -c "kdestroy"', raiseonerr=False)
+
+ log_lines_debug = self._kcm_log_length(multihost)
+ assert log_lines_debug > log_lines_pre + 100
+
+ @staticmethod
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_kdestroy_retval(multihost):
+ """
+ :title: kcm: Test that destroying an empty cache does
+ not return a non-zero return code
+ :id: 2826097f-e6d7-4d99-ac85-3ee081aa681a
+ """
+
+ user = 'foo3'
+ client = sssdTools(multihost.master[0])
+ ssh0 = client.auth_from_client(user, 'Secret123') == 3
+ assert ssh0, f"Authentication Failed as user {user}."
+
+ kd1 = multihost.master[0].run_command(
+ f'su -l {user} -c "kdestroy"', raiseonerr=False)
+ assert kd1.returncode == 0, "First kdestroy failed!"
+
+ # Run the command again in case there was something in the ccache
+ # previously
+ kd2 = multihost.master[0].run_command(
+ f'su -l {user} -c "kdestroy"', raiseonerr=False)
+ assert kd2.returncode == 0, "Second kdestroy failed!"
+
+ @staticmethod
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_ssh_forward_creds(multihost):
+ """
+ :title: kcm: Test that SSH can forward credentials with KCM
+ :id: f4b0c785-a895-48a1-a55e-7519cf221393
+ :ticket: https://github.com/SSSD/sssd/issues/4863
+ """
+ ssh = pxssh.pxssh(options={"StrictHostKeyChecking": "no",
+ "UserKnownHostsFile": "/dev/null"})
+ ssh.force_password = True
+ try:
+ ssh.login(multihost.master[0].sys_hostname, 'foo3', 'Secret123')
+ ssh.sendline('kdestroy -A -q')
+ ssh.prompt(timeout=5)
+ ssh.sendline('kinit foo9')
+ ssh.expect('Password for .*:', timeout=10)
+ ssh.sendline('Secret123')
+ ssh.prompt(timeout=5)
+ ssh.sendline('klist')
+ ssh.prompt(timeout=5)
+ klist = str(ssh.before)
+ ssh.sendline(f'ssh -v -o StrictHostKeyChecking=no -K -l foo9 '
+ f'{multihost.master[0].sys_hostname} klist')
+ ssh.prompt(timeout=30)
+ ssh_output = str(ssh.before)
+ ssh.logout()
+ except pxssh.ExceptionPxssh as ex:
+ pytest.fail(ex)
+ # Note: The cache is based on uid so for foo3 it is 14583103 and
+ # for foo9 it is 14583109 (see create_posix_usersgroups fixture)
+ assert 'KCM:14583103' in klist, "kinit did not work!"
+ assert 'KCM:14583109' in ssh_output, "Ticket not forwarded!"
+
+ @staticmethod
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_kvno_display(multihost):
+ """
+ :title: kcm: Test kvno correctly displays version numbers of principals
+ :id: 7c9178e6-fea5-44a1-b473-76667624cee2
+ :ticket: https://github.com/SSSD/sssd/issues/4763
+ """
+ host_princ = f'host/{multihost.master[0].sys_hostname}@EXAMPLE.TEST'
+ kvno_cmd = f'kvno {host_princ}'
+
+ client = sssdTools(multihost.master[0])
+ client.auth_from_client('foo4', 'Secret123')
+
+ kvno = multihost.master[0].run_command(
+ f'su -l foo4 -c "{kvno_cmd}"', raiseonerr=False)
+ assert kvno.returncode == 0, "kvno failed!"
+
+ for line in kvno.stdout_text.splitlines():
+ kvno_check = re.search(r'%s: kvno = (\d+)' % host_princ, line)
+ if kvno_check:
+ print(kvno_check.group())
+ else:
+ pytest.fail("kvno display was improper")
+
+ @pytest.mark.usefixtures("enable_kcm", "create_many_user_principals")
+ def test_kcm_peruid_quota(self, multihost):
+ """
+ :title: kcm: Make sure the quota limits a client, but only that client
+ :id: 3ac8f62e-05e4-4ca7-b588-145fd6258c2a
+ """
+ # It is easier to keep these tests stable and independent from others
+ # if they start from a clean slate
+ self._remove_secret_db(multihost)
+
+ client = sssdTools(multihost.master[0])
+ client.auth_from_client('foo2', 'Secret123')
+ client.auth_from_client('foo3', 'Secret123')
+
+ # The loop would request 63 users, plus there is foo3 we authenticated
+ # earlier, so this should exactly deplete the quota, but should succeed
+ for i in range(1, 64):
+ username = "user%04d" % i
+ kinit = multihost.master[0].run_command(
+ f'su -l foo3 -c "kinit {username}"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit.returncode == 0
+
+ # this kinit should be exactly one over the peruid limit
+ kinit_f = multihost.master[0].run_command(
+ 'su -l foo3 -c "kinit user0064"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit_f.returncode != 0
+
+ # Since this is a per-uid limit, another user should be able to kinit
+ # just fine
+ # this kinit should be exactly one over the peruid limit
+ kinit_o = multihost.master[0].run_command(
+ 'su -l foo2 -c "kinit user0064"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit_o.returncode == 0
+
+ # kdestroy as the original user, the quota should allow a subsequent
+ # kinit
+ multihost.master[0].run_command(
+ 'su -l foo3 -c "kdestroy -A"', raiseonerr=False)
+ kinit_p = multihost.master[0].run_command(
+ 'su -l foo3 -c "kinit user0064"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit_p.returncode == 0
+
+ multihost.master[0].run_command(
+ 'su -l foo2 -c "kdestroy -A"', raiseonerr=False)
+
+ multihost.master[0].run_command(
+ 'su -l foo3 -c "kdestroy -A"', raiseonerr=False)
+
+ @pytest.mark.usefixtures("enable_kcm", "create_many_user_principals")
+ def test_kcm_peruid_quota_increase(self, multihost):
+ """
+ :title: kcm: Quota increase
+ :id: 0b3cab49-befb-4ab2-bb12-b102d94249aa
+ :description: Increasing the peruid quota allows a client to store
+ more data
+ """
+ # It is easier to keep these tests stable and independent from others
+ # if they start from a clean slate
+ self._remove_secret_db(multihost)
+ user = 'foo3'
+ client = sssdTools(multihost.master[0])
+ client.auth_from_client(user, 'Secret123')
+
+ # The loop would request 63 users, plus there is foo3 we authenticated
+ # earlier, so this should exactly deplete the quota, but should succeed
+ for i in range(1, 64):
+ username = "user%04d" % i
+ kinit = multihost.master[0].run_command(
+ f'su -l {user} -c "kinit {username}"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit.returncode == 0
+
+ # this kinit should be exactly one over the peruid limit
+ kinit_f = multihost.master[0].run_command(
+ f'su -l {user} -c "kinit user0064"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit_f.returncode != 0
+
+ set_param(multihost, 'kcm', 'max_uid_ccaches', '65')
+ self._restart_kcm(multihost)
+
+ # Now the kinit should work as we increased the limit
+ kinit_p = multihost.master[0].run_command(
+ f'su -l {user} -c "kinit user0064"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kinit_p.returncode == 0
+
+ multihost.master[0].run_command(
+ f'su -l {user} -c "kdestroy -A"', raiseonerr=False)
+
+ @pytest.mark.usefixtures("enable_kcm")
+ def test_kcm_payload_low_quota(self, multihost):
+ """
+ :title: kcm: Quota enforcement
+ :id: cb3daadb-c5e7-48f8-b419-11c616f0d602
+ :description: Set a prohibitive quota for the per-ccache payload
+ limit and make sure it gets enforced
+ """
+ # It is easier to keep these tests stable and independent from others
+ # if they start from a clean slate
+ self._remove_secret_db(multihost)
+ user = 'foo3'
+ client = sssdTools(multihost.master[0])
+ client.auth_from_client(user, 'Secret123')
+
+ multihost.master[0].run_command(
+ f'su -l {user} -c "kdestroy -A"', raiseonerr=False)
+
+ set_param(multihost, 'kcm', 'max_ccache_size', '1')
+ self._restart_kcm(multihost)
+
+ # We use kinit to exceed the maximum ccache size as it creates payload
+ # of 1280 bytes by acquiring tgt and also some control credentials.
+ # SSH authentication is not sufficient as it stores only tgt.
+ kv_p = multihost.master[0].run_command(
+ f'su -l foo3 -c "kinit {user}@EXAMPLE.TEST"',
+ stdin_text='Secret123', raiseonerr=False)
+ assert kv_p.returncode != 0
diff --git a/src/tests/multihost/basic/test_sssctl_config_check.py b/src/tests/multihost/basic/test_sssctl_config_check.py
new file mode 100644
index 0000000..1ada5c7
--- /dev/null
+++ b/src/tests/multihost/basic/test_sssctl_config_check.py
@@ -0,0 +1,107 @@
+"""sssctl config-check Test Cases
+
+:requirement: IDM-SSSD-REQ: Status utility
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+
+import re
+
+import pytest
+
+
+class TestSssctlConfigCheck(object):
+ @pytest.mark.converted('test_sssctl.py', 'test_sssctl__check_typo_option_name')
+ def test_verify_typo_option_name(self, multihost):
+ """
+ :title: sssctl: Verify typos in option name (not value)
+ of configuration file
+ :id: 4089f5d6-cdeb-4bcb-9028-cabd97d43045
+ """
+ cfgget = '/etc/sssd/sssd.conf'
+ cfgput = '/tmp/sssd.conf.backup'
+ multihost.master[0].run_command(['/bin/cp',
+ '-a', cfgget, cfgput],
+ raiseonerr=False)
+ sssdcfg = multihost.master[0].get_file_contents(cfgget)
+
+ # replacing ldap_search_base option with search_base
+ sssdcfg = re.sub(b"ldap_search_base",
+ b"search_base", sssdcfg)
+ multihost.master[0].put_file_contents(cfgget, sssdcfg)
+ sssctl_cmd = 'sssctl config-check'
+ cmd = multihost.master[0].run_command(sssctl_cmd, raiseonerr=False)
+ if cmd.returncode == 1:
+ log = re.compile(r'Attribute\s.search.base.\sis\snot\sallowed.*')
+ if log.search(cmd.stdout_text):
+ assert True
+ else:
+ assert False
+ else:
+ assert False
+ multihost.master[0].run_command(['/bin/cp', '-a', cfgput, cfgget],
+ raiseonerr=False)
+
+ @pytest.mark.converted('test_sssctl.py', 'test_sssctl__typo_domain_name')
+ def test_verify_typo_domain_name(self, multihost):
+ """
+ :title: sssctl: Verify typos in domain name of configuration file
+ :id: a5d3a3a5-f832-4fc6-a628-9165dab69dd2
+ """
+ cfgget = '/etc/sssd/sssd.conf'
+ cfgput = '/tmp/sssd.conf.backup'
+ multihost.master[0].run_command(['/bin/cp',
+ '-a', cfgget, cfgput],
+ raiseonerr=False)
+ sssdcfg = multihost.master[0].get_file_contents(cfgget)
+
+ # replacing the domain name with typo
+ sssdcfg = re.sub(b"domain/EXAMPLE.TEST",
+ b"domain/", sssdcfg)
+ multihost.master[0].put_file_contents(cfgget, sssdcfg)
+ sssctl_cmd = 'sssctl config-check'
+ cmd = multihost.master[0].run_command(sssctl_cmd, raiseonerr=False)
+ if cmd.returncode == 1:
+ log = re.compile(r'Section\s\[domain\/\]\sis\snot\sallowed.*')
+ if log.search(cmd.stdout_text):
+ assert True
+ else:
+ assert False
+ else:
+ assert False
+ multihost.master[0].run_command(['/bin/cp', '-a', cfgput, cfgget],
+ raiseonerr=False)
+
+ @pytest.mark.converted('test_sssctl.py', 'test_sssctl__misplaced_option')
+ def test_misplaced_option(self, multihost):
+ """
+ :title: sssctl: Verify misplace options in default configuration file
+ :id: ed814158-dea5-4f62-8500-fe62087332f9
+ """
+ cfgget = '/etc/sssd/sssd.conf'
+ cfgput = '/tmp/sssd.conf.backup'
+ sssdcfg = multihost.master[0].get_file_contents(cfgget)
+
+ # adding services option under domain section
+ sssdcfg = re.sub(b"services = nss, pam, sudo, ifp",
+ b"#services = nss, pam, sudo, ifp", sssdcfg)
+ sssdcfg = re.sub(b".domain/EXAMPLE.TEST.",
+ b"[domain/EXAMPLE.TEST]"
+ b"\nservices = nss, pam, sudo, ifp", sssdcfg)
+ multihost.master[0].put_file_contents(cfgget, sssdcfg)
+ sssctl_cmd = 'sssctl config-check'
+ cmd = multihost.master[0].run_command(sssctl_cmd,
+ raiseonerr=False)
+ if cmd.returncode == 1:
+ log = re.compile(
+ r'.Attribute\s.services.\sis\snot\sallowed\sin\ssection\s.*')
+ if log.search(cmd.stdout_text):
+ assert True
+ else:
+ assert False
+ else:
+ assert False
+ multihost.master[0].run_command(['/bin/cp', '-a', cfgput, cfgget],
+ raiseonerr=False)
diff --git a/src/tests/multihost/basic/test_sudo.py b/src/tests/multihost/basic/test_sudo.py
new file mode 100644
index 0000000..35861de
--- /dev/null
+++ b/src/tests/multihost/basic/test_sudo.py
@@ -0,0 +1,66 @@
+""" SUDO responder sanity Test Cases
+
+:requirement: sudo
+:casecomponent: sssd
+:subsystemteam: sst_idm_sssd
+:upstream: yes
+:status: approved
+"""
+
+import time
+import pytest
+from sssd.testlib.common.utils import sssdTools
+
+
+class TestSanitySudo(object):
+ """ Basic Sanity Test cases for sudo service in sssd """
+ @staticmethod
+ @pytest.mark.converted('test_sudo.py', 'test_sudo__case_sensitive_false')
+ @pytest.mark.usefixtures(
+ "case_sensitive_sudorule", "enable_sss_sudo_nsswitch",
+ "set_case_sensitive_false")
+ def test_case_senitivity(multihost):
+ """
+ :title: sudo: Verify case sensitivity in sudo responder
+ :id: 64ab80be-17fd-4c3b-9d9b-7d07c6279975
+ """
+ user = 'capsuser-1'
+ # Test ssh login
+ client = sssdTools(multihost.master[0])
+ ssh_result = client.auth_from_client(user, 'Secret123') == 3
+ cmd = multihost.master[0].run_command(
+ f'su - {user} -c "sudo -l"', raiseonerr=False)
+ rule_result = cmd.returncode == 0 and \
+ '(root) NOPASSWD: /usr/bin/less' in cmd.stdout_text
+ rule2_result = cmd.returncode == 0 and \
+ '(root) NOPASSWD: /usr/bin/more' in cmd.stdout_text
+ assert ssh_result, f"Ssh failed for user: {user}."
+ assert rule_result, f"Rules missing for user: {user}."
+ assert rule2_result, f"Rules missing for user: {user}."
+
+ @staticmethod
+ @pytest.mark.converted('test_sudo.py', 'test_sudo__rules_refresh')
+ @pytest.mark.usefixtures("enable_sss_sudo_nsswitch", "generic_sudorule",
+ "set_entry_cache_sudo_timeout")
+ def test_refresh_expired_rule(multihost):
+ """
+ :title: sudo: Verify refreshing expired sudo rules
+ do not crash sssd_sudo
+ :id: 532513b2-15bc-46ac-8fc9-19fd0bf485c4
+ """
+
+ user = 'foo1'
+ # Test ssh login
+ client = sssdTools(multihost.master[0])
+ ssh_result = client.auth_from_client(user, 'Secret123') == 3
+ cmd = multihost.master[0].run_command(
+ f'su - {user} -c "sudo -l"', raiseonerr=False)
+ time.sleep(30)
+ cmd2 = multihost.master[0].run_command(
+ f'su - {user} -c "sudo -l"', raiseonerr=False)
+
+ assert ssh_result, f"Ssh failed for user: {user}."
+ assert cmd.returncode == 0, \
+ f"First sudo -l failed for user: {user}."
+ assert cmd2.returncode == 0, \
+ f"Second sudo -l failed for user: {user}."
diff --git a/src/tests/multihost/basic/utils_config.py b/src/tests/multihost/basic/utils_config.py
new file mode 100644
index 0000000..11b718e
--- /dev/null
+++ b/src/tests/multihost/basic/utils_config.py
@@ -0,0 +1,32 @@
+""" Various utilities for manipulating SSSD configuration """
+import configparser as ConfigParser
+
+
+def set_param(multihost, section, key, value):
+ multihost.master[0].transport.get_file('/etc/sssd/sssd.conf',
+ '/tmp/sssd.conf')
+ sssdconfig = ConfigParser.ConfigParser()
+ sssdconfig.read('/tmp/sssd.conf')
+ if section not in sssdconfig.sections():
+ sssdconfig.add_section(section)
+
+ sssdconfig.set(section, key, value)
+ with open(str('/tmp/sssd.conf'), "w") as sssconf:
+ sssdconfig.write(sssconf)
+
+ multihost.master[0].transport.put_file('/tmp/sssd.conf',
+ '/etc/sssd/sssd.conf')
+
+
+def remove_section(multihost, section):
+ multihost.master[0].transport.get_file('/etc/sssd/sssd.conf',
+ '/tmp/sssd.conf')
+ sssdconfig = ConfigParser.ConfigParser()
+ sssdconfig.read('/tmp/sssd.conf')
+ sssdconfig.remove_section(section)
+
+ with open(str('/tmp/sssd.conf'), "w") as sssconf:
+ sssdconfig.write(sssconf)
+
+ multihost.master[0].transport.put_file('/tmp/sssd.conf',
+ '/etc/sssd/sssd.conf')