xref: /freebsd/crypto/krb5/src/clients/kdeltkt/kdeltkt.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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