Ejemplo n.º 1
0
class TestBackupAndRestore(IntegrationTest):
    topology = 'star'

    def test_full_backup_and_restore(self):
        """backup, uninstall, restore"""
        with restore_checker(self.master):
            backup_path = tasks.get_backup_dir(self.master)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_KEYS)
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_CONF)

            dirman_password = self.master.config.dirman_password
            self.master.run_command(['ipa-restore', backup_path],
                                    stdin_text=dirman_password + '\nyes')

            # check the file permssion and ownership is set to 770 and
            # dirsrv:dirsrv after restore on /var/log/dirsrv/slapd-<instance>
            # related ticket : https://pagure.io/freeipa/issue/7725
            instance = realm_to_serverid(self.master.domain.realm)
            log_path = paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % instance
            cmd = self.master.run_command(['stat', '-c',
                                           '"%a %G:%U"', log_path])
            assert "770 dirsrv:dirsrv" in cmd.stdout_text

    def test_full_backup_and_restore_with_removed_users(self):
        """regression test for https://fedorahosted.org/freeipa/ticket/3866"""
        with restore_checker(self.master):
            backup_path = tasks.get_backup_dir(self.master)

            logger.info('Backup path for %s is %s', self.master, backup_path)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])

            homedir = os.path.join(self.master.config.test_dir,
                                   'testuser_homedir')
            self.master.run_command(['useradd', 'ipatest_user1',
                                     '--system',
                                     '-d', homedir])
            try:
                dirman_password = self.master.config.dirman_password
                self.master.run_command(['ipa-restore', backup_path],
                                        stdin_text=dirman_password + '\nyes')
            finally:
                self.master.run_command(['userdel', 'ipatest_user1'])

    @pytest.mark.skipif(
        not platformtasks.is_selinux_enabled(),
        reason="Test needs SELinux enabled")
    def test_full_backup_and_restore_with_selinux_booleans_off(self):
        """regression test for https://fedorahosted.org/freeipa/ticket/4157"""
        with restore_checker(self.master):
            backup_path = tasks.get_backup_dir(self.master)

            logger.info('Backup path for %s is %s', self.master, backup_path)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])

            self.master.run_command([
                'setsebool', '-P',
                'httpd_can_network_connect=off',
                'httpd_manage_ipa=off',
            ])

            dirman_password = self.master.config.dirman_password
            self.master.run_command(['ipa-restore', backup_path],
                                    stdin_text=dirman_password + '\nyes')

        result = self.master.run_command([
            'getsebool',
            'httpd_can_network_connect',
            'httpd_manage_ipa',
        ])
        assert 'httpd_can_network_connect --> on' in result.stdout_text
        assert 'httpd_manage_ipa --> on' in result.stdout_text
Ejemplo n.º 2
0
class TestInstallMaster(IntegrationTest):

    num_replicas = 0

    @classmethod
    def install(cls, mh):
        pass

    def test_install_master(self):
        tasks.install_master(self.master, setup_dns=False)

    def test_install_kra(self):
        tasks.install_kra(self.master, first_instance=True)

    def test_install_dns(self):
        tasks.install_dns(
            self.master,
            extra_args=['--dnssec-master', '--no-dnssec-validation'])

    def test_WSGI_worker_process(self):
        """ Test if WSGI worker process count is set to 4

        related ticket : https://pagure.io/freeipa/issue/7587
        """
        # check process count in httpd conf file i.e expected string
        exp = b'WSGIDaemonProcess ipa processes=%d' % constants.WSGI_PROCESSES
        httpd_conf = self.master.get_file_contents(paths.HTTPD_IPA_CONF)
        assert exp in httpd_conf

        # check the process count
        cmd = self.master.run_command('ps -eF')
        wsgi_count = cmd.stdout_text.count('wsgi:ipa')
        assert constants.WSGI_PROCESSES == wsgi_count

    def test_error_for_yubikey(self):
        """ Test error when yubikey hardware not present

        In order to work with IPA and Yubikey, libyubikey is required.
        Before the fix, if yubikey added without having packages, it used to
        result in traceback. Now it the exception is handeled properly.
        It needs Yubikey hardware to make command successfull. This test
        just check of proper error thrown when hardware is not attached.

        related ticket : https://pagure.io/freeipa/issue/6979
        """
        # try to add yubikey to the user
        args = ['ipa', 'otptoken-add-yubikey', '--owner=admin']
        cmd = self.master.run_command(args, raiseonerr=False)
        assert cmd.returncode != 0
        exp_str = ("ipa: ERROR: No YubiKey found")
        assert exp_str in cmd.stderr_text

    def test_pki_certs(self):
        certs, keys = tasks.certutil_certs_keys(
            self.master, paths.PKI_TOMCAT_ALIAS_DIR,
            paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT)

        expected_certs = {
            # CA
            'caSigningCert cert-pki-ca': 'CTu,Cu,Cu',
            'ocspSigningCert cert-pki-ca': 'u,u,u',
            'subsystemCert cert-pki-ca': 'u,u,u',
            'auditSigningCert cert-pki-ca': 'u,u,Pu',  # why P?
            # KRA
            'transportCert cert-pki-kra': 'u,u,u',
            'storageCert cert-pki-kra': 'u,u,u',
            'auditSigningCert cert-pki-kra': 'u,u,Pu',
            # server
            'Server-Cert cert-pki-ca': 'u,u,u',
        }
        assert certs == expected_certs
        assert len(certs) == len(keys)

        for nickname in sorted(certs):
            cert = tasks.certutil_fetch_cert(
                self.master, paths.PKI_TOMCAT_ALIAS_DIR,
                paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT, nickname)
            key_size = cert.public_key().key_size
            if nickname == 'caSigningCert cert-pki-ca':
                assert key_size == 3072
            else:
                assert key_size == 2048
            assert cert.signature_hash_algorithm.name == hashes.SHA256.name

    def test_p11_kit_softhsm2(self):
        # check that p11-kit-proxy does not inject SoftHSM2
        result = self.master.run_command(
            ["modutil", "-dbdir", paths.PKI_TOMCAT_ALIAS_DIR, "-list"])
        assert "softhsm" not in result.stdout_text.lower()
        assert "opendnssec" not in result.stdout_text.lower()

    @pytest.mark.skipif(not platformtasks.is_selinux_enabled(),
                        reason="Test needs SELinux enabled")
    def test_selinux_avcs(self):
        # Use journalctl instead of ausearch. The ausearch command is not
        # installed by default and journalctl gives us all AVCs.
        result = self.master.run_command(
            ["journalctl", "--full", "--grep=AVC", "--since=yesterday"])
        avcs = list(line.strip() for line in result.stdout_text.split('\n')
                    if "AVC avc:" in line)
        if avcs:
            print('\n'.join(avcs))
            # Use expected failure until all SELinux violations are fixed
            pytest.xfail("{} AVCs found".format(len(avcs)))
Ejemplo n.º 3
0
class TestBackupAndRestore(IntegrationTest):
    topology = 'star'

    def test_full_backup_and_restore(self):
        """backup, uninstall, restore"""
        with restore_checker(self.master):
            backup_path = backup(self.master)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_KEYS)
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_CONF)

            dirman_password = self.master.config.dirman_password
            self.master.run_command(['ipa-restore', backup_path],
                                    stdin_text=dirman_password + '\nyes')

    def test_full_backup_and_restore_with_removed_users(self):
        """regression test for https://fedorahosted.org/freeipa/ticket/3866"""
        with restore_checker(self.master):
            backup_path = backup(self.master)

            logger.info('Backup path for %s is %s', self.master, backup_path)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])

            homedir = os.path.join(self.master.config.test_dir,
                                   'testuser_homedir')
            self.master.run_command(['useradd', 'ipatest_user1',
                                     '--system',
                                     '-d', homedir])
            try:
                dirman_password = self.master.config.dirman_password
                self.master.run_command(['ipa-restore', backup_path],
                                        stdin_text=dirman_password + '\nyes')
            finally:
                self.master.run_command(['userdel', 'ipatest_user1'])

    @pytest.mark.skipif(
        not platformtasks.is_selinux_enabled(),
        reason="Test needs SELinux enabled")
    def test_full_backup_and_restore_with_selinux_booleans_off(self):
        """regression test for https://fedorahosted.org/freeipa/ticket/4157"""
        with restore_checker(self.master):
            backup_path = backup(self.master)

            logger.info('Backup path for %s is %s', self.master, backup_path)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])

            self.master.run_command([
                'setsebool', '-P',
                'httpd_can_network_connect=off',
                'httpd_manage_ipa=off',
            ])

            dirman_password = self.master.config.dirman_password
            self.master.run_command(['ipa-restore', backup_path],
                                    stdin_text=dirman_password + '\nyes')

        result = self.master.run_command([
            'getsebool',
            'httpd_can_network_connect',
            'httpd_manage_ipa',
        ])
        assert 'httpd_can_network_connect --> on' in result.stdout_text
        assert 'httpd_manage_ipa --> on' in result.stdout_text
