1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <krb5.h>
7 #include "k5-platform.h"
8
9 static char *prog;
10 static int quiet = 0;
11
12 static void
xusage()13 xusage()
14 {
15 fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 "
16 "service2 ...\n", prog);
17 exit(1);
18 }
19
20 static void
21 do_kdeltkt(int argc, char *argv[], char *ccachestr, char *etypestr, int flags);
22
23 int
main(int argc,char * argv[])24 main(int argc, char *argv[])
25 {
26 int option;
27 char *etypestr = NULL, *ccachestr = NULL;
28 int flags = 0;
29
30 prog = strrchr(argv[0], '/');
31 prog = (prog != NULL) ? prog + 1 : argv[0];
32
33 while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) {
34 switch (option) {
35 case 'c':
36 ccachestr = optarg;
37 break;
38 case 'e':
39 etypestr = optarg;
40 break;
41 case 'f':
42 flags = atoi(optarg);
43 break;
44 case 'q':
45 quiet = 1;
46 break;
47 case 'h':
48 default:
49 xusage();
50 break;
51 }
52 }
53
54 if (argc - optind < 1)
55 xusage();
56
57 do_kdeltkt(argc - optind, argv + optind, ccachestr, etypestr, flags);
58 return 0;
59 }
60
61 static void
do_kdeltkt(int count,char * names[],const char * ccachestr,char * etypestr,int flags)62 do_kdeltkt(int count, char *names[], const char *ccachestr, char *etypestr,
63 int flags)
64 {
65 krb5_context context;
66 krb5_error_code ret;
67 int i, errors;
68 krb5_enctype etype;
69 krb5_ccache ccache;
70 krb5_principal me;
71 krb5_creds in_creds, out_creds;
72 int retflags;
73 char *princ;
74
75 ret = krb5_init_context(&context);
76 if (ret) {
77 com_err(prog, ret, "while initializing krb5 library");
78 exit(1);
79 }
80
81 if (etypestr != NULL) {
82 ret = krb5_string_to_enctype(etypestr, &etype);
83 if (ret) {
84 com_err(prog, ret, "while converting etype");
85 exit(1);
86 }
87 retflags = KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES;
88 } else {
89 etype = 0;
90 retflags = KRB5_TC_MATCH_SRV_NAMEONLY;
91 }
92
93 if (ccachestr)
94 ret = krb5_cc_resolve(context, ccachestr, &ccache);
95 else
96 ret = krb5_cc_default(context, &ccache);
97 if (ret) {
98 com_err(prog, ret, "while opening ccache");
99 exit(1);
100 }
101
102 ret = krb5_cc_get_principal(context, ccache, &me);
103 if (ret) {
104 com_err(prog, ret, "while getting client principal name");
105 exit(1);
106 }
107
108 errors = 0;
109
110 for (i = 0; i < count; i++) {
111 memset(&in_creds, 0, sizeof(in_creds));
112
113 in_creds.client = me;
114
115 ret = krb5_parse_name(context, names[i], &in_creds.server);
116 if (ret) {
117 if (!quiet) {
118 fprintf(stderr, "%s: %s while parsing principal name\n",
119 names[i], error_message(ret));
120 }
121 errors++;
122 continue;
123 }
124
125 ret = krb5_unparse_name(context, in_creds.server, &princ);
126 if (ret) {
127 fprintf(stderr, "%s: %s while printing principal name\n",
128 names[i], error_message(ret));
129 errors++;
130 continue;
131 }
132
133 in_creds.keyblock.enctype = etype;
134
135 ret = krb5_cc_retrieve_cred(context, ccache, retflags,
136 &in_creds, &out_creds);
137 if (ret) {
138 fprintf(stderr, "%s: %s while retrieving credentials\n",
139 princ, error_message(ret));
140 krb5_free_unparsed_name(context, princ);
141 errors++;
142 continue;
143 }
144
145 ret = krb5_cc_remove_cred(context, ccache, flags, &out_creds);
146
147 krb5_free_principal(context, in_creds.server);
148
149 if (ret) {
150 fprintf(stderr, "%s: %s while removing credentials\n",
151 princ, error_message(ret));
152 krb5_free_cred_contents(context, &out_creds);
153 krb5_free_unparsed_name(context, princ);
154 errors++;
155 continue;
156 }
157 krb5_free_unparsed_name(context, princ);
158 krb5_free_cred_contents(context, &out_creds);
159 }
160
161 krb5_free_principal(context, me);
162 krb5_cc_close(context, ccache);
163 krb5_free_context(context);
164
165 if (errors)
166 exit(1);
167
168 exit(0);
169 }
170