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