Fix logic for adding digestAlgorithm, original patch from Douglas E Engert.
[heimdal.git] / kuser / kvno.c
blobf66ab2bd58c9f05fe2997be875bd6b969717d135
1 /*
2 * Copyright (C) 1998 by the FundsXpress, INC.
3 *
4 * All rights reserved.
5 *
6 * Export of this software from the United States of America may require
7 * a specific license from the United States Government. It is the
8 * responsibility of any person or organization contemplating export to
9 * obtain such a license before exporting.
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of FundsXpress. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. FundsXpress makes no representations about the suitability of
19 * this software for any purpose. It is provided "as is" without express
20 * or implied warranty.
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
24 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 #include "kuser_locl.h"
29 static char *etype_str = NULL;
30 static char *ccache_name = NULL;
31 static char *keytab_name = NULL;
32 static char *sname = NULL;
34 static int version_flag = 0;
35 static int help_flag = 0;
36 static int quiet_flag = 0;
38 static void do_v5_kvno (int argc, char *argv[],
39 char *ccache_name, char *etype_str, char *keytab_name,
40 char *sname);
42 struct getargs args[] = {
43 { "enctype", 'e', arg_string, &etype_str,
44 NP_("Encryption type to use", ""), "enctype" },
45 { "cache", 'c', arg_string, &ccache_name,
46 NP_("Credentials cache", ""), "cachename" },
47 { "keytab", 'k', arg_string, &keytab_name,
48 NP_("Keytab to use", ""), "keytabname" },
49 { "server", 'S', arg_string, &sname,
50 NP_("Server to get ticket for", ""), "principal" },
51 { "quiet", 'q', arg_flag, &quiet_flag,
52 NP_("Quiet", "") },
53 { "version", 0, arg_flag, &version_flag },
54 { "help", 0, arg_flag, &help_flag }
57 static void
58 usage(int ret)
60 arg_printusage_i18n (args, sizeof(args)/sizeof(*args),
61 N_("Usage: ", ""), NULL,
62 "principal1 [principal2 ...]",
63 getarg_i18n);
64 exit (ret);
67 int main(int argc, char *argv[])
69 int optidx = 0;
71 setprogname (argv[0]);
73 setlocale(LC_ALL, "");
74 bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
75 textdomain("heimdal_kuser");
77 if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx))
78 usage(1);
80 if (help_flag)
81 usage (0);
83 if (version_flag) {
84 print_version(NULL);
85 exit (0);
88 argc -= optidx;
89 argv += optidx;
91 do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname);
93 return 0;
96 static void do_v5_kvno (int count, char *names[],
97 char * ccache_name, char *etype_str, char *keytab_name,
98 char *sname)
100 krb5_error_code ret;
101 krb5_context context = 0;
102 int i, errors;
103 krb5_enctype etype;
104 krb5_ccache ccache;
105 krb5_principal me;
106 krb5_creds in_creds, *out_creds = NULL;
107 Ticket ticket;
108 size_t len;
109 char *princ = NULL;
110 krb5_keytab keytab = NULL;
112 ret = krb5_init_context(&context);
113 if (ret)
114 errx(1, "krb5_init_context failed: %d", ret);
116 if (etype_str) {
117 ret = krb5_string_to_enctype(context, etype_str, &etype);
118 if (ret)
119 krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str);
120 } else {
121 etype = 0;
124 if (ccache_name)
125 ret = krb5_cc_resolve(context, ccache_name, &ccache);
126 else
127 ret = krb5_cc_default(context, &ccache);
128 if (ret)
129 krb5_err(context, 1, ret, "Failed to open credentials cache %s",
130 (ccache_name) ? ccache_name : "(Default)");
132 if (keytab_name) {
133 ret = krb5_kt_resolve(context, keytab_name, &keytab);
134 if (ret)
135 krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name);
138 ret = krb5_cc_get_principal(context, ccache, &me);
139 if (ret)
140 krb5_err(context, 1, ret, "krb5_cc_get_principal");
142 errors = 0;
144 for (i = 0; i < count; i++) {
145 memset(&in_creds, 0, sizeof(in_creds));
146 memset(&ticket, 0, sizeof(ticket));
148 in_creds.client = me;
150 if (sname != NULL) {
151 ret = krb5_sname_to_principal(context, names[i],
152 sname, KRB5_NT_SRV_HST,
153 &in_creds.server);
154 } else {
155 ret = krb5_parse_name(context, names[i], &in_creds.server);
157 if (ret) {
158 if (!quiet_flag)
159 krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]);
160 errors++;
161 continue;
164 ret = krb5_unparse_name(context, in_creds.server, &princ);
165 if (ret) {
166 krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'",
167 names[i]);
168 errors++;
169 goto next;
172 in_creds.session.keytype = etype;
174 ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds);
176 if (ret) {
177 krb5_warn(context, ret, "Couldn't get credentials for %s", princ);
178 errors++;
179 goto next;
182 ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length,
183 &ticket, &len);
184 if (ret) {
185 krb5_err(context, 1, ret, "Can't decode ticket for %s", princ);
186 errors++;
187 goto next;
188 continue;
191 if (keytab) {
192 krb5_keytab_entry kte;
193 krb5_crypto crypto;
194 krb5_data dec_data;
195 EncTicketPart decr_part;
197 ret = krb5_kt_get_entry(context, keytab, in_creds.server,
198 (ticket.enc_part.kvno != NULL)?
199 *ticket.enc_part.kvno : 0,
200 ticket.enc_part.etype,
201 &kte);
202 if (ret) {
203 krb5_warn(context, ret, "Can't decrypt ticket for %s", princ);
204 if (!quiet_flag)
205 printf("%s: kvno = %d, keytab entry invalid", princ,
206 (ticket.enc_part.kvno != NULL)?
207 *ticket.enc_part.kvno : 0);
208 errors ++;
209 goto next;
212 ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto);
213 if (ret) {
214 krb5_warn(context, ret, "krb5_crypto_init");
215 errors ++;
216 krb5_kt_free_entry(context, &kte);
217 goto next;
220 ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
221 &ticket.enc_part, &dec_data);
222 krb5_crypto_destroy(context, crypto);
223 krb5_kt_free_entry(context, &kte);
225 if (ret) {
226 krb5_warn(context, ret, "krb5_decrypt_EncryptedData");
227 errors ++;
228 goto next;
231 ret = decode_EncTicketPart(dec_data.data, dec_data.length,
232 &decr_part, &len);
233 krb5_data_free(&dec_data);
234 if (ret) {
235 krb5_warn(context, ret, "decode_EncTicketPart");
236 errors ++;
237 goto next;
240 if (!quiet_flag)
241 printf("%s: kvno = %d, keytab entry valid\n", princ,
242 (ticket.enc_part.kvno != NULL)?
243 *ticket.enc_part.kvno : 0);
245 free_EncTicketPart(&decr_part);
246 } else {
247 if (!quiet_flag)
248 printf("%s: kvno = %d\n", princ,
249 (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0);
252 next:
253 if (out_creds) {
254 krb5_free_creds(context, out_creds);
255 out_creds = NULL;
258 if (princ) {
259 krb5_free_unparsed_name(context, princ);
260 princ = NULL;
263 krb5_free_principal(context, in_creds.server);
265 free_Ticket(&ticket);
268 if (keytab)
269 krb5_kt_close(context, keytab);
270 krb5_free_principal(context, me);
271 krb5_cc_close(context, ccache);
272 krb5_free_context(context);
274 if (errors)
275 exit(1);
277 exit(0);