Blame SOURCES/0067-PAM-Add-application-services.patch

bb7cd1
From 855201c70f69f2b1dbcb3faef780fbdb84354f18 Mon Sep 17 00:00:00 2001
bb7cd1
From: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
Date: Sun, 26 Mar 2017 18:28:41 +0200
bb7cd1
Subject: [PATCH 67/72] PAM: Add application services
bb7cd1
bb7cd1
Related to:
bb7cd1
https://pagure.io/SSSD/sssd/issue/3310
bb7cd1
bb7cd1
Adds a new PAM responder option 'pam_app_services'. This option can hold
bb7cd1
a list of PAM services that are allowed to contact the application
bb7cd1
non-POSIX domains. These services are NOT allowed to contact any of the
bb7cd1
POSIX domains.
bb7cd1
bb7cd1
Reviewed-by: Sumit Bose <sbose@redhat.com>
bb7cd1
---
bb7cd1
 src/confdb/confdb.h                  |   1 +
bb7cd1
 src/config/SSSDConfig/__init__.py.in |   1 +
bb7cd1
 src/config/cfg_rules.ini             |   1 +
bb7cd1
 src/config/etc/sssd.api.conf         |   1 +
bb7cd1
 src/man/sssd.conf.5.xml              |  12 +++
bb7cd1
 src/responder/pam/pamsrv.c           |  33 +++++++
bb7cd1
 src/responder/pam/pamsrv.h           |   5 ++
bb7cd1
 src/responder/pam/pamsrv_cmd.c       |  26 +++++-
bb7cd1
 src/tests/cmocka/test_pam_srv.c      | 167 ++++++++++++++++++++++++++++++++++-
bb7cd1
 9 files changed, 241 insertions(+), 6 deletions(-)
bb7cd1
bb7cd1
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
bb7cd1
index 5a8d377c312f641f544b1c7cf38826192462ea3c..8719c239362b371fcdb1b78956bcddde871f141b 100644
bb7cd1
--- a/src/confdb/confdb.h
bb7cd1
+++ b/src/confdb/confdb.h
bb7cd1
@@ -129,6 +129,7 @@
bb7cd1
 #define CONFDB_PAM_CERT_AUTH "pam_cert_auth"
bb7cd1
 #define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path"
bb7cd1
 #define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout"
bb7cd1
+#define CONFDB_PAM_APP_SERVICES "pam_app_services"
bb7cd1
 
bb7cd1
 /* SUDO */
bb7cd1
 #define CONFDB_SUDO_CONF_ENTRY "config/sudo"
bb7cd1
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
bb7cd1
index 806611b6076048c08ce08c772dbd3cea5fdd656c..211338778e81c1c60ffb3cdbc67c9619343d7798 100644
bb7cd1
--- a/src/config/SSSDConfig/__init__.py.in
bb7cd1
+++ b/src/config/SSSDConfig/__init__.py.in
bb7cd1
@@ -102,6 +102,7 @@ option_strings = {
bb7cd1
     'pam_cert_auth' : _('Allow certificate based/Smartcard authentication.'),
bb7cd1
     'pam_cert_db_path' : _('Path to certificate databse with PKCS#11 modules.'),
bb7cd1
     'p11_child_timeout' : _('How many seconds will pam_sss wait for p11_child to finish'),
bb7cd1
+    'pam_app_services' : _('Which PAM services are permitted to contact application domains'),
bb7cd1
 
bb7cd1
     # [sudo]
bb7cd1
     'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'),
bb7cd1
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
bb7cd1
index 8fd2d2c5236246394353a88c50d1510bd6233f77..1a749db754cedd87f263f7ae596d6f8238bb4357 100644
bb7cd1
--- a/src/config/cfg_rules.ini
bb7cd1
+++ b/src/config/cfg_rules.ini
bb7cd1
@@ -119,6 +119,7 @@ option = pam_account_locked_message
bb7cd1
 option = pam_cert_auth
bb7cd1
 option = pam_cert_db_path
bb7cd1
 option = p11_child_timeout
bb7cd1
+option = pam_app_services
bb7cd1
 
bb7cd1
 [rule/allowed_sudo_options]
bb7cd1
 validator = ini_allowed_options
bb7cd1
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
bb7cd1
index a38b24208f89e4502e41625c540ea9958d5bbffe..a1a0c2992925a4c7df86832117eec2a0cf7894c9 100644
bb7cd1
--- a/src/config/etc/sssd.api.conf
bb7cd1
+++ b/src/config/etc/sssd.api.conf
bb7cd1
@@ -73,6 +73,7 @@ pam_account_locked_message = str, None, false
bb7cd1
 pam_cert_auth = bool, None, false
