1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* clients/kdestroy/kdestroy.c - Destroy contents of credential cache */ 3 /* 4 * Copyright 1990 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include "k5-platform.h" 28 #include <krb5.h> 29 #include <com_err.h> 30 #include <locale.h> 31 #include <string.h> 32 #include <stdio.h> 33 34 #ifdef __STDC__ 35 #define BELL_CHAR '\a' 36 #else 37 #define BELL_CHAR '\007' 38 #endif 39 40 #ifndef _WIN32 41 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x)) 42 #else 43 #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) 44 #endif 45 46 char *progname; 47 48 49 static void 50 usage() 51 { 52 fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name] [-p princ_name]\n"), 53 progname); 54 fprintf(stderr, _("\t-A destroy all credential caches in collection\n")); 55 fprintf(stderr, _("\t-q quiet mode\n")); 56 fprintf(stderr, _("\t-c specify name of credentials cache\n")); 57 fprintf(stderr, _("\t-p specify principal name within collection\n")); 58 exit(2); 59 } 60 61 /* Print a warning if there are still un-destroyed caches in the collection. */ 62 static void 63 print_remaining_cc_warning(krb5_context context) 64 { 65 krb5_error_code ret; 66 krb5_ccache cache; 67 krb5_cccol_cursor cursor; 68 69 ret = krb5_cccol_cursor_new(context, &cursor); 70 if (ret) { 71 com_err(progname, ret, _("while listing credential caches")); 72 exit(1); 73 } 74 75 ret = krb5_cccol_cursor_next(context, cursor, &cache); 76 if (ret == 0 && cache != NULL) { 77 fprintf(stderr, 78 _("Other credential caches present, use -A to destroy all\n")); 79 krb5_cc_close(context, cache); 80 } 81 82 krb5_cccol_cursor_free(context, &cursor); 83 } 84 85 int 86 main(int argc, char *argv[]) 87 { 88 krb5_context context; 89 krb5_error_code ret; 90 krb5_ccache cache = NULL; 91 krb5_cccol_cursor cursor; 92 krb5_principal princ; 93 char *cache_name = NULL; 94 const char *princ_name = NULL; 95 int code = 0, errflg = 0, quiet = 0, all = 0, c; 96 97 setlocale(LC_ALL, ""); 98 progname = GET_PROGNAME(argv[0]); 99 100 while ((c = getopt(argc, argv, "54Aqc:p:")) != -1) { 101 switch (c) { 102 case 'A': 103 all = 1; 104 break; 105 case 'q': 106 quiet = 1; 107 break; 108 case 'c': 109 if (cache_name) { 110 fprintf(stderr, _("Only one -c option allowed\n")); 111 errflg++; 112 } else { 113 cache_name = optarg; 114 } 115 break; 116 case 'p': 117 if (princ_name != NULL) { 118 fprintf(stderr, _("Only one -p option allowed\n")); 119 errflg++; 120 } else { 121 princ_name = optarg; 122 } 123 break; 124 case '4': 125 fprintf(stderr, _("Kerberos 4 is no longer supported\n")); 126 exit(3); 127 break; 128 case '5': 129 break; 130 case '?': 131 default: 132 errflg++; 133 break; 134 } 135 } 136 137 if (all && princ_name != NULL) { 138 fprintf(stderr, _("-A option is exclusive with -p option\n")); 139 errflg++; 140 } 141 142 if (optind != argc) 143 errflg++; 144 145 if (errflg) 146 usage(); 147 148 ret = krb5_init_context(&context); 149 if (ret) { 150 com_err(progname, ret, _("while initializing krb5")); 151 exit(1); 152 } 153 154 if (cache_name != NULL) { 155 code = krb5_cc_set_default_name(context, cache_name); 156 if (code) { 157 com_err(progname, code, _("while setting default cache name")); 158 exit(1); 159 } 160 } 161 162 if (all) { 163 code = krb5_cccol_cursor_new(context, &cursor); 164 if (code) { 165 com_err(progname, code, _("while listing credential caches")); 166 exit(1); 167 } 168 while (krb5_cccol_cursor_next(context, cursor, &cache) == 0 && 169 cache != NULL) { 170 code = krb5_cc_get_full_name(context, cache, &cache_name); 171 if (code) { 172 com_err(progname, code, _("composing ccache name")); 173 exit(1); 174 } 175 code = krb5_cc_destroy(context, cache); 176 if (code && code != KRB5_FCC_NOFILE) { 177 com_err(progname, code, _("while destroying cache %s"), 178 cache_name); 179 } 180 krb5_free_string(context, cache_name); 181 } 182 krb5_cccol_cursor_free(context, &cursor); 183 krb5_free_context(context); 184 return 0; 185 } 186 187 if (princ_name != NULL) { 188 code = krb5_parse_name(context, princ_name, &princ); 189 if (code) { 190 com_err(progname, code, _("while parsing principal name %s"), 191 princ_name); 192 exit(1); 193 } 194 code = krb5_cc_cache_match(context, princ, &cache); 195 if (code) { 196 com_err(progname, code, _("while finding cache for %s"), 197 princ_name); 198 exit(1); 199 } 200 krb5_free_principal(context, princ); 201 } else { 202 code = krb5_cc_default(context, &cache); 203 if (code) { 204 com_err(progname, code, _("while resolving ccache")); 205 exit(1); 206 } 207 } 208 209 code = krb5_cc_destroy(context, cache); 210 if (code != 0) { 211 com_err(progname, code, _("while destroying cache")); 212 if (code != KRB5_FCC_NOFILE) { 213 if (quiet) { 214 fprintf(stderr, _("Ticket cache NOT destroyed!\n")); 215 } else { 216 fprintf(stderr, _("Ticket cache %cNOT%c destroyed!\n"), 217 BELL_CHAR, BELL_CHAR); 218 } 219 errflg = 1; 220 } 221 } 222 223 if (!quiet && !errflg && princ_name == NULL) 224 print_remaining_cc_warning(context); 225 226 krb5_free_context(context); 227 228 return errflg; 229 } 230