Blob Blame History Raw
From 24c6ea3c9f2df757b3d714044c16083716e377ca Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Wed, 18 Mar 2020 11:09:01 +0300
Subject: [PATCH 1/8] pki-proxy: Don't rely on running apache until it's
 configured

This partially restores the pre-ec73de969f state of `http_proxy`,
which fails to restart the apache service during master
installation. The failure happens because of apache is not
configured yet on 'pki-tomcatd' installation phase. The mentioned
code and proposed one relies on the installer which bootstraps the
master.

Fixes: https://pagure.io/freeipa/issue/8233
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 ipaserver/install/dogtaginstance.py | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index efcf81509..650ccfff9 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -363,12 +363,6 @@ class DogtagInstance(service.Service):
         with open(paths.HTTPD_IPA_PKI_PROXY_CONF, "w") as fd:
             fd.write(template)
             os.fchmod(fd.fileno(), 0o640)
-        # Restart httpd
-        http_service = services.knownservices.httpd
-        logger.debug("Restarting %s to apply AJP changes",
-                     http_service.service_name)
-        http_service.restart()
-        logger.debug("%s successfully restarted", http_service.service_name)
 
     def configure_certmonger_renewal_helpers(self):
         """
-- 
2.24.1


From 7905891341197cb90faf635cf93ce63ae7a7a38b Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 18 Mar 2020 15:20:36 +0100
Subject: [PATCH 2/8] idviews: prevent applying to a master

Custom IDViews should not be applied to IPA master nodes. Add a
check enforcing this rule in idview_apply command.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
---
 ipaserver/plugins/idviews.py | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/ipaserver/plugins/idviews.py b/ipaserver/plugins/idviews.py
index 52134860a..018c1f605 100644
--- a/ipaserver/plugins/idviews.py
+++ b/ipaserver/plugins/idviews.py
@@ -26,6 +26,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
                        LDAPAddAttributeViaOption,
                        LDAPRemoveAttributeViaOption,
                        LDAPRetrieve, global_output_params,
+                       host_is_master,
                        add_missing_object_class)
 from .hostgroup import get_complete_hostgroup_member_list
 from ipalib import (
@@ -360,6 +361,16 @@ class baseidview_apply(LDAPQuery):
 
         for host in hosts_to_apply:
             try:
+                # Check that the host is not a master
+                # IDView must not be applied to masters
+                try:
+                    host_is_master(ldap, host)
+                except errors.ValidationError:
+                    failed['host'].append(
+                        (host,
+                         unicode(_("ID View cannot be applied to IPA master")))
+                    )
+                    continue
                 host_dn = api.Object['host'].get_dn_if_exists(host)
 
                 host_entry = ldap.get_entry(host_dn,
-- 
2.24.1


From c37a84628601d369f83546085b7e29be8fe11a59 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 18 Mar 2020 15:22:22 +0100
Subject: [PATCH 3/8] xmlrpc tests: add a test for idview-apply on a master

Add a new XMLRPC test trying to apply an IDview:
- to a master
- to a hostgroup containing a master
The command must refuse to apply the IDview to a master node.

Related: https://pagure.io/freeipa/issue/5662

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
---
 ipatests/test_xmlrpc/test_idviews_plugin.py | 48 +++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/ipatests/test_xmlrpc/test_idviews_plugin.py b/ipatests/test_xmlrpc/test_idviews_plugin.py
index 3d4cce5ea..be96e27dc 100644
--- a/ipatests/test_xmlrpc/test_idviews_plugin.py
+++ b/ipatests/test_xmlrpc/test_idviews_plugin.py
@@ -778,6 +778,54 @@ class test_idviews(Declarative):
         ),
 
 
+        # Test ID View applying to a master
+        # Try to apply to the localhost = master
+        dict(
+            desc=u'Apply %s to %s' % (idview1, api.env.host),
+            command=(
+                'idview_apply',
+                [idview1],
+                dict(host=api.env.host)
+            ),
+            expected=dict(
+                completed=0,
+                succeeded=dict(
+                    host=tuple(),
+                ),
+                failed=dict(
+                    memberhost=dict(
+                        host=([api.env.host,
+                               u'ID View cannot be applied to IPA master'],),
+                        hostgroup=tuple(),
+                    ),
+                ),
+                summary=u'Applied ID View "%s"' % idview1,
+            ),
+        ),
+        # Try to apply to the group ipaservers = all masters
+        dict(
+            desc=u'Apply %s to %s' % (idview1, 'ipaservers'),
+            command=(
+                'idview_apply',
+                [idview1],
+                dict(hostgroup=u'ipaservers')
+            ),
+            expected=dict(
+                completed=0,
+                succeeded=dict(
+                    host=tuple(),
+                ),
+                failed=dict(
+                    memberhost=dict(
+                        host=([api.env.host,
+                               u'ID View cannot be applied to IPA master'],),
+                        hostgroup=tuple(),
+                    ),
+                ),
+                summary=u'Applied ID View "%s"' % idview1,
+            ),
+        ),
+
         # Test ID View applying
 
         dict(
-- 
2.24.1


From 7d4687926e9866c378db8075dd7b55b3c40e71a9 Mon Sep 17 00:00:00 2001
From: sumenon <sumenon@redhat.com>
Date: Tue, 24 Sep 2019 12:46:15 +0530
Subject: [PATCH 4/8] ipatests: Added testcase to check logrotate is added for
 healthcheck tool

Issue: freeipa/freeipa-healthcheck#35
---
 .../test_integration/test_ipahealthcheck.py   | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
index cfa600a25..d0483459a 100644
--- a/ipatests/test_integration/test_ipahealthcheck.py
+++ b/ipatests/test_integration/test_ipahealthcheck.py
@@ -101,6 +101,7 @@ DEFAULT_PKI_CA_CERTS = [
     "auditSigningCert cert-pki-ca",
     "Server-Cert cert-pki-ca",
 ]
+
 DEFAULT_PKI_KRA_CERTS = [
     "transportCert cert-pki-kra",
     "storageCert cert-pki-kra",
@@ -402,6 +403,28 @@ class TestIpaHealthCheck(IntegrationTest):
         for check in data:
             assert check["result"] == "SUCCESS"
 
+    def test_ipa_healthcheck_log_rotate_file_exist_issue35(self):
+        """
+        This test checks if log rotation has been added
+        for ipa-healthcheck tool so that logs are rotated
+        in /var/log/ipa/healthcheck folder.
+        The test also checks that the logrotate configuration
+        file is syntactically correct by calling logrotate --debug
+        This is a testcase for below pagure issue
+        https://github.com/freeipa/freeipa-healthcheck/issues/35
+        """
+        msg = "error: {}:".format(HEALTHCHECK_LOG_ROTATE_CONF)
+        tasks.uninstall_packages(self.master, HEALTHCHECK_PKG)
+        assert not self.master.transport.file_exists(
+            HEALTHCHECK_LOG_ROTATE_CONF
+        )
+        tasks.install_packages(self.master, HEALTHCHECK_PKG)
+        assert self.master.transport.file_exists(HEALTHCHECK_LOG_ROTATE_CONF)
+        cmd = self.master.run_command(
+            ['logrotate', '--debug', HEALTHCHECK_LOG_ROTATE_CONF]
+        )
+        assert msg not in cmd.stdout_text
+
     def test_ipa_healthcheck_remove(self):
         """
         This testcase checks the removal of of healthcheck tool
