From: Greg Hudson Date: Thu, 14 Jun 2012 17:53:09 +0000 (-0400) Subject: Add krb5_cccol_have_content API X-Git-Tag: krb5-1.11-alpha1~501 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85afc74759792cfd3ed53daa7f42bce11ca4c536;p=thirdparty%2Fkrb5.git Add krb5_cccol_have_content API Add a new API to determine whether any krb5 credentials are available in the ccache collection. Add tests to t_cccol.py. ticket: 7173 (new) --- diff --git a/doc/rst_source/krb_appldev/refs/api/index.rst b/doc/rst_source/krb_appldev/refs/api/index.rst index 67e32cf412..c61f2a00b1 100644 --- a/doc/rst_source/krb_appldev/refs/api/index.rst +++ b/doc/rst_source/krb_appldev/refs/api/index.rst @@ -160,6 +160,7 @@ Rarely used public interfaces krb5_cccol_cursor_free.rst krb5_cccol_cursor_new.rst krb5_cccol_cursor_next.rst + krb5_cccol_have_content.rst krb5_cccol_last_change_time.rst krb5_cccol_lock.rst krb5_cccol_unlock.rst diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index ca5ccbd0ea..67d67e2d79 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -2631,6 +2631,17 @@ krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_free(krb5_context context, krb5_cccol_cursor *cursor); +/** + * Check if the credential cache collection contains any credentials. + * + * @param [in] context Library context + * + * @retval 0 Credentials are available in the collection + * @retval KRB5_CC_NOTFOUND The collection contains no credentials + */ +krb5_error_code KRB5_CALLCONV +krb5_cccol_have_content(krb5_context context); + /** * Return a timestamp of the last modification of any known credential cache. * diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c index 9f366ce060..2b1893a6c4 100644 --- a/src/lib/krb5/ccache/cccursor.c +++ b/src/lib/krb5/ccache/cccursor.c @@ -218,3 +218,38 @@ krb5_cc_cache_match(krb5_context context, krb5_principal client, *cache_out = cache; return ret; } + +krb5_error_code KRB5_CALLCONV +krb5_cccol_have_content(krb5_context context) +{ + krb5_cccol_cursor col_cursor; + krb5_cc_cursor cache_cursor; + krb5_ccache cache; + krb5_creds creds; + krb5_boolean found = FALSE; + + if (krb5_cccol_cursor_new(context, &col_cursor)) + goto no_entries; + + while (!found && !krb5_cccol_cursor_next(context, col_cursor, &cache) && + cache != NULL) { + if (krb5_cc_start_seq_get(context, cache, &cache_cursor)) + continue; + while (!found && + !krb5_cc_next_cred(context, cache, &cache_cursor, &creds)) { + if (!krb5_is_config_principal(context, creds.client)) + found = TRUE; + krb5_free_cred_contents(context, &creds); + } + krb5_cc_end_seq_get(context, cache, &cache_cursor); + krb5_cc_close(context, cache); + } + krb5_cccol_cursor_free(context, &col_cursor); + if (found) + return 0; + +no_entries: + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + _("No Kerberos credentials available")); + return KRB5_CC_NOTFOUND; +} diff --git a/src/lib/krb5/ccache/t_cccol.py b/src/lib/krb5/ccache/t_cccol.py index 4c4d239d48..2b2c8450cc 100644 --- a/src/lib/krb5/ccache/t_cccol.py +++ b/src/lib/krb5/ccache/t_cccol.py @@ -37,8 +37,15 @@ mbar = 'MEMORY:bar' cursor_test('filemem', [fccname, mfoo, mbar], [fccname, mfoo, mbar]) cursor_test('dirmem', [dccname, mfoo], [duser, dalice, dbob, mfoo]) +# Test krb5_cccol_have_content. +realm.run_as_client(['./t_cccursor', dccname, 'CONTENT']) +realm.run_as_client(['./t_cccursor', fccname, 'CONTENT']) +realm.run_as_client(['./t_cccursor', realm.ccache, 'CONTENT']) +realm.run_as_client(['./t_cccursor', mfoo, 'CONTENT'], expected_code=1) + # Make sure FILE doesn't yield a nonexistent default cache. realm.run_as_client([kdestroy]) cursor_test('noexist', [], []) +realm.run_as_client(['./t_cccursor', fccname, 'CONTENT'], expected_code=1) success('Renewing credentials') diff --git a/src/lib/krb5/ccache/t_cccursor.c b/src/lib/krb5/ccache/t_cccursor.c index a0c758603a..dc5fa5b616 100644 --- a/src/lib/krb5/ccache/t_cccursor.c +++ b/src/lib/krb5/ccache/t_cccursor.c @@ -28,7 +28,9 @@ * Displays a list of caches returned by the cccol cursor. The first argument, * if given, is set to the default cache name for the context before iterating. * Any remaining argments are resolved as caches and kept open during the - * iteration. + * iteration. If the argument "CONTENT" is given as one of the cache names, + * immediately exit with status 0 if the collection contains credentials and 1 + * if it does not. */ #include "k5-int.h" @@ -48,8 +50,11 @@ main(int argc, char **argv) if (argc > 2) { assert(argc < 60); - for (i = 2; i < argc; i++) + for (i = 2; i < argc; i++) { + if (strcmp(argv[i], "CONTENT") == 0) + return (krb5_cccol_have_content(ctx) != 0); assert(krb5_cc_resolve(ctx, argv[i], &hold[i - 2]) == 0); + } } assert(krb5_cccol_cursor_new(ctx, &cursor) == 0); diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index 53b5082253..0af5150ccb 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -212,6 +212,7 @@ krb5_cc_switch krb5_cccol_cursor_free krb5_cccol_cursor_new krb5_cccol_cursor_next +krb5_cccol_have_content krb5_change_cache krb5_change_password krb5_check_clockskew diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index 54fd081de6..08653ed42c 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -428,3 +428,4 @@ EXPORTS ; new in 1.11 (note that 399-400 are used above) krb5_chpw_message @398 krb5_kt_have_content @401 + krb5_cccol_have_content @402