bb7cd1
 pam_cert_db_path = str, None, false
bb7cd1
 p11_child_timeout = int, None, false
bb7cd1
+pam_app_services = str, None, false
bb7cd1
 
bb7cd1
 [sudo]
bb7cd1
 # sudo service
bb7cd1
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
bb7cd1
index 8294793c765bfa6bf481693c7d7f206950454681..c4e30396f16c40db37af2f56ac218b6e37201ef7 100644
bb7cd1
--- a/src/man/sssd.conf.5.xml
bb7cd1
+++ b/src/man/sssd.conf.5.xml
bb7cd1
@@ -1325,6 +1325,18 @@ pam_account_locked_message = Account locked, please contact help desk.
bb7cd1
                         </para>
bb7cd1
                     </listitem>
bb7cd1
                 </varlistentry>
bb7cd1
+                <varlistentry>
bb7cd1
+                    <term>pam_app_services (string)</term>
bb7cd1
+                    <listitem>
bb7cd1
+                        <para>
bb7cd1
+                            Which PAM services are permitted to contact
bb7cd1
+                            domains of type <quote>application</quote>
bb7cd1
+                        </para>
bb7cd1
+                        <para>
bb7cd1
+                            Default: Not set
bb7cd1
+                        </para>
bb7cd1
+                    </listitem>
bb7cd1
+                </varlistentry>
bb7cd1
 
bb7cd1
             </variablelist>
bb7cd1
         </refsect2>
bb7cd1
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
bb7cd1
index ab3f4545520f3fcb2492a6089a039c46f0fb847f..79470823d18138da6ef9235e6336a3220ead1797 100644
bb7cd1
--- a/src/responder/pam/pamsrv.c
bb7cd1
+++ b/src/responder/pam/pamsrv.c
bb7cd1
@@ -166,6 +166,32 @@ done:
bb7cd1
     return ret;
bb7cd1
 }
bb7cd1
 
bb7cd1
+static errno_t get_app_services(struct pam_ctx *pctx)
bb7cd1
+{
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    ret = confdb_get_string_as_list(pctx->rctx->cdb, pctx,
bb7cd1
+                                    CONFDB_PAM_CONF_ENTRY,
bb7cd1
+                                    CONFDB_PAM_APP_SERVICES,
bb7cd1
+                                    &pctx->app_services);
bb7cd1
+    if (ret == ENOENT) {
bb7cd1
+        pctx->app_services = talloc_zero_array(pctx, char *, 1);
bb7cd1
+        if (pctx->app_services == NULL) {
bb7cd1
+            return ENOMEM;
bb7cd1
+        }
bb7cd1
+        /* Allocating an empty array makes it easier for the consumer
bb7cd1
+         * to iterate over it
bb7cd1
+         */
bb7cd1
+    } else if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_CRIT_FAILURE,
bb7cd1
+              "Cannot read "CONFDB_PAM_APP_SERVICES" [%d]: %s\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
+        return ret;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    return EOK;
bb7cd1
+}
bb7cd1
+
bb7cd1
 static int pam_process_init(TALLOC_CTX *mem_ctx,
bb7cd1
                             struct tevent_context *ev,
bb7cd1
                             struct confdb_ctx *cdb,
bb7cd1
@@ -219,6 +245,13 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
bb7cd1
         goto done;
bb7cd1
     }
bb7cd1
 
bb7cd1
+    ret = get_app_services(pctx);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "get_app_services failed: %d:[%s].\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
     /* Enable automatic reconnection to the Data Provider */
bb7cd1
 
bb7cd1
     /* FIXME: "retries" is too generic, either get it from a global config
bb7cd1
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
bb7cd1
index b3eb56441048ecdba82866a95f1d6d6d5e786c60..b569748fe2a2005cee5df34bef55e803175492a9 100644
bb7cd1
--- a/src/responder/pam/pamsrv.h
bb7cd1
+++ b/src/responder/pam/pamsrv.h
bb7cd1
@@ -26,6 +26,7 @@
bb7cd1
 #include "util/util.h"
bb7cd1
 #include "sbus/sssd_dbus.h"
bb7cd1
 #include "responder/common/responder.h"
bb7cd1
+#include "responder/common/cache_req/cache_req.h"
bb7cd1
 
bb7cd1
 struct pam_auth_req;
bb7cd1
 
bb7cd1
@@ -42,6 +43,9 @@ struct pam_ctx {
bb7cd1
     char **public_domains;
bb7cd1
     int public_domains_count;
bb7cd1
 
bb7cd1
+    /* What services are permitted to access application domains */
bb7cd1
+    char **app_services;
bb7cd1
+
bb7cd1
     bool cert_auth;
