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