xref: /freebsd/crypto/heimdal/kuser/klist.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6*ae771770SStanislav Sedov  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7*ae771770SStanislav Sedov  *
8b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
9b528cefcSMark Murray  * modification, are permitted provided that the following conditions
10b528cefcSMark Murray  * are met:
11b528cefcSMark Murray  *
12b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
13b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
14b528cefcSMark Murray  *
15b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
16b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
17b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
18b528cefcSMark Murray  *
19b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
20b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
21b528cefcSMark Murray  *    without specific prior written permission.
22b528cefcSMark Murray  *
23b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33b528cefcSMark Murray  * SUCH DAMAGE.
34b528cefcSMark Murray  */
35b528cefcSMark Murray 
36b528cefcSMark Murray #include "kuser_locl.h"
375e9cd1aeSAssar Westerlund #include "rtbl.h"
38*ae771770SStanislav Sedov #include "parse_units.h"
39*ae771770SStanislav Sedov #include "kcc-commands.h"
40b528cefcSMark Murray 
41*ae771770SStanislav Sedov static char*
printable_time_internal(time_t t,int x)42*ae771770SStanislav Sedov printable_time_internal(time_t t, int x)
43*ae771770SStanislav Sedov {
44*ae771770SStanislav Sedov     static char s[128];
45*ae771770SStanislav Sedov     char *p;
46*ae771770SStanislav Sedov 
47*ae771770SStanislav Sedov     if ((p = ctime(&t)) == NULL)
48*ae771770SStanislav Sedov 	strlcpy(s, "?", sizeof(s));
49*ae771770SStanislav Sedov     else
50*ae771770SStanislav Sedov 	strlcpy(s, p + 4, sizeof(s));
51*ae771770SStanislav Sedov     s[x] = 0;
52*ae771770SStanislav Sedov     return s;
53*ae771770SStanislav Sedov }
54b528cefcSMark Murray 
55b528cefcSMark Murray static char*
printable_time(time_t t)56b528cefcSMark Murray printable_time(time_t t)
57b528cefcSMark Murray {
58*ae771770SStanislav Sedov     return printable_time_internal(t, 20);
59b528cefcSMark Murray }
60b528cefcSMark Murray 
61b528cefcSMark Murray static char*
printable_time_long(time_t t)62b528cefcSMark Murray printable_time_long(time_t t)
63b528cefcSMark Murray {
64*ae771770SStanislav Sedov     return printable_time_internal(t, 20);
65b528cefcSMark Murray }
66b528cefcSMark Murray 
67*ae771770SStanislav Sedov #define COL_ISSUED		NP_("  Issued","")
68*ae771770SStanislav Sedov #define COL_EXPIRES		NP_("  Expires", "")
69*ae771770SStanislav Sedov #define COL_FLAGS		NP_("Flags", "")
70*ae771770SStanislav Sedov #define COL_NAME		NP_("  Name", "")
71*ae771770SStanislav Sedov #define COL_PRINCIPAL		NP_("  Principal", "in klist output")
72*ae771770SStanislav Sedov #define COL_PRINCIPAL_KVNO	NP_("  Principal (kvno)", "in klist output")
73*ae771770SStanislav Sedov #define COL_CACHENAME		NP_("  Cache name", "name in klist output")
74*ae771770SStanislav Sedov #define COL_DEFCACHE		NP_("", "")
755e9cd1aeSAssar Westerlund 
76b528cefcSMark Murray static void
print_cred(krb5_context context,krb5_creds * cred,rtbl_t ct,int do_flags)775e9cd1aeSAssar Westerlund print_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags)
78b528cefcSMark Murray {
79b528cefcSMark Murray     char *str;
80b528cefcSMark Murray     krb5_error_code ret;
8113e3f4d6SMark Murray     krb5_timestamp sec;
82b528cefcSMark Murray 
83b528cefcSMark Murray     krb5_timeofday (context, &sec);
84b528cefcSMark Murray 
855e9cd1aeSAssar Westerlund 
86b528cefcSMark Murray     if(cred->times.starttime)
875e9cd1aeSAssar Westerlund 	rtbl_add_column_entry(ct, COL_ISSUED,
885e9cd1aeSAssar Westerlund 			      printable_time(cred->times.starttime));
89b528cefcSMark Murray     else
905e9cd1aeSAssar Westerlund 	rtbl_add_column_entry(ct, COL_ISSUED,
915e9cd1aeSAssar Westerlund 			      printable_time(cred->times.authtime));
92b528cefcSMark Murray 
93b528cefcSMark Murray     if(cred->times.endtime > sec)
945e9cd1aeSAssar Westerlund 	rtbl_add_column_entry(ct, COL_EXPIRES,
955e9cd1aeSAssar Westerlund 			      printable_time(cred->times.endtime));
96b528cefcSMark Murray     else
97*ae771770SStanislav Sedov 	rtbl_add_column_entry(ct, COL_EXPIRES, N_(">>>Expired<<<", ""));
98b528cefcSMark Murray     ret = krb5_unparse_name (context, cred->server, &str);
99b528cefcSMark Murray     if (ret)
100b528cefcSMark Murray 	krb5_err(context, 1, ret, "krb5_unparse_name");
1015e9cd1aeSAssar Westerlund     rtbl_add_column_entry(ct, COL_PRINCIPAL, str);
1025e9cd1aeSAssar Westerlund     if(do_flags) {
1035e9cd1aeSAssar Westerlund 	char s[16], *sp = s;
1045e9cd1aeSAssar Westerlund 	if(cred->flags.b.forwardable)
1055e9cd1aeSAssar Westerlund 	    *sp++ = 'F';
1065e9cd1aeSAssar Westerlund 	if(cred->flags.b.forwarded)
1075e9cd1aeSAssar Westerlund 	    *sp++ = 'f';
1085e9cd1aeSAssar Westerlund 	if(cred->flags.b.proxiable)
1095e9cd1aeSAssar Westerlund 	    *sp++ = 'P';
1105e9cd1aeSAssar Westerlund 	if(cred->flags.b.proxy)
1115e9cd1aeSAssar Westerlund 	    *sp++ = 'p';
1125e9cd1aeSAssar Westerlund 	if(cred->flags.b.may_postdate)
1135e9cd1aeSAssar Westerlund 	    *sp++ = 'D';
1145e9cd1aeSAssar Westerlund 	if(cred->flags.b.postdated)
1155e9cd1aeSAssar Westerlund 	    *sp++ = 'd';
1165e9cd1aeSAssar Westerlund 	if(cred->flags.b.renewable)
1175e9cd1aeSAssar Westerlund 	    *sp++ = 'R';
1185e9cd1aeSAssar Westerlund 	if(cred->flags.b.initial)
1195e9cd1aeSAssar Westerlund 	    *sp++ = 'I';
1205e9cd1aeSAssar Westerlund 	if(cred->flags.b.invalid)
1215e9cd1aeSAssar Westerlund 	    *sp++ = 'i';
1225e9cd1aeSAssar Westerlund 	if(cred->flags.b.pre_authent)
1235e9cd1aeSAssar Westerlund 	    *sp++ = 'A';
1245e9cd1aeSAssar Westerlund 	if(cred->flags.b.hw_authent)
1255e9cd1aeSAssar Westerlund 	    *sp++ = 'H';
126*ae771770SStanislav Sedov 	*sp = '\0';
1275e9cd1aeSAssar Westerlund 	rtbl_add_column_entry(ct, COL_FLAGS, s);
1285e9cd1aeSAssar Westerlund     }
129b528cefcSMark Murray     free(str);
130b528cefcSMark Murray }
131b528cefcSMark Murray 
132b528cefcSMark Murray static void
print_cred_verbose(krb5_context context,krb5_creds * cred)133b528cefcSMark Murray print_cred_verbose(krb5_context context, krb5_creds *cred)
134b528cefcSMark Murray {
135*ae771770SStanislav Sedov     size_t j;
136b528cefcSMark Murray     char *str;
137b528cefcSMark Murray     krb5_error_code ret;
13813e3f4d6SMark Murray     krb5_timestamp sec;
139b528cefcSMark Murray 
140b528cefcSMark Murray     krb5_timeofday (context, &sec);
141b528cefcSMark Murray 
142b528cefcSMark Murray     ret = krb5_unparse_name(context, cred->server, &str);
143b528cefcSMark Murray     if(ret)
144b528cefcSMark Murray 	exit(1);
145*ae771770SStanislav Sedov     printf(N_("Server: %s\n", ""), str);
146b528cefcSMark Murray     free (str);
147c19800e8SDoug Rabson 
148c19800e8SDoug Rabson     ret = krb5_unparse_name(context, cred->client, &str);
149c19800e8SDoug Rabson     if(ret)
150c19800e8SDoug Rabson 	exit(1);
151*ae771770SStanislav Sedov     printf(N_("Client: %s\n", ""), str);
152c19800e8SDoug Rabson     free (str);
153c19800e8SDoug Rabson 
154b528cefcSMark Murray     {
155b528cefcSMark Murray 	Ticket t;
156b528cefcSMark Murray 	size_t len;
157b528cefcSMark Murray 	char *s;
158b528cefcSMark Murray 
159b528cefcSMark Murray 	decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
160b528cefcSMark Murray 	ret = krb5_enctype_to_string(context, t.enc_part.etype, &s);
161*ae771770SStanislav Sedov 	printf(N_("Ticket etype: ", ""));
162b528cefcSMark Murray 	if (ret == 0) {
1635e9cd1aeSAssar Westerlund 	    printf("%s", s);
164b528cefcSMark Murray 	    free(s);
165b528cefcSMark Murray 	} else {
166*ae771770SStanislav Sedov 	    printf(N_("unknown-enctype(%d)", ""), t.enc_part.etype);
167b528cefcSMark Murray 	}
168b528cefcSMark Murray 	if(t.enc_part.kvno)
169*ae771770SStanislav Sedov 	    printf(N_(", kvno %d", ""), *t.enc_part.kvno);
170b528cefcSMark Murray 	printf("\n");
171b528cefcSMark Murray 	if(cred->session.keytype != t.enc_part.etype) {
172c19800e8SDoug Rabson 	    ret = krb5_enctype_to_string(context, cred->session.keytype, &str);
173b528cefcSMark Murray 	    if(ret)
174b528cefcSMark Murray 		krb5_warn(context, ret, "session keytype");
175b528cefcSMark Murray 	    else {
176*ae771770SStanislav Sedov 		printf(N_("Session key: %s\n", "enctype"), str);
177b528cefcSMark Murray 		free(str);
178b528cefcSMark Murray 	    }
179b528cefcSMark Murray 	}
180b528cefcSMark Murray 	free_Ticket(&t);
181*ae771770SStanislav Sedov 	printf(N_("Ticket length: %lu\n", ""),
182*ae771770SStanislav Sedov 	       (unsigned long)cred->ticket.length);
183b528cefcSMark Murray     }
184*ae771770SStanislav Sedov     printf(N_("Auth time:  %s\n", ""),
185*ae771770SStanislav Sedov 	   printable_time_long(cred->times.authtime));
186b528cefcSMark Murray     if(cred->times.authtime != cred->times.starttime)
187*ae771770SStanislav Sedov 	printf(N_("Start time: %s\n", ""),
188*ae771770SStanislav Sedov 	       printable_time_long(cred->times.starttime));
189*ae771770SStanislav Sedov     printf(N_("End time:   %s", ""),
190*ae771770SStanislav Sedov 	   printable_time_long(cred->times.endtime));
191b528cefcSMark Murray     if(sec > cred->times.endtime)
192*ae771770SStanislav Sedov 	printf(N_(" (expired)", ""));
193b528cefcSMark Murray     printf("\n");
194b528cefcSMark Murray     if(cred->flags.b.renewable)
195*ae771770SStanislav Sedov 	printf(N_("Renew till: %s\n", ""),
196b528cefcSMark Murray 	       printable_time_long(cred->times.renew_till));
197*ae771770SStanislav Sedov     {
198*ae771770SStanislav Sedov 	char flags[1024];
199*ae771770SStanislav Sedov 	unparse_flags(TicketFlags2int(cred->flags.b),
200*ae771770SStanislav Sedov 		      asn1_TicketFlags_units(),
201*ae771770SStanislav Sedov 		      flags, sizeof(flags));
202*ae771770SStanislav Sedov 	printf(N_("Ticket flags: %s\n", ""), flags);
203*ae771770SStanislav Sedov     }
204*ae771770SStanislav Sedov     printf(N_("Addresses: ", ""));
205c19800e8SDoug Rabson     if (cred->addresses.len != 0) {
206b528cefcSMark Murray 	for(j = 0; j < cred->addresses.len; j++){
207b528cefcSMark Murray 	    char buf[128];
208b528cefcSMark Murray 	    size_t len;
209b528cefcSMark Murray 	    if(j) printf(", ");
210b528cefcSMark Murray 	    ret = krb5_print_address(&cred->addresses.val[j],
211b528cefcSMark Murray 				     buf, sizeof(buf), &len);
212b528cefcSMark Murray 
213b528cefcSMark Murray 	    if(ret == 0)
214b528cefcSMark Murray 		printf("%s", buf);
215b528cefcSMark Murray 	}
216c19800e8SDoug Rabson     } else {
217*ae771770SStanislav Sedov 	printf(N_("addressless", ""));
218c19800e8SDoug Rabson     }
219b528cefcSMark Murray     printf("\n\n");
220b528cefcSMark Murray }
221b528cefcSMark Murray 
222b528cefcSMark Murray /*
223b528cefcSMark Murray  * Print all tickets in `ccache' on stdout, verbosily iff do_verbose.
224b528cefcSMark Murray  */
225b528cefcSMark Murray 
226b528cefcSMark Murray static void
print_tickets(krb5_context context,krb5_ccache ccache,krb5_principal principal,int do_verbose,int do_flags,int do_hidden)227b528cefcSMark Murray print_tickets (krb5_context context,
228b528cefcSMark Murray 	       krb5_ccache ccache,
229b528cefcSMark Murray 	       krb5_principal principal,
2305e9cd1aeSAssar Westerlund 	       int do_verbose,
231c19800e8SDoug Rabson 	       int do_flags,
232c19800e8SDoug Rabson 	       int do_hidden)
233b528cefcSMark Murray {
234b528cefcSMark Murray     krb5_error_code ret;
235*ae771770SStanislav Sedov     char *str, *name;
236b528cefcSMark Murray     krb5_cc_cursor cursor;
237b528cefcSMark Murray     krb5_creds creds;
238*ae771770SStanislav Sedov     krb5_deltat sec;
239b528cefcSMark Murray 
2405e9cd1aeSAssar Westerlund     rtbl_t ct = NULL;
2415e9cd1aeSAssar Westerlund 
242b528cefcSMark Murray     ret = krb5_unparse_name (context, principal, &str);
243b528cefcSMark Murray     if (ret)
244b528cefcSMark Murray 	krb5_err (context, 1, ret, "krb5_unparse_name");
245b528cefcSMark Murray 
246b528cefcSMark Murray     printf ("%17s: %s:%s\n",
247*ae771770SStanislav Sedov 	    N_("Credentials cache", ""),
248b528cefcSMark Murray 	    krb5_cc_get_type(context, ccache),
249b528cefcSMark Murray 	    krb5_cc_get_name(context, ccache));
250*ae771770SStanislav Sedov     printf ("%17s: %s\n", N_("Principal", ""), str);
251*ae771770SStanislav Sedov 
252*ae771770SStanislav Sedov     ret = krb5_cc_get_friendly_name(context, ccache, &name);
253*ae771770SStanislav Sedov     if (ret == 0) {
254*ae771770SStanislav Sedov 	if (strcmp(name, str) != 0)
255*ae771770SStanislav Sedov 	    printf ("%17s: %s\n", N_("Friendly name", ""), name);
256*ae771770SStanislav Sedov 	free(name);
257*ae771770SStanislav Sedov     }
258b528cefcSMark Murray     free (str);
259b528cefcSMark Murray 
260*ae771770SStanislav Sedov     if(do_verbose) {
261*ae771770SStanislav Sedov 	printf ("%17s: %d\n", N_("Cache version", ""),
262b528cefcSMark Murray 		krb5_cc_get_version(context, ccache));
263*ae771770SStanislav Sedov     } else {
264*ae771770SStanislav Sedov         krb5_cc_set_flags(context, ccache, KRB5_TC_NOTICKET);
265*ae771770SStanislav Sedov     }
266b528cefcSMark Murray 
267*ae771770SStanislav Sedov     ret = krb5_cc_get_kdc_offset(context, ccache, &sec);
268c19800e8SDoug Rabson 
269*ae771770SStanislav Sedov     if (ret == 0 && do_verbose && sec != 0) {
270b528cefcSMark Murray 	char buf[BUFSIZ];
271b528cefcSMark Murray 	int val;
272b528cefcSMark Murray 	int sig;
273b528cefcSMark Murray 
274c19800e8SDoug Rabson 	val = sec;
275b528cefcSMark Murray 	sig = 1;
276b528cefcSMark Murray 	if (val < 0) {
277b528cefcSMark Murray 	    sig = -1;
278b528cefcSMark Murray 	    val = -val;
279b528cefcSMark Murray 	}
280b528cefcSMark Murray 
281b528cefcSMark Murray 	unparse_time (val, buf, sizeof(buf));
282b528cefcSMark Murray 
283*ae771770SStanislav Sedov 	printf ("%17s: %s%s\n", N_("KDC time offset", ""),
284b528cefcSMark Murray 		sig == -1 ? "-" : "", buf);
285b528cefcSMark Murray     }
286b528cefcSMark Murray 
287b528cefcSMark Murray     printf("\n");
288b528cefcSMark Murray 
289b528cefcSMark Murray     ret = krb5_cc_start_seq_get (context, ccache, &cursor);
290b528cefcSMark Murray     if (ret)
291b528cefcSMark Murray 	krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
292b528cefcSMark Murray 
2935e9cd1aeSAssar Westerlund     if(!do_verbose) {
2945e9cd1aeSAssar Westerlund 	ct = rtbl_create();
2955e9cd1aeSAssar Westerlund 	rtbl_add_column(ct, COL_ISSUED, 0);
2965e9cd1aeSAssar Westerlund 	rtbl_add_column(ct, COL_EXPIRES, 0);
2975e9cd1aeSAssar Westerlund 	if(do_flags)
2985e9cd1aeSAssar Westerlund 	    rtbl_add_column(ct, COL_FLAGS, 0);
2995e9cd1aeSAssar Westerlund 	rtbl_add_column(ct, COL_PRINCIPAL, 0);
300c19800e8SDoug Rabson 	rtbl_set_separator(ct, "  ");
3015e9cd1aeSAssar Westerlund     }
3021c43270aSJacques Vidrine     while ((ret = krb5_cc_next_cred (context,
303b528cefcSMark Murray 				     ccache,
304adb0ddaeSAssar Westerlund 				     &cursor,
3051c43270aSJacques Vidrine 				     &creds)) == 0) {
306*ae771770SStanislav Sedov 	if (!do_hidden && krb5_is_config_principal(context, creds.server)) {
307c19800e8SDoug Rabson 	    ;
308c19800e8SDoug Rabson 	}else if(do_verbose){
309b528cefcSMark Murray 	    print_cred_verbose(context, &creds);
310b528cefcSMark Murray 	}else{
3115e9cd1aeSAssar Westerlund 	    print_cred(context, &creds, ct, do_flags);
312b528cefcSMark Murray 	}
313c19800e8SDoug Rabson 	krb5_free_cred_contents (context, &creds);
314b528cefcSMark Murray     }
3151c43270aSJacques Vidrine     if(ret != KRB5_CC_END)
3161c43270aSJacques Vidrine 	krb5_err(context, 1, ret, "krb5_cc_get_next");
317b528cefcSMark Murray     ret = krb5_cc_end_seq_get (context, ccache, &cursor);
318b528cefcSMark Murray     if (ret)
319b528cefcSMark Murray 	krb5_err (context, 1, ret, "krb5_cc_end_seq_get");
3205e9cd1aeSAssar Westerlund     if(!do_verbose) {
3215e9cd1aeSAssar Westerlund 	rtbl_format(ct, stdout);
3225e9cd1aeSAssar Westerlund 	rtbl_destroy(ct);
3235e9cd1aeSAssar Westerlund     }
324b528cefcSMark Murray }
325b528cefcSMark Murray 
326b528cefcSMark Murray /*
327b528cefcSMark Murray  * Check if there's a tgt for the realm of `principal' and ccache and
328b528cefcSMark Murray  * if so return 0, else 1
329b528cefcSMark Murray  */
330b528cefcSMark Murray 
331b528cefcSMark Murray static int
check_for_tgt(krb5_context context,krb5_ccache ccache,krb5_principal principal,time_t * expiration)332b528cefcSMark Murray check_for_tgt (krb5_context context,
333b528cefcSMark Murray 	       krb5_ccache ccache,
334c19800e8SDoug Rabson 	       krb5_principal principal,
335c19800e8SDoug Rabson 	       time_t *expiration)
336b528cefcSMark Murray {
337b528cefcSMark Murray     krb5_error_code ret;
338b528cefcSMark Murray     krb5_creds pattern;
339b528cefcSMark Murray     krb5_creds creds;
340*ae771770SStanislav Sedov     krb5_const_realm client_realm;
341b528cefcSMark Murray     int expired;
342b528cefcSMark Murray 
343c19800e8SDoug Rabson     krb5_cc_clear_mcred(&pattern);
344c19800e8SDoug Rabson 
345*ae771770SStanislav Sedov     client_realm = krb5_principal_get_realm(context, principal);
346b528cefcSMark Murray 
347b528cefcSMark Murray     ret = krb5_make_principal (context, &pattern.server,
348*ae771770SStanislav Sedov 			       client_realm, KRB5_TGS_NAME, client_realm, NULL);
349b528cefcSMark Murray     if (ret)
350b528cefcSMark Murray 	krb5_err (context, 1, ret, "krb5_make_principal");
351c19800e8SDoug Rabson     pattern.client = principal;
352b528cefcSMark Murray 
353b528cefcSMark Murray     ret = krb5_cc_retrieve_cred (context, ccache, 0, &pattern, &creds);
354b528cefcSMark Murray     krb5_free_principal (context, pattern.server);
355b528cefcSMark Murray     if (ret) {
356b528cefcSMark Murray 	if (ret == KRB5_CC_END)
357b528cefcSMark Murray 	    return 1;
358b528cefcSMark Murray 	krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");
359b528cefcSMark Murray     }
360c19800e8SDoug Rabson 
361c19800e8SDoug Rabson     expired = time(NULL) > creds.times.endtime;
362c19800e8SDoug Rabson 
363c19800e8SDoug Rabson     if (expiration)
364c19800e8SDoug Rabson 	*expiration = creds.times.endtime;
365c19800e8SDoug Rabson 
366c19800e8SDoug Rabson     krb5_free_cred_contents (context, &creds);
367c19800e8SDoug Rabson 
368b528cefcSMark Murray     return expired;
369b528cefcSMark Murray }
370b528cefcSMark Murray 
371b528cefcSMark Murray /*
372b528cefcSMark Murray  * Print a list of all AFS tokens
373b528cefcSMark Murray  */
374b528cefcSMark Murray 
375*ae771770SStanislav Sedov #ifndef NO_AFS
376*ae771770SStanislav Sedov 
377b528cefcSMark Murray static void
display_tokens(int do_verbose)378b528cefcSMark Murray display_tokens(int do_verbose)
379b528cefcSMark Murray {
380c19800e8SDoug Rabson     uint32_t i;
3818373020dSJacques Vidrine     unsigned char t[4096];
382b528cefcSMark Murray     struct ViceIoctl parms;
383b528cefcSMark Murray 
384b528cefcSMark Murray     parms.in = (void *)&i;
385b528cefcSMark Murray     parms.in_size = sizeof(i);
386b528cefcSMark Murray     parms.out = (void *)t;
387b528cefcSMark Murray     parms.out_size = sizeof(t);
388b528cefcSMark Murray 
3898373020dSJacques Vidrine     for (i = 0;; i++) {
390b528cefcSMark Murray         int32_t size_secret_tok, size_public_tok;
391b528cefcSMark Murray         unsigned char *cell;
392b528cefcSMark Murray 	struct ClearToken ct;
393b528cefcSMark Murray 	unsigned char *r = t;
394b528cefcSMark Murray 	struct timeval tv;
395b528cefcSMark Murray 	char buf1[20], buf2[20];
396b528cefcSMark Murray 
3978373020dSJacques Vidrine 	if(k_pioctl(NULL, VIOCGETTOK, &parms, 0) < 0) {
3988373020dSJacques Vidrine 	    if(errno == EDOM)
3998373020dSJacques Vidrine 		break;
4008373020dSJacques Vidrine 	    continue;
4018373020dSJacques Vidrine 	}
4025bda878eSJacques Vidrine 	if(parms.out_size > sizeof(t))
4038373020dSJacques Vidrine 	    continue;
4048373020dSJacques Vidrine 	if(parms.out_size < sizeof(size_secret_tok))
4058373020dSJacques Vidrine 	    continue;
406bbd80c28SJacques Vidrine 	t[min(parms.out_size,sizeof(t)-1)] = 0;
407b528cefcSMark Murray 	memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
408b528cefcSMark Murray 	/* dont bother about the secret token */
409b528cefcSMark Murray 	r += size_secret_tok + sizeof(size_secret_tok);
4108373020dSJacques Vidrine 	if (parms.out_size < (r - t) + sizeof(size_public_tok))
4118373020dSJacques Vidrine 	    continue;
412b528cefcSMark Murray 	memcpy(&size_public_tok, r, sizeof(size_public_tok));
413b528cefcSMark Murray 	r += sizeof(size_public_tok);
4148373020dSJacques Vidrine 	if (parms.out_size < (r - t) + size_public_tok + sizeof(int32_t))
4158373020dSJacques Vidrine 	    continue;
416b528cefcSMark Murray 	memcpy(&ct, r, size_public_tok);
417b528cefcSMark Murray 	r += size_public_tok;
418b528cefcSMark Murray 	/* there is a int32_t with length of cellname, but we dont read it */
419b528cefcSMark Murray 	r += sizeof(int32_t);
420b528cefcSMark Murray 	cell = r;
421b528cefcSMark Murray 
422b528cefcSMark Murray 	gettimeofday (&tv, NULL);
423b528cefcSMark Murray 	strlcpy (buf1, printable_time(ct.BeginTimestamp),
424b528cefcSMark Murray 		 sizeof(buf1));
425b528cefcSMark Murray 	if (do_verbose || tv.tv_sec < ct.EndTimestamp)
426b528cefcSMark Murray 	    strlcpy (buf2, printable_time(ct.EndTimestamp),
427b528cefcSMark Murray 		     sizeof(buf2));
428b528cefcSMark Murray 	else
429*ae771770SStanislav Sedov 	    strlcpy (buf2, N_(">>> Expired <<<", ""), sizeof(buf2));
430b528cefcSMark Murray 
431b528cefcSMark Murray 	printf("%s  %s  ", buf1, buf2);
432b528cefcSMark Murray 
433b528cefcSMark Murray 	if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
434*ae771770SStanislav Sedov 	    printf(N_("User's (AFS ID %d) tokens for %s", ""), ct.ViceId, cell);
435b528cefcSMark Murray 	else
436*ae771770SStanislav Sedov 	    printf(N_("Tokens for %s", ""), cell);
437b528cefcSMark Murray 	if (do_verbose)
438b528cefcSMark Murray 	    printf(" (%d)", ct.AuthHandle);
439b528cefcSMark Murray 	putchar('\n');
440b528cefcSMark Murray     }
441b528cefcSMark Murray }
442*ae771770SStanislav Sedov #endif
4435e9cd1aeSAssar Westerlund 
4445e9cd1aeSAssar Westerlund /*
4455e9cd1aeSAssar Westerlund  * display the ccache in `cred_cache'
4465e9cd1aeSAssar Westerlund  */
4475e9cd1aeSAssar Westerlund 
4485e9cd1aeSAssar Westerlund static int
display_v5_ccache(krb5_context context,krb5_ccache ccache,int do_test,int do_verbose,int do_flags,int do_hidden)449*ae771770SStanislav Sedov display_v5_ccache (krb5_context context, krb5_ccache ccache,
450*ae771770SStanislav Sedov 		   int do_test, int do_verbose,
451c19800e8SDoug Rabson 		   int do_flags, int do_hidden)
4525e9cd1aeSAssar Westerlund {
4535e9cd1aeSAssar Westerlund     krb5_error_code ret;
4545e9cd1aeSAssar Westerlund     krb5_principal principal;
4555e9cd1aeSAssar Westerlund     int exit_status = 0;
4565e9cd1aeSAssar Westerlund 
4575e9cd1aeSAssar Westerlund 
4585e9cd1aeSAssar Westerlund     ret = krb5_cc_get_principal (context, ccache, &principal);
4595e9cd1aeSAssar Westerlund     if (ret) {
4605e9cd1aeSAssar Westerlund 	if(ret == ENOENT) {
4615e9cd1aeSAssar Westerlund 	    if (!do_test)
462*ae771770SStanislav Sedov 		krb5_warnx(context, N_("No ticket file: %s", ""),
4635e9cd1aeSAssar Westerlund 			   krb5_cc_get_name(context, ccache));
4645e9cd1aeSAssar Westerlund 	    return 1;
4655e9cd1aeSAssar Westerlund 	} else
4665e9cd1aeSAssar Westerlund 	    krb5_err (context, 1, ret, "krb5_cc_get_principal");
4675e9cd1aeSAssar Westerlund     }
4685e9cd1aeSAssar Westerlund     if (do_test)
469c19800e8SDoug Rabson 	exit_status = check_for_tgt (context, ccache, principal, NULL);
4705e9cd1aeSAssar Westerlund     else
471c19800e8SDoug Rabson 	print_tickets (context, ccache, principal, do_verbose,
472c19800e8SDoug Rabson 		       do_flags, do_hidden);
4735e9cd1aeSAssar Westerlund 
4745e9cd1aeSAssar Westerlund     ret = krb5_cc_close (context, ccache);
4755e9cd1aeSAssar Westerlund     if (ret)
4765e9cd1aeSAssar Westerlund 	krb5_err (context, 1, ret, "krb5_cc_close");
4775e9cd1aeSAssar Westerlund 
4785e9cd1aeSAssar Westerlund     krb5_free_principal (context, principal);
479*ae771770SStanislav Sedov 
4805e9cd1aeSAssar Westerlund     return exit_status;
4815e9cd1aeSAssar Westerlund }
482b528cefcSMark Murray 
483c19800e8SDoug Rabson /*
484c19800e8SDoug Rabson  *
485c19800e8SDoug Rabson  */
486c19800e8SDoug Rabson 
487c19800e8SDoug Rabson static int
list_caches(krb5_context context)488*ae771770SStanislav Sedov list_caches(krb5_context context)
489c19800e8SDoug Rabson {
490c19800e8SDoug Rabson     krb5_cc_cache_cursor cursor;
491*ae771770SStanislav Sedov     const char *cdef_name;
492*ae771770SStanislav Sedov     char *def_name;
493c19800e8SDoug Rabson     krb5_error_code ret;
494c19800e8SDoug Rabson     krb5_ccache id;
495c19800e8SDoug Rabson     rtbl_t ct;
496c19800e8SDoug Rabson 
497*ae771770SStanislav Sedov     cdef_name = krb5_cc_default_name(context);
498*ae771770SStanislav Sedov     if (cdef_name == NULL)
499*ae771770SStanislav Sedov 	krb5_errx(context, 1, "krb5_cc_default_name");
500*ae771770SStanislav Sedov     def_name = strdup(cdef_name);
501c19800e8SDoug Rabson 
502c19800e8SDoug Rabson     ret = krb5_cc_cache_get_first (context, NULL, &cursor);
503c19800e8SDoug Rabson     if (ret == KRB5_CC_NOSUPP)
504c19800e8SDoug Rabson 	return 0;
505c19800e8SDoug Rabson     else if (ret)
506c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "krb5_cc_cache_get_first");
507c19800e8SDoug Rabson 
508c19800e8SDoug Rabson     ct = rtbl_create();
509*ae771770SStanislav Sedov     rtbl_add_column(ct, COL_NAME, 0);
510c19800e8SDoug Rabson     rtbl_add_column(ct, COL_CACHENAME, 0);
511c19800e8SDoug Rabson     rtbl_add_column(ct, COL_EXPIRES, 0);
512*ae771770SStanislav Sedov     rtbl_add_column(ct, COL_DEFCACHE, 0);
513c19800e8SDoug Rabson     rtbl_set_prefix(ct, "   ");
514*ae771770SStanislav Sedov     rtbl_set_column_prefix(ct, COL_NAME, "");
515c19800e8SDoug Rabson 
516*ae771770SStanislav Sedov     while (krb5_cc_cache_next (context, cursor, &id) == 0) {
517*ae771770SStanislav Sedov 	krb5_principal principal = NULL;
518*ae771770SStanislav Sedov 	int expired = 0;
519c19800e8SDoug Rabson 	char *name;
520*ae771770SStanislav Sedov 	time_t t;
521c19800e8SDoug Rabson 
522c19800e8SDoug Rabson 	ret = krb5_cc_get_principal(context, id, &principal);
523*ae771770SStanislav Sedov 	if (ret)
524*ae771770SStanislav Sedov 	    continue;
525c19800e8SDoug Rabson 
526*ae771770SStanislav Sedov 	expired = check_for_tgt (context, id, principal, &t);
527*ae771770SStanislav Sedov 
528*ae771770SStanislav Sedov 	ret = krb5_cc_get_friendly_name(context, id, &name);
529c19800e8SDoug Rabson 	if (ret == 0) {
530*ae771770SStanislav Sedov 	    const char *str;
531*ae771770SStanislav Sedov 	    char *fname;
532*ae771770SStanislav Sedov 	    rtbl_add_column_entry(ct, COL_NAME, name);
533c19800e8SDoug Rabson 	    rtbl_add_column_entry(ct, COL_CACHENAME,
534c19800e8SDoug Rabson 				  krb5_cc_get_name(context, id));
535*ae771770SStanislav Sedov 	    if (expired)
536*ae771770SStanislav Sedov 		str = N_(">>> Expired <<<", "");
537*ae771770SStanislav Sedov 	    else
538*ae771770SStanislav Sedov 		str = printable_time(t);
539*ae771770SStanislav Sedov 	    rtbl_add_column_entry(ct, COL_EXPIRES, str);
540c19800e8SDoug Rabson 	    free(name);
541*ae771770SStanislav Sedov 
542*ae771770SStanislav Sedov 	    ret = krb5_cc_get_full_name(context, id, &fname);
543*ae771770SStanislav Sedov 	    if (ret)
544*ae771770SStanislav Sedov 		krb5_err (context, 1, ret, "krb5_cc_get_full_name");
545*ae771770SStanislav Sedov 
546*ae771770SStanislav Sedov 	    if (strcmp(fname, def_name) == 0)
547*ae771770SStanislav Sedov 		rtbl_add_column_entry(ct, COL_DEFCACHE, "*");
548*ae771770SStanislav Sedov 	    else
549*ae771770SStanislav Sedov 		rtbl_add_column_entry(ct, COL_DEFCACHE, "");
550*ae771770SStanislav Sedov 
551*ae771770SStanislav Sedov 	    krb5_xfree(fname);
552c19800e8SDoug Rabson 	}
553c19800e8SDoug Rabson 	krb5_cc_close(context, id);
554*ae771770SStanislav Sedov 
555*ae771770SStanislav Sedov 	krb5_free_principal(context, principal);
556c19800e8SDoug Rabson     }
557c19800e8SDoug Rabson 
558c19800e8SDoug Rabson     krb5_cc_cache_end_seq_get(context, cursor);
559c19800e8SDoug Rabson 
560*ae771770SStanislav Sedov     free(def_name);
561c19800e8SDoug Rabson     rtbl_format(ct, stdout);
562c19800e8SDoug Rabson     rtbl_destroy(ct);
563c19800e8SDoug Rabson 
564c19800e8SDoug Rabson     return 0;
565c19800e8SDoug Rabson }
566c19800e8SDoug Rabson 
567c19800e8SDoug Rabson /*
568c19800e8SDoug Rabson  *
569c19800e8SDoug Rabson  */
570c19800e8SDoug Rabson 
571b528cefcSMark Murray int
klist(struct klist_options * opt,int argc,char ** argv)572*ae771770SStanislav Sedov klist(struct klist_options *opt, int argc, char **argv)
573b528cefcSMark Murray {
574*ae771770SStanislav Sedov     krb5_error_code ret;
575b528cefcSMark Murray     int exit_status = 0;
576b528cefcSMark Murray 
577*ae771770SStanislav Sedov     int do_verbose =
578*ae771770SStanislav Sedov 	opt->verbose_flag ||
579*ae771770SStanislav Sedov 	opt->a_flag ||
580*ae771770SStanislav Sedov 	opt->n_flag;
581*ae771770SStanislav Sedov     int do_test =
582*ae771770SStanislav Sedov 	opt->test_flag ||
583*ae771770SStanislav Sedov 	opt->s_flag;
584b528cefcSMark Murray 
585*ae771770SStanislav Sedov     if (opt->list_all_flag) {
586*ae771770SStanislav Sedov 	exit_status = list_caches(kcc_context);
587c19800e8SDoug Rabson 	return exit_status;
588c19800e8SDoug Rabson     }
589c19800e8SDoug Rabson 
590*ae771770SStanislav Sedov     if (opt->v5_flag) {
591*ae771770SStanislav Sedov 	krb5_ccache id;
592*ae771770SStanislav Sedov 
593*ae771770SStanislav Sedov 	if (opt->all_content_flag) {
594*ae771770SStanislav Sedov 	    krb5_cc_cache_cursor cursor;
595*ae771770SStanislav Sedov 
596*ae771770SStanislav Sedov 	    ret = krb5_cc_cache_get_first(kcc_context, NULL, &cursor);
597*ae771770SStanislav Sedov 	    if (ret)
598*ae771770SStanislav Sedov 		krb5_err(kcc_context, 1, ret, "krb5_cc_cache_get_first");
599*ae771770SStanislav Sedov 
600*ae771770SStanislav Sedov 
601*ae771770SStanislav Sedov 	    while (krb5_cc_cache_next(kcc_context, cursor, &id) == 0) {
602*ae771770SStanislav Sedov 		exit_status |= display_v5_ccache(kcc_context, id, do_test,
603*ae771770SStanislav Sedov 						 do_verbose, opt->flags_flag,
604*ae771770SStanislav Sedov 						 opt->hidden_flag);
605*ae771770SStanislav Sedov 		printf("\n\n");
606*ae771770SStanislav Sedov 	    }
607*ae771770SStanislav Sedov 	    krb5_cc_cache_end_seq_get(kcc_context, cursor);
608*ae771770SStanislav Sedov 
609*ae771770SStanislav Sedov 	} else {
610*ae771770SStanislav Sedov 	    if(opt->cache_string) {
611*ae771770SStanislav Sedov 		ret = krb5_cc_resolve(kcc_context, opt->cache_string, &id);
612*ae771770SStanislav Sedov 		if (ret)
613*ae771770SStanislav Sedov 		    krb5_err(kcc_context, 1, ret, "%s", opt->cache_string);
614*ae771770SStanislav Sedov 	    } else {
615*ae771770SStanislav Sedov 		ret = krb5_cc_default(kcc_context, &id);
616*ae771770SStanislav Sedov 		if (ret)
617*ae771770SStanislav Sedov 		    krb5_err(kcc_context, 1, ret, "krb5_cc_resolve");
618*ae771770SStanislav Sedov 	    }
619*ae771770SStanislav Sedov 	    exit_status = display_v5_ccache(kcc_context, id, do_test,
620*ae771770SStanislav Sedov 					    do_verbose, opt->flags_flag,
621*ae771770SStanislav Sedov 					    opt->hidden_flag);
622*ae771770SStanislav Sedov 	}
623*ae771770SStanislav Sedov     }
624b528cefcSMark Murray 
6255e9cd1aeSAssar Westerlund     if (!do_test) {
626*ae771770SStanislav Sedov #ifndef NO_AFS
627*ae771770SStanislav Sedov 	if (opt->tokens_flag && k_hasafs()) {
628*ae771770SStanislav Sedov 	    if (opt->v5_flag)
6295e9cd1aeSAssar Westerlund 		printf("\n");
630*ae771770SStanislav Sedov 	    display_tokens(opt->verbose_flag);
6315e9cd1aeSAssar Westerlund 	}
632*ae771770SStanislav Sedov #endif
6335e9cd1aeSAssar Westerlund     }
634b528cefcSMark Murray 
635b528cefcSMark Murray     return exit_status;
636b528cefcSMark Murray }
637