URL: https://github.com/freeipa/freeipa/pull/3682
Author: wladich
 Title: #3682: [Backport][ipa-4-8] ipatests: add tests for cached_auth_timeout 
in sssd.conf
Action: opened

PR body:
"""
This is a manual backport of #3602 

The tests check that auth cache
* is disabled by default
* is working when enabled
* expires after specified time
* is inherited by trusted domain

Related to: https://bugzilla.redhat.com/1685581
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/3682/head:pr3682
git checkout pr3682
From f4f4844eed0df0e40fed19ab5dab20131e53e57a Mon Sep 17 00:00:00 2001
From: Sergey Orlov <[email protected]>
Date: Wed, 18 Sep 2019 11:43:06 +0200
Subject: [PATCH 1/3] ipatests: add new utilities for file management

Added utilities for working with remote hosts
* backup and restore files
* modify .ini files
* check if selinux is enabled

Reviewed-By: Florence Blanc-Renaud <[email protected]>
---
 ipatests/pytest_ipa/integration/tasks.py | 70 ++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index 5a4653bcd0..8ab7a3682b 100644
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -31,6 +31,8 @@
 import tempfile
 import time
 from pipes import quote
+import configparser
+from contextlib import contextmanager
 
 import dns
 from ldif import LDIFWriter
@@ -1872,3 +1874,71 @@ def run_command_as_user(host, user, command, *args, **kwargs):
 
 def kinit_as_user(host, user, password):
     host.run_command(['kinit', user], stdin_text=password + '\n')
+
+
+class FileBackup:
+    """Create file backup and do restore on remote host
+
+    Examples:
+
+        config_backup = FileBackup(host, '/etc/some.conf')
+        ... modify the file and do the test ...
+        config_backup.restore()
+
+    Use as a context manager:
+
+        with FileBackup(host, '/etc/some.conf'):
+            ... modify the file and do the test ...
+
+    """
+
+    def __init__(self, host, filename):
+        """Create file backup."""
+        self._host = host
+        self._filename = filename
+        self._backup = create_temp_file(host)
+        self._cp_cmd = ['cp']
+        if is_selinux_enabled(host):
+            self._cp_cmd.append('--preserve=context')
+        host.run_command(self._cp_cmd + [filename, self._backup])
+
+    def restore(self):
+        """Restore file. Can be called multiple times."""
+        self._host.run_command(self._cp_cmd + [self._backup, self._filename])
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.restore()
+
+
+@contextmanager
+def remote_ini_file(host, filename):
+    """Context manager for editing an ini file on a remote host.
+
+    It provides RawConfigParser object which is automatically serialized and
+    uploaded to remote host upon exit from the context.
+
+    If exception is raised inside the context then the ini file is NOT updated
+    on remote host.
+
+    Example:
+
+        with remote_ini_file(master, '/etc/some.conf') as some_conf:
+            some_conf.set('main', 'timeout', 10)
+
+
+    """
+    data = host.get_file_contents(filename, encoding='utf-8')
+    ini_file = configparser.RawConfigParser()
+    ini_file.read_string(data)
+    yield ini_file
+    data = StringIO()
+    ini_file.write(data)
+    host.put_file_contents(filename, data.getvalue())
+
+
+def is_selinux_enabled(host):
+    res = host.run_command('selinuxenabled', ok_returncode=(0, 1))
+    return res.returncode == 0

From e17ee62be26770cd814063fd6abf8a9af34e36cb Mon Sep 17 00:00:00 2001
From: Sergey Orlov <[email protected]>
Date: Wed, 18 Sep 2019 11:43:47 +0200
Subject: [PATCH 2/3] ipatests: refactoring: use library function to check if
 selinux is enabled

Reviewed-By: Florence Blanc-Renaud <[email protected]>
---
 ipatests/test_integration/test_smb.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/ipatests/test_integration/test_smb.py b/ipatests/test_integration/test_smb.py
index fa9d340549..52cdbcda79 100644
--- a/ipatests/test_integration/test_smb.py
+++ b/ipatests/test_integration/test_smb.py
@@ -97,9 +97,7 @@ def samba_share_public(self):
         smbserver.run_command(['mkdir', share_path])
         smbserver.run_command(['chmod', '777', share_path])
         # apply selinux context only if selinux is enabled
-        res = smbserver.run_command('selinuxenabled', ok_returncode=(0, 1))
-        selinux_enabled = res.returncode == 0
-        if selinux_enabled:
+        if tasks.is_selinux_enabled(smbserver):
             smbserver.run_command(['chcon', '-t', 'samba_share_t', share_path])
         smbconf_save_file = tasks.create_temp_file(smbserver)
         smbserver.run_command(['cp', paths.SMB_CONF, smbconf_save_file])

From dfeb3b8f3985766e6c4df7437c271239362a1115 Mon Sep 17 00:00:00 2001
From: Sergey Orlov <[email protected]>
Date: Wed, 18 Sep 2019 11:44:27 +0200
Subject: [PATCH 3/3] ipatests: add tests for cached_auth_timeout in sssd.conf

The tests check that auth cache
* is disabled by default
* is working when enabled
* expires after specified time
* is inherited by trusted domain

Related to: https://bugzilla.redhat.com/1685581

Reviewed-By: Florence Blanc-Renaud <[email protected]>
---
 .../prci_definitions/nightly_ipa-4-8.yaml     |  16 +++
 ipatests/test_integration/test_sssd.py        | 110 ++++++++++++++++++
 2 files changed, 126 insertions(+)
 create mode 100644 ipatests/test_integration/test_sssd.py

diff --git a/ipatests/prci_definitions/nightly_ipa-4-8.yaml b/ipatests/prci_definitions/nightly_ipa-4-8.yaml
index d689fb3b10..ad1eacdfa5 100644
--- a/ipatests/prci_definitions/nightly_ipa-4-8.yaml
+++ b/ipatests/prci_definitions/nightly_ipa-4-8.yaml
@@ -31,6 +31,10 @@ topologies:
     name: ad_master_2client
     cpu: 4
     memory: 12000
+  ad_master: &ad_master
+   name: ad_master
+   cpu: 4
+   memory: 12000
 
 jobs:
   fedora-30/build:
@@ -1320,3 +1324,15 @@ jobs:
         template: *ci-master-f30
         timeout: 10800
         topology: *master_1repl
+
+  fedora-30/test_sssd:
+    requires: [fedora-30/build]
+    priority: 50
+    job:
+      class: RunADTests
+      args:
+        build_url: '{fedora-30/build_url}'
+        test_suite: test_integration/test_sssd.py
+        template: *ci-master-f30
+        timeout: 3600
+        topology: *ad_master
diff --git a/ipatests/test_integration/test_sssd.py b/ipatests/test_integration/test_sssd.py
new file mode 100644
index 0000000000..ac31d42104
--- /dev/null
+++ b/ipatests/test_integration/test_sssd.py
@@ -0,0 +1,110 @@
+#
+# Copyright (C) 2019  FreeIPA Contributors see COPYING for license
+#
+
+"""This module provides tests for SSSD as used in IPA"""
+
+from __future__ import absolute_import
+
+import time
+from contextlib import contextmanager
+
+import pytest
+
+from ipatests.test_integration.base import IntegrationTest
+from ipatests.pytest_ipa.integration import tasks
+from ipaplatform.paths import paths
+
+
+class TestSSSDAuthCache(IntegrationTest):
+    """Regression tests for cached_auth_timeout option
+
+       https://bugzilla.redhat.com/show_bug.cgi?id=1685581
+   """
+
+    topology = 'star'
+    num_ad_domains = 1
+
+    users = {
+        'ipa': {
+            'name': 'user1',
+            'password': 'SecretUser1'
+        },
+        'ad': {
+            'name_tmpl': 'testuser@{domain}',
+            'password': 'Secret123'
+        },
+    }
+    ipa_user = 'user1'
+    ipa_user_password = 'SecretUser1'
+    intermed_user = 'user2'
+    ad_user_tmpl = 'testuser@{domain}'
+    ad_user_password = 'Secret123'
+
+    @classmethod
+    def install(cls, mh):
+        super(TestSSSDAuthCache, cls).install(mh)
+
+        cls.ad = cls.ads[0]  # pylint: disable=no-member
+
+        tasks.install_adtrust(cls.master)
+        tasks.configure_dns_for_trust(cls.master, cls.ad)
+        tasks.establish_trust_with_ad(cls.master, cls.ad.domain.name)
+
+        cls.users['ad']['name'] = cls.users['ad']['name_tmpl'].format(
+            domain=cls.ad.domain.name)
+        tasks.user_add(cls.master, cls.intermed_user)
+        tasks.create_active_user(cls.master, cls.ipa_user,
+                                 cls.ipa_user_password)
+
+    @contextmanager
+    def config_sssd_cache_auth(self, cached_auth_timeout):
+        sssd_conf_backup = tasks.FileBackup(self.master, paths.SSSD_CONF)
+        with tasks.remote_ini_file(self.master, paths.SSSD_CONF) as sssd_conf:
+            domain_section = 'domain/{}'.format(self.master.domain.name)
+            if cached_auth_timeout is None:
+                sssd_conf.remove_option(domain_section, 'cached_auth_timeout')
+            else:
+                sssd_conf.set(domain_section, 'cached_auth_timeout',
+                              cached_auth_timeout)
+            sssd_conf.set('pam', 'pam_verbosity', '2')
+
+        try:
+            tasks.clear_sssd_cache(self.master)
+            yield
+        finally:
+            sssd_conf_backup.restore()
+            tasks.clear_sssd_cache(self.master)
+
+    def is_auth_cached(self, user):
+        cmd = ['su', '-l', user['name'], '-c', 'true']
+        res = tasks.run_command_as_user(self.master, self.intermed_user, cmd,
+                                        stdin_text=user['password'] + '\n')
+        return 'Authenticated with cached credentials.' in res.stdout_text
+
+    @pytest.mark.parametrize('user', ['ipa', 'ad'])
+    def test_auth_cache_disabled_by_default(self, user):
+        with self.config_sssd_cache_auth(cached_auth_timeout=None):
+            assert not self.is_auth_cached(self.users[user])
+            assert not self.is_auth_cached(self.users[user])
+
+    @pytest.mark.parametrize('user', ['ipa', 'ad'])
+    def test_auth_cache_disabled_with_value_0(self, user):
+        with self.config_sssd_cache_auth(cached_auth_timeout=0):
+            assert not self.is_auth_cached(self.users[user])
+            assert not self.is_auth_cached(self.users[user])
+
+    @pytest.mark.parametrize('user', ['ipa', 'ad'])
+    def test_auth_cache_enabled_when_configured(self, user):
+        timeout = 30
+        with self.config_sssd_cache_auth(cached_auth_timeout=timeout):
+            start = time.time()
+            # check auth is cached after first login
+            assert not self.is_auth_cached(self.users[user])
+            assert self.is_auth_cached(self.users[user])
+            # check cache expires after configured timeout
+            elapsed = time.time() - start
+            time.sleep(timeout - 5 - elapsed)
+            assert self.is_auth_cached(self.users[user])
+            time.sleep(10)
+            assert not self.is_auth_cached(self.users[user])
_______________________________________________
FreeIPA-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/[email protected]

Reply via email to