bb7cd1
     int p11_child_debug_fd;
bb7cd1
     char *nss_db;
bb7cd1
@@ -54,6 +58,7 @@ struct pam_auth_dp_req {
bb7cd1
 struct pam_auth_req {
bb7cd1
     struct cli_ctx *cctx;
bb7cd1
     struct sss_domain_info *domain;
bb7cd1
+    enum cache_req_dom_type req_dom_type;
bb7cd1
 
bb7cd1
     struct pam_data *pd;
bb7cd1
 
bb7cd1
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
bb7cd1
index fa6d2cc10fe1404196f9d9221a469d7a9a768211..f2b3c74b483e527932dda42279d14a9ac184b475 100644
bb7cd1
--- a/src/responder/pam/pamsrv_cmd.c
bb7cd1
+++ b/src/responder/pam/pamsrv_cmd.c
bb7cd1
@@ -1161,6 +1161,25 @@ static bool is_domain_public(char *name,
bb7cd1
     return false;
bb7cd1
 }
bb7cd1
 
bb7cd1
+static enum cache_req_dom_type
bb7cd1
+get_domain_request_type(struct pam_auth_req *preq,
bb7cd1
+                        struct pam_ctx *pctx)
bb7cd1
+{
bb7cd1
+    enum cache_req_dom_type req_dom_type;
bb7cd1
+
bb7cd1
+    /* By default, only POSIX domains are to be contacted */
bb7cd1
+    req_dom_type = CACHE_REQ_POSIX_DOM;
bb7cd1
+
bb7cd1
+    for (int i = 0; pctx->app_services[i]; i++) {
bb7cd1
+        if (strcmp(pctx->app_services[i], preq->pd->service) == 0) {
bb7cd1
+            req_dom_type = CACHE_REQ_APPLICATION_DOM;
bb7cd1
+            break;
bb7cd1
+        }
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    return req_dom_type;
bb7cd1
+}
bb7cd1
+
bb7cd1
 static errno_t check_cert(TALLOC_CTX *mctx,
bb7cd1
                           struct tevent_context *ev,
bb7cd1
                           struct pam_ctx *pctx,
bb7cd1
@@ -1257,6 +1276,9 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
bb7cd1
         goto done;
bb7cd1
     }
bb7cd1
 
bb7cd1
+    /* Determine what domain type to contact */
bb7cd1
+    preq->req_dom_type = get_domain_request_type(preq, pctx);
bb7cd1
+
bb7cd1
     /* try backend first for authentication before doing local Smartcard
bb7cd1
      * authentication */
bb7cd1
     if (pd->cmd != SSS_PAM_AUTHENTICATE && may_do_cert_auth(pctx, pd)) {
bb7cd1
@@ -1316,7 +1338,7 @@ static void pam_forwarder_cert_cb(struct tevent_req *req)
bb7cd1
 
bb7cd1
     req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx,
bb7cd1
                                       pctx->rctx->ncache, 0,
bb7cd1
-                                      CACHE_REQ_POSIX_DOM, NULL,
bb7cd1
+                                      preq->req_dom_type, NULL,
bb7cd1
                                       cert);
bb7cd1
     if (req == NULL) {
bb7cd1
         DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n");
bb7cd1
@@ -1509,7 +1531,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
bb7cd1
                            preq->cctx->rctx,
bb7cd1
                            preq->cctx->rctx->ncache,
bb7cd1
                            0,
bb7cd1
-                           CACHE_REQ_POSIX_DOM,
bb7cd1
+                           preq->req_dom_type,
bb7cd1
                            preq->pd->domain,
bb7cd1
                            data);
bb7cd1
     if (!dpreq) {
bb7cd1
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
bb7cd1
index 847419658bb983e6548722d6fa6fb22c63ee86b8..d249b8f1ea48f1c17b461c3add9e8c63774e5f88 100644
bb7cd1
--- a/src/tests/cmocka/test_pam_srv.c
bb7cd1
+++ b/src/tests/cmocka/test_pam_srv.c
bb7cd1
@@ -186,6 +186,15 @@ struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
bb7cd1
     ret = sss_hash_create(pctx, 10, &pctx->id_table);
bb7cd1
     assert_int_equal(ret, EOK);
bb7cd1
 
bb7cd1
+    /* Two NULLs so that tests can just assign a const to the first slot
bb7cd1
+     * should they need it. The code iterates until first NULL anyway
bb7cd1
+     */
bb7cd1
+    pctx->app_services = talloc_zero_array(pctx, char *, 2);
bb7cd1
+    if (pctx->app_services == NULL) {
bb7cd1
+        talloc_free(pctx);
bb7cd1
+        return NULL;
bb7cd1
+    }
bb7cd1
+
bb7cd1
     return pctx;
bb7cd1
 }
bb7cd1
 
bb7cd1
@@ -495,8 +504,12 @@ int __wrap_pam_dp_send_req(struct pam_auth_req *preq, int timeout)
bb7cd1
     return EOK;
bb7cd1
 }
bb7cd1
 
bb7cd1
-static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
bb7cd1
-                           const char *pwd, const char *fa2)
bb7cd1
+static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
bb7cd1
+                              const char *name,
bb7cd1
+                              const char *pwd,
bb7cd1
+                              const char *fa2,
bb7cd1
+                              const char *svc,
bb7cd1
+                              bool contact_dp)
bb7cd1
 {
bb7cd1
     size_t buf_size;
bb7cd1
     uint8_t *m_buf;
bb7cd1
@@ -536,7 +549,10 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
bb7cd1
         }
