From: Greg Hudson Date: Wed, 8 Aug 2018 15:45:28 +0000 (-0400) Subject: Add kdestroy -p option X-Git-Tag: krb5-1.17-beta1~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F825%2Fhead;p=thirdparty%2Fkrb5.git Add kdestroy -p option Add an option to destroy a cache within a collection by principal name. This option can be used together with -c to specify the collection. Also document that kdestroy -A and -c can be used together (ticket 8602). ticket: 8724 (new) --- diff --git a/doc/user/user_commands/kdestroy.rst b/doc/user/user_commands/kdestroy.rst index b8c67aba4c..37dcae99ee 100644 --- a/doc/user/user_commands/kdestroy.rst +++ b/doc/user/user_commands/kdestroy.rst @@ -26,7 +26,8 @@ OPTIONS **-A** Destroys all caches in the collection, if a cache collection is - available. + available. May be used with the **-c** option to specify the + collection to be destroyed. **-q** Run quietly. Normally kdestroy beeps if it fails to destroy the @@ -41,6 +42,11 @@ OPTIONS **KRB5CCNAME** environment variable is set, its value is used to name the default ticket cache. +**-p** *princ_name* + If a cache collection is available, destroy the cache for + *princ_name* instead of the primary cache. May be used with the + **-c** option to specify the collection to be searched. + NOTE ---- diff --git a/src/clients/kdestroy/kdestroy.c b/src/clients/kdestroy/kdestroy.c index 4e16bec252..774b729fdb 100644 --- a/src/clients/kdestroy/kdestroy.c +++ b/src/clients/kdestroy/kdestroy.c @@ -49,10 +49,12 @@ char *progname; static void usage() { - fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name]\n"), progname); + fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name] [-p princ_name]\n"), + progname); fprintf(stderr, _("\t-A destroy all credential caches in collection\n")); fprintf(stderr, _("\t-q quiet mode\n")); fprintf(stderr, _("\t-c specify name of credentials cache\n")); + fprintf(stderr, _("\t-p specify principal name within collection\n")); exit(2); } @@ -87,13 +89,15 @@ main(int argc, char *argv[]) krb5_error_code ret; krb5_ccache cache = NULL; krb5_cccol_cursor cursor; + krb5_principal princ; char *cache_name = NULL; + const char *princ_name = NULL; int code = 0, errflg = 0, quiet = 0, all = 0, c; setlocale(LC_ALL, ""); progname = GET_PROGNAME(argv[0]); - while ((c = getopt(argc, argv, "54Aqc:")) != -1) { + while ((c = getopt(argc, argv, "54Aqc:p:")) != -1) { switch (c) { case 'A': all = 1; @@ -109,6 +113,14 @@ main(int argc, char *argv[]) cache_name = optarg; } break; + case 'p': + if (princ_name != NULL) { + fprintf(stderr, _("Only one -p option allowed\n")); + errflg++; + } else { + princ_name = optarg; + } + break; case '4': fprintf(stderr, _("Kerberos 4 is no longer supported\n")); exit(3); @@ -122,6 +134,11 @@ main(int argc, char *argv[]) } } + if (all && princ_name != NULL) { + fprintf(stderr, _("-A option is exclusive with -p option\n")); + errflg++; + } + if (optind != argc) errflg++; @@ -167,10 +184,26 @@ main(int argc, char *argv[]) return 0; } - code = krb5_cc_default(context, &cache); - if (code) { - com_err(progname, code, _("while resolving ccache")); - exit(1); + if (princ_name != NULL) { + code = krb5_parse_name(context, princ_name, &princ); + if (code) { + com_err(progname, code, _("while parsing principal name %s"), + princ_name); + exit(1); + } + code = krb5_cc_cache_match(context, princ, &cache); + if (code) { + com_err(progname, code, _("while finding cache for %s"), + princ_name); + exit(1); + } + krb5_free_principal(context, princ); + } else { + code = krb5_cc_default(context, &cache); + if (code) { + com_err(progname, code, _("while resolving ccache")); + exit(1); + } } code = krb5_cc_destroy(context, cache); @@ -187,7 +220,7 @@ main(int argc, char *argv[]) } } - if (!quiet && !errflg) + if (!quiet && !errflg && princ_name == NULL) print_remaining_cc_warning(context); krb5_free_context(context); diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py index 48022600be..fcf1a611e1 100755 --- a/src/tests/t_ccache.py +++ b/src/tests/t_ccache.py @@ -56,6 +56,7 @@ realm.run([klist, '-s'], expected_code=1) realm.addprinc('alice', password('alice')) realm.addprinc('bob', password('bob')) realm.addprinc('carol', password('carol')) +realm.addprinc('doug', password('doug')) def collection_test(realm, ccname): cctype = ccname.partition(':')[0] @@ -86,14 +87,16 @@ def collection_test(realm, ccname): output = realm.run([klist, '-l']) if '---\nalice@' not in output or output.count('\n') != 4: fail('klist -l did not show expected output after re-kinit for alice.') + realm.kinit('doug', password('doug')) realm.kinit('bob', password('bob')) output = realm.run([klist, '-A', ccname]) if 'bob@' not in output.splitlines()[1] or 'alice@' not in output or \ - 'carol' not in output or output.count('Default principal:') != 3: - fail('klist -A did not show expected output after kinit for bob.') + 'carol@' not in output or 'doug@' not in output or \ + output.count('Default principal:') != 4: + fail('klist -A did not show expected output after kinit doug+bob.') realm.run([kswitch, '-p', 'carol']) output = realm.run([klist, '-l']) - if '---\ncarol@' not in output or output.count('\n') != 5: + if '---\ncarol@' not in output or output.count('\n') != 6: fail('klist -l did not show expected output after kswitch to carol.') # Switch to specifying the collection name on the command line @@ -103,10 +106,14 @@ def collection_test(realm, ccname): mark('%s collection, command-line specifier' % cctype) realm.run([kdestroy, '-c', ccname]) output = realm.run([klist, '-l', ccname]) - if 'carol@' in output or 'bob@' not in output or output.count('\n') != 4: + if 'carol@' in output or 'bob@' not in output or output.count('\n') != 5: fail('kdestroy failed to remove only primary ccache.') realm.run([klist, '-s', ccname], expected_code=1) realm.run([klist, '-A', '-s', ccname]) + realm.run([kdestroy, '-p', 'alice', '-c', ccname]) + output = realm.run([klist, '-l', ccname]) + if 'alice@' in output or 'bob@' not in output or output.count('\n') != 4: + fail('kdestroy -p failed to remove alice') realm.run([kdestroy, '-A', '-c', ccname]) output = realm.run([klist, '-l', ccname], expected_code=1) if not output.endswith('---\n') or output.count('\n') != 2: