xref: /freebsd/crypto/heimdal/admin/purge.c (revision 4137ff4cc173ea2e05227027e1c9e0ea42bcc0dc)
1b528cefcSMark Murray /*
2adb0ddaeSAssar Westerlund  * Copyright (c) 1997 - 2001 Kungliga Tekniska H�gskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "ktutil_locl.h"
35b528cefcSMark Murray 
364137ff4cSJacques Vidrine RCSID("$Id: purge.c,v 1.6 2001/07/23 09:46:41 joda Exp $");
37b528cefcSMark Murray 
38b528cefcSMark Murray /*
39b528cefcSMark Murray  * keep track of the highest version for every principal.
40b528cefcSMark Murray  */
41b528cefcSMark Murray 
42b528cefcSMark Murray struct e {
43b528cefcSMark Murray     krb5_principal principal;
44b528cefcSMark Murray     int max_vno;
45b528cefcSMark Murray     struct e *next;
46b528cefcSMark Murray };
47b528cefcSMark Murray 
48b528cefcSMark Murray static struct e *
49b528cefcSMark Murray get_entry (krb5_principal princ, struct e *head)
50b528cefcSMark Murray {
51b528cefcSMark Murray     struct e *e;
52b528cefcSMark Murray 
53b528cefcSMark Murray     for (e = head; e != NULL; e = e->next)
54b528cefcSMark Murray 	if (krb5_principal_compare (context, princ, e->principal))
55b528cefcSMark Murray 	    return e;
56b528cefcSMark Murray     return NULL;
57b528cefcSMark Murray }
58b528cefcSMark Murray 
59b528cefcSMark Murray static void
60b528cefcSMark Murray add_entry (krb5_principal princ, int vno, struct e **head)
61b528cefcSMark Murray {
62b528cefcSMark Murray     krb5_error_code ret;
63b528cefcSMark Murray     struct e *e;
64b528cefcSMark Murray 
65b528cefcSMark Murray     e = get_entry (princ, *head);
66b528cefcSMark Murray     if (e != NULL) {
67b528cefcSMark Murray 	e->max_vno = max (e->max_vno, vno);
68b528cefcSMark Murray 	return;
69b528cefcSMark Murray     }
70b528cefcSMark Murray     e = malloc (sizeof (*e));
71b528cefcSMark Murray     if (e == NULL)
72b528cefcSMark Murray 	krb5_errx (context, 1, "malloc: out of memory");
73b528cefcSMark Murray     ret = krb5_copy_principal (context, princ, &e->principal);
74b528cefcSMark Murray     if (ret)
75b528cefcSMark Murray 	krb5_err (context, 1, ret, "krb5_copy_principal");
76b528cefcSMark Murray     e->max_vno = vno;
77b528cefcSMark Murray     e->next    = *head;
78b528cefcSMark Murray     *head      = e;
79b528cefcSMark Murray }
80b528cefcSMark Murray 
81b528cefcSMark Murray static void
82b528cefcSMark Murray delete_list (struct e *head)
83b528cefcSMark Murray {
84b528cefcSMark Murray     while (head != NULL) {
85b528cefcSMark Murray 	struct e *next = head->next;
86b528cefcSMark Murray 	krb5_free_principal (context, head->principal);
87b528cefcSMark Murray 	free (head);
88b528cefcSMark Murray 	head = next;
89b528cefcSMark Murray     }
90b528cefcSMark Murray }
91b528cefcSMark Murray 
92b528cefcSMark Murray /*
93b528cefcSMark Murray  * Remove all entries that have newer versions and that are older
94b528cefcSMark Murray  * than `age'
95b528cefcSMark Murray  */
96b528cefcSMark Murray 
97b528cefcSMark Murray int
98b528cefcSMark Murray kt_purge(int argc, char **argv)
99b528cefcSMark Murray {
100adb0ddaeSAssar Westerlund     krb5_error_code ret = 0;
101b528cefcSMark Murray     krb5_kt_cursor cursor;
102adb0ddaeSAssar Westerlund     krb5_keytab keytab;
103b528cefcSMark Murray     krb5_keytab_entry entry;
104b528cefcSMark Murray     int help_flag = 0;
1055e9cd1aeSAssar Westerlund     char *age_str = "1 week";
1065e9cd1aeSAssar Westerlund     int age;
107b528cefcSMark Murray     struct getargs args[] = {
1085e9cd1aeSAssar Westerlund 	{ "age",   0,  arg_string, NULL, "age to retire" },
109b528cefcSMark Murray 	{ "help", 'h', arg_flag, NULL }
110b528cefcSMark Murray     };
111b528cefcSMark Murray     int num_args = sizeof(args) / sizeof(args[0]);
112b528cefcSMark Murray     int optind = 0;
113b528cefcSMark Murray     int i = 0;
114b528cefcSMark Murray     struct e *head = NULL;
115b528cefcSMark Murray     time_t judgement_day;
116b528cefcSMark Murray 
1175e9cd1aeSAssar Westerlund     args[i++].value = &age_str;
118b528cefcSMark Murray     args[i++].value = &help_flag;
119b528cefcSMark Murray 
120b528cefcSMark Murray     if(getarg(args, num_args, argc, argv, &optind)) {
121adb0ddaeSAssar Westerlund 	arg_printusage(args, num_args, "ktutil purge", "");
122adb0ddaeSAssar Westerlund 	return 1;
123b528cefcSMark Murray     }
124b528cefcSMark Murray     if(help_flag) {
125adb0ddaeSAssar Westerlund 	arg_printusage(args, num_args, "ktutil purge", "");
126adb0ddaeSAssar Westerlund 	return 1;
127b528cefcSMark Murray     }
128b528cefcSMark Murray 
1295e9cd1aeSAssar Westerlund     age = parse_time(age_str, "s");
1305e9cd1aeSAssar Westerlund     if(age < 0) {
1315e9cd1aeSAssar Westerlund 	krb5_warnx(context, "unparasable time `%s'", age_str);
132adb0ddaeSAssar Westerlund 	return 1;
133adb0ddaeSAssar Westerlund     }
134adb0ddaeSAssar Westerlund 
1354137ff4cSJacques Vidrine     if((keytab = ktutil_open_keytab()) == NULL)
136adb0ddaeSAssar Westerlund 	return 1;
1375e9cd1aeSAssar Westerlund 
138b528cefcSMark Murray     ret = krb5_kt_start_seq_get(context, keytab, &cursor);
139b528cefcSMark Murray     if(ret){
1405e9cd1aeSAssar Westerlund 	krb5_warn(context, ret, "krb5_kt_start_seq_get %s", keytab_string);
141adb0ddaeSAssar Westerlund 	goto out;
142b528cefcSMark Murray     }
143b528cefcSMark Murray 
144b528cefcSMark Murray     while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
145b528cefcSMark Murray 	add_entry (entry.principal, entry.vno, &head);
146b528cefcSMark Murray 	krb5_kt_free_entry(context, &entry);
147b528cefcSMark Murray     }
148b528cefcSMark Murray     ret = krb5_kt_end_seq_get(context, keytab, &cursor);
149b528cefcSMark Murray 
150b528cefcSMark Murray     judgement_day = time (NULL);
151b528cefcSMark Murray 
152b528cefcSMark Murray     ret = krb5_kt_start_seq_get(context, keytab, &cursor);
153b528cefcSMark Murray     if(ret){
1545e9cd1aeSAssar Westerlund 	krb5_warn(context, ret, "krb5_kt_start_seq_get, %s", keytab_string);
155adb0ddaeSAssar Westerlund 	goto out;
156b528cefcSMark Murray     }
157b528cefcSMark Murray 
158b528cefcSMark Murray     while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
159b528cefcSMark Murray 	struct e *e = get_entry (entry.principal, head);
160b528cefcSMark Murray 
161b528cefcSMark Murray 	if (e == NULL) {
162b528cefcSMark Murray 	    krb5_warnx (context, "ignoring extra entry");
163b528cefcSMark Murray 	    continue;
164b528cefcSMark Murray 	}
165b528cefcSMark Murray 
166b528cefcSMark Murray 	if (entry.vno < e->max_vno
167b528cefcSMark Murray 	    && judgement_day - entry.timestamp > age) {
168b528cefcSMark Murray 	    if (verbose_flag) {
169b528cefcSMark Murray 		char *name_str;
170b528cefcSMark Murray 
171b528cefcSMark Murray 		krb5_unparse_name (context, entry.principal, &name_str);
172b528cefcSMark Murray 		printf ("removing %s vno %d\n", name_str, entry.vno);
173b528cefcSMark Murray 		free (name_str);
174b528cefcSMark Murray 	    }
175b528cefcSMark Murray 	    ret = krb5_kt_remove_entry (context, keytab, &entry);
176b528cefcSMark Murray 	    if (ret)
177b528cefcSMark Murray 		krb5_warn (context, ret, "remove");
178b528cefcSMark Murray 	}
179b528cefcSMark Murray 	krb5_kt_free_entry(context, &entry);
180b528cefcSMark Murray     }
181b528cefcSMark Murray     ret = krb5_kt_end_seq_get(context, keytab, &cursor);
182b528cefcSMark Murray 
183b528cefcSMark Murray     delete_list (head);
184b528cefcSMark Murray 
185adb0ddaeSAssar Westerlund  out:
186adb0ddaeSAssar Westerlund     krb5_kt_close (context, keytab);
187adb0ddaeSAssar Westerlund     return ret != 0;
188b528cefcSMark Murray }
189