URL: https://github.com/SSSD/sssd/pull/985
Author: sumit-bose
 Title: #985: ssh: improvements for ssh_use_certificate_matching_rules
Action: opened

PR body:
"""
ssh: add 'no_rules' and 'all_rules' to ssh_use_certificate_matching_rules

To make ssh_use_certificate_matching_rules option more flexible and
predictable the keywords 'all_rules' and 'no_rules' are added.
'no_rules' can be used to allow all certificates.

If rules names are given but no matching rules can be found this is
considered an error and no ssh keys will be derived from the certificates.

ssh: do not mix different certificate lists

There was a list of binary certificates and a list with base64 encoded ones
which might be different depending on the active matching rules. Only the
base64 one with the filtered results should be used.

Related to https://pagure.io/SSSD/sssd/issue/4121
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/985/head:pr985
git checkout pr985
From d91ff9582c305a95cf3ae3ae50174d752d13ff82 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 8 Jan 2020 13:46:22 +0100
Subject: [PATCH 1/2] ssh: do not mix different certificate lists

There was a list of binary certificates and a list with base64 encoded
ones which might be different depending on the active matching rules.
Only the base64 one with the filtered results should be used.

Related to https://pagure.io/SSSD/sssd/issue/4121
---
 src/tests/cmocka/test_cert_utils.c    | 80 +++++++++++++++++++++++++++
 src/util/cert.h                       |  3 +
 src/util/cert/cert_common.c           | 20 +++++++
 src/util/cert/cert_common_p11_child.c | 12 ++--
 4 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
index 325e49f009..c2c9ca2707 100644
--- a/src/tests/cmocka/test_cert_utils.c
+++ b/src/tests/cmocka/test_cert_utils.c
@@ -711,6 +711,84 @@ void test_cert_to_ssh_2keys_with_certmap_send(void **state)
     talloc_free(ev);
 }
 
+void test_cert_to_ssh_2keys_with_certmap_2_done(struct tevent_req *req)
+{
+    int ret;
+    struct test_state *ts = tevent_req_callback_data(req, struct test_state);
+    struct ldb_val *keys;
+    uint8_t *exp_key;
+    size_t exp_key_size;
+    size_t valid_keys;
+
+    assert_non_null(ts);
+    ts->done = true;
+
+    ret = cert_to_ssh_key_recv(req, ts, &keys, &valid_keys);
+    talloc_free(req);
+    assert_int_equal(ret, 0);
+    assert_non_null(keys[0].data);
+    assert_int_equal(valid_keys, 1);
+
+    exp_key = sss_base64_decode(ts, SSSD_TEST_CERT_SSH_KEY_0002, &exp_key_size);
+    assert_non_null(exp_key);
+    assert_int_equal(keys[0].length, exp_key_size);
+    assert_memory_equal(keys[0].data, exp_key, exp_key_size);
+    talloc_free(exp_key);
+
+    talloc_free(keys);
+    sss_certmap_free_ctx(ts->sss_certmap_ctx);
+}
+
+void test_cert_to_ssh_2keys_with_certmap_2_send(void **state)
+{
+    int ret;
+    struct tevent_context *ev;
+    struct tevent_req *req;
+    struct ldb_val val[2];
+
+    struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+    assert_non_null(ts);
+    ts->done = false;
+
+    ret = sss_certmap_init(ts, NULL, NULL, &ts->sss_certmap_ctx);
+    assert_int_equal(ret, EOK);
+
+    ret = sss_certmap_add_rule(ts->sss_certmap_ctx, -1,
+                               "<SUBJECT>CN=SSSD test cert 0002,.*", NULL,
+                               NULL);
+    assert_int_equal(ret, EOK);
+
+    val[0].data = sss_base64_decode(ts, SSSD_TEST_CERT_0001,
+                                          &val[0].length);
+    assert_non_null(val[0].data);
+
+    val[1].data = sss_base64_decode(ts, SSSD_TEST_CERT_0002,
+                                          &val[1].length);
+    assert_non_null(val[1].data);
+
+    ev = tevent_context_init(ts);
+    assert_non_null(ev);
+
+    req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+#ifdef HAVE_NSS
+                            "sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
+#else
+                            ABS_BUILD_DIR "/src/tests/test_CA/SSSD_test_CA.pem",
+#endif
+                            ts->sss_certmap_ctx, 2, &val[0], NULL);
+    assert_non_null(req);
+
+    tevent_req_set_callback(req, test_cert_to_ssh_2keys_with_certmap_2_done, ts);
+
+    while (!ts->done) {
+        tevent_loop_once(ev);
+    }
+
+    talloc_free(val[0].data);
+    talloc_free(val[1].data);
+    talloc_free(ev);
+}
+
 int main(int argc, const char *argv[])
 {
     poptContext pc;
@@ -746,6 +824,8 @@ int main(int argc, const char *argv[])
                                         setup, teardown),
         cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_send,
                                         setup, teardown),
+        cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_2_send,
+                                        setup, teardown),
 #endif
     };
 
diff --git a/src/util/cert.h b/src/util/cert.h
index e0d44e3d63..d038a99f67 100644
--- a/src/util/cert.h
+++ b/src/util/cert.h
@@ -52,6 +52,9 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
                               uint8_t *der_blob, size_t der_size,
                               uint8_t **key_blob, size_t *key_size);
 
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
+                                uint8_t **key_blob, size_t *key_size);
+
 struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
                                         struct tevent_context *ev,
                                         int child_debug_fd, time_t timeout,
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
index 7668770894..511fddd4d8 100644
--- a/src/util/cert/cert_common.c
+++ b/src/util/cert/cert_common.c
@@ -206,3 +206,23 @@ errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
 
     return ret;
 }
+
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
+                                uint8_t **key_blob, size_t *key_size)
+{
+    int ret;
+    uint8_t *der_blob;
+    size_t der_size;
+
+    der_blob = sss_base64_decode(mem_ctx, derb64, &der_size);
+    if (der_blob == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+        return EIO;
+    }
+
+    ret = get_ssh_key_from_cert(mem_ctx, der_blob, der_size,
+                                key_blob, key_size);
+    talloc_free(der_blob);
+
+    return ret;
+}
diff --git a/src/util/cert/cert_common_p11_child.c b/src/util/cert/cert_common_p11_child.c
index 80c10eff1f..1846ff89a7 100644
--- a/src/util/cert/cert_common_p11_child.c
+++ b/src/util/cert/cert_common_p11_child.c
@@ -28,7 +28,6 @@ struct cert_to_ssh_key_state {
     time_t timeout;
     const char **extra_args;
     const char **certs;
-    struct ldb_val *bin_certs;
     struct ldb_val *keys;
     size_t cert_count;
     size_t iter;
@@ -74,7 +73,6 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
     state->child_debug_fd = (child_debug_fd == -1) ? STDERR_FILENO
                                                    : child_debug_fd;
     state->timeout = timeout;
-    state->bin_certs = bin_certs;
     state->io = talloc(state, struct child_io_fds);
     if (state->io == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n");
@@ -138,6 +136,7 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
             ret = EINVAL;
             goto done;
         }
+
         state->cert_count++;
     }
 
@@ -289,11 +288,10 @@ static void cert_to_ssh_key_done(int child_status,
     if (valid) {
         DEBUG(SSSDBG_TRACE_LIBS, "Certificate [%s] is valid.\n",
                                   state->certs[state->iter]);
-        ret = get_ssh_key_from_cert(state->keys,
-                                    state->bin_certs[state->iter].data,
-                                    state->bin_certs[state->iter].length,
-                                    &state->keys[state->iter].data,
-                                    &state->keys[state->iter].length);
+        ret = get_ssh_key_from_derb64(state->keys,
+                                      state->certs[state->iter],
+                                      &state->keys[state->iter].data,
+                                      &state->keys[state->iter].length);
         if (ret == EOK) {
             state->valid_keys++;
         } else {

From f7bb1b3f375d42b9ad955610251b2c1260f1a9a6 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Fri, 7 Feb 2020 20:32:45 +0100
Subject: [PATCH 2/2] ssh: add 'no_rules' and 'all_rules' to
 ssh_use_certificate_matching_rules

To make ssh_use_certificate_matching_rules option more flexible and
predictable the keywords 'all_rules' and 'no_rules' are added.
'no_rules' can be used to allow all certificates.

If rules names are given but no matching rules can be found this is
considered an error and no ssh keys will be derived from the
certificates.

Related to https://pagure.io/SSSD/sssd/issue/4121
---
 src/man/sssd.conf.5.xml         |  16 +++--
 src/responder/ssh/ssh_cmd.c     |  33 ++++++---
 src/responder/ssh/ssh_private.h |   1 +
 src/responder/ssh/ssh_reply.c   |   8 +++
 src/tests/cmocka/test_ssh_srv.c | 122 +++++++++++++++++++++++++++++++-
 5 files changed, 165 insertions(+), 15 deletions(-)

diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index ef07c43d37..f71fbf4aa7 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1760,12 +1760,20 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2
                             will be ignored.
                         </para>
                         <para>
-                            If a non-existing rule name is given all rules will
-                            be ignored and all available certificates will be
-                            used to derive ssh keys.
+                            There are two special key words 'all_rules' and
+                            'no_rules' which will enable all or no rules,
+                            respectively. The latter means that no certificates
+                            will be filtered out and ssh keys will be generated
+                            from all valid certificates.
                         </para>
                         <para>
-                            Default: not set, all found rules are used
+                            A non-existing rule name is considered an error.
+                            If as a result no rule is selected all certificates
+                            will be ignored.
+                        </para>
+                        <para>
+                            Default: not set, equivalent to 'all_rules,
+                            all found rules are used
                         </para>
                     </listitem>
                 </varlistentry>
diff --git a/src/responder/ssh/ssh_cmd.c b/src/responder/ssh/ssh_cmd.c
index 09f9b73b63..d1e7c667b1 100644
--- a/src/responder/ssh/ssh_cmd.c
+++ b/src/responder/ssh/ssh_cmd.c
@@ -157,10 +157,26 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
     size_t c;
     int ret;
     bool rule_added;
+    bool all_rules = false;
+    bool no_rules = false;
+
+    ssh_ctx->cert_rules_error = false;
+
+    if (ssh_ctx->cert_rules == NULL || ssh_ctx->cert_rules[0] == NULL) {
+        all_rules = true;
+    } else if (ssh_ctx->cert_rules[0] != NULL
+                    && ssh_ctx->cert_rules[1] == NULL) {
+        if (strcmp(ssh_ctx->cert_rules[0], "all_rules") == 0) {
+            all_rules = true;
+        } else if (strcmp(ssh_ctx->cert_rules[0], "no_rules") == 0) {
+            no_rules = true;
+        }
+    }
 
     if (!ssh_ctx->use_cert_keys
             || ssh_ctx->certmap_last_read
-                    >= ssh_ctx->rctx->get_domains_last_call.tv_sec) {
+                    >= ssh_ctx->rctx->get_domains_last_call.tv_sec
+            || no_rules) {
         DEBUG(SSSDBG_TRACE_ALL, "No certmap update needed.\n");
         return EOK;
     }
@@ -180,9 +196,8 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
 
         for (c = 0; certmap_list[c] != NULL; c++) {
 
-            if (ssh_ctx->cert_rules != NULL
-                        && !string_in_list(certmap_list[c]->name,
-                                           ssh_ctx->cert_rules, true)) {
+            if (!all_rules && !string_in_list(certmap_list[c]->name,
+                                              ssh_ctx->cert_rules, true)) {
                 DEBUG(SSSDBG_TRACE_ALL, "Skipping matching rule [%s], it is "
                       "not listed in the ssh_use_certificate_matching_rules "
                       "option.\n", certmap_list[c]->name);
@@ -212,11 +227,12 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
     }
 
     if (!rule_added) {
-        DEBUG(SSSDBG_TRACE_ALL,
-              "No matching rule added, all certificates will be used.\n");
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              "No matching rule added, please check "
+              "ssh_use_certificate_matching_rules option values for typos .\n");
 
-        sss_certmap_free_ctx(sss_certmap_ctx);
-        sss_certmap_ctx = NULL;
+        ret = EINVAL;
+        goto done;
     }
 
     ret = EOK;
@@ -228,6 +244,7 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
         ssh_ctx->certmap_last_read = ssh_ctx->rctx->get_domains_last_call.tv_sec;
     } else {
         sss_certmap_free_ctx(sss_certmap_ctx);
+        ssh_ctx->cert_rules_error = true;
     }
 
     return ret;
diff --git a/src/responder/ssh/ssh_private.h b/src/responder/ssh/ssh_private.h
index 76a1aead36..028ccd616b 100644
--- a/src/responder/ssh/ssh_private.h
+++ b/src/responder/ssh/ssh_private.h
@@ -40,6 +40,7 @@ struct ssh_ctx {
     time_t certmap_last_read;
     struct sss_certmap_ctx *sss_certmap_ctx;
     char **cert_rules;
+    bool cert_rules_error;
 };
 
 struct sss_cmd_table *get_ssh_cmds(void);
diff --git a/src/responder/ssh/ssh_reply.c b/src/responder/ssh/ssh_reply.c
index 1200a3a365..97914266d6 100644
--- a/src/responder/ssh/ssh_reply.c
+++ b/src/responder/ssh/ssh_reply.c
@@ -196,6 +196,14 @@ struct tevent_req *ssh_get_output_keys_send(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
+    if (state->ssh_ctx->cert_rules_error) {
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              "Skipping keys from certificates because there was an error "
+              "while processing matching rules.\n");
+        ret = EOK;
+        goto done;
+    }
+
     ret = confdb_get_string(cli_ctx->rctx->cdb, state,
                             CONFDB_MONITOR_CONF_ENTRY,
                             CONFDB_MONITOR_CERT_VERIFICATION, NULL,
diff --git a/src/tests/cmocka/test_ssh_srv.c b/src/tests/cmocka/test_ssh_srv.c
index 45915f681b..fc43663a7f 100644
--- a/src/tests/cmocka/test_ssh_srv.c
+++ b/src/tests/cmocka/test_ssh_srv.c
@@ -712,6 +712,120 @@ void test_ssh_user_pubkey_cert_with_rule(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_ssh_user_pubkey_cert_with_all_rules(void **state)
+{
+    int ret;
+    struct sysdb_attrs *attrs;
+    /* Both rules are enabled, both certificates should be handled. */
+    const char *rule_list[] = { "all_rules", NULL };
+    struct certmap_info *certmap_list[] = { &rule_1, &rule_2, NULL};
+
+    attrs = sysdb_new_attrs(ssh_test_ctx);
+    assert_non_null(attrs);
+    ret = sysdb_attrs_add_string(attrs, SYSDB_SSH_PUBKEY, TEST_SSH_PUBKEY);
+    assert_int_equal(ret, EOK);
+    ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+                                      SSSD_TEST_CERT_0001);
+    assert_int_equal(ret, EOK);
+    ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+                                      SSSD_TEST_CERT_0002);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_set_user_attr(ssh_test_ctx->tctx->dom,
+                              ssh_test_ctx->ssh_user_fqdn,
+                              attrs,
+                              LDB_FLAG_MOD_ADD);
+    talloc_free(attrs);
+    assert_int_equal(ret, EOK);
+
+    mock_input_user(ssh_test_ctx, ssh_test_ctx->ssh_user_fqdn);
+    will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Enable certificate support */
+    ssh_test_ctx->ssh_ctx->use_cert_keys = true;
+    ssh_test_ctx->ssh_ctx->rctx->domains->certmaps = certmap_list;
+    ssh_test_ctx->ssh_ctx->certmap_last_read = 0;
+    ssh_test_ctx->ssh_ctx->rctx->get_domains_last_call.tv_sec = 1;
+    ssh_test_ctx->ssh_ctx->cert_rules = discard_const(rule_list);
+#ifdef HAVE_NSS
+    ssh_test_ctx->ssh_ctx->ca_db = discard_const("sql:" ABS_BUILD_DIR
+                                                "/src/tests/test_CA/p11_nssdb");
+#else
+    ssh_test_ctx->ssh_ctx->ca_db = discard_const(ABS_BUILD_DIR
+                                                "/src/tests/test_CA/SSSD_test_CA.pem");
+#endif
+
+    set_cmd_cb(test_ssh_user_pubkey_cert_check);
+    ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
+                          ssh_test_ctx->ssh_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(ssh_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
+void test_ssh_user_pubkey_cert_with_no_rules(void **state)
+{
+    int ret;
+    struct sysdb_attrs *attrs;
+    /* No rules should be used, both certificates should be handled. */
+    const char *rule_list[] = { "no_rules", NULL };
+    struct certmap_info *certmap_list[] = { &rule_1, &rule_2, NULL};
+
+    attrs = sysdb_new_attrs(ssh_test_ctx);
+    assert_non_null(attrs);
+    ret = sysdb_attrs_add_string(attrs, SYSDB_SSH_PUBKEY, TEST_SSH_PUBKEY);
+    assert_int_equal(ret, EOK);
+    ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+                                      SSSD_TEST_CERT_0001);
+    assert_int_equal(ret, EOK);
+    ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+                                      SSSD_TEST_CERT_0002);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_set_user_attr(ssh_test_ctx->tctx->dom,
+                              ssh_test_ctx->ssh_user_fqdn,
+                              attrs,
+                              LDB_FLAG_MOD_ADD);
+    talloc_free(attrs);
+    assert_int_equal(ret, EOK);
+
+    mock_input_user(ssh_test_ctx, ssh_test_ctx->ssh_user_fqdn);
+    will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Enable certificate support */
+    ssh_test_ctx->ssh_ctx->use_cert_keys = true;
+    ssh_test_ctx->ssh_ctx->rctx->domains->certmaps = certmap_list;
+    ssh_test_ctx->ssh_ctx->certmap_last_read = 0;
+    ssh_test_ctx->ssh_ctx->rctx->get_domains_last_call.tv_sec = 1;
+    ssh_test_ctx->ssh_ctx->cert_rules = discard_const(rule_list);
+#ifdef HAVE_NSS
+    ssh_test_ctx->ssh_ctx->ca_db = discard_const("sql:" ABS_BUILD_DIR
+                                                "/src/tests/test_CA/p11_nssdb");
+#else
+    ssh_test_ctx->ssh_ctx->ca_db = discard_const(ABS_BUILD_DIR
+                                                "/src/tests/test_CA/SSSD_test_CA.pem");
+#endif
+
+    set_cmd_cb(test_ssh_user_pubkey_cert_check);
+    ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
+                          ssh_test_ctx->ssh_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(ssh_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
 void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
 {
     int ret;
@@ -743,8 +857,6 @@ void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
     will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
-    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
-    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
 
     /* Enable certificate support */
     ssh_test_ctx->ssh_ctx->use_cert_keys = true;
@@ -760,7 +872,7 @@ void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
                                                 "/src/tests/test_CA/SSSD_test_CA.pem");
 #endif
 
-    set_cmd_cb(test_ssh_user_pubkey_cert_check);
+    set_cmd_cb(test_ssh_user_one_pubkey_check);
     ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
                           ssh_test_ctx->ssh_cmds);
     assert_int_equal(ret, EOK);
@@ -852,6 +964,10 @@ int main(int argc, const char *argv[])
                                         ssh_test_setup, ssh_test_teardown),
         cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_rule,
                                         ssh_test_setup, ssh_test_teardown),
+        cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_all_rules,
+                                        ssh_test_setup, ssh_test_teardown),
+        cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_no_rules,
+                                        ssh_test_setup, ssh_test_teardown),
         cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_unknow_rule_name,
                                         ssh_test_setup, ssh_test_teardown),
         cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_rule_1,
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to