klist.c revision 178826
129415Sjmg/*
250723Scg * Copyright (c) 1997-2004 Kungliga Tekniska H�gskolan
339899Sluigi * (Royal Institute of Technology, Stockholm, Sweden).
429415Sjmg * All rights reserved.
529415Sjmg *
629415Sjmg * Redistribution and use in source and binary forms, with or without
729415Sjmg * modification, are permitted provided that the following conditions
850723Scg * are met:
950723Scg *
1029415Sjmg * 1. Redistributions of source code must retain the above copyright
1129415Sjmg *    notice, this list of conditions and the following disclaimer.
1230869Sjmg *
1330869Sjmg * 2. Redistributions in binary form must reproduce the above copyright
1430869Sjmg *    notice, this list of conditions and the following disclaimer in the
1530869Sjmg *    documentation and/or other materials provided with the distribution.
1650723Scg *
1750723Scg * 3. Neither the name of the Institute nor the names of its contributors
1830869Sjmg *    may be used to endorse or promote products derived from this software
1950723Scg *    without specific prior written permission.
2050723Scg *
2150723Scg * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2250723Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2350723Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2450723Scg * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2550723Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2650723Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2750723Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2850723Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2950723Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3050723Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3150959Speter * SUCH DAMAGE.
3229415Sjmg */
3329415Sjmg
3453465Scg#include "kuser_locl.h"
3529415Sjmg#include "rtbl.h"
3653465Scg
3753553StanimuraRCSID("$Id: klist.c 20516 2007-04-22 10:40:41Z lha $");
3829415Sjmg
3967803Scgstatic char*
4055706Scgprintable_time(time_t t)
4155254Scg{
4250723Scg    static char s[128];
4367803Scg    strlcpy(s, ctime(&t)+ 4, sizeof(s));
4467803Scg    s[15] = 0;
4567803Scg    return s;
4667803Scg}
4767803Scg
4867803Scgstatic char*
4967803Scgprintable_time_long(time_t t)
5067803Scg{
5167803Scg    static char s[128];
5229415Sjmg    strlcpy(s, ctime(&t)+ 4, sizeof(s));
5367803Scg    s[20] = 0;
5450723Scg    return s;
5550723Scg}
5664881Scg
5750723Scg#define COL_ISSUED		"  Issued"
5867803Scg#define COL_EXPIRES		"  Expires"
5929415Sjmg#define COL_FLAGS		"Flags"
6067803Scg#define COL_PRINCIPAL		"  Principal"
6164881Scg#define COL_PRINCIPAL_KVNO	"  Principal (kvno)"
6250723Scg#define COL_CACHENAME		"  Cache name"
6364881Scg
6450723Scgstatic void
6567803Scgprint_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags)
6629415Sjmg{
6764881Scg    char *str;
6864881Scg    krb5_error_code ret;
6964881Scg    krb5_timestamp sec;
7064881Scg
7164881Scg    krb5_timeofday (context, &sec);
7264881Scg
7354462Scg
7464881Scg    if(cred->times.starttime)
7554462Scg	rtbl_add_column_entry(ct, COL_ISSUED,
7650723Scg			      printable_time(cred->times.starttime));
7767803Scg    else
7867803Scg	rtbl_add_column_entry(ct, COL_ISSUED,
7967803Scg			      printable_time(cred->times.authtime));
8067803Scg
8167803Scg    if(cred->times.endtime > sec)
8267803Scg	rtbl_add_column_entry(ct, COL_EXPIRES,
8367803Scg			      printable_time(cred->times.endtime));
8467803Scg    else
8565340Scg	rtbl_add_column_entry(ct, COL_EXPIRES, ">>>Expired<<<");
8667803Scg    ret = krb5_unparse_name (context, cred->server, &str);
8767803Scg    if (ret)
8865340Scg	krb5_err(context, 1, ret, "krb5_unparse_name");
8965340Scg    rtbl_add_column_entry(ct, COL_PRINCIPAL, str);
9065340Scg    if(do_flags) {
9165340Scg	char s[16], *sp = s;
9265340Scg	if(cred->flags.b.forwardable)
9350723Scg	    *sp++ = 'F';
9429415Sjmg	if(cred->flags.b.forwarded)
9550723Scg	    *sp++ = 'f';
9629415Sjmg	if(cred->flags.b.proxiable)
9750723Scg	    *sp++ = 'P';
9850723Scg	if(cred->flags.b.proxy)
9950723Scg	    *sp++ = 'p';
10050723Scg	if(cred->flags.b.may_postdate)
10167803Scg	    *sp++ = 'D';
10267803Scg	if(cred->flags.b.postdated)
10350723Scg	    *sp++ = 'd';
10429415Sjmg	if(cred->flags.b.renewable)
10550723Scg	    *sp++ = 'R';
10650723Scg	if(cred->flags.b.initial)
10750723Scg	    *sp++ = 'I';
10854462Scg	if(cred->flags.b.invalid)
10954462Scg	    *sp++ = 'i';
11065644Scg	if(cred->flags.b.pre_authent)
11155706Scg	    *sp++ = 'A';
11229415Sjmg	if(cred->flags.b.hw_authent)
11350723Scg	    *sp++ = 'H';
11450723Scg	*sp++ = '\0';
11567803Scg	rtbl_add_column_entry(ct, COL_FLAGS, s);
11650723Scg    }
11750723Scg    free(str);
11850723Scg}
11950723Scg
12050723Scgstatic void
12150723Scgprint_cred_verbose(krb5_context context, krb5_creds *cred)
12250723Scg{
12367803Scg    int j;
12450723Scg    char *str;
12550723Scg    krb5_error_code ret;
12650723Scg    int first_flag;
12750723Scg    krb5_timestamp sec;
12854462Scg
12929415Sjmg    krb5_timeofday (context, &sec);
13050723Scg
13150723Scg    ret = krb5_unparse_name(context, cred->server, &str);
13267803Scg    if(ret)
13367803Scg	exit(1);
13467803Scg    printf("Server: %s\n", str);
13550723Scg    free (str);
13667803Scg
13767803Scg    ret = krb5_unparse_name(context, cred->client, &str);
13867803Scg    if(ret)
13965340Scg	exit(1);
14067652Scg    printf("Client: %s\n", str);
14167803Scg    free (str);
14267803Scg
14350723Scg    {
14450723Scg	Ticket t;
14550723Scg	size_t len;
14650723Scg	char *s;
14729415Sjmg
14850723Scg	decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
14929415Sjmg	ret = krb5_enctype_to_string(context, t.enc_part.etype, &s);
15050723Scg	printf("Ticket etype: ");
15150723Scg	if (ret == 0) {
15250723Scg	    printf("%s", s);
15350723Scg	    free(s);
15429415Sjmg	} else {
15529415Sjmg	    printf("unknown(%d)", t.enc_part.etype);
15629415Sjmg	}
15750723Scg	if(t.enc_part.kvno)
15829415Sjmg	    printf(", kvno %d", *t.enc_part.kvno);
15967803Scg	printf("\n");
16050723Scg	if(cred->session.keytype != t.enc_part.etype) {
16129415Sjmg	    ret = krb5_enctype_to_string(context, cred->session.keytype, &str);
16250723Scg	    if(ret)
16350723Scg		krb5_warn(context, ret, "session keytype");
16450723Scg	    else {
16567803Scg		printf("Session key: %s\n", str);
16629415Sjmg		free(str);
16729415Sjmg	    }
16829415Sjmg	}
16950723Scg	free_Ticket(&t);
17029415Sjmg	printf("Ticket length: %lu\n", (unsigned long)cred->ticket.length);
17150723Scg    }
17250723Scg    printf("Auth time:  %s\n", printable_time_long(cred->times.authtime));
17329415Sjmg    if(cred->times.authtime != cred->times.starttime)
17450723Scg	printf("Start time: %s\n", printable_time_long(cred->times.starttime));
17550723Scg    printf("End time:   %s", printable_time_long(cred->times.endtime));
17650723Scg    if(sec > cred->times.endtime)
17750723Scg	printf(" (expired)");
17829415Sjmg    printf("\n");
17929415Sjmg    if(cred->flags.b.renewable)
18050723Scg	printf("Renew till: %s\n",
18150723Scg	       printable_time_long(cred->times.renew_till));
18250723Scg    printf("Ticket flags: ");
18350723Scg#define PRINT_FLAG2(f, s) if(cred->flags.b.f) { if(!first_flag) printf(", "); printf("%s", #s); first_flag = 0; }
18450723Scg#define PRINT_FLAG(f) PRINT_FLAG2(f, f)
18529415Sjmg    first_flag = 1;
18629415Sjmg    PRINT_FLAG(forwardable);
18750723Scg    PRINT_FLAG(forwarded);
18829415Sjmg    PRINT_FLAG(proxiable);
18950723Scg    PRINT_FLAG(proxy);
19029415Sjmg    PRINT_FLAG2(may_postdate, may-postdate);
19150723Scg    PRINT_FLAG(postdated);
19250723Scg    PRINT_FLAG(invalid);
19350723Scg    PRINT_FLAG(renewable);
19450723Scg    PRINT_FLAG(initial);
19550723Scg    PRINT_FLAG2(pre_authent, pre-authenticated);
19650723Scg    PRINT_FLAG2(hw_authent, hw-authenticated);
19750723Scg    PRINT_FLAG2(transited_policy_checked, transited-policy-checked);
19850723Scg    PRINT_FLAG2(ok_as_delegate, ok-as-delegate);
19950723Scg    PRINT_FLAG(anonymous);
20050723Scg    printf("\n");
20129415Sjmg    printf("Addresses: ");
20250723Scg    if (cred->addresses.len != 0) {
20350723Scg	for(j = 0; j < cred->addresses.len; j++){
20450723Scg	    char buf[128];
20550723Scg	    size_t len;
20650723Scg	    if(j) printf(", ");
20750723Scg	    ret = krb5_print_address(&cred->addresses.val[j],
20850723Scg				     buf, sizeof(buf), &len);
20950723Scg
21029415Sjmg	    if(ret == 0)
21167803Scg		printf("%s", buf);
21250723Scg	}
21350723Scg    } else {
21450723Scg	printf("addressless");
21550723Scg    }
21650723Scg    printf("\n\n");
21750723Scg}
21850723Scg
21950723Scg/*
22050723Scg * Print all tickets in `ccache' on stdout, verbosily iff do_verbose.
22150723Scg */
22267803Scg
22329415Sjmgstatic void
22450723Scgprint_tickets (krb5_context context,
22550723Scg	       krb5_ccache ccache,
22650723Scg	       krb5_principal principal,
22750723Scg	       int do_verbose,
22850723Scg	       int do_flags,
22950723Scg	       int do_hidden)
23050723Scg{
23150723Scg    krb5_error_code ret;
23250723Scg    char *str;
23350723Scg    krb5_cc_cursor cursor;
23450723Scg    krb5_creds creds;
23529415Sjmg    int32_t sec, usec;
23650723Scg
23750723Scg    rtbl_t ct = NULL;
23850723Scg
23950723Scg    ret = krb5_unparse_name (context, principal, &str);
24050723Scg    if (ret)
24150723Scg	krb5_err (context, 1, ret, "krb5_unparse_name");
24250723Scg
24350723Scg    printf ("%17s: %s:%s\n",
24429415Sjmg	    "Credentials cache",
24550723Scg	    krb5_cc_get_type(context, ccache),
24650723Scg	    krb5_cc_get_name(context, ccache));
24750723Scg    printf ("%17s: %s\n", "Principal", str);
24850723Scg    free (str);
24950723Scg
25050723Scg    if(do_verbose)
25150723Scg	printf ("%17s: %d\n", "Cache version",
25231361Sjmg		krb5_cc_get_version(context, ccache));
25350723Scg
25450723Scg    krb5_get_kdc_sec_offset(context, &sec, &usec);
25550723Scg
25650723Scg    if (do_verbose && sec != 0) {
25750723Scg	char buf[BUFSIZ];
25829415Sjmg	int val;
25950723Scg	int sig;
26050723Scg
26150723Scg	val = sec;
26250723Scg	sig = 1;
26350723Scg	if (val < 0) {
26450723Scg	    sig = -1;
26529415Sjmg	    val = -val;
26650723Scg	}
26750723Scg
26829415Sjmg	unparse_time (val, buf, sizeof(buf));
26950723Scg
27050723Scg	printf ("%17s: %s%s\n", "KDC time offset",
27150723Scg		sig == -1 ? "-" : "", buf);
27250723Scg    }
27329415Sjmg
27450723Scg    printf("\n");
27550723Scg
27650723Scg    ret = krb5_cc_start_seq_get (context, ccache, &cursor);
27750723Scg    if (ret)
27850723Scg	krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
27950723Scg
28050723Scg    if(!do_verbose) {
28150723Scg	ct = rtbl_create();
28229415Sjmg	rtbl_add_column(ct, COL_ISSUED, 0);
28350723Scg	rtbl_add_column(ct, COL_EXPIRES, 0);
28450723Scg	if(do_flags)
28529415Sjmg	    rtbl_add_column(ct, COL_FLAGS, 0);
28650723Scg	rtbl_add_column(ct, COL_PRINCIPAL, 0);
28750723Scg	rtbl_set_separator(ct, "  ");
28850723Scg    }
28950723Scg    while ((ret = krb5_cc_next_cred (context,
29050723Scg				     ccache,
29150723Scg				     &cursor,
29250723Scg				     &creds)) == 0) {
29350723Scg	const char *str;
29450723Scg	str = krb5_principal_get_comp_string(context, creds.server, 0);
29529415Sjmg	if (!do_hidden && str && str[0] == '@') {
29629415Sjmg	    ;
29767803Scg	}else if(do_verbose){
29867803Scg	    print_cred_verbose(context, &creds);
29967803Scg	}else{
30067803Scg	    print_cred(context, &creds, ct, do_flags);
30167803Scg	}
30267803Scg	krb5_free_cred_contents (context, &creds);
30367803Scg    }
30467803Scg    if(ret != KRB5_CC_END)
30567803Scg	krb5_err(context, 1, ret, "krb5_cc_get_next");
30667803Scg    ret = krb5_cc_end_seq_get (context, ccache, &cursor);
30767803Scg    if (ret)
30867803Scg	krb5_err (context, 1, ret, "krb5_cc_end_seq_get");
30967803Scg    if(!do_verbose) {
31067803Scg	rtbl_format(ct, stdout);
31167803Scg	rtbl_destroy(ct);
31267803Scg    }
31367803Scg}
31467803Scg
31567803Scg/*
31667803Scg * Check if there's a tgt for the realm of `principal' and ccache and
31767803Scg * if so return 0, else 1
31867803Scg */
31967803Scg
32067803Scgstatic int
32167803Scgcheck_for_tgt (krb5_context context,
32267803Scg	       krb5_ccache ccache,
32367803Scg	       krb5_principal principal,
32467803Scg	       time_t *expiration)
32567803Scg{
32667803Scg    krb5_error_code ret;
32767803Scg    krb5_creds pattern;
32867803Scg    krb5_creds creds;
32967803Scg    krb5_realm *client_realm;
33067803Scg    int expired;
33167803Scg
33267803Scg    krb5_cc_clear_mcred(&pattern);
33367803Scg
33467803Scg    client_realm = krb5_princ_realm (context, principal);
33567803Scg
33667803Scg    ret = krb5_make_principal (context, &pattern.server,
33767803Scg			       *client_realm, KRB5_TGS_NAME, *client_realm,
33867803Scg			       NULL);
33967803Scg    if (ret)
34067803Scg	krb5_err (context, 1, ret, "krb5_make_principal");
34167803Scg    pattern.client = principal;
34267803Scg
34367803Scg    ret = krb5_cc_retrieve_cred (context, ccache, 0, &pattern, &creds);
34467803Scg    krb5_free_principal (context, pattern.server);
34567803Scg    if (ret) {
34667803Scg	if (ret == KRB5_CC_END)
34767803Scg	    return 1;
34867803Scg	krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");
34967803Scg    }
35067803Scg
35167803Scg    expired = time(NULL) > creds.times.endtime;
35267803Scg
35367803Scg    if (expiration)
35467803Scg	*expiration = creds.times.endtime;
35567803Scg
35668376Scg    krb5_free_cred_contents (context, &creds);
35767803Scg
35867803Scg    return expired;
35967803Scg}
36067803Scg
36167803Scg/*
36267803Scg * Print a list of all AFS tokens
36367803Scg */
36467803Scg
36567803Scgstatic void
36667803Scgdisplay_tokens(int do_verbose)
36767803Scg{
36867803Scg    uint32_t i;
36967803Scg    unsigned char t[4096];
37067803Scg    struct ViceIoctl parms;
37167803Scg
37267803Scg    parms.in = (void *)&i;
37367803Scg    parms.in_size = sizeof(i);
37467803Scg    parms.out = (void *)t;
37567803Scg    parms.out_size = sizeof(t);
37667803Scg
37767803Scg    for (i = 0;; i++) {
37867803Scg        int32_t size_secret_tok, size_public_tok;
37967803Scg        unsigned char *cell;
38067803Scg	struct ClearToken ct;
38167803Scg	unsigned char *r = t;
38267803Scg	struct timeval tv;
38367803Scg	char buf1[20], buf2[20];
38467803Scg
38567803Scg	if(k_pioctl(NULL, VIOCGETTOK, &parms, 0) < 0) {
38667803Scg	    if(errno == EDOM)
38767803Scg		break;
38867803Scg	    continue;
38967803Scg	}
39067803Scg	if(parms.out_size > sizeof(t))
39167803Scg	    continue;
39267803Scg	if(parms.out_size < sizeof(size_secret_tok))
39367803Scg	    continue;
39467803Scg	t[min(parms.out_size,sizeof(t)-1)] = 0;
39567803Scg	memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
39667803Scg	/* dont bother about the secret token */
39767803Scg	r += size_secret_tok + sizeof(size_secret_tok);
39867803Scg	if (parms.out_size < (r - t) + sizeof(size_public_tok))
39967803Scg	    continue;
40067803Scg	memcpy(&size_public_tok, r, sizeof(size_public_tok));
40167803Scg	r += sizeof(size_public_tok);
40267803Scg	if (parms.out_size < (r - t) + size_public_tok + sizeof(int32_t))
40329415Sjmg	    continue;
40467803Scg	memcpy(&ct, r, size_public_tok);
40529415Sjmg	r += size_public_tok;
40650723Scg	/* there is a int32_t with length of cellname, but we dont read it */
40765644Scg	r += sizeof(int32_t);
40865644Scg	cell = r;
40965644Scg
41050723Scg	gettimeofday (&tv, NULL);
41150723Scg	strlcpy (buf1, printable_time(ct.BeginTimestamp),
41250723Scg		 sizeof(buf1));
41354462Scg	if (do_verbose || tv.tv_sec < ct.EndTimestamp)
41450723Scg	    strlcpy (buf2, printable_time(ct.EndTimestamp),
41550723Scg		     sizeof(buf2));
41650723Scg	else
41754462Scg	    strlcpy (buf2, ">>> Expired <<<", sizeof(buf2));
41850723Scg
41950723Scg	printf("%s  %s  ", buf1, buf2);
42050723Scg
42154462Scg	if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
42250723Scg	    printf("User's (AFS ID %d) tokens for %s", ct.ViceId, cell);
42350723Scg	else
42465644Scg	    printf("Tokens for %s", cell);
42565644Scg	if (do_verbose)
42665644Scg	    printf(" (%d)", ct.AuthHandle);
42765644Scg	putchar('\n');
42865644Scg    }
42950723Scg}
43029415Sjmg
43150723Scg/*
43267803Scg * display the ccache in `cred_cache'
43350723Scg */
43454462Scg
43554462Scgstatic int
43654462Scgdisplay_v5_ccache (const char *cred_cache, int do_test, int do_verbose,
43750723Scg		   int do_flags, int do_hidden)
43867803Scg{
43967803Scg    krb5_error_code ret;
44054462Scg    krb5_context context;
44150723Scg    krb5_ccache ccache;
44267803Scg    krb5_principal principal;
44367803Scg    int exit_status = 0;
44454462Scg
44550723Scg    ret = krb5_init_context (&context);
44667803Scg    if (ret)
44767803Scg	errx (1, "krb5_init_context failed: %d", ret);
44854462Scg
44958756Scg    if(cred_cache) {
45067803Scg	ret = krb5_cc_resolve(context, cred_cache, &ccache);
45129415Sjmg	if (ret)
45250723Scg	    krb5_err (context, 1, ret, "%s", cred_cache);
45367803Scg    } else {
45455424Scg	ret = krb5_cc_default (context, &ccache);
45554462Scg	if (ret)
45655424Scg	    krb5_err (context, 1, ret, "krb5_cc_resolve");
45729415Sjmg    }
45850723Scg
45954462Scg    ret = krb5_cc_get_principal (context, ccache, &principal);
46055424Scg    if (ret) {
46154462Scg	if(ret == ENOENT) {
46250723Scg	    if (!do_test)
46350723Scg		krb5_warnx(context, "No ticket file: %s",
46429415Sjmg			   krb5_cc_get_name(context, ccache));
46529415Sjmg	    return 1;
46654462Scg	} else
46767803Scg	    krb5_err (context, 1, ret, "krb5_cc_get_principal");
46829415Sjmg    }
46967803Scg    if (do_test)
47067803Scg	exit_status = check_for_tgt (context, ccache, principal, NULL);
47129415Sjmg    else
47267803Scg	print_tickets (context, ccache, principal, do_verbose,
47367803Scg		       do_flags, do_hidden);
47467803Scg
47567803Scg    ret = krb5_cc_close (context, ccache);
47629415Sjmg    if (ret)
47767803Scg	krb5_err (context, 1, ret, "krb5_cc_close");
47867803Scg
47941653Sbrian    krb5_free_principal (context, principal);
48067803Scg    krb5_free_context (context);
48167803Scg    return exit_status;
48267803Scg}
48367803Scg
48429415Sjmg/*
48567803Scg *
48667803Scg */
48767803Scg
48867803Scgstatic int
48967803Scglist_caches(void)
49067803Scg{
49129415Sjmg    krb5_cc_cache_cursor cursor;
49267803Scg    krb5_context context;
49367803Scg    krb5_error_code ret;
49467803Scg    krb5_ccache id;
49567803Scg    rtbl_t ct;
49667803Scg
49750723Scg    ret = krb5_init_context (&context);
49850723Scg    if (ret)
49950723Scg	errx (1, "krb5_init_context failed: %d", ret);
50050723Scg
50167803Scg    ret = krb5_cc_cache_get_first (context, NULL, &cursor);
50250723Scg    if (ret == KRB5_CC_NOSUPP)
50367803Scg	return 0;
50467803Scg    else if (ret)
50550723Scg	krb5_err (context, 1, ret, "krb5_cc_cache_get_first");
50667803Scg
50755706Scg    ct = rtbl_create();
50855706Scg    rtbl_add_column(ct, COL_PRINCIPAL, 0);
50967803Scg    rtbl_add_column(ct, COL_CACHENAME, 0);
51055706Scg    rtbl_add_column(ct, COL_EXPIRES, 0);
51155706Scg    rtbl_set_prefix(ct, "   ");
51250723Scg    rtbl_set_column_prefix(ct, COL_PRINCIPAL, "");
51331361Sjmg
51450723Scg    while ((ret = krb5_cc_cache_next (context, cursor, &id)) == 0) {
51567803Scg	krb5_principal principal;
51650723Scg	char *name;
51767803Scg
51867803Scg	ret = krb5_cc_get_principal(context, id, &principal);
51967803Scg	if (ret == 0) {
52029415Sjmg	    time_t t;
52167803Scg	    int expired = check_for_tgt (context, id, principal, &t);
52267803Scg
52367803Scg	    ret = krb5_unparse_name(context, principal, &name);
52467803Scg	    if (ret == 0) {
52567803Scg		rtbl_add_column_entry(ct, COL_PRINCIPAL, name);
52629415Sjmg		rtbl_add_column_entry(ct, COL_CACHENAME,
52767803Scg				      krb5_cc_get_name(context, id));
52829415Sjmg		rtbl_add_column_entry(ct, COL_EXPIRES,
52967803Scg				      expired ? ">>> Expired <<<" :
53067803Scg				      printable_time(t));
53167803Scg		free(name);
53267803Scg		krb5_free_principal(context, principal);
53367803Scg	    }
53467803Scg	}
53567803Scg	krb5_cc_close(context, id);
53667803Scg    }
53767803Scg
53867803Scg    krb5_cc_cache_end_seq_get(context, cursor);
53967803Scg
54067803Scg    rtbl_format(ct, stdout);
54167803Scg    rtbl_destroy(ct);
54267803Scg
54367803Scg    return 0;
54467803Scg}
54550723Scg
54667803Scg/*
54729415Sjmg *
54867803Scg */
54967803Scg
55029415Sjmgstatic int version_flag		= 0;
55167803Scgstatic int help_flag		= 0;
55267803Scgstatic int do_verbose		= 0;
55329415Sjmgstatic int do_list_caches	= 0;
55467803Scgstatic int do_test		= 0;
55567803Scgstatic int do_tokens		= 0;
55667803Scgstatic int do_v5		= 1;
55767803Scgstatic char *cred_cache;
55855706Scgstatic int do_flags	 	= 0;
55967803Scgstatic int do_hidden	 	= 0;
56067803Scg
56167803Scgstatic struct getargs args[] = {
56267803Scg    { NULL, 'f', arg_flag, &do_flags },
56367803Scg    { "cache",			'c', arg_string, &cred_cache,
56467803Scg      "credentials cache to list", "cache" },
56555706Scg    { "test",			't', arg_flag, &do_test,
56667803Scg      "test for having tickets", NULL },
56767803Scg    { NULL,			's', arg_flag, &do_test },
56867803Scg    { "tokens",			'T',   arg_flag, &do_tokens,
56967803Scg      "display AFS tokens", NULL },
57067803Scg    { "v5",			'5',	arg_flag, &do_v5,
57167803Scg      "display v5 cred cache", NULL},
57267803Scg    { "list-caches",		'l', arg_flag, &do_list_caches,
57367803Scg      "verbose output", NULL },
57467803Scg    { "verbose",		'v', arg_flag, &do_verbose,
57567803Scg      "verbose output", NULL },
57667803Scg    { "hidden",			0,   arg_flag, &do_hidden,
57767803Scg      "display hidden credentials", NULL },
57867803Scg    { NULL,			'a', arg_flag, &do_verbose },
57967803Scg    { NULL,			'n', arg_flag, &do_verbose },
58067803Scg    { "version", 		0,   arg_flag, &version_flag,
58167803Scg      "print version", NULL },
58250723Scg    { "help",			0,   arg_flag, &help_flag,
58350723Scg      NULL, NULL}
58467803Scg};
58567803Scg
58667803Scgstatic void
58767803Scgusage (int ret)
58867803Scg{
58967803Scg    arg_printusage (args,
59029415Sjmg		    sizeof(args)/sizeof(*args),
59167803Scg		    NULL,
59267803Scg		    "");
59367803Scg    exit (ret);
59467803Scg}
59567803Scg
59667803Scgint
59767803Scgmain (int argc, char **argv)
59867803Scg{
59967803Scg    int optidx = 0;
60067803Scg    int exit_status = 0;
60167803Scg
60267803Scg    setprogname (argv[0]);
60367803Scg
60467803Scg    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
60567803Scg	usage(1);
60667803Scg
60729415Sjmg    if (help_flag)
60867803Scg	usage (0);
60967803Scg
61050723Scg    if(version_flag){
61129415Sjmg	print_version(NULL);
61255706Scg	exit(0);
61355706Scg    }
61467803Scg
61555706Scg    argc -= optidx;
61655706Scg    argv += optidx;
61755706Scg
61855706Scg    if (argc != 0)
61955706Scg	usage (1);
62055706Scg
62155706Scg    if (do_list_caches) {
62267803Scg	exit_status = list_caches();
62367803Scg	return exit_status;
62467803Scg    }
62555706Scg
62655706Scg    if (do_v5)
62767803Scg	exit_status = display_v5_ccache (cred_cache, do_test,
62855706Scg					 do_verbose, do_flags, do_hidden);
62955706Scg
63055706Scg    if (!do_test) {
63155706Scg	if (do_tokens && k_hasafs ()) {
63267803Scg	    if (do_v5)
63355706Scg		printf ("\n");
63455706Scg	    display_tokens (do_verbose);
63567803Scg	}
63655706Scg    }
63767803Scg
63867803Scg    return exit_status;
63967803Scg}
64067803Scg