-- 
2.24.1


From 04cc0450125e3c9e989c3e769a25ba2f1f336060 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Fri, 20 Mar 2020 10:08:07 +0100
Subject: [PATCH 5/8] Integrate ipa_custodia policy

ipa-custodia is an internal service for IPA. The upstream SELinux policy
has a separate module for ipa_custodia. Fold the current policy from
Fedora rawhide into ipa's SELinux policy.

Related: https://pagure.io/freeipa/issue/6891
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 selinux/ipa.fc |  8 +++++
 selinux/ipa.if | 57 ++++++++++++++++++++++++++++++
 selinux/ipa.te | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)

diff --git a/selinux/ipa.fc b/selinux/ipa.fc
index 375be9917..2d7189344 100644
--- a/selinux/ipa.fc
+++ b/selinux/ipa.fc
@@ -24,3 +24,11 @@
 /var/log/ipareplica-conncheck.log.*	--	gen_context(system_u:object_r:ipa_log_t,s0)
 
 /var/run/ipa(/.*)?              gen_context(system_u:object_r:ipa_var_run_t,s0)
+
+/usr/libexec/ipa/ipa-custodia					--	gen_context(system_u:object_r:ipa_custodia_exec_t,s0)
+/usr/libexec/ipa/custodia/ipa-custodia-dmldap			--	gen_context(system_u:object_r:ipa_custodia_dmldap_exec_t,s0)
+/usr/libexec/ipa/custodia/ipa-custodia-pki-tomcat		--	gen_context(system_u:object_r:ipa_custodia_pki_tomcat_exec_t,s0)
+/usr/libexec/ipa/custodia/ipa-custodia-pki-tomcat-wrapped	--	gen_context(system_u:object_r:ipa_custodia_pki_tomcat_exec_t,s0)
+/usr/libexec/ipa/custodia/ipa-custodia-ra-agent		--	gen_context(system_u:object_r:ipa_custodia_ra_agent_exec_t,s0)
+
+/var/log/ipa-custodia.audit.log(/.*)?				--	gen_context(system_u:object_r:ipa_custodia_log_t,s0)
diff --git a/selinux/ipa.if b/selinux/ipa.if
index 72a6b78ba..44c0a9366 100644
--- a/selinux/ipa.if
+++ b/selinux/ipa.if
@@ -308,3 +308,60 @@ interface(`ipa_read_tmp',`
 
     read_files_pattern($1, ipa_tmp_t, ipa_tmp_t)
 ')
+
+########################################
+## <summary>
+##	Execute ipa_custodia_exec_t in the ipa_custodia domain.
+## </summary>
+## <param name="domain">
+## <summary>
+##	Domain allowed to transition.
+## </summary>
+## </param>
+#
+interface(`ipa_custodia_domtrans',`
+	gen_require(`
+		type ipa_custodia_t, ipa_custodia_exec_t;
+	')
+
+	corecmd_search_bin($1)
+	domtrans_pattern($1, ipa_custodia_exec_t, ipa_custodia_t)
+')
+
+######################################
+## <summary>
+##	Execute ipa_custodia in the caller domain.
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`ipa_custodia_exec',`
+	gen_require(`
+		type ipa_custodia_exec_t;
+	')
+
+	corecmd_search_bin($1)
+	can_exec($1, ipa_custodia_exec_t)
+')
+
+#####################################
+## <summary>
+##	Connect to ipa_custodia with a unix
+##	domain stream socket.
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`ipa_custodia_stream_connect',`
+	gen_require(`
+		type ipa_custodia_t;
+	')
+
+    allow $1 ipa_custodia_t:unix_stream_socket { connectto };
+')
diff --git a/selinux/ipa.te b/selinux/ipa.te
index d8753ff7a..257e6f857 100644
--- a/selinux/ipa.te
+++ b/selinux/ipa.te
@@ -53,6 +53,25 @@ miscfiles_cert_type(ipa_cert_t)
 type ipa_tmp_t;
 files_tmp_file(ipa_tmp_t)
 
+type ipa_custodia_t;
+type ipa_custodia_exec_t;
+init_daemon_domain(ipa_custodia_t, ipa_custodia_exec_t)
+
+type ipa_custodia_dmldap_exec_t;
+init_script_file(ipa_custodia_dmldap_exec_t)
+
+type ipa_custodia_pki_tomcat_exec_t;
+init_script_file(ipa_custodia_pki_tomcat_exec_t)
+
+type ipa_custodia_ra_agent_exec_t;
+init_script_file(ipa_custodia_ra_agent_exec_t)
+
+type ipa_custodia_log_t;
+logging_log_file(ipa_custodia_log_t)
+
+type ipa_custodia_tmp_t;
+files_tmp_file(ipa_custodia_tmp_t)
+
 ########################################
 #
 # ipa_otpd local policy
@@ -286,3 +305,78 @@ optional_policy(`
 optional_policy(`
     ldap_stream_connect(ipa_ods_exporter_t)
 ')
+
+########################################
+#
+# ipa_custodia local policy
+#
+allow ipa_custodia_t self:capability { setgid setuid };
+allow ipa_custodia_t self:fifo_file rw_fifo_file_perms;
+allow ipa_custodia_t self:netlink_route_socket { create_socket_perms nlmsg_read };
+allow ipa_custodia_t self:unix_stream_socket create_stream_socket_perms;
+allow ipa_custodia_t self:unix_dgram_socket create_socket_perms;
+allow ipa_custodia_t self:udp_socket create_socket_perms;
+
+manage_dirs_pattern(ipa_custodia_t,ipa_custodia_log_t,ipa_custodia_log_t)
+manage_files_pattern(ipa_custodia_t, ipa_custodia_log_t, ipa_custodia_log_t)
+logging_log_filetrans(ipa_custodia_t, ipa_custodia_log_t, { dir file })
+
+manage_dirs_pattern(ipa_custodia_t, ipa_custodia_tmp_t, ipa_custodia_tmp_t)
+manage_files_pattern(ipa_custodia_t, ipa_custodia_tmp_t, ipa_custodia_tmp_t)
+files_tmp_filetrans(ipa_custodia_t, ipa_custodia_tmp_t, { dir file })
+
+kernel_dgram_send(ipa_custodia_t)
+
+auth_read_passwd(ipa_custodia_t)
+
+can_exec(ipa_custodia_t, ipa_custodia_dmldap_exec_t)
+can_exec(ipa_custodia_t, ipa_custodia_pki_tomcat_exec_t)
+can_exec(ipa_custodia_t, ipa_custodia_ra_agent_exec_t)
+
+corecmd_exec_bin(ipa_custodia_t)
+corecmd_mmap_bin_files(ipa_custodia_t)
+
+domain_use_interactive_fds(ipa_custodia_t)
+
+files_mmap_usr_files(ipa_custodia_t)
+
+fs_getattr_xattr_fs(ipa_custodia_t)
+
+files_read_etc_files(ipa_custodia_t)
+
+libs_exec_ldconfig(ipa_custodia_t)
+libs_ldconfig_exec_entry_type(ipa_custodia_t)
+
+miscfiles_read_generic_certs(ipa_custodia_t)
+miscfiles_read_localization(ipa_custodia_t)
+
+sysnet_read_config(ipa_custodia_t)
+
+optional_policy(`
+	apache_search_config(ipa_custodia_t)
+	apache_systemctl(ipa_custodia_t)
+	apache_manage_pid_files(ipa_custodia_t)
+')
+
+optional_policy(`
+	dirsrv_manage_var_run(ipa_custodia_t)
+	dirsrv_stream_connect(ipa_custodia_t)
+')
+
+optional_policy(`
+	ipa_read_lib(ipa_custodia_t)
+	ipa_search_lib(ipa_custodia_t)
+')
+
+optional_policy(`
+	pki_manage_tomcat_etc_rw(ipa_custodia_t)
+	pki_read_tomcat_cert(ipa_custodia_t)
+	pki_rw_tomcat_cert(ipa_custodia_t)
+')
+
+optional_policy(`
+	sssd_read_public_files(ipa_custodia_t)
+	sssd_run_stream_connect(ipa_custodia_t)
+	sssd_search_lib(ipa_custodia_t)
+	sssd_stream_connect(ipa_custodia_t)
+')
-- 
2.24.1


From 7d525ab4308060435808a311de55a76fb26a28c6 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Fri, 20 Mar 2020 10:00:06 +0100
Subject: [PATCH 6/8] Move freeipa-selinux dependency to freeipa-common

The SELinux policy defines file contexts that are also used by clients,
e.g. /var/log/ipa/. Make freeipa-selinux a dependency of freeipa-common.

Related: https://pagure.io/freeipa/issue/6891
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 Makefile.am       | 14 ++++++++++++--
 freeipa.spec.in   | 12 +++++++-----
 selinux/README.md | 11 +++++++++++
 3 files changed, 30 insertions(+), 7 deletions(-)
 create mode 100644 selinux/README.md

diff --git a/Makefile.am b/Makefile.am
index 5ef2e9c8f..9c273ee10 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ ACLOCAL_AMFLAGS = -I m4
 
 if ENABLE_SERVER
     IPASERVER_SUBDIRS = ipaserver
-    SERVER_SUBDIRS = daemons init install selinux
+    SERVER_SUBDIRS = daemons init install
 endif
 
 if WITH_IPATESTS
@@ -26,7 +26,17 @@ PYTHON_SCRIPT_SUBDIRS = \
 AZURE_PYTHON_SCRIPT_SUBDIR = $(top_builddir)/ipatests/azure
 
 IPA_PLACEHOLDERS = freeipa ipa ipaserver ipatests
-SUBDIRS = asn1 util client contrib po pypi $(PYTHON_SUBDIRS) $(SERVER_SUBDIRS)
+SUBDIRS = \
+        asn1 \
+        util \
+        client \
+        contrib \
+        po \
+        pypi \
+        selinux \
+        $(PYTHON_SUBDIRS) \
+        $(SERVER_SUBDIRS) \
+        $(NULL)
 
 GENERATED_PYTHON_FILES = \
 	$(top_builddir)/ipaplatform/override.py \
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 7c3c8dfcf..7d716a139 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -363,11 +363,6 @@ Requires: oddjob
 # 0.7.0-2: https://pagure.io/gssproxy/pull-request/172
 Requires: gssproxy >= 0.7.0-2
 Requires: sssd-dbus >= %{sssd_version}
-%if 0%{?with_selinux}
-# This ensures that the *-selinux package and all it’s dependencies are not pulled
-# into containers and other systems that do not use SELinux
-Requires:       (%{name}-selinux if selinux-policy-%{selinuxtype})
-%endif
 
 Provides: %{alt_name}-server = %{version}
 Conflicts: %{alt_name}-server
@@ -715,6 +710,13 @@ Obsoletes: %{alt_name}-common < %{version}
 
 Conflicts: %{alt_name}-python < %{version}
 
+%if 0%{?with_selinux}
+# This ensures that the *-selinux package and all it’s dependencies are not
+# pulled into containers and other systems that do not use SELinux. The
+# policy defines types and file contexts for client and server.
+Requires:       (%{name}-selinux if selinux-policy-%{selinuxtype})
+%endif
+
 %description common
 IPA is an integrated solution to provide centrally managed Identity (users,
 hosts, services), Authentication (SSO, 2FA), and Authorization
diff --git a/selinux/README.md b/selinux/README.md
new file mode 100644
index 000000000..5b7ee9d36
--- /dev/null
+++ b/selinux/README.md
@@ -0,0 +1,11 @@
+# IPA SELinux policy
+
+The ``ipa`` SELinux policy is used by IPA client and server. The
+policy was forked off from [Fedora upstream policy](https://github.com/fedora-selinux/selinux-policy-contrib)
+at commit ``b1751347f4af99de8c88630e2f8d0a352d7f5937``.
+
+Some file locations are owned by other policies:
+
+* ``/var/lib/ipa/pki-ca/publish(/.*)?`` is owned by Dogtag PKI policy
+* ``/usr/lib/ipa/certmonger(/.*)?`` is owned by certmonger policy
+* ``/var/lib/ipa-client(/.*)?`` is owned by realmd policy
-- 
2.24.1


From 127b8d9cf23bf65aa42e6ee9ed8d7f8628bbac19 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 16 Mar 2020 10:35:02 +0200
Subject: [PATCH 7/8] Prevent adding IPA objects as external members of
 external groups

The purpose of external groups in FreeIPA is to be able to reference
objects only existing in trusted domains. These members get resolved
through SSSD interfaces but there is nothing that prevents SSSD from
resolving any IPA user or group if they have security identifiers
associated.

Enforce a check that a SID returned by SSSD does not belong to IPA
domain and raise a validation error if this is the case. This would
prevent adding IPA users or groups as external members of an external
group.

RN: Command 'ipa group-add-member' allowed to specify any user or group
RN: for '--external' option. A stricter check is added to verify that
RN: a group or user to be added as an external member does not come
RN: from IPA domain.

Fixes: https://pagure.io/freeipa/issue/8236
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
 ipaserver/dcerpc.py                    |  7 ++++++-
 ipatests/test_integration/test_sssd.py | 24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index 50e0ec895..27d075425 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -408,7 +408,12 @@ class DomainValidator:
         if object_name in result and \
            (pysss_nss_idmap.SID_KEY in result[object_name]):
             object_sid = result[object_name][pysss_nss_idmap.SID_KEY]
-            return object_sid
+            if self.is_trusted_sid_valid(object_sid):
+                return object_sid
+            else:
+                raise errors.ValidationError(name=_('trusted domain object'),
+                                             error=_('Object does not belong '
+                                                     'to a trusted domain'))
 
         # If fallback to AD DC LDAP is not allowed, bail out
         if not fallback_to_ldap:
diff --git a/ipatests/test_integration/test_sssd.py b/ipatests/test_integration/test_sssd.py
index 69a477166..872863a73 100644
--- a/ipatests/test_integration/test_sssd.py
+++ b/ipatests/test_integration/test_sssd.py
@@ -19,6 +19,7 @@ from ipaplatform.tasks import tasks as platform_tasks
 from ipaplatform.osinfo import osinfo
 from ipaplatform.paths import paths
 from ipapython.dn import DN
+from ipalib import errors
 
 
 class TestSSSDWithAdTrust(IntegrationTest):
@@ -329,3 +330,26 @@ class TestSSSDWithAdTrust(IntegrationTest):
         finally:
             self.master.run_command(['ipa', 'user-del', user])
             self.master.run_command(['ipa', 'group-del', user, ext_group])
+
+    @pytest.mark.parametrize('user_origin', ['ipa', 'ad'])
+    def test_external_group_member_mismatch(self, user_origin):
+        """Prevent adding IPA objects as external group external members
+
+        External groups must only allow adding non-IPA objects as external
+        members in 'ipa group-add-member foo --external bar'.
+        """
+        master = self.master
+        tasks.clear_sssd_cache(master)
+        tasks.kinit_admin(master)
+        master.run_command(['ipa', 'group-add', '--external',
+                            'ext-ipatest'])
+        try:
+            master.run_command(['ipa', 'group-add-member',
+                                'ext-ipatest',
+                                '--external',
+                                self.users[user_origin]['name']])
+        except errors.ValidationError:
+            # Only 'ipa' origin should throw a validation error
+            assert user_origin == 'ipa'
+        finally:
+            master.run_command(['ipa', 'group-del', 'ext-ipatest'])
-- 
2.24.1


From ebb3c22ddb998997eb05e7bd4da2157e88b6c8f3 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 18 Mar 2020 11:13:19 +0100
Subject: [PATCH 8/8] ipatests: wait for SSSD to become online in
 backup/restore tests

The backup/restore tests are calling 'id admin' after restore
to make sure that the user name can be resolved after a restore.
The test should wait for SSSD backend to become online before
doing any check, otherwise there is a risk that the call to
'id admin' fails.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Sergey Orlov <sorlov@redhat.com>
---
 ipatests/pytest_ipa/integration/tasks.py      | 24 +++++++++++++++++++
 .../test_backup_and_restore.py                |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index f805a2f52..0b8eca1f3 100755
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -2108,3 +2108,27 @@ def wait_for_request(host, request_id, timeout=120):
         raise RuntimeError("request timed out")
 
     return state
+
+
+def wait_for_sssd_domain_status_online(host, timeout=120):
+    """Wait up to timeout (in seconds) for sssd domain status to become Online
+
+    The method is checking the Online Status of the domain as displayed by
+    the command sssctl domain-status <domain> -o and returns successfully
+    when the status is Online.
+    This call is useful for instance when 389-ds has been stopped and restarted
+    as SSSD may need a while before it reconnects and switches from Offline
+    mode to Online.
+    """
+    pattern = re.compile(r'Online status: (?P<state>.*)\n')
+    for _i in range(0, timeout, 5):
+        result = host.run_command(
+            [paths.SSSCTL, "domain-status", host.domain.name, "-o"]
+        )
+        match = pattern.search(result.stdout_text)
+        state = match.group('state')
+        if state == 'Online':
+            break
+        time.sleep(5)
+    else:
+        raise RuntimeError("SSSD still offline")
diff --git a/ipatests/test_integration/test_backup_and_restore.py b/ipatests/test_integration/test_backup_and_restore.py
index eadc8cbef..9182ac9b8 100644
--- a/ipatests/test_integration/test_backup_and_restore.py
+++ b/ipatests/test_integration/test_backup_and_restore.py
@@ -151,6 +151,8 @@ def restore_checker(host):
 
     yield
 
+    # Wait for SSSD to become online before doing any other check
+    tasks.wait_for_sssd_domain_status_online(host)
     tasks.kinit_admin(host)
 
     for (check, assert_func), expected in zip(CHECKS, results):
-- 
2.24.1