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