bb7cd1
     }
bb7cd1
 
bb7cd1
-    pi.pam_service = "pam_test_service";
bb7cd1
+    if (svc == NULL) {
bb7cd1
+        svc = "pam_test_service";
bb7cd1
+    }
bb7cd1
+    pi.pam_service = svc;
bb7cd1
     pi.pam_service_size = strlen(pi.pam_service) + 1;
bb7cd1
     pi.pam_tty = "/dev/tty";
bb7cd1
     pi.pam_tty_size = strlen(pi.pam_tty) + 1;
bb7cd1
@@ -559,7 +575,17 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
bb7cd1
     will_return(__wrap_sss_packet_get_body, buf_size);
bb7cd1
 
bb7cd1
     mock_parse_inp(name, NULL, EOK);
bb7cd1
-    mock_account_recv_simple();
bb7cd1
+    if (contact_dp) {
bb7cd1
+        mock_account_recv_simple();
bb7cd1
+    }
bb7cd1
+}
bb7cd1
+
bb7cd1
+static void mock_input_pam(TALLOC_CTX *mem_ctx,
bb7cd1
+                           const char *name,
bb7cd1
+                           const char *pwd,
bb7cd1
+                           const char *fa2)
bb7cd1
+{
bb7cd1
+    return mock_input_pam_ex(mem_ctx, name, pwd, fa2, NULL, true);
bb7cd1
 }
bb7cd1
 
bb7cd1
 static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
bb7cd1
@@ -2097,6 +2123,127 @@ void test_filter_response(void **state)
bb7cd1
     talloc_free(pd);
bb7cd1
 }
bb7cd1
 
