Blob Blame History Raw
From abfba08af067f70b736108310c3e55534ef7085e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 29 Mar 2019 10:38:50 +0100
Subject: [PATCH 21/21] intg: add test for password prompt configuration

Related to Related to https://pagure.io/SSSD/sssd/issue/3264

Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked with fixes from commit 45efba71befd96c8e9fe0a51fc300cafa93bd703)
---
 src/tests/intg/Makefile.am           |  32 +++++-
 src/tests/intg/test_pam_responder.py | 154 ++++++++++++++++++++++++++-
 2 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index 91dc86a4f..884c903b6 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -105,13 +105,36 @@ passwd: root
 group:
 	echo "root:x:0:" > $@
 
+PAM_SERVICE_DIR=pam_service_dir
+pam_sss_service:
+	$(MKDIR_P) $(PAM_SERVICE_DIR)
+	echo "auth     required       $(DESTDIR)$(pammoddir)/pam_sss.so"  > $(PAM_SERVICE_DIR)/$@
+	echo "account  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+	echo "password required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+	echo "session  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+
+pam_sss_alt_service:
+	$(MKDIR_P) $(PAM_SERVICE_DIR)
+	echo "auth     required       $(DESTDIR)$(pammoddir)/pam_sss.so"  > $(PAM_SERVICE_DIR)/$@
+	echo "account  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+	echo "password required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+	echo "session  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
+
 CLEANFILES=config.py config.pyc passwd group
 
 clean-local:
 	rm -Rf root
 	rm -f $(builddir)/cwrap-dbus-system.conf
 