Ejemplo n.º 4
0
class TestInstallMaster(IntegrationTest):

    num_replicas = 0

    @classmethod
    def install(cls, mh):
        pass

    def test_install_master(self):
        tasks.install_master(self.master, setup_dns=False)

    def test_schema_compat_attribute_and_tree_disable(self):
        """Test if schema-compat-entry-attribute is set

        This is to ensure if said entry is set after installation.
        It also checks if compat tree is disable.

        related: https://pagure.io/freeipa/issue/8193
        """
        conn = self.master.ldap_connect()
        entry = conn.get_entry(DN(             # pylint: disable=no-member
            "cn=groups,cn=Schema Compatibility,cn=plugins,cn=config"))

        entry_list = list(entry['schema-compat-entry-attribute'])
        value = (r'ipaexternalmember=%deref_r('
                 '"member","ipaexternalmember")')
        assert value in entry_list
        assert 'schema-compat-lookup-nsswitch' not in entry_list

    def test_install_kra(self):
        tasks.install_kra(self.master, first_instance=True)

    def test_install_dns(self):
        tasks.install_dns(
            self.master,
            extra_args=['--dnssec-master', '--no-dnssec-validation']
        )

    def test_ipactl_restart_pki_tomcat(self):
        """ Test if ipactl restart restarts the pki-tomcatd

        Wrong logic was triggering the start instead of restart
        for pki-tomcatd. This test validates that restart
        called on pki-tomcat properly.

        related ticket : https://pagure.io/freeipa/issue/7927
        """
        # get process id of pki-tomcatd
        pki_pid = get_pki_tomcatd_pid(self.master)

        # check if pki-tomcad restarted
        cmd = self.master.run_command(['ipactl', 'restart'])
        assert "Restarting pki-tomcatd Service" in cmd.stdout_text

        # check if pid for pki-tomcad changed
        pki_pid_after_restart = get_pki_tomcatd_pid(self.master)
        assert pki_pid != pki_pid_after_restart

        # check if pki-tomcad restarted
        cmd = self.master.run_command(['ipactl', 'restart'])
        assert "Restarting pki-tomcatd Service" in cmd.stdout_text

        # check if pid for pki-tomcad changed
        pki_pid_after_restart_2 = get_pki_tomcatd_pid(self.master)
        assert pki_pid_after_restart != pki_pid_after_restart_2

    def test_ipactl_scenario_check(self):
        """ Test if ipactl starts services stopped by systemctl
        This will first check if all services are running then it will stop
        few service. After that it will restart all services and then check
        the status and pid of services.It will also compare pid after ipactl
        start and restart in case of start it will remain unchanged on the
        other hand in case of restart it will change.
        """
        # listing all services
        ipa_services_name = [
            "Directory", "krb5kdc", "kadmin", "named", "httpd", "ipa-custodia",
            "pki-tomcatd", "ipa-otpd", "ipa-dnskeysyncd"
        ]

        # checking the service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in ipa_services_name:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # stopping few services
        service_stop = ["krb5kdc", "kadmin", "httpd"]
        for service in service_stop:
            service_name = services.knownservices[service].systemd_name
            self.master.run_command(['systemctl', 'stop', service_name])

        # checking service status
        service_start = [
            svcs for svcs in ipa_services_name if svcs not in service_stop
        ]
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in service_start:
            assert f"{service} Service: RUNNING" in cmd.stdout_text
        for service in service_stop:
            assert f'{service} Service: STOPPED' in cmd.stdout_text

        # starting all services again
        self.master.run_command(['ipactl', 'start'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in ipa_services_name:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # get process id of services
        ipa_services_pids = get_ipa_services_pids(self.master)

        # restarting all services again
        self.master.run_command(['ipactl', 'restart'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in ipa_services_name:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # check if pid for services are different
        svcs_pids_after_restart = get_ipa_services_pids(self.master)
        assert ipa_services_pids != svcs_pids_after_restart

        # starting all services again
        self.master.run_command(['ipactl', 'start'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in ipa_services_name:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # check if pid for services are same
        svcs_pids_after_start = get_ipa_services_pids(self.master)
        assert svcs_pids_after_restart == svcs_pids_after_start

    def test_WSGI_worker_process(self):
        """ Test if WSGI worker process count is set to 4

        related ticket : https://pagure.io/freeipa/issue/7587
        """
        # check process count in httpd conf file i.e expected string
        exp = b'WSGIDaemonProcess ipa processes=%d' % constants.WSGI_PROCESSES
        httpd_conf = self.master.get_file_contents(paths.HTTPD_IPA_CONF)
        assert exp in httpd_conf

        # check the process count
        cmd = self.master.run_command('ps -eF')
        wsgi_count = cmd.stdout_text.count('wsgi:ipa')
        assert constants.WSGI_PROCESSES == wsgi_count

    def test_error_for_yubikey(self):
        """ Test error when yubikey hardware not present

        In order to work with IPA and Yubikey, libyubikey is required.
        Before the fix, if yubikey added without having packages, it used to
        result in traceback. Now it the exception is handeled properly.
        It needs Yubikey hardware to make command successfull. This test
        just check of proper error thrown when hardware is not attached.

        related ticket : https://pagure.io/freeipa/issue/6979
        """
        # try to add yubikey to the user
        args = ['ipa', 'otptoken-add-yubikey', '--owner=admin']
        cmd = self.master.run_command(args, raiseonerr=False)
        assert cmd.returncode != 0
        exp_str = ("ipa: ERROR: No YubiKey found")
        assert exp_str in cmd.stderr_text

    def test_pki_certs(self):
        certs, keys = tasks.certutil_certs_keys(
            self.master,
            paths.PKI_TOMCAT_ALIAS_DIR,
            paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT
        )

        expected_certs = {
            # CA
            'caSigningCert cert-pki-ca': 'CTu,Cu,Cu',
            'ocspSigningCert cert-pki-ca': 'u,u,u',
            'subsystemCert cert-pki-ca': 'u,u,u',
            'auditSigningCert cert-pki-ca': 'u,u,Pu',  # why P?
            # KRA
            'transportCert cert-pki-kra': 'u,u,u',
            'storageCert cert-pki-kra': 'u,u,u',
            'auditSigningCert cert-pki-kra': 'u,u,Pu',
            # server
            'Server-Cert cert-pki-ca': 'u,u,u',
        }
        assert certs == expected_certs
        assert len(certs) == len(keys)

        for nickname in sorted(certs):
            cert = tasks.certutil_fetch_cert(
                self.master,
                paths.PKI_TOMCAT_ALIAS_DIR,
                paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT,
                nickname
            )
            key_size = cert.public_key().key_size
            if nickname == 'caSigningCert cert-pki-ca':
                assert key_size == 3072
            else:
                assert key_size == 2048
            assert cert.signature_hash_algorithm.name == hashes.SHA256.name

    def test_http_cert(self):
        """
        Test that HTTP certificate contains ipa-ca.$DOMAIN
        DNS name.

        """
        data = self.master.get_file_contents(paths.HTTPD_CERT_FILE)
        cert = x509.load_pem_x509_certificate(data)
        name = f'ipa-ca.{self.master.domain.name}'
        assert crypto_x509.DNSName(name) in cert.san_general_names

    def test_p11_kit_softhsm2(self):
        # check that p11-kit-proxy does not inject SoftHSM2
        result = self.master.run_command([
            "modutil", "-dbdir", paths.PKI_TOMCAT_ALIAS_DIR, "-list"
        ])
        assert "softhsm" not in result.stdout_text.lower()
        assert "opendnssec" not in result.stdout_text.lower()

    @pytest.mark.skipif(
        not platformtasks.is_selinux_enabled(),
        reason="Test needs SELinux enabled")
    def test_selinux_avcs(self):
        # Use journalctl instead of ausearch. The ausearch command is not
        # installed by default and journalctl gives us all AVCs.
        result = self.master.run_command([
            "journalctl", "--full", "--grep=AVC", "--since=yesterday"
        ])
        avcs = list(
            line.strip() for line in result.stdout_text.split('\n')
            if "AVC avc:" in line
        )
        if avcs:
            print('\n'.join(avcs))
            # Use expected failure until all SELinux violations are fixed
            pytest.xfail("{} AVCs found".format(len(avcs)))

    def test_file_permissions(self):
        args = [
            "rpm", "-V",
            "python3-ipaclient",
            "python3-ipalib",
            "python3-ipaserver"
        ]

        if osinfo.id == 'fedora':
            args.extend([
                "freeipa-client",
                "freeipa-client-common",
                "freeipa-common",
                "freeipa-server",
                "freeipa-server-common",
                "freeipa-server-dns",
                "freeipa-server-trust-ad"
            ])
        else:
            args.extend([
                "ipa-client",
                "ipa-client-common",
                "ipa-common",
                "ipa-server",
                "ipa-server-common",
                "ipa-server-dns"
            ])

        result = self.master.run_command(args, raiseonerr=False)
        if result.returncode != 0:
            # Check the mode errors
            mode_warnings = re.findall(
                r"^.M.......  [cdglr ]+ (?P<filename>.*)$",
                result.stdout_text, re.MULTILINE)
            msg = "rpm -V found mode issues for the following files: {}"
            assert mode_warnings == [], msg.format(mode_warnings)
            # Check the owner errors
            user_warnings = re.findall(
                r"^.....U...  [cdglr ]+ (?P<filename>.*)$",
                result.stdout_text, re.MULTILINE)
            msg = "rpm -V found ownership issues for the following files: {}"
            assert user_warnings == [], msg.format(user_warnings)
            # Check the group errors
            group_warnings = re.findall(
                r"^......G..  [cdglr ]+ (?P<filename>.*)$",
                result.stdout_text, re.MULTILINE)
            msg = "rpm -V found group issues for the following files: {}"
            assert group_warnings == [], msg.format(group_warnings)

    def test_ds_disable_upgrade_hash(self):
        # Test case for https://pagure.io/freeipa/issue/8315
        # Disable password schema migration on LDAP bind
        result = tasks.ldapsearch_dm(
            self.master,
            "cn=config",
            ldap_args=["nsslapd-enable-upgrade-hash"],
            scope="base"
        )
        assert "nsslapd-enable-upgrade-hash: off" in result.stdout_text

    def test_admin_root_alias_CVE_2020_10747(self):
        # Test for CVE-2020-10747 fix
        # https://bugzilla.redhat.com/show_bug.cgi?id=1810160
        rootprinc = "root@{}".format(self.master.domain.realm)
        result = self.master.run_command(["ipa", "user-show", "admin"])
        assert rootprinc in result.stdout_text

        result = self.master.run_command(
            ["ipa", "user-add", "root", "--first", "root", "--last", "root"],
            raiseonerr=False
        )
        assert result.returncode != 0
        assert 'user with name "root" already exists' in result.stderr_text
Ejemplo n.º 5
0
class TestInstallMaster(IntegrationTest):

    num_replicas = 0

    @classmethod
    def install(cls, mh):
        pass

    def test_install_master(self):
        tasks.install_master(self.master, setup_dns=False)

    def test_install_kra(self):
        tasks.install_kra(self.master, first_instance=True)

    def test_install_dns(self):
        tasks.install_dns(
            self.master,
            extra_args=['--dnssec-master', '--no-dnssec-validation'])

    def test_ipactl_restart_pki_tomcat(self):
        """ Test if ipactl restart restarts the pki-tomcatd

        Wrong logic was triggering the start instead of restart
        for pki-tomcatd. This test validates that restart
        called on pki-tomcat properly.

        related ticket : https://pagure.io/freeipa/issue/7927
        """
        # get process id of pki-tomcatd
        pki_pid = get_pki_tomcatd_pid(self.master)

        # check if pki-tomcad restarted
        cmd = self.master.run_command(['ipactl', 'restart'])
        assert "Restarting pki-tomcatd Service" in cmd.stdout_text

        # check if pid for pki-tomcad changed
        pki_pid_after_restart = get_pki_tomcatd_pid(self.master)
        assert pki_pid != pki_pid_after_restart

        # check if pki-tomcad restarted
        cmd = self.master.run_command(['ipactl', 'restart'])
        assert "Restarting pki-tomcatd Service" in cmd.stdout_text

        # check if pid for pki-tomcad changed
        pki_pid_after_restart_2 = get_pki_tomcatd_pid(self.master)
        assert pki_pid_after_restart != pki_pid_after_restart_2

    def test_ipactl_scenario_check(self):
        """ Test if ipactl starts services stopped by systemctl
        This will first check if all services are running then it will stop
        few service. After that it will restart all services and then check
        the status and pid of services.It will also compare pid after ipactl
        start and restart in case of start it will remain unchanged on the
        other hand in case of restart it will change.
        """
        # listing all services
        services = [
            "Directory", "krb5kdc", "kadmin", "named", "httpd", "ipa-custodia",
            "pki-tomcatd", "ipa-otpd", "ipa-dnskeysyncd"
        ]

        # checking the service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in services:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # stopping few services
        service_stop = ["krb5kdc", "kadmin", "httpd"]
        for service in service_stop:
            self.master.run_command(['systemctl', 'stop', service])

        # checking service status
        service_start = [svcs for svcs in services if svcs not in service_stop]
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in service_start:
            assert f"{service} Service: RUNNING" in cmd.stdout_text
        for service in service_stop:
            assert f'{service} Service: STOPPED' in cmd.stdout_text

        # starting all services again
        self.master.run_command(['ipactl', 'start'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in services:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # get process id of services
        ipa_services_pids = get_ipa_services_pids(self.master)

        # restarting all services again
        self.master.run_command(['ipactl', 'restart'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in services:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # check if pid for services are different
        svcs_pids_after_restart = get_ipa_services_pids(self.master)
        assert ipa_services_pids != svcs_pids_after_restart

        # starting all services again
        self.master.run_command(['ipactl', 'start'])

        # checking service status
        cmd = self.master.run_command(['ipactl', 'status'])
        for service in services:
            assert f"{service} Service: RUNNING" in cmd.stdout_text

        # check if pid for services are same
        svcs_pids_after_start = get_ipa_services_pids(self.master)
        assert svcs_pids_after_restart == svcs_pids_after_start

    def test_WSGI_worker_process(self):
        """ Test if WSGI worker process count is set to 4

        related ticket : https://pagure.io/freeipa/issue/7587
        """
        # check process count in httpd conf file i.e expected string
        exp = b'WSGIDaemonProcess ipa processes=%d' % constants.WSGI_PROCESSES
        httpd_conf = self.master.get_file_contents(paths.HTTPD_IPA_CONF)
        assert exp in httpd_conf

        # check the process count
        cmd = self.master.run_command('ps -eF')
        wsgi_count = cmd.stdout_text.count('wsgi:ipa')
        assert constants.WSGI_PROCESSES == wsgi_count

    def test_error_for_yubikey(self):
        """ Test error when yubikey hardware not present

        In order to work with IPA and Yubikey, libyubikey is required.
        Before the fix, if yubikey added without having packages, it used to
        result in traceback. Now it the exception is handeled properly.
        It needs Yubikey hardware to make command successfull. This test
        just check of proper error thrown when hardware is not attached.

        related ticket : https://pagure.io/freeipa/issue/6979
        """
        # try to add yubikey to the user
        args = ['ipa', 'otptoken-add-yubikey', '--owner=admin']
        cmd = self.master.run_command(args, raiseonerr=False)
        assert cmd.returncode != 0
        exp_str = ("ipa: ERROR: No YubiKey found")
        assert exp_str in cmd.stderr_text

    def test_pki_certs(self):
        certs, keys = tasks.certutil_certs_keys(
            self.master, paths.PKI_TOMCAT_ALIAS_DIR,
            paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT)

        expected_certs = {
            # CA
            'caSigningCert cert-pki-ca': 'CTu,Cu,Cu',
            'ocspSigningCert cert-pki-ca': 'u,u,u',
            'subsystemCert cert-pki-ca': 'u,u,u',
            'auditSigningCert cert-pki-ca': 'u,u,Pu',  # why P?
            # KRA
            'transportCert cert-pki-kra': 'u,u,u',
            'storageCert cert-pki-kra': 'u,u,u',
            'auditSigningCert cert-pki-kra': 'u,u,Pu',
            # server
            'Server-Cert cert-pki-ca': 'u,u,u',
        }
        assert certs == expected_certs
        assert len(certs) == len(keys)

        for nickname in sorted(certs):
            cert = tasks.certutil_fetch_cert(
                self.master, paths.PKI_TOMCAT_ALIAS_DIR,
                paths.PKI_TOMCAT_ALIAS_PWDFILE_TXT, nickname)
            key_size = cert.public_key().key_size
            if nickname == 'caSigningCert cert-pki-ca':
                assert key_size == 3072
            else:
                assert key_size == 2048
            assert cert.signature_hash_algorithm.name == hashes.SHA256.name

    def test_p11_kit_softhsm2(self):
        # check that p11-kit-proxy does not inject SoftHSM2
        result = self.master.run_command(
            ["modutil", "-dbdir", paths.PKI_TOMCAT_ALIAS_DIR, "-list"])
        assert "softhsm" not in result.stdout_text.lower()
        assert "opendnssec" not in result.stdout_text.lower()

    @pytest.mark.skipif(not platformtasks.is_selinux_enabled(),
                        reason="Test needs SELinux enabled")
    def test_selinux_avcs(self):
        # Use journalctl instead of ausearch. The ausearch command is not
        # installed by default and journalctl gives us all AVCs.
        result = self.master.run_command(
            ["journalctl", "--full", "--grep=AVC", "--since=yesterday"])
        avcs = list(line.strip() for line in result.stdout_text.split('\n')
                    if "AVC avc:" in line)
        if avcs:
            print('\n'.join(avcs))
            # Use expected failure until all SELinux violations are fixed
            pytest.xfail("{} AVCs found".format(len(avcs)))

    def test_file_permissions(self):
        args = [
            "rpm", "-V", "python3-ipaclient", "python3-ipalib",
            "python3-ipaserver"
        ]

        if osinfo.id == 'fedora':
            args.extend([
                "freeipa-client", "freeipa-client-common", "freeipa-common",
                "freeipa-server", "freeipa-server-common",
                "freeipa-server-dns", "freeipa-server-trust-ad"
            ])
        else:
            args.extend([
                "ipa-client", "ipa-client-common", "ipa-common", "ipa-server",
                "ipa-server-common", "ipa-server-dns"
            ])

        result = self.master.run_command(args, raiseonerr=False)
        if result.returncode != 0:
            # Check the mode errors
            mode_warnings = re.findall(
                r"^.M.......  [cdglr ]+ (?P<filename>.*)$", result.stdout_text,
                re.MULTILINE)
            msg = "rpm -V found mode issues for the following files: {}"
            assert mode_warnings == [], msg.format(mode_warnings)
            # Check the owner errors
            user_warnings = re.findall(
                r"^.....U...  [cdglr ]+ (?P<filename>.*)$", result.stdout_text,
                re.MULTILINE)
            msg = "rpm -V found ownership issues for the following files: {}"
            assert user_warnings == [], msg.format(user_warnings)
            # Check the group errors
            group_warnings = re.findall(
                r"^......G..  [cdglr ]+ (?P<filename>.*)$", result.stdout_text,
                re.MULTILINE)
            msg = "rpm -V found group issues for the following files: {}"
            assert group_warnings == [], msg.format(group_warnings)
Ejemplo n.º 6
0
class TestUserPermissions(IntegrationTest):
    topology = 'star'
    altadmin = "altadmin"

    @classmethod
    def install(cls, mh):
        super(TestUserPermissions, cls).install(mh)
        tasks.kinit_admin(cls.master)

        # Create a new user altadmin
        password_confirmation = "%s\n%s\n" % (cls.master.config.admin_password,
                                              cls.master.config.admin_password)
        cls.master.run_command([
            'ipa', 'user-add', cls.altadmin, '--first', cls.altadmin, '--last',
            cls.altadmin, '--password'
        ],
                               stdin_text=password_confirmation)

        # Add altadmin to the group cn=admins
        cls.master.run_command(
            ['ipa', 'group-add-member', 'admins', '--users', cls.altadmin])

        # kinit as altadmin to initialize the password
        altadmin_kinit = "%s\n%s\n%s\n" % (cls.master.config.admin_password,
                                           cls.master.config.admin_password,
                                           cls.master.config.admin_password)
        cls.master.run_command(['kinit', cls.altadmin],
                               stdin_text=altadmin_kinit)
        cls.master.run_command(['kdestroy', '-A'])

    def test_delete_preserve_as_alternate_admin(self):
        """
        Test that a user member of admins group can call delete --preserve.

        This is a test case for issue 7342
        """

        # kinit admin
        tasks.kinit_admin(self.master)

        # Create a new user 'testuser' with a password
        testuser = '******'
        password = '******'
        testuser_password_confirmation = "%s\n%s\n" % (password, password)
        self.master.run_command([
            'ipa', 'user-add', testuser, '--first', testuser, '--last',
            testuser, '--password'
        ],
                                stdin_text=testuser_password_confirmation)

        # kinit as altadmin
        self.master.run_command(['kinit', self.altadmin],
                                stdin_text=self.master.config.admin_password)

        # call ipa user-del --preserve
        self.master.run_command(['ipa', 'user-del', '--preserve', testuser])

    @pytest.mark.skipif(not platformtasks.is_selinux_enabled(),
                        reason="Test needs SELinux enabled")
    @pytest.mark.xfail(osinfo.id == 'fedora' and osinfo.version_number <=
                       (28, ),
                       reason='sssd ticket 3819',
                       strict=True)
    def test_selinux_user_optimized(self):
        """
        Check that SELinux login context is set on first login for the
        user, even if the user is not mapped to a specific SELinux user.

        Related ticket https://pagure.io/SSSD/sssd/issue/3819.
        """
        if self.master.is_fips_mode:  # pylint: disable=no-member
            pytest.skip("paramiko is not compatible with FIPS mode")

        # Scenario: add an IPA user with non-default home dir, login through
        # ssh as this user and check that there is a SELinux user mapping
        # for the user with `semanage login -l`.

        # kinit admin
        tasks.kinit_admin(self.master)

        testuser = '******'
        password = '******'
        testuser_password_confirmation = "%s\n%s\n" % (password, password)
        self.master.run_command([
            'ipa', 'user-add', testuser, '--first', testuser, '--last',
            testuser, '--password', '--homedir', '/root/{}'.format(testuser)
        ],
                                stdin_text=testuser_password_confirmation)

        # login to the system
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(self.master.hostname,
                       username=testuser,
                       password=password)
        client.close()

        # check if user listed in output
        cmd = self.master.run_command(['semanage', 'login', '-l'])
        assert testuser in cmd.stdout_text

        # call ipa user-del
        self.master.run_command(['ipa', 'user-del', testuser])

    def test_stageuser_show_as_alternate_admin(self):
        """
        Test that a user member of admins group can call stageuser-show
        and read the 'Kerberos Keys available' information.

        This is a test case for issue 7342
        """
        # kinit admin
        tasks.kinit_admin(self.master)

        # Create a new stage user 'stageuser' with a password
        stageuser = '******'
        password = '******'
        stageuser_password_confirmation = "%s\n%s\n" % (password, password)
        self.master.run_command([
            'ipa', 'stageuser-add', stageuser, '--first', stageuser, '--last',
            stageuser, '--password'
        ],
                                stdin_text=stageuser_password_confirmation)

        # kinit as altadmin
        self.master.run_command(['kinit', self.altadmin],
                                stdin_text=self.master.config.admin_password)

        # call ipa stageuser-show
        # the field Kerberos Keys available must contain True
        result = self.master.run_command(['ipa', 'stageuser-show', stageuser])
        assert 'Kerberos keys available: True' in result.stdout_text

    def test_user_add_withradius(self):
        """
        Test that a user with User Administrator role can call
        ipa user-add --radius myradius
        to create a user with an assigned Radius Proxy Server.

        This is a test case for issue 7570
        """
        # kinit admin
        tasks.kinit_admin(self.master)

        # Create a radius proxy server
        radiusproxy = 'myradius'
        secret = 'Secret123'
        radius_secret_confirmation = "%s\n%s\n" % (secret, secret)
        self.master.run_command([
            'ipa', 'radiusproxy-add', radiusproxy, '--server',
            'radius.example.com', '--secret'
        ],
                                stdin_text=radius_secret_confirmation)

        # Create a user with 'User Administrator' role
        altuser = '******'
        password = '******'
        password_confirmation = "%s\n%s\n" % (password, password)
        self.master.run_command([
            'ipa', 'user-add', altuser, '--first', altuser, '--last', altuser,
            '--password'
        ],
                                stdin_text=password_confirmation)
        self.master.run_command([
            'ipa', 'role-add-member', "User Administrator", '--user', altuser
        ])

        # kinit as altuser to initialize the password
        altuser_kinit = "%s\n%s\n%s\n" % (password, password, password)
        self.master.run_command(['kinit', altuser], stdin_text=altuser_kinit)
        # call ipa user-add with --radius=...
        # this call requires read access to radius proxy servers
        self.master.run_command([
            'ipa', 'user-add', '--first', 'test', '--last', 'test',
            '--user-auth-type', 'radius', '--radius-username', 'testradius',
            'testradius', '--radius', radiusproxy
        ])