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
usage()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
print_remaining_cc_warning(krb5_context context)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
main(int argc,char * argv[])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