-intgcheck-installed: config.py passwd group
+if HAVE_NSS
+PAM_CERT_DB_PATH="sql:$(DESTDIR)$(sysconfdir)/pki/nssdb"
+SOFTHSM2_CONF=""
+else
+PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem"
+SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf"
+endif
+
+intgcheck-installed: config.py passwd group pam_sss_service pam_sss_alt_service
 	pipepath="$(DESTDIR)$(pipepath)"; \
 	if test $${#pipepath} -gt 80; then \
 	    echo "error: Pipe directory path too long," \
@@ -126,16 +149,23 @@ intgcheck-installed: config.py passwd group
 	PATH="$$(dirname -- $(SLAPD)):$$PATH" \
 	PATH="$(DESTDIR)$(sbindir):$(DESTDIR)$(bindir):$$PATH" \
 	PATH="$$PATH:$(abs_builddir):$(abs_srcdir)" \
+	LANG=C \
 	PYTHONPATH="$(abs_builddir):$(abs_srcdir)" \
 	LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \
 	NON_WRAPPED_UID=$$(id -u) \
 	LD_PRELOAD="$(libdir)/getsockopt_wrapper.so:$$nss_wrapper:$$uid_wrapper" \
+	LD_LIBRARY_PATH="$$LD_LIBRARY_PATH:$(DESTDIR)$(nsslibdir)" \
 	NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \
 	NSS_WRAPPER_GROUP="$(abs_builddir)/group" \
 	NSS_WRAPPER_MODULE_SO_PATH="$(DESTDIR)$(nsslibdir)/libnss_sss.so.2" \
 	NSS_WRAPPER_MODULE_FN_PREFIX="sss" \
 	UID_WRAPPER=1 \
 	UID_WRAPPER_ROOT=1 \
+	PAM_WRAPPER=0 \
+	PAM_WRAPPER_SERVICE_DIR="$(abs_builddir)/$(PAM_SERVICE_DIR)" \
+	PAM_WRAPPER_PATH=$$(pkg-config --libs pam_wrapper) \
+	PAM_CERT_DB_PATH=$(PAM_CERT_DB_PATH) \
+	SOFTHSM2_CONF=$(SOFTHSM2_CONF) \
 	DBUS_SOCK_DIR="$(DESTDIR)$(runstatedir)/dbus/" \
 	DBUS_SESSION_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/fake_socket" \
 	DBUS_SYSTEM_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/system_bus_socket" \
diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py
index cf6fff2db..7e5828dde 100644
--- a/src/tests/intg/test_pam_responder.py
+++ b/src/tests/intg/test_pam_responder.py
@@ -30,9 +30,84 @@ import time
 import pytest
 
 import config
-
+import shutil
 from util import unindent
 
+import intg.ds_openldap
+
+import pytest
+
+from intg.util import unindent
+from intg.files_ops import passwd_ops_setup
+
+LDAP_BASE_DN = "dc=example,dc=com"
+
+
+@pytest.fixture(scope="module")
+def ad_inst(request):
+    """Fake AD server instance fixture"""
+    instance = intg.ds_openldap.FakeAD(
+        config.PREFIX, 10389, LDAP_BASE_DN,
+        "cn=admin", "Secret123"
+    )
+
+    try:
+        instance.setup()
+    except:
+        instance.teardown()
+        raise
+    request.addfinalizer(instance.teardown)
+    return instance
+
+
+@pytest.fixture(scope="module")
+def ldap_conn(request, ad_inst):
+    """LDAP server connection fixture"""
+    ldap_conn = ad_inst.bind()
+    ldap_conn.ad_inst = ad_inst
+    request.addfinalizer(ldap_conn.unbind_s)
+    return ldap_conn
+
+
+def format_basic_conf(ldap_conn):
+    """Format a basic SSSD configuration"""
+    return unindent("""\
+        [sssd]
+        domains = FakeAD
+        services = pam, nss
+
+        [nss]
+
+        [pam]
+        debug_level = 10
+
+        [domain/FakeAD]
+        debug_level = 10
+        ldap_search_base = {ldap_conn.ad_inst.base_dn}
+        ldap_referrals = false
+
+        id_provider = ldap
+        auth_provider = ldap
+        chpass_provider = ldap
+        access_provider = ldap
+
+        ldap_uri = {ldap_conn.ad_inst.ldap_url}
+        ldap_default_bind_dn = {ldap_conn.ad_inst.admin_dn}
+        ldap_default_authtok_type = password
+        ldap_default_authtok = {ldap_conn.ad_inst.admin_pw}
+
+        ldap_schema = ad
+        ldap_id_mapping = true
+        ldap_idmap_default_domain_sid = S-1-5-21-1305200397-2901131868-73388776
+        case_sensitive = False
+
+        [prompting/password]
+        password_prompt = My global prompt
+
+        [prompting/password/pam_sss_alt_service]
+        password_prompt = My alt service prompt
+    """).format(**locals())
+
 
 def format_pam_cert_auth_conf():
     """Format a basic SSSD configuration"""
@@ -79,6 +154,8 @@ def create_conf_fixture(request, contents):
 
 def create_sssd_process():
     """Start the SSSD process"""
+    os.environ["SSS_FILES_PASSWD"] = os.environ["NSS_WRAPPER_PASSWD"]
+    os.environ["SSS_FILES_GROUP"] = os.environ["NSS_WRAPPER_GROUP"]
     if subprocess.call(["sssd", "-D", "-f"]) != 0:
         raise Exception("sssd start failed")
 
@@ -129,3 +206,78 @@ def test_preauth_indicator(simple_pam_cert_auth):
     """Check if preauth indicator file is created"""
     statinfo = os.stat(config.PUBCONF_PATH + "/pam_preauth_available")
     assert stat.S_ISREG(statinfo.st_mode)
+
+
+@pytest.fixture
+def pam_prompting_config(request, ldap_conn):
+    """Setup SSSD with PAM prompting config"""
+    conf = format_basic_conf(ldap_conn)
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
+def test_password_prompting_config_global(ldap_conn, pam_prompting_config,
+                                          env_for_sssctl):
+    """Check global change of the password prompt"""
+
+    sssctl = subprocess.Popen(["sssctl", "user-checks", "user1_dom1-19661",
+                               "--action=auth", "--service=pam_sss_service"],
+                              universal_newlines=True,
+                              env=env_for_sssctl, stdin=subprocess.PIPE,
+                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+    try:
+        out, err = sssctl.communicate(input="111")
+    except:
+        sssctl.kill()
+        out, err = sssctl.communicate()
+
+    sssctl.stdin.close()
+    sssctl.stdout.close()
+
+    if sssctl.wait() != 0:
+        raise Exception("sssctl failed")
+
+    assert err.find("My global prompt") != -1
+
+
+def test_password_prompting_config_srv(ldap_conn, pam_prompting_config,
+                                       env_for_sssctl):
+    """Check change of the password prompt for dedicated service"""
+
+    sssctl = subprocess.Popen(["sssctl", "user-checks", "user1_dom1-19661",
+                               "--action=auth",
+                               "--service=pam_sss_alt_service"],
+                              universal_newlines=True,
+                              env=env_for_sssctl, stdin=subprocess.PIPE,
+                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+    try:
+        out, err = sssctl.communicate(input="111")
+    except:
+        sssctl.kill()
+        out, err = sssctl.communicate()
+
+    sssctl.stdin.close()
+    sssctl.stdout.close()
+
+    if sssctl.wait() != 0:
+        raise Exception("sssctl failed")
+
+    assert err.find("My alt service prompt") != -1
+
+
+@pytest.fixture
+def env_for_sssctl(request):
+    pwrap_runtimedir = os.getenv("PAM_WRAPPER_SERVICE_DIR")
+    if pwrap_runtimedir is None:
+        raise ValueError("The PAM_WRAPPER_SERVICE_DIR variable is unset\n")
+
+    env_for_sssctl = os.environ.copy()
+    env_for_sssctl['PAM_WRAPPER'] = "1"
+    env_for_sssctl['SSSD_INTG_PEER_UID'] = "0"
+    env_for_sssctl['SSSD_INTG_PEER_GID'] = "0"
+    env_for_sssctl['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH']
+
+    return env_for_sssctl
-- 
2.19.1