155682Smarkm/*
2233294Sstas * Copyright (c) 1997-2006 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "kadmin_locl.h"
35178825Sdfr#include "kadmin-commands.h"
3655682Smarkm#include <parse_units.h>
37178825Sdfr#include <rtbl.h>
3855682Smarkm
39178825Sdfrstatic struct field_name {
40178825Sdfr    const char *fieldname;
41178825Sdfr    unsigned int fieldvalue;
42178825Sdfr    unsigned int subvalue;
43178825Sdfr    uint32_t extra_mask;
44178825Sdfr    const char *default_header;
45178825Sdfr    const char *def_longheader;
46178825Sdfr    unsigned int flags;
47178825Sdfr} field_names[] = {
48178825Sdfr    { "principal", KADM5_PRINCIPAL, 0, 0, "Principal", "Principal", 0 },
49178825Sdfr    { "princ_expire_time", KADM5_PRINC_EXPIRE_TIME, 0, 0, "Expiration", "Principal expires", 0 },
50178825Sdfr    { "pw_expiration", KADM5_PW_EXPIRATION, 0, 0, "PW-exp", "Password expires", 0 },
51178825Sdfr    { "last_pwd_change", KADM5_LAST_PWD_CHANGE, 0, 0, "PW-change", "Last password change", 0 },
52178825Sdfr    { "max_life", KADM5_MAX_LIFE, 0, 0, "Max life", "Max ticket life", 0 },
53178825Sdfr    { "max_rlife", KADM5_MAX_RLIFE, 0, 0, "Max renew", "Max renewable life", 0 },
54178825Sdfr    { "mod_time", KADM5_MOD_TIME, 0, 0, "Mod time", "Last modified", 0 },
55178825Sdfr    { "mod_name", KADM5_MOD_NAME, 0, 0, "Modifier", "Modifier", 0 },
56178825Sdfr    { "attributes", KADM5_ATTRIBUTES, 0, 0, "Attributes", "Attributes", 0 },
57178825Sdfr    { "kvno", KADM5_KVNO, 0, 0, "Kvno", "Kvno", RTBL_ALIGN_RIGHT  },
58178825Sdfr    { "mkvno", KADM5_MKVNO, 0, 0, "Mkvno", "Mkvno", RTBL_ALIGN_RIGHT },
59178825Sdfr    { "last_success", KADM5_LAST_SUCCESS, 0, 0, "Last login", "Last successful login", 0 },
60178825Sdfr    { "last_failed", KADM5_LAST_FAILED, 0, 0, "Last fail", "Last failed login", 0 },
61178825Sdfr    { "fail_auth_count", KADM5_FAIL_AUTH_COUNT, 0, 0, "Fail count", "Failed login count", RTBL_ALIGN_RIGHT },
62178825Sdfr    { "policy", KADM5_POLICY, 0, 0, "Policy", "Policy", 0 },
63178825Sdfr    { "keytypes", KADM5_KEY_DATA, 0, KADM5_PRINCIPAL, "Keytypes", "Keytypes", 0 },
64178825Sdfr    { "password", KADM5_TL_DATA, KRB5_TL_PASSWORD, KADM5_KEY_DATA, "Password", "Password", 0 },
65178825Sdfr    { "pkinit-acl", KADM5_TL_DATA, KRB5_TL_PKINIT_ACL, 0, "PK-INIT ACL", "PK-INIT ACL", 0 },
66178825Sdfr    { "aliases", KADM5_TL_DATA, KRB5_TL_ALIASES, 0, "Aliases", "Aliases", 0 },
67178825Sdfr    { NULL }
6855682Smarkm};
6955682Smarkm
70178825Sdfrstruct field_info {
71178825Sdfr    struct field_name *ff;
72178825Sdfr    char *header;
73178825Sdfr    struct field_info *next;
74178825Sdfr};
7555682Smarkm
76178825Sdfrstruct get_entry_data {
77178825Sdfr    void (*format)(struct get_entry_data*, kadm5_principal_ent_t);
78178825Sdfr    rtbl_t table;
79178825Sdfr    uint32_t mask;
80178825Sdfr    uint32_t extra_mask;
81178825Sdfr    struct field_info *chead, **ctail;
82178825Sdfr};
8355682Smarkm
84178825Sdfrstatic int
85178825Sdfradd_column(struct get_entry_data *data, struct field_name *ff, const char *header)
8655682Smarkm{
87178825Sdfr    struct field_info *f = malloc(sizeof(*f));
88178825Sdfr    if (f == NULL)
89178825Sdfr	return ENOMEM;
90178825Sdfr    f->ff = ff;
91178825Sdfr    if(header)
92178825Sdfr	f->header = strdup(header);
93178825Sdfr    else
94178825Sdfr	f->header = NULL;
95178825Sdfr    f->next = NULL;
96178825Sdfr    *data->ctail = f;
97178825Sdfr    data->ctail = &f->next;
98178825Sdfr    data->mask |= ff->fieldvalue;
99178825Sdfr    data->extra_mask |= ff->extra_mask;
100178825Sdfr    if(data->table != NULL)
101233294Sstas	rtbl_add_column_by_id(data->table, ff->fieldvalue,
102178825Sdfr			      header ? header : ff->default_header, ff->flags);
103178825Sdfr    return 0;
10455682Smarkm}
10555682Smarkm
10672445Sassar/*
10772445Sassar * return 0 iff `salt' actually is the same as the current salt in `k'
10872445Sassar */
10972445Sassar
11072445Sassarstatic int
11172445Sassarcmp_salt (const krb5_salt *salt, const krb5_key_data *k)
11272445Sassar{
113233294Sstas    if (salt->salttype != (size_t)k->key_data_type[1])
11472445Sassar	return 1;
115233294Sstas    if (salt->saltvalue.length != (size_t)k->key_data_length[1])
11672445Sassar	return 1;
11772445Sassar    return memcmp (salt->saltvalue.data, k->key_data_contents[1],
11872445Sassar		   salt->saltvalue.length);
11972445Sassar}
12072445Sassar
12155682Smarkmstatic void
122178825Sdfrformat_keytype(krb5_key_data *k, krb5_salt *def_salt, char *buf, size_t buf_len)
12355682Smarkm{
124178825Sdfr    krb5_error_code ret;
125178825Sdfr    char *s;
126178825Sdfr
127178825Sdfr    ret = krb5_enctype_to_string (context,
128178825Sdfr				  k->key_data_type[0],
129178825Sdfr				  &s);
130178825Sdfr    if (ret)
131178825Sdfr	asprintf (&s, "unknown(%d)", k->key_data_type[0]);
132178825Sdfr    strlcpy(buf, s, buf_len);
133178825Sdfr    free(s);
134178825Sdfr
135178825Sdfr    strlcat(buf, "(", buf_len);
136178825Sdfr
137178825Sdfr    ret = krb5_salttype_to_string (context,
138178825Sdfr				   k->key_data_type[0],
139178825Sdfr				   k->key_data_type[1],
140178825Sdfr				   &s);
141178825Sdfr    if (ret)
142178825Sdfr	asprintf (&s, "unknown(%d)", k->key_data_type[1]);
143178825Sdfr    strlcat(buf, s, buf_len);
144178825Sdfr    free(s);
145178825Sdfr
146178825Sdfr    if (cmp_salt(def_salt, k) == 0)
147178825Sdfr	s = strdup("");
148178825Sdfr    else if(k->key_data_length[1] == 0)
149178825Sdfr	s = strdup("()");
150178825Sdfr    else
151178825Sdfr	asprintf (&s, "(%.*s)", k->key_data_length[1],
152178825Sdfr		  (char *)k->key_data_contents[1]);
153178825Sdfr    strlcat(buf, s, buf_len);
154178825Sdfr    free(s);
155178825Sdfr
156178825Sdfr    strlcat(buf, ")", buf_len);
157178825Sdfr}
158178825Sdfr
159178825Sdfrstatic void
160233294Sstasformat_field(kadm5_principal_ent_t princ, unsigned int field,
161178825Sdfr	     unsigned int subfield, char *buf, size_t buf_len, int condensed)
162178825Sdfr{
163178825Sdfr    switch(field) {
164178825Sdfr    case KADM5_PRINCIPAL:
165178825Sdfr	if(condensed)
166178825Sdfr	    krb5_unparse_name_fixed_short(context, princ->principal, buf, buf_len);
167178825Sdfr	else
168178825Sdfr	    krb5_unparse_name_fixed(context, princ->principal, buf, buf_len);
169178825Sdfr	break;
170233294Sstas
171178825Sdfr    case KADM5_PRINC_EXPIRE_TIME:
172178825Sdfr	time_t2str(princ->princ_expire_time, buf, buf_len, !condensed);
173178825Sdfr	break;
174233294Sstas
175178825Sdfr    case KADM5_PW_EXPIRATION:
176178825Sdfr	time_t2str(princ->pw_expiration, buf, buf_len, !condensed);
177178825Sdfr	break;
178233294Sstas
179178825Sdfr    case KADM5_LAST_PWD_CHANGE:
180178825Sdfr	time_t2str(princ->last_pwd_change, buf, buf_len, !condensed);
181178825Sdfr	break;
182233294Sstas
183178825Sdfr    case KADM5_MAX_LIFE:
184178825Sdfr	deltat2str(princ->max_life, buf, buf_len);
185178825Sdfr	break;
186233294Sstas
187178825Sdfr    case KADM5_MAX_RLIFE:
188178825Sdfr	deltat2str(princ->max_renewable_life, buf, buf_len);
189178825Sdfr	break;
190233294Sstas
191178825Sdfr    case KADM5_MOD_TIME:
192178825Sdfr	time_t2str(princ->mod_date, buf, buf_len, !condensed);
193178825Sdfr	break;
19455682Smarkm
195178825Sdfr    case KADM5_MOD_NAME:
196178825Sdfr	if (princ->mod_name == NULL)
197178825Sdfr	    strlcpy(buf, "unknown", buf_len);
198178825Sdfr	else if(condensed)
199178825Sdfr	    krb5_unparse_name_fixed_short(context, princ->mod_name, buf, buf_len);
200178825Sdfr	else
201178825Sdfr	    krb5_unparse_name_fixed(context, princ->mod_name, buf, buf_len);
202178825Sdfr	break;
203178825Sdfr    case KADM5_ATTRIBUTES:
204178825Sdfr	attributes2str (princ->attributes, buf, buf_len);
205178825Sdfr	break;
206178825Sdfr    case KADM5_KVNO:
207178825Sdfr	snprintf(buf, buf_len, "%d", princ->kvno);
208178825Sdfr	break;
209178825Sdfr    case KADM5_MKVNO:
210233294Sstas	/* XXX libkadm5srv decrypts the keys, so mkvno is always 0. */
211233294Sstas	strlcpy(buf, "unknown", buf_len);
212178825Sdfr	break;
213178825Sdfr    case KADM5_LAST_SUCCESS:
214178825Sdfr	time_t2str(princ->last_success, buf, buf_len, !condensed);
215178825Sdfr	break;
216178825Sdfr    case KADM5_LAST_FAILED:
217178825Sdfr	time_t2str(princ->last_failed, buf, buf_len, !condensed);
218178825Sdfr	break;
219178825Sdfr    case KADM5_FAIL_AUTH_COUNT:
220178825Sdfr	snprintf(buf, buf_len, "%d", princ->fail_auth_count);
221178825Sdfr	break;
222178825Sdfr    case KADM5_POLICY:
223178825Sdfr	if(princ->policy != NULL)
224178825Sdfr	    strlcpy(buf, princ->policy, buf_len);
225178825Sdfr	else
226178825Sdfr	    strlcpy(buf, "none", buf_len);
227178825Sdfr	break;
228178825Sdfr    case KADM5_KEY_DATA:{
229178825Sdfr	krb5_salt def_salt;
230178825Sdfr	int i;
231178825Sdfr	char buf2[1024];
232178825Sdfr	krb5_get_pw_salt (context, princ->principal, &def_salt);
233178825Sdfr
234178825Sdfr	*buf = '\0';
235178825Sdfr	for (i = 0; i < princ->n_key_data; ++i) {
236178825Sdfr	    format_keytype(&princ->key_data[i], &def_salt, buf2, sizeof(buf2));
237178825Sdfr	    if(i > 0)
238178825Sdfr		strlcat(buf, ", ", buf_len);
239178825Sdfr	    strlcat(buf, buf2, buf_len);
240178825Sdfr	}
241178825Sdfr	krb5_free_salt (context, def_salt);
242178825Sdfr	break;
24372445Sassar    }
244178825Sdfr    case KADM5_TL_DATA: {
245178825Sdfr	krb5_tl_data *tl;
24655682Smarkm
247178825Sdfr	for (tl = princ->tl_data; tl != NULL; tl = tl->tl_data_next)
248233294Sstas	    if ((unsigned)tl->tl_data_type == subfield)
249178825Sdfr		break;
250178825Sdfr	if (tl == NULL) {
251178825Sdfr	    strlcpy(buf, "", buf_len);
252178825Sdfr	    break;
253178825Sdfr	}
25455682Smarkm
255178825Sdfr	switch (subfield) {
256178825Sdfr	case KRB5_TL_PASSWORD:
257178825Sdfr	    snprintf(buf, buf_len, "\"%.*s\"",
258178825Sdfr		     (int)tl->tl_data_length,
259178825Sdfr		     (const char *)tl->tl_data_contents);
260178825Sdfr	    break;
261178825Sdfr	case KRB5_TL_PKINIT_ACL: {
262178825Sdfr	    HDB_Ext_PKINIT_acl acl;
263178825Sdfr	    size_t size;
264233294Sstas	    int ret;
265233294Sstas	    size_t i;
26672445Sassar
267178825Sdfr	    ret = decode_HDB_Ext_PKINIT_acl(tl->tl_data_contents,
268178825Sdfr					    tl->tl_data_length,
269178825Sdfr					    &acl,
270178825Sdfr					    &size);
271178825Sdfr	    if (ret) {
272178825Sdfr		snprintf(buf, buf_len, "failed to decode ACL");
273178825Sdfr		break;
274178825Sdfr	    }
27555682Smarkm
276178825Sdfr	    buf[0] = '\0';
277178825Sdfr	    for (i = 0; i < acl.len; i++) {
278178825Sdfr		strlcat(buf, "subject: ", buf_len);
279178825Sdfr		strlcat(buf, acl.val[i].subject, buf_len);
280178825Sdfr		if (acl.val[i].issuer) {
281178825Sdfr		    strlcat(buf, " issuer:", buf_len);
282178825Sdfr		    strlcat(buf, *acl.val[i].issuer, buf_len);
283178825Sdfr		}
284178825Sdfr		if (acl.val[i].anchor) {
285178825Sdfr		    strlcat(buf, " anchor:", buf_len);
286178825Sdfr		    strlcat(buf, *acl.val[i].anchor, buf_len);
287178825Sdfr		}
288178825Sdfr		if (i + 1 < acl.len)
289178825Sdfr		    strlcat(buf, ", ", buf_len);
290178825Sdfr	    }
291178825Sdfr	    free_HDB_Ext_PKINIT_acl(&acl);
292178825Sdfr	    break;
293178825Sdfr	}
294178825Sdfr	case KRB5_TL_ALIASES: {
295178825Sdfr	    HDB_Ext_Aliases alias;
296178825Sdfr	    size_t size;
297233294Sstas	    int ret;
298233294Sstas	    size_t i;
29955682Smarkm
300178825Sdfr	    ret = decode_HDB_Ext_Aliases(tl->tl_data_contents,
301178825Sdfr					 tl->tl_data_length,
302178825Sdfr					 &alias,
303178825Sdfr					 &size);
304178825Sdfr	    if (ret) {
305178825Sdfr		snprintf(buf, buf_len, "failed to decode alias");
306178825Sdfr		break;
307178825Sdfr	    }
308178825Sdfr	    buf[0] = '\0';
309178825Sdfr	    for (i = 0; i < alias.aliases.len; i++) {
310178825Sdfr		char *p;
311178825Sdfr		ret = krb5_unparse_name(context, &alias.aliases.val[i], &p);
312178825Sdfr		if (ret)
313178825Sdfr		    break;
314233294Sstas		if (i > 0)
315178825Sdfr		    strlcat(buf, " ", buf_len);
316178825Sdfr		strlcat(buf, p, buf_len);
317178825Sdfr		free(p);
318178825Sdfr	    }
319178825Sdfr	    free_HDB_Ext_Aliases(&alias);
320178825Sdfr	    break;
321178825Sdfr	}
322178825Sdfr	default:
323178825Sdfr	    snprintf(buf, buf_len, "unknown type %d", subfield);
324178825Sdfr	    break;
325178825Sdfr	}
326178825Sdfr	break;
327178825Sdfr    }
328178825Sdfr    default:
329178825Sdfr	strlcpy(buf, "<unknown>", buf_len);
330178825Sdfr	break;
331178825Sdfr    }
332178825Sdfr}
33355682Smarkm
334178825Sdfrstatic void
335178825Sdfrprint_entry_short(struct get_entry_data *data, kadm5_principal_ent_t princ)
336178825Sdfr{
337178825Sdfr    char buf[1024];
338178825Sdfr    struct field_info *f;
339233294Sstas
340178825Sdfr    for(f = data->chead; f != NULL; f = f->next) {
341178825Sdfr	format_field(princ, f->ff->fieldvalue, f->ff->subvalue, buf, sizeof(buf), 1);
342178825Sdfr	rtbl_add_column_entry_by_id(data->table, f->ff->fieldvalue, buf);
343178825Sdfr    }
344178825Sdfr}
34572445Sassar
346178825Sdfrstatic void
347178825Sdfrprint_entry_long(struct get_entry_data *data, kadm5_principal_ent_t princ)
348178825Sdfr{
349178825Sdfr    char buf[1024];
350178825Sdfr    struct field_info *f;
351178825Sdfr    int width = 0;
352233294Sstas
353178825Sdfr    for(f = data->chead; f != NULL; f = f->next) {
354178825Sdfr	int w = strlen(f->header ? f->header : f->ff->def_longheader);
355178825Sdfr	if(w > width)
356178825Sdfr	    width = w;
35755682Smarkm    }
358178825Sdfr    for(f = data->chead; f != NULL; f = f->next) {
359178825Sdfr	format_field(princ, f->ff->fieldvalue, f->ff->subvalue, buf, sizeof(buf), 0);
360178825Sdfr	printf("%*s: %s\n", width, f->header ? f->header : f->ff->def_longheader, buf);
361178825Sdfr    }
362178825Sdfr    printf("\n");
36355682Smarkm}
36455682Smarkm
36555682Smarkmstatic int
36655682Smarkmdo_get_entry(krb5_principal principal, void *data)
36755682Smarkm{
36855682Smarkm    kadm5_principal_ent_rec princ;
36955682Smarkm    krb5_error_code ret;
37055682Smarkm    struct get_entry_data *e = data;
371233294Sstas
37255682Smarkm    memset(&princ, 0, sizeof(princ));
373233294Sstas    ret = kadm5_get_principal(kadm_handle, principal,
37455682Smarkm			      &princ,
375178825Sdfr			      e->mask | e->extra_mask);
37655682Smarkm    if(ret)
37755682Smarkm	return ret;
37855682Smarkm    else {
379178825Sdfr	(e->format)(e, &princ);
38055682Smarkm	kadm5_free_principal_ent(kadm_handle, &princ);
38155682Smarkm    }
38255682Smarkm    return 0;
38355682Smarkm}
38455682Smarkm
385178825Sdfrstatic void
386178825Sdfrfree_columns(struct get_entry_data *data)
387178825Sdfr{
388178825Sdfr    struct field_info *f, *next;
389178825Sdfr    for(f = data->chead; f != NULL; f = next) {
390178825Sdfr	free(f->header);
391178825Sdfr	next = f->next;
392178825Sdfr	free(f);
393178825Sdfr    }
394178825Sdfr    data->chead = NULL;
395178825Sdfr    data->ctail = &data->chead;
396178825Sdfr}
397178825Sdfr
39872445Sassarstatic int
399178825Sdfrsetup_columns(struct get_entry_data *data, const char *column_info)
40055682Smarkm{
401178825Sdfr    char buf[1024], *q;
402178825Sdfr    char *field, *header;
403178825Sdfr    struct field_name *f;
404178825Sdfr
405178825Sdfr    while(strsep_copy(&column_info, ",", buf, sizeof(buf)) != -1) {
406178825Sdfr	q = buf;
407178825Sdfr	field = strsep(&q, "=");
408178825Sdfr	header = strsep(&q, "=");
409178825Sdfr	for(f = field_names; f->fieldname != NULL; f++) {
410178825Sdfr	    if(strcasecmp(field, f->fieldname) == 0) {
411178825Sdfr		add_column(data, f, header);
412178825Sdfr		break;
413178825Sdfr	    }
414178825Sdfr	}
415178825Sdfr	if(f->fieldname == NULL) {
416178825Sdfr	    krb5_warnx(context, "unknown field name \"%s\"", field);
417178825Sdfr	    free_columns(data);
418178825Sdfr	    return -1;
419178825Sdfr	}
420178825Sdfr    }
421178825Sdfr    return 0;
422178825Sdfr}
423178825Sdfr
424233294Sstasstatic int
425233294Sstasdo_list_entry(krb5_principal principal, void *data)
426233294Sstas{
427233294Sstas    char buf[1024];
428233294Sstas    krb5_error_code ret;
429233294Sstas
430233294Sstas    ret = krb5_unparse_name_fixed_short(context, principal, buf, sizeof(buf));
431233294Sstas    if (ret != 0)
432233294Sstas        return ret;
433233294Sstas    printf("%s\n", buf);
434233294Sstas    return 0;
435233294Sstas}
436233294Sstas
437233294Sstasstatic int
438233294Sstaslistit(const char *funcname, int argc, char **argv)
439233294Sstas{
440233294Sstas    int i;
441233294Sstas    krb5_error_code ret, saved_ret = 0;
442233294Sstas
443233294Sstas    for (i = 0; i < argc; i++) {
444233294Sstas	ret = foreach_principal(argv[i], do_list_entry, funcname, NULL);
445233294Sstas        if (saved_ret == 0 && ret != 0)
446233294Sstas            saved_ret = ret;
447233294Sstas    }
448233294Sstas    return saved_ret != 0;
449233294Sstas}
450233294Sstas
451178825Sdfr#define DEFAULT_COLUMNS_SHORT "principal,princ_expire_time,pw_expiration,last_pwd_change,max_life,max_rlife"
452178825Sdfr#define DEFAULT_COLUMNS_LONG "principal,princ_expire_time,pw_expiration,last_pwd_change,max_life,max_rlife,kvno,mkvno,last_success,last_failed,fail_auth_count,mod_time,mod_name,attributes,keytypes,pkinit-acl,aliases"
453178825Sdfr
454178825Sdfrstatic int
455178825Sdfrgetit(struct get_options *opt, const char *name, int argc, char **argv)
456178825Sdfr{
45755682Smarkm    int i;
45855682Smarkm    krb5_error_code ret;
45955682Smarkm    struct get_entry_data data;
460233294Sstas
461178825Sdfr    if(opt->long_flag == -1 && (opt->short_flag == 1 || opt->terse_flag == 1))
462178825Sdfr	opt->long_flag = 0;
463178825Sdfr    if(opt->short_flag == -1 && (opt->long_flag == 1 || opt->terse_flag == 1))
464178825Sdfr	opt->short_flag = 0;
465178825Sdfr    if(opt->terse_flag == -1 && (opt->long_flag == 1 || opt->short_flag == 1))
466178825Sdfr	opt->terse_flag = 0;
467178825Sdfr    if(opt->long_flag == 0 && opt->short_flag == 0 && opt->terse_flag == 0)
468178825Sdfr	opt->short_flag = 1;
46972445Sassar
470233294Sstas    if (opt->terse_flag)
471233294Sstas        return listit(name, argc, argv);
472233294Sstas
473178825Sdfr    data.table = NULL;
474178825Sdfr    data.chead = NULL;
475178825Sdfr    data.ctail = &data.chead;
476178825Sdfr    data.mask = 0;
477178825Sdfr    data.extra_mask = 0;
47855682Smarkm
479233294Sstas    if(opt->short_flag) {
480178825Sdfr	data.table = rtbl_create();
481178825Sdfr	rtbl_set_separator(data.table, "  ");
482178825Sdfr	data.format = print_entry_short;
483178825Sdfr    } else
48455682Smarkm	data.format = print_entry_long;
485178825Sdfr    if(opt->column_info_string == NULL) {
486178825Sdfr	if(opt->long_flag)
487178825Sdfr	    ret = setup_columns(&data, DEFAULT_COLUMNS_LONG);
488233294Sstas	else
489178825Sdfr	    ret = setup_columns(&data, DEFAULT_COLUMNS_SHORT);
490178825Sdfr    } else
491178825Sdfr	ret = setup_columns(&data, opt->column_info_string);
492233294Sstas
493178825Sdfr    if(ret != 0) {
494178825Sdfr	if(data.table != NULL)
495178825Sdfr	    rtbl_destroy(data.table);
496178825Sdfr	return 0;
49755682Smarkm    }
498233294Sstas
49955682Smarkm    for(i = 0; i < argc; i++)
500233294Sstas	ret = foreach_principal(argv[i], do_get_entry, name, &data);
501233294Sstas
502178825Sdfr    if(data.table != NULL) {
503178825Sdfr	rtbl_format(data.table, stdout);
504178825Sdfr	rtbl_destroy(data.table);
505178825Sdfr    }
506178825Sdfr    free_columns(&data);
507178825Sdfr    return ret != 0;
50855682Smarkm}
50955682Smarkm
51055682Smarkmint
511178825Sdfrget_entry(struct get_options *opt, int argc, char **argv)
51272445Sassar{
513178825Sdfr    return getit(opt, "get", argc, argv);
51472445Sassar}
51572445Sassar
51672445Sassarint
517178825Sdfrlist_princs(struct list_options *opt, int argc, char **argv)
51855682Smarkm{
519178825Sdfr    if(sizeof(struct get_options) != sizeof(struct list_options)) {
520178825Sdfr	krb5_warnx(context, "programmer error: sizeof(struct get_options) != sizeof(struct list_options)");
521178825Sdfr	return 0;
522178825Sdfr    }
523178825Sdfr    return getit((struct get_options*)opt, "list", argc, argv);
52455682Smarkm}
525