summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2017-03-20 11:49:43 +0100
committerJakub Hrozek <jhrozek@redhat.com>2017-03-27 09:58:48 +0200
commitcac0db2f8004ae88b9263dc3888a11a2d3d3d114 (patch)
treef1f73ae5080f1d38522ac609dae4411d3679171e /src/tests
parentc9db8b8b19827c3d492b8d2769aa77a37dbc12d3 (diff)
downloadsssd-cac0db2f8004ae88b9263dc3888a11a2d3d3d114.tar.gz
sssd-cac0db2f8004ae88b9263dc3888a11a2d3d3d114.tar.xz
sssd-cac0db2f8004ae88b9263dc3888a11a2d3d3d114.zip
KCM: Store ccaches in secrets
Adds a new KCM responder ccache back end that forwards all requests to sssd-secrets. Reviewed-by: Michal Židek <mzidek@redhat.com> Reviewed-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/cmocka/test_kcm_json_marshalling.c234
-rw-r--r--src/tests/intg/test_kcm.py132
2 files changed, 343 insertions, 23 deletions
diff --git a/src/tests/cmocka/test_kcm_json_marshalling.c b/src/tests/cmocka/test_kcm_json_marshalling.c
new file mode 100644
index 000000000..8eff2f501
--- /dev/null
+++ b/src/tests/cmocka/test_kcm_json_marshalling.c
@@ -0,0 +1,234 @@
+/*
+ Copyright (C) 2017 Red Hat
+
+ SSSD tests: Test KCM JSON marshalling
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <popt.h>
+
+#include "util/util_creds.h"
+#include "responder/kcm/kcmsrv_ccache.h"
+#include "responder/kcm/kcmsrv_ccache_be.h"
+#include "tests/cmocka/common_mock.h"
+
+#define TEST_REALM "TESTREALM"
+#define TEST_PRINC_COMPONENT "PRINC_NAME"
+
+#define TEST_CREDS "TESTCREDS"
+
+const struct kcm_ccdb_ops ccdb_mem_ops;
+const struct kcm_ccdb_ops ccdb_sec_ops;
+
+struct kcm_marshalling_test_ctx {
+ krb5_context kctx;
+ krb5_principal princ;
+};
+
+static int setup_kcm_marshalling(void **state)
+{
+ struct kcm_marshalling_test_ctx *test_ctx;
+ krb5_error_code kerr;
+
+ test_ctx = talloc_zero(NULL, struct kcm_marshalling_test_ctx);
+ assert_non_null(test_ctx);
+
+ kerr = krb5_init_context(&test_ctx->kctx);
+ assert_int_equal(kerr, 0);
+
+ kerr = krb5_build_principal(test_ctx->kctx,
+ &test_ctx->princ,
+ sizeof(TEST_REALM)-1, TEST_REALM,
+ TEST_PRINC_COMPONENT, NULL);
+ assert_int_equal(kerr, 0);
+
+ *state = test_ctx;
+ return 0;
+}
+
+static int teardown_kcm_marshalling(void **state)
+{
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
+ struct kcm_marshalling_test_ctx);
+ assert_non_null(test_ctx);
+
+ krb5_free_principal(test_ctx->kctx, test_ctx->princ);
+ krb5_free_context(test_ctx->kctx);
+ talloc_free(test_ctx);
+ return 0;
+}
+
+static void assert_cc_name_equal(struct kcm_ccache *cc1,
+ struct kcm_ccache *cc2)
+{
+ const char *name1, *name2;
+
+ name1 = kcm_cc_get_name(cc1);
+ name2 = kcm_cc_get_name(cc2);
+ assert_string_equal(name1, name2);
+}
+
+static void assert_cc_uuid_equal(struct kcm_ccache *cc1,
+ struct kcm_ccache *cc2)
+{
+ uuid_t u1, u2;
+ errno_t ret;
+
+ ret = kcm_cc_get_uuid(cc1, u1);
+ assert_int_equal(ret, EOK);
+ ret = kcm_cc_get_uuid(cc2, u2);
+ assert_int_equal(ret, EOK);
+ ret = uuid_compare(u1, u2);
+ assert_int_equal(ret, 0);
+}
+
+static void assert_cc_princ_equal(struct kcm_ccache *cc1,
+ struct kcm_ccache *cc2)
+{
+ krb5_principal p1;
+ krb5_principal p2;
+ char *name1;
+ char *name2;
+ krb5_error_code kerr;
+
+ p1 = kcm_cc_get_client_principal(cc1);
+ p2 = kcm_cc_get_client_principal(cc1);
+
+ kerr = krb5_unparse_name(NULL, p1, &name1);
+ assert_int_equal(kerr, 0);
+ kerr = krb5_unparse_name(NULL, p2, &name2);
+ assert_int_equal(kerr, 0);
+
+ assert_string_equal(name1, name2);
+ krb5_free_unparsed_name(NULL, name1);
+ krb5_free_unparsed_name(NULL, name2);
+}
+
+static void assert_cc_offset_equal(struct kcm_ccache *cc1,
+ struct kcm_ccache *cc2)
+{
+ int32_t off1;
+ int32_t off2;
+
+ off1 = kcm_cc_get_offset(cc1);
+ off2 = kcm_cc_get_offset(cc2);
+ assert_int_equal(off1, off2);
+}
+
+static void assert_cc_equal(struct kcm_ccache *cc1,
+ struct kcm_ccache *cc2)
+{
+ assert_cc_name_equal(cc1, cc2);
+ assert_cc_uuid_equal(cc1, cc2);
+ assert_cc_princ_equal(cc1, cc2);
+ assert_cc_offset_equal(cc1, cc2);
+}
+
+static void test_kcm_ccache_marshall_unmarshall(void **state)
+{
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
+ struct kcm_marshalling_test_ctx);
+ errno_t ret;
+ struct cli_creds owner;
+ struct kcm_ccache *cc;
+ struct kcm_ccache *cc2;
+ const char *url;
+ struct sss_iobuf *payload;
+ const char *name;
+ const char *key;
+ uint8_t *data;
+
+ owner.ucred.uid = getuid();
+ owner.ucred.gid = getuid();
+
+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid());
+ assert_non_null(name);
+
+ ret = kcm_cc_new(test_ctx,
+ test_ctx->kctx,
+ &owner,
+ name,
+ test_ctx->princ,
+ &cc);
+ assert_int_equal(ret, EOK);
+
+ ret = kcm_ccache_to_sec_input(test_ctx,
+ cc,
+ &owner,
+ &url,
+ &payload);
+ assert_int_equal(ret, EOK);
+
+ key = strrchr(url, '/') + 1;
+ assert_non_null(key);
+
+ data = sss_iobuf_get_data(payload);
+ assert_non_null(data);
+
+ ret = sec_kv_to_ccache(test_ctx,
+ key,
+ (const char *) data,
+ &owner,
+ &cc2);
+ assert_int_equal(ret, EOK);
+
+ assert_cc_equal(cc, cc2);
+}
+
+int main(int argc, const char *argv[])
+{
+ poptContext pc;
+ int opt;
+ int rv;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ POPT_TABLEEND
+ };
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall,
+ setup_kcm_marshalling,
+ teardown_kcm_marshalling),
+ };
+
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
+ debug_level = SSSDBG_INVALID;
+
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch(opt) {
+ default:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ }
+ poptFreeContext(pc);
+
+ DEBUG_CLI_INIT(debug_level);
+
+ /* Even though normally the tests should clean up after themselves
+ * they might not after a failed run. Remove the old db to be sure */
+ tests_set_cwd();
+
+ rv = cmocka_run_group_tests(tests, NULL, NULL);
+
+ return rv;
+}
diff --git a/src/tests/intg/test_kcm.py b/src/tests/intg/test_kcm.py
index ad1e4923b..11f80a180 100644
--- a/src/tests/intg/test_kcm.py
+++ b/src/tests/intg/test_kcm.py
@@ -27,7 +27,8 @@ import signal
import kdc
import krb5utils
import config
-from util import unindent, run_shell
+from util import unindent
+from test_secrets import create_sssd_secrets_fixture
class KcmTestEnv(object):
def __init__(self, k5kdc, k5util):
@@ -107,15 +108,8 @@ def create_sssd_kcm_fixture(sock_path, request):
return kcm_pid
-@pytest.fixture
-def setup_for_kcm(request, kdc_instance):
- """
- Just set up the local provider for tests and enable the KCM
- responder
- """
- kcm_path = os.path.join(config.RUNSTATEDIR, "kcm.socket")
-
- sssd_conf = unindent("""\
+def create_sssd_conf(kcm_path, ccache_storage):
+ return unindent("""\
[sssd]
domains = local
services = nss
@@ -125,8 +119,11 @@ def setup_for_kcm(request, kdc_instance):
[kcm]
socket_path = {kcm_path}
+ ccache_storage = {ccache_storage}
""").format(**locals())
+
+def common_setup_for_kcm_mem(request, kdc_instance, kcm_path, sssd_conf):
kcm_socket_include = unindent("""
[libdefaults]
default_ccache_name = KCM:
@@ -142,11 +139,35 @@ def setup_for_kcm(request, kdc_instance):
return KcmTestEnv(kdc_instance, k5util)
-def test_kcm_init_list_destroy(setup_for_kcm):
+@pytest.fixture
+def setup_for_kcm_mem(request, kdc_instance):
+ """
+ Just set up the local provider for tests and enable the KCM
+ responder
+ """
+ kcm_path = os.path.join(config.RUNSTATEDIR, "kcm.socket")
+ sssd_conf = create_sssd_conf(kcm_path, "memory")
+ return common_setup_for_kcm_mem(request, kdc_instance, kcm_path, sssd_conf)
+
+@pytest.fixture
+def setup_secrets(request):
+ create_sssd_secrets_fixture(request)
+
+@pytest.fixture
+def setup_for_kcm_sec(request, kdc_instance):
+ """
+ Just set up the local provider for tests and enable the KCM
+ responder
+ """
+ kcm_path = os.path.join(config.RUNSTATEDIR, "kcm.socket")
+ sssd_conf = create_sssd_conf(kcm_path, "secrets")
+ return common_setup_for_kcm_mem(request, kdc_instance, kcm_path, sssd_conf)
+
+
+def kcm_init_list_destroy(testenv):
"""
Test that kinit, kdestroy and klist work with KCM
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("kcmtest", "Secret123")
ok = testenv.k5util.has_principal("kcmtest@KCMTEST")
@@ -172,12 +193,22 @@ def test_kcm_init_list_destroy(setup_for_kcm):
assert nprincs == 0
-def test_kcm_overwrite(setup_for_kcm):
+def test_kcm_mem_init_list_destroy(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ kcm_init_list_destroy(testenv)
+
+
+def test_kcm_sec_init_list_destroy(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ kcm_init_list_destroy(testenv)
+
+
+def kcm_overwrite(testenv):
"""
That that reusing a ccache reinitializes the cache and doesn't
add the same principal twice
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("kcmtest", "Secret123")
exp_ccache = {'kcmtest@KCMTEST': ['krbtgt/KCMTEST@KCMTEST']}
@@ -192,12 +223,22 @@ def test_kcm_overwrite(setup_for_kcm):
assert exp_ccache == testenv.k5util.list_all_princs()
-def test_collection_init_list_destroy(setup_for_kcm):
+def test_kcm_mem_overwrite(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ kcm_overwrite(testenv)
+
+
+def test_kcm_sec_overwrite(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ kcm_overwrite(testenv)
+
+
+def collection_init_list_destroy(testenv):
"""
Test that multiple principals and service tickets can be stored
in a collection.
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("alice", "alicepw")
testenv.k5kdc.add_principal("bob", "bobpw")
testenv.k5kdc.add_principal("carol", "carolpw")
@@ -241,7 +282,11 @@ def test_collection_init_list_destroy(setup_for_kcm):
out = testenv.k5util.kdestroy()
assert out == 0
- assert testenv.k5util.default_principal() == 'bob@KCMTEST'
+ # If the default is removed, KCM just uses whetever is the first entry
+ # in the collection as the default. And sine the KCM back ends don't
+ # guarantee if they are FIFO or LIFO, just check for either alice or bob
+ assert testenv.k5util.default_principal() in \
+ ['alice@KCMTEST', 'bob@KCMTEST']
cc_coll = testenv.k5util.list_all_princs()
assert len(cc_coll) == 2
assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
@@ -255,11 +300,21 @@ def test_collection_init_list_destroy(setup_for_kcm):
#assert len(cc_coll) == 0
-def test_kswitch(setup_for_kcm):
+def test_kcm_mem_collection_init_list_destroy(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ collection_init_list_destroy(testenv)
+
+
+def test_kcm_sec_collection_init_list_destroy(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ collection_init_list_destroy(testenv)
+
+
+def exercise_kswitch(testenv):
"""
Test switching between principals
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("alice", "alicepw")
testenv.k5kdc.add_principal("bob", "bobpw")
testenv.k5kdc.add_principal("host/somehostname")
@@ -301,12 +356,22 @@ def test_kswitch(setup_for_kcm):
'host/differenthostname@KCMTEST'])
-def test_subsidiaries(setup_for_kcm):
+def test_kcm_mem_kswitch(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ exercise_kswitch(testenv)
+
+
+def test_kcm_sec_kswitch(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ exercise_kswitch(testenv)
+
+
+def exercise_subsidiaries(testenv):
"""
Test that subsidiary caches are usable and KCM: without specifying UID
can be used to identify the collection
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("alice", "alicepw")
testenv.k5kdc.add_principal("bob", "bobpw")
testenv.k5kdc.add_principal("host/somehostname")
@@ -346,11 +411,21 @@ def test_subsidiaries(setup_for_kcm):
'host/differenthostname@KCMTEST'])
-def test_kdestroy_nocache(setup_for_kcm):
+def test_kcm_mem_subsidiaries(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ exercise_subsidiaries(testenv)
+
+
+def test_kcm_sec_subsidiaries(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ exercise_subsidiaries(testenv)
+
+
+def kdestroy_nocache(testenv):
"""
Destroying a non-existing ccache should not throw an error
"""
- testenv = setup_for_kcm
testenv.k5kdc.add_principal("alice", "alicepw")
out, _, _ = testenv.k5util.kinit("alice", "alicepw")
assert out == 0
@@ -359,3 +434,14 @@ def test_kdestroy_nocache(setup_for_kcm):
assert out == 0
out = testenv.k5util.kdestroy()
assert out == 0
+
+
+def test_kcm_mem_kdestroy_nocache(setup_for_kcm_mem):
+ testenv = setup_for_kcm_mem
+ exercise_subsidiaries(testenv)
+
+
+def test_kcm_sec_kdestroy_nocache(setup_for_kcm_sec,
+ setup_secrets):
+ testenv = setup_for_kcm_sec
+ exercise_subsidiaries(testenv)