From abfba08af067f70b736108310c3e55534ef7085e Mon Sep 17 00:00:00 2001 From: Sumit Bose 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 (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