bb7cd1
+static int pam_test_setup_appsvc_posix_dom(void **state)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    ret = pam_test_setup(state);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        return ret;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    /* This config option is only read on startup, which is not executed
bb7cd1
+     * in test, so we can't just pass in a param
bb7cd1
+     */
bb7cd1
+    pam_test_ctx->pctx->app_services[0] = discard_const("app_svc");
bb7cd1
+    return 0;
bb7cd1
+}
bb7cd1
+
bb7cd1
+void test_appsvc_posix_dom(void **state)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    /* The domain is POSIX, the request will skip over it */
bb7cd1
+    mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "app_svc", false);
bb7cd1
+    pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
bb7cd1
+
bb7cd1
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
bb7cd1
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
bb7cd1
+
bb7cd1
+    set_cmd_cb(test_pam_user_unknown_check);
bb7cd1
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
bb7cd1
+                          pam_test_ctx->pam_cmds);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+
bb7cd1
+    ret = test_ev_loop(pam_test_ctx->tctx);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+}
bb7cd1
+
bb7cd1
+void test_not_appsvc_posix_dom(void **state)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    /* A different service than the app one can authenticate against a POSIX domain */
bb7cd1
+    mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "not_app_svc", true);
bb7cd1
+
bb7cd1
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
bb7cd1
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
bb7cd1
+
bb7cd1
+    set_cmd_cb(test_pam_simple_check);
bb7cd1
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
bb7cd1
+                          pam_test_ctx->pam_cmds);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+
bb7cd1
+    /* Wait until the test finishes with EOK */
bb7cd1
+    ret = test_ev_loop(pam_test_ctx->tctx);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+}
bb7cd1
+
bb7cd1
+static int pam_test_setup_appsvc_app_dom(void **state)
bb7cd1
+{
bb7cd1
+    struct sss_test_conf_param dom_params[] = {
bb7cd1
+        { "domain_type", "application" },
bb7cd1
+        { NULL, NULL },             /* Sentinel */
bb7cd1
+    };
bb7cd1
+    struct sss_test_conf_param pam_params[] = {
bb7cd1
+        { NULL, NULL },             /* Sentinel */
bb7cd1
+    };
bb7cd1
+    struct sss_test_conf_param monitor_params[] = {
bb7cd1
+        { NULL, NULL },             /* Sentinel */
bb7cd1
+    };
bb7cd1
+
bb7cd1
+
bb7cd1
+    test_pam_setup(dom_params, pam_params, monitor_params, state);
bb7cd1
+    pam_test_setup_common();
bb7cd1
+
bb7cd1
+    /* This config option is only read on startup, which is not executed
bb7cd1
+     * in test, so we can't just pass in a param
bb7cd1
+     */
bb7cd1
+    pam_test_ctx->pctx->app_services[0] = discard_const("app_svc");
bb7cd1
+    return 0;
bb7cd1
+}
bb7cd1
+
bb7cd1
+void test_appsvc_app_dom(void **state)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    /* The domain is POSIX, the request will skip over it */
bb7cd1
+    mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "app_svc", true);
bb7cd1
+
bb7cd1
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
bb7cd1
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
bb7cd1
+
bb7cd1
+    set_cmd_cb(test_pam_simple_check);
bb7cd1
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
bb7cd1
+                          pam_test_ctx->pam_cmds);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+
bb7cd1
+    /* Wait until the test finishes with EOK */
bb7cd1
+    ret = test_ev_loop(pam_test_ctx->tctx);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+}
bb7cd1
+
bb7cd1
+void test_not_appsvc_app_dom(void **state)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    /* A different service than the app one can authenticate against a POSIX domain */
bb7cd1
+    mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "not_app_svc", false);
bb7cd1
+
bb7cd1
+    pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
bb7cd1
+
bb7cd1
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
bb7cd1
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
bb7cd1
+
bb7cd1
+    set_cmd_cb(test_pam_user_unknown_check);
bb7cd1
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
bb7cd1
+                          pam_test_ctx->pam_cmds);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+
bb7cd1
+    ret = test_ev_loop(pam_test_ctx->tctx);
bb7cd1
+    assert_int_equal(ret, EOK);
bb7cd1
+}
bb7cd1
+
bb7cd1
 int main(int argc, const char *argv[])
bb7cd1
 {
bb7cd1
     int rv;
bb7cd1
@@ -2216,6 +2363,18 @@ int main(int argc, const char *argv[])
bb7cd1
 
bb7cd1
         cmocka_unit_test_setup_teardown(test_filter_response,
bb7cd1
                                         pam_test_setup, pam_test_teardown),
bb7cd1
+        cmocka_unit_test_setup_teardown(test_appsvc_posix_dom,
bb7cd1
+                                        pam_test_setup_appsvc_posix_dom,
bb7cd1
+                                        pam_test_teardown),
bb7cd1
+        cmocka_unit_test_setup_teardown(test_not_appsvc_posix_dom,
bb7cd1
+                                        pam_test_setup_appsvc_posix_dom,
bb7cd1
+                                        pam_test_teardown),
bb7cd1
+        cmocka_unit_test_setup_teardown(test_appsvc_app_dom,
bb7cd1
+                                        pam_test_setup_appsvc_app_dom,
bb7cd1
+                                        pam_test_teardown),
bb7cd1
+        cmocka_unit_test_setup_teardown(test_not_appsvc_app_dom,
bb7cd1
+                                        pam_test_setup_appsvc_posix_dom,
bb7cd1
+                                        pam_test_teardown),
bb7cd1
     };
bb7cd1
 
bb7cd1
     /* Set debug level to invalid value so we can deside if -d 0 was used. */
bb7cd1
-- 
bb7cd1
2.9.3
bb7cd1