From 8ff83e6f82531f177fc6b9c10d0d218ec370c5e0 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 5 Dec 2014 13:23:12 +0100 Subject: [PATCH] krb5: add wrapper for krb5_kt_have_content() krb5_kt_have_content() was introduced in MIT Kerberos 1.11. For older platforms this patch adds sss_krb5_kt_have_content() as a wrapper. Resolves https://fedorahosted.org/sssd/ticket/2518 --- src/external/krb5.m4 | 1 + src/providers/krb5/krb5_keytab.c | 2 +- src/tests/cmocka/test_copy_keytab.c | 33 ++++++++++++++++++++++++++++++ src/util/sss_krb5.c | 40 +++++++++++++++++++++++++++++++++++++ src/util/sss_krb5.h | 2 ++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/external/krb5.m4 b/src/external/krb5.m4 index 90b4a25830086291dbabe049b4985d7fa20aba7f..8fc9096c7fe70cf9bb682f1086b3bba07e936936 100644 --- a/src/external/krb5.m4 +++ b/src/external/krb5.m4 @@ -64,6 +64,7 @@ AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \ krb5_timestamp_to_sfstring \ krb5_set_trace_callback \ krb5_find_authdata \ + krb5_kt_have_content \ krb5_cc_get_full_name]) CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS diff --git a/src/providers/krb5/krb5_keytab.c b/src/providers/krb5/krb5_keytab.c index 855f69419611b863a7aea79e2788272f819b0736..0d6a85c0b8b02937fb2ee6b058174243b2e56114 100644 --- a/src/providers/krb5/krb5_keytab.c +++ b/src/providers/krb5/krb5_keytab.c @@ -61,7 +61,7 @@ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, return kerr; } - kerr = krb5_kt_have_content(kctx, keytab); + kerr = sss_krb5_kt_have_content(kctx, keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "keytab [%s] has not entries.\n", keytab_file); diff --git a/src/tests/cmocka/test_copy_keytab.c b/src/tests/cmocka/test_copy_keytab.c index 9d2b801564f738b4a75445045bd7602b2fd01625..f46e321950eaeda642459982e199c55da0727660 100644 --- a/src/tests/cmocka/test_copy_keytab.c +++ b/src/tests/cmocka/test_copy_keytab.c @@ -29,6 +29,7 @@ #define KEYTAB_TEST_PRINC "test/keytab@TEST.KEYTAB" #define KEYTAB_PATH TEST_DIR "/keytab_test.keytab" +#define EMPTY_KEYTAB_PATH TEST_DIR "/empty_keytab_test.keytab" struct keytab_test_ctx { krb5_context kctx; @@ -170,6 +171,36 @@ void test_copy_keytab(void **state) assert_int_equal(kerr, 0); } +void test_sss_krb5_kt_have_content(void **state) +{ + krb5_error_code kerr; + krb5_keytab keytab; + struct keytab_test_ctx *test_ctx = talloc_get_type(*state, + struct keytab_test_ctx); + assert_non_null(test_ctx); + + kerr = krb5_kt_resolve(test_ctx->kctx, test_ctx->keytab_file_name, &keytab); + assert_int_equal(kerr, 0); + + kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab); + assert_int_equal(kerr, 0); + + kerr = krb5_kt_close(test_ctx->kctx, keytab); + assert_int_equal(kerr, 0); + + kerr = krb5_kt_resolve(test_ctx->kctx, "FILE:" EMPTY_KEYTAB_PATH, &keytab); + assert_int_equal(kerr, 0); + + kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab); + assert_int_equal(kerr, KRB5_KT_NOTFOUND); + + kerr = krb5_kt_close(test_ctx->kctx, keytab); + assert_int_equal(kerr, 0); + + /* no need to remove EMPTY_KEYTAB_PATH because krb5_kt_close() does not + * create empty keytab files */ +} + int main(int argc, const char *argv[]) { poptContext pc; @@ -184,6 +215,8 @@ int main(int argc, const char *argv[]) const UnitTest tests[] = { unit_test_setup_teardown(test_copy_keytab, setup_keytab, teardown_keytab), + unit_test_setup_teardown(test_sss_krb5_kt_have_content, + setup_keytab, teardown_keytab), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c index b5cc5537602c66d5f2296e296d8e127d34d27a8d..447b5a5bc941c3ff0cf72fbaa0f2293dc4311194 100644 --- a/src/util/sss_krb5.c +++ b/src/util/sss_krb5.c @@ -1029,3 +1029,43 @@ done: return NULL; #endif /* HAVE_KRB5_CC_COLLECTION */ } + +krb5_error_code sss_krb5_kt_have_content(krb5_context context, + krb5_keytab keytab) +{ +#ifdef HAVE_KRB5_KT_HAVE_CONTENT + return krb5_kt_have_content(context, keytab); +#else + krb5_keytab_entry entry; + krb5_kt_cursor cursor; + krb5_error_code kerr; + krb5_error_code kerr_end; + + kerr = krb5_kt_start_seq_get(context, keytab, &cursor); + if (kerr != 0) { + DEBUG(SSSDBG_OP_FAILURE, + "krb5_kt_start_seq_get failed, assuming no entries.\n"); + return KRB5_KT_NOTFOUND; + } + + kerr = krb5_kt_next_entry(context, keytab, &entry, &cursor); + kerr_end = krb5_kt_end_seq_get(context, keytab, &cursor); + if (kerr != 0) { + DEBUG(SSSDBG_OP_FAILURE, + "krb5_kt_next_entry failed, assuming no entries.\n"); + return KRB5_KT_NOTFOUND; + } + kerr = krb5_free_keytab_entry_contents(context, &entry); + + if (kerr_end != 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "krb5_kt_end_seq_get failed, ignored.\n"); + } + if (kerr != 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "krb5_free_keytab_entry_contents failed, ignored.\n"); + } + + return 0; +#endif +} diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h index afa0d1943d8a23ae1543ae3874b5abbfbb4b3372..462dbbe0bda8969432c8ac2f062a0123c1f098f0 100644 --- a/src/util/sss_krb5.h +++ b/src/util/sss_krb5.h @@ -187,4 +187,6 @@ sss_krb5_get_primary(TALLOC_CTX *mem_ctx, const char *pattern, const char *hostname); +krb5_error_code sss_krb5_kt_have_content(krb5_context context, + krb5_keytab keytab); #endif /* __SSS_KRB5_H__ */ -- 2.1.0