xref: /freebsd/crypto/heimdal/lib/kadm5/iprop-log.c (revision 5040a7a9)
1c19800e8SDoug Rabson /*
2ae771770SStanislav Sedov  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson  *    without specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson  * SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34c19800e8SDoug Rabson #include "iprop.h"
35c19800e8SDoug Rabson #include <sl.h>
36c19800e8SDoug Rabson #include <parse_time.h>
37c19800e8SDoug Rabson #include "iprop-commands.h"
38c19800e8SDoug Rabson 
39ae771770SStanislav Sedov RCSID("$Id$");
40c19800e8SDoug Rabson 
41c19800e8SDoug Rabson static krb5_context context;
42c19800e8SDoug Rabson 
43c19800e8SDoug Rabson static kadm5_server_context *
get_kadmin_context(const char * config_file,char * realm)44c19800e8SDoug Rabson get_kadmin_context(const char *config_file, char *realm)
45c19800e8SDoug Rabson {
46c19800e8SDoug Rabson     kadm5_config_params conf;
47c19800e8SDoug Rabson     krb5_error_code ret;
48c19800e8SDoug Rabson     void *kadm_handle;
49c19800e8SDoug Rabson     char **files;
50c19800e8SDoug Rabson 
51c19800e8SDoug Rabson     if (config_file == NULL) {
52c19800e8SDoug Rabson 	char *file;
53c19800e8SDoug Rabson 	asprintf(&file, "%s/kdc.conf", hdb_db_dir(context));
54c19800e8SDoug Rabson 	if (file == NULL)
55c19800e8SDoug Rabson 	    errx(1, "out of memory");
56c19800e8SDoug Rabson 	config_file = file;
57c19800e8SDoug Rabson     }
58c19800e8SDoug Rabson 
59c19800e8SDoug Rabson     ret = krb5_prepend_config_files_default(config_file, &files);
60c19800e8SDoug Rabson     if (ret)
61c19800e8SDoug Rabson 	krb5_err(context, 1, ret, "getting configuration files");
62c19800e8SDoug Rabson 
63c19800e8SDoug Rabson     ret = krb5_set_config_files(context, files);
64c19800e8SDoug Rabson     krb5_free_config_files(files);
65c19800e8SDoug Rabson     if (ret)
66c19800e8SDoug Rabson 	krb5_err(context, 1, ret, "reading configuration files");
67c19800e8SDoug Rabson 
68c19800e8SDoug Rabson     memset(&conf, 0, sizeof(conf));
69c19800e8SDoug Rabson     if(realm) {
70c19800e8SDoug Rabson 	conf.mask |= KADM5_CONFIG_REALM;
71c19800e8SDoug Rabson 	conf.realm = realm;
72c19800e8SDoug Rabson     }
73c19800e8SDoug Rabson 
74c19800e8SDoug Rabson     ret = kadm5_init_with_password_ctx (context,
75c19800e8SDoug Rabson 					KADM5_ADMIN_SERVICE,
76c19800e8SDoug Rabson 					NULL,
77c19800e8SDoug Rabson 					KADM5_ADMIN_SERVICE,
78c19800e8SDoug Rabson 					&conf, 0, 0,
79c19800e8SDoug Rabson 					&kadm_handle);
80c19800e8SDoug Rabson     if (ret)
81c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
82c19800e8SDoug Rabson 
83c19800e8SDoug Rabson     return (kadm5_server_context *)kadm_handle;
84c19800e8SDoug Rabson }
85c19800e8SDoug Rabson 
86c19800e8SDoug Rabson /*
87c19800e8SDoug Rabson  * dump log
88c19800e8SDoug Rabson  */
89c19800e8SDoug Rabson 
90c19800e8SDoug Rabson static const char *op_names[] = {
91c19800e8SDoug Rabson     "get",
92c19800e8SDoug Rabson     "delete",
93c19800e8SDoug Rabson     "create",
94c19800e8SDoug Rabson     "rename",
95c19800e8SDoug Rabson     "chpass",
96c19800e8SDoug Rabson     "modify",
97c19800e8SDoug Rabson     "randkey",
98c19800e8SDoug Rabson     "get_privs",
99c19800e8SDoug Rabson     "get_princs",
100c19800e8SDoug Rabson     "chpass_with_key",
101c19800e8SDoug Rabson     "nop"
102c19800e8SDoug Rabson };
103c19800e8SDoug Rabson 
104c19800e8SDoug Rabson static void
print_entry(kadm5_server_context * server_context,uint32_t ver,time_t timestamp,enum kadm_ops op,uint32_t len,krb5_storage * sp,void * ctx)105c19800e8SDoug Rabson print_entry(kadm5_server_context *server_context,
106c19800e8SDoug Rabson 	    uint32_t ver,
107c19800e8SDoug Rabson 	    time_t timestamp,
108c19800e8SDoug Rabson 	    enum kadm_ops op,
109c19800e8SDoug Rabson 	    uint32_t len,
110c19800e8SDoug Rabson 	    krb5_storage *sp,
111c19800e8SDoug Rabson 	    void *ctx)
112c19800e8SDoug Rabson {
113c19800e8SDoug Rabson     char t[256];
114c19800e8SDoug Rabson     int32_t mask;
115c19800e8SDoug Rabson     hdb_entry ent;
116c19800e8SDoug Rabson     krb5_principal source;
117c19800e8SDoug Rabson     char *name1, *name2;
118c19800e8SDoug Rabson     krb5_data data;
119c19800e8SDoug Rabson     krb5_context scontext = server_context->context;
120c19800e8SDoug Rabson 
121c19800e8SDoug Rabson     off_t end = krb5_storage_seek(sp, 0, SEEK_CUR) + len;
122c19800e8SDoug Rabson 
123c19800e8SDoug Rabson     krb5_error_code ret;
124c19800e8SDoug Rabson 
125c19800e8SDoug Rabson     strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
126c19800e8SDoug Rabson 
127ae771770SStanislav Sedov     if((int)op < (int)kadm_get || (int)op > (int)kadm_nop) {
128c19800e8SDoug Rabson 	printf("unknown op: %d\n", op);
129c19800e8SDoug Rabson 	krb5_storage_seek(sp, end, SEEK_SET);
130c19800e8SDoug Rabson 	return;
131c19800e8SDoug Rabson     }
132c19800e8SDoug Rabson 
133c19800e8SDoug Rabson     printf ("%s: ver = %u, timestamp = %s, len = %u\n",
134c19800e8SDoug Rabson 	    op_names[op], ver, t, len);
135c19800e8SDoug Rabson     switch(op) {
136c19800e8SDoug Rabson     case kadm_delete:
1375040a7a9SCy Schubert 	ret = krb5_unparse_name(scontext, source, &name1);
1385040a7a9SCy Schubert 	if (ret == 0)
1395040a7a9SCy Schubert 	    ret = krb5_ret_principal(sp, &source);
1405040a7a9SCy Schubert 	if (ret)
1415040a7a9SCy Schubert 	    krb5_err(scontext, 1, ret, "Failed to read a delete record");
142c19800e8SDoug Rabson 	printf("    %s\n", name1);
143c19800e8SDoug Rabson 	free(name1);
144c19800e8SDoug Rabson 	krb5_free_principal(scontext, source);
145c19800e8SDoug Rabson 	break;
146c19800e8SDoug Rabson     case kadm_rename:
147c19800e8SDoug Rabson 	ret = krb5_data_alloc(&data, len);
1485040a7a9SCy Schubert 	if (ret == 0)
1495040a7a9SCy Schubert 	    krb5_ret_principal(sp, &source);
1505040a7a9SCy Schubert 	if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
1515040a7a9SCy Schubert 	    ret = errno;
1525040a7a9SCy Schubert 	if (ret == 0)
1535040a7a9SCy Schubert 	    ret = hdb_value2entry(scontext, &data, &ent);
1545040a7a9SCy Schubert 	if (ret == 0)
1555040a7a9SCy Schubert 	    ret = krb5_unparse_name(scontext, source, &name1);
1565040a7a9SCy Schubert 	if (ret == 0)
1575040a7a9SCy Schubert 	    ret = krb5_unparse_name(scontext, ent.principal, &name2);
158c19800e8SDoug Rabson 	if (ret)
159c19800e8SDoug Rabson 	    krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len);
160c19800e8SDoug Rabson 	printf("    %s -> %s\n", name1, name2);
161c19800e8SDoug Rabson 	free(name1);
162c19800e8SDoug Rabson 	free(name2);
163c19800e8SDoug Rabson 	krb5_free_principal(scontext, source);
164c19800e8SDoug Rabson 	free_hdb_entry(&ent);
165c19800e8SDoug Rabson 	break;
166c19800e8SDoug Rabson     case kadm_create:
167c19800e8SDoug Rabson 	ret = krb5_data_alloc(&data, len);
1685040a7a9SCy Schubert 	if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
1695040a7a9SCy Schubert 	    ret = errno;
1705040a7a9SCy Schubert 	if (ret == 0)
171c19800e8SDoug Rabson 	    ret = hdb_value2entry(scontext, &data, &ent);
172c19800e8SDoug Rabson 	if (ret)
1735040a7a9SCy Schubert 	    krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len);
174c19800e8SDoug Rabson 	mask = ~0;
175c19800e8SDoug Rabson 	goto foo;
176c19800e8SDoug Rabson     case kadm_modify:
177c19800e8SDoug Rabson 	ret = krb5_data_alloc(&data, len);
1785040a7a9SCy Schubert 	if (ret == 0)
1795040a7a9SCy Schubert 	    ret = krb5_ret_int32(sp, &mask);
1805040a7a9SCy Schubert 	if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
1815040a7a9SCy Schubert 	    ret = errno;
1825040a7a9SCy Schubert 	if (ret == 0)
183c19800e8SDoug Rabson 	    ret = hdb_value2entry(scontext, &data, &ent);
184c19800e8SDoug Rabson 	if (ret)
1855040a7a9SCy Schubert 	    krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);
186c19800e8SDoug Rabson     foo:
187c19800e8SDoug Rabson 	if(ent.principal /* mask & KADM5_PRINCIPAL */) {
1885040a7a9SCy Schubert 	    ret = krb5_unparse_name(scontext, ent.principal, &name1);
1895040a7a9SCy Schubert 	    if (ret)
1905040a7a9SCy Schubert 		krb5_err(scontext, 1, ret,
1915040a7a9SCy Schubert 			 "Failed to process a create or modify record");
192c19800e8SDoug Rabson 	    printf("    principal = %s\n", name1);
193c19800e8SDoug Rabson 	    free(name1);
194c19800e8SDoug Rabson 	}
195c19800e8SDoug Rabson 	if(mask & KADM5_PRINC_EXPIRE_TIME) {
196c19800e8SDoug Rabson 	    if(ent.valid_end == NULL) {
197c19800e8SDoug Rabson 		strlcpy(t, "never", sizeof(t));
198c19800e8SDoug Rabson 	    } else {
199c19800e8SDoug Rabson 		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
200c19800e8SDoug Rabson 			 localtime(ent.valid_end));
201c19800e8SDoug Rabson 	    }
202c19800e8SDoug Rabson 	    printf("    expires = %s\n", t);
203c19800e8SDoug Rabson 	}
204c19800e8SDoug Rabson 	if(mask & KADM5_PW_EXPIRATION) {
205c19800e8SDoug Rabson 	    if(ent.pw_end == NULL) {
206c19800e8SDoug Rabson 		strlcpy(t, "never", sizeof(t));
207c19800e8SDoug Rabson 	    } else {
208c19800e8SDoug Rabson 		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
209c19800e8SDoug Rabson 			 localtime(ent.pw_end));
210c19800e8SDoug Rabson 	    }
211c19800e8SDoug Rabson 	    printf("    password exp = %s\n", t);
212c19800e8SDoug Rabson 	}
213c19800e8SDoug Rabson 	if(mask & KADM5_LAST_PWD_CHANGE) {
214c19800e8SDoug Rabson 	}
215c19800e8SDoug Rabson 	if(mask & KADM5_ATTRIBUTES) {
216c19800e8SDoug Rabson 	    unparse_flags(HDBFlags2int(ent.flags),
217c19800e8SDoug Rabson 			  asn1_HDBFlags_units(), t, sizeof(t));
218c19800e8SDoug Rabson 	    printf("    attributes = %s\n", t);
219c19800e8SDoug Rabson 	}
220c19800e8SDoug Rabson 	if(mask & KADM5_MAX_LIFE) {
221c19800e8SDoug Rabson 	    if(ent.max_life == NULL)
222c19800e8SDoug Rabson 		strlcpy(t, "for ever", sizeof(t));
223c19800e8SDoug Rabson 	    else
224c19800e8SDoug Rabson 		unparse_time(*ent.max_life, t, sizeof(t));
225c19800e8SDoug Rabson 	    printf("    max life = %s\n", t);
226c19800e8SDoug Rabson 	}
227c19800e8SDoug Rabson 	if(mask & KADM5_MAX_RLIFE) {
228c19800e8SDoug Rabson 	    if(ent.max_renew == NULL)
229c19800e8SDoug Rabson 		strlcpy(t, "for ever", sizeof(t));
230c19800e8SDoug Rabson 	    else
231c19800e8SDoug Rabson 		unparse_time(*ent.max_renew, t, sizeof(t));
232c19800e8SDoug Rabson 	    printf("    max rlife = %s\n", t);
233c19800e8SDoug Rabson 	}
234c19800e8SDoug Rabson 	if(mask & KADM5_MOD_TIME) {
235c19800e8SDoug Rabson 	    printf("    mod time\n");
236c19800e8SDoug Rabson 	}
237c19800e8SDoug Rabson 	if(mask & KADM5_MOD_NAME) {
238c19800e8SDoug Rabson 	    printf("    mod name\n");
239c19800e8SDoug Rabson 	}
240c19800e8SDoug Rabson 	if(mask & KADM5_KVNO) {
241c19800e8SDoug Rabson 	    printf("    kvno = %d\n", ent.kvno);
242c19800e8SDoug Rabson 	}
243c19800e8SDoug Rabson 	if(mask & KADM5_MKVNO) {
244c19800e8SDoug Rabson 	    printf("    mkvno\n");
245c19800e8SDoug Rabson 	}
246c19800e8SDoug Rabson 	if(mask & KADM5_AUX_ATTRIBUTES) {
247c19800e8SDoug Rabson 	    printf("    aux attributes\n");
248c19800e8SDoug Rabson 	}
249c19800e8SDoug Rabson 	if(mask & KADM5_POLICY) {
250c19800e8SDoug Rabson 	    printf("    policy\n");
251c19800e8SDoug Rabson 	}
252c19800e8SDoug Rabson 	if(mask & KADM5_POLICY_CLR) {
253c19800e8SDoug Rabson 	    printf("    mod time\n");
254c19800e8SDoug Rabson 	}
255c19800e8SDoug Rabson 	if(mask & KADM5_LAST_SUCCESS) {
256c19800e8SDoug Rabson 	    printf("    last success\n");
257c19800e8SDoug Rabson 	}
258c19800e8SDoug Rabson 	if(mask & KADM5_LAST_FAILED) {
259c19800e8SDoug Rabson 	    printf("    last failed\n");
260c19800e8SDoug Rabson 	}
261c19800e8SDoug Rabson 	if(mask & KADM5_FAIL_AUTH_COUNT) {
262c19800e8SDoug Rabson 	    printf("    fail auth count\n");
263c19800e8SDoug Rabson 	}
264c19800e8SDoug Rabson 	if(mask & KADM5_KEY_DATA) {
265c19800e8SDoug Rabson 	    printf("    key data\n");
266c19800e8SDoug Rabson 	}
267c19800e8SDoug Rabson 	if(mask & KADM5_TL_DATA) {
268c19800e8SDoug Rabson 	    printf("    tl data\n");
269c19800e8SDoug Rabson 	}
270c19800e8SDoug Rabson 	free_hdb_entry(&ent);
271c19800e8SDoug Rabson 	break;
272c19800e8SDoug Rabson     case kadm_nop :
273c19800e8SDoug Rabson 	break;
274c19800e8SDoug Rabson     default:
2755040a7a9SCy Schubert 	krb5_errx(scontext, 1, "Unknown record type");
276c19800e8SDoug Rabson     }
277c19800e8SDoug Rabson     krb5_storage_seek(sp, end, SEEK_SET);
278c19800e8SDoug Rabson }
279c19800e8SDoug Rabson 
280c19800e8SDoug Rabson int
iprop_dump(struct dump_options * opt,int argc,char ** argv)281c19800e8SDoug Rabson iprop_dump(struct dump_options *opt, int argc, char **argv)
282c19800e8SDoug Rabson {
283c19800e8SDoug Rabson     kadm5_server_context *server_context;
284c19800e8SDoug Rabson     krb5_error_code ret;
285c19800e8SDoug Rabson 
286c19800e8SDoug Rabson     server_context = get_kadmin_context(opt->config_file_string,
287c19800e8SDoug Rabson 					opt->realm_string);
288c19800e8SDoug Rabson 
289c19800e8SDoug Rabson     ret = kadm5_log_init (server_context);
290c19800e8SDoug Rabson     if (ret)
291c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_log_init");
292c19800e8SDoug Rabson 
293c19800e8SDoug Rabson     ret = kadm5_log_foreach (server_context, print_entry, NULL);
294c19800e8SDoug Rabson     if(ret)
295c19800e8SDoug Rabson 	krb5_warn(context, ret, "kadm5_log_foreach");
296c19800e8SDoug Rabson 
297c19800e8SDoug Rabson     ret = kadm5_log_end (server_context);
298c19800e8SDoug Rabson     if (ret)
299c19800e8SDoug Rabson 	krb5_warn(context, ret, "kadm5_log_end");
300c19800e8SDoug Rabson     return 0;
301c19800e8SDoug Rabson }
302c19800e8SDoug Rabson 
303c19800e8SDoug Rabson int
iprop_truncate(struct truncate_options * opt,int argc,char ** argv)304c19800e8SDoug Rabson iprop_truncate(struct truncate_options *opt, int argc, char **argv)
305c19800e8SDoug Rabson {
306c19800e8SDoug Rabson     kadm5_server_context *server_context;
307c19800e8SDoug Rabson     krb5_error_code ret;
308c19800e8SDoug Rabson 
309c19800e8SDoug Rabson     server_context = get_kadmin_context(opt->config_file_string,
310c19800e8SDoug Rabson 					opt->realm_string);
311c19800e8SDoug Rabson 
312c19800e8SDoug Rabson     ret = kadm5_log_truncate (server_context);
313c19800e8SDoug Rabson     if (ret)
314c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_log_truncate");
315c19800e8SDoug Rabson 
316c19800e8SDoug Rabson     return 0;
317c19800e8SDoug Rabson }
318c19800e8SDoug Rabson 
319c19800e8SDoug Rabson int
last_version(struct last_version_options * opt,int argc,char ** argv)320c19800e8SDoug Rabson last_version(struct last_version_options *opt, int argc, char **argv)
321c19800e8SDoug Rabson {
322c19800e8SDoug Rabson     kadm5_server_context *server_context;
323c19800e8SDoug Rabson     krb5_error_code ret;
324c19800e8SDoug Rabson     uint32_t version;
325c19800e8SDoug Rabson 
326c19800e8SDoug Rabson     server_context = get_kadmin_context(opt->config_file_string,
327c19800e8SDoug Rabson 					opt->realm_string);
328c19800e8SDoug Rabson 
329c19800e8SDoug Rabson     ret = kadm5_log_init (server_context);
330c19800e8SDoug Rabson     if (ret)
331c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_log_init");
332c19800e8SDoug Rabson 
333c19800e8SDoug Rabson     ret = kadm5_log_get_version (server_context, &version);
334c19800e8SDoug Rabson     if (ret)
335c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_log_get_version");
336c19800e8SDoug Rabson 
337c19800e8SDoug Rabson     ret = kadm5_log_end (server_context);
338c19800e8SDoug Rabson     if (ret)
339c19800e8SDoug Rabson 	krb5_warn(context, ret, "kadm5_log_end");
340c19800e8SDoug Rabson 
341c19800e8SDoug Rabson     printf("version: %lu\n", (unsigned long)version);
342c19800e8SDoug Rabson 
343c19800e8SDoug Rabson     return 0;
344c19800e8SDoug Rabson }
345c19800e8SDoug Rabson 
346c19800e8SDoug Rabson /*
347c19800e8SDoug Rabson  * Replay log
348c19800e8SDoug Rabson  */
349c19800e8SDoug Rabson 
350c19800e8SDoug Rabson int start_version = -1;
351c19800e8SDoug Rabson int end_version = -1;
352c19800e8SDoug Rabson 
353c19800e8SDoug Rabson static void
apply_entry(kadm5_server_context * server_context,uint32_t ver,time_t timestamp,enum kadm_ops op,uint32_t len,krb5_storage * sp,void * ctx)354c19800e8SDoug Rabson apply_entry(kadm5_server_context *server_context,
355c19800e8SDoug Rabson 	    uint32_t ver,
356c19800e8SDoug Rabson 	    time_t timestamp,
357c19800e8SDoug Rabson 	    enum kadm_ops op,
358c19800e8SDoug Rabson 	    uint32_t len,
359c19800e8SDoug Rabson 	    krb5_storage *sp,
360c19800e8SDoug Rabson 	    void *ctx)
361c19800e8SDoug Rabson {
362c19800e8SDoug Rabson     struct replay_options *opt = ctx;
363c19800e8SDoug Rabson     krb5_error_code ret;
364c19800e8SDoug Rabson 
365ae771770SStanislav Sedov     if((opt->start_version_integer != -1 && ver < (uint32_t)opt->start_version_integer) ||
366ae771770SStanislav Sedov        (opt->end_version_integer != -1 && ver > (uint32_t)opt->end_version_integer)) {
367c19800e8SDoug Rabson 	/* XXX skip this entry */
368c19800e8SDoug Rabson 	krb5_storage_seek(sp, len, SEEK_CUR);
369c19800e8SDoug Rabson 	return;
370c19800e8SDoug Rabson     }
371c19800e8SDoug Rabson     printf ("ver %u... ", ver);
372c19800e8SDoug Rabson     fflush (stdout);
373c19800e8SDoug Rabson 
374c19800e8SDoug Rabson     ret = kadm5_log_replay (server_context,
375c19800e8SDoug Rabson 			    op, ver, len, sp);
376c19800e8SDoug Rabson     if (ret)
377c19800e8SDoug Rabson 	krb5_warn (server_context->context, ret, "kadm5_log_replay");
378c19800e8SDoug Rabson 
379c19800e8SDoug Rabson     printf ("done\n");
380c19800e8SDoug Rabson }
381c19800e8SDoug Rabson 
382c19800e8SDoug Rabson int
iprop_replay(struct replay_options * opt,int argc,char ** argv)383c19800e8SDoug Rabson iprop_replay(struct replay_options *opt, int argc, char **argv)
384c19800e8SDoug Rabson {
385c19800e8SDoug Rabson     kadm5_server_context *server_context;
386c19800e8SDoug Rabson     krb5_error_code ret;
387c19800e8SDoug Rabson 
388c19800e8SDoug Rabson     server_context = get_kadmin_context(opt->config_file_string,
389c19800e8SDoug Rabson 					opt->realm_string);
390c19800e8SDoug Rabson 
391c19800e8SDoug Rabson     ret = server_context->db->hdb_open(context,
392c19800e8SDoug Rabson 				       server_context->db,
393c19800e8SDoug Rabson 				       O_RDWR | O_CREAT, 0600);
394c19800e8SDoug Rabson     if (ret)
395c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "db->open");
396c19800e8SDoug Rabson 
397c19800e8SDoug Rabson     ret = kadm5_log_init (server_context);
398c19800e8SDoug Rabson     if (ret)
399c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "kadm5_log_init");
400c19800e8SDoug Rabson 
401c19800e8SDoug Rabson     ret = kadm5_log_foreach (server_context, apply_entry, opt);
402c19800e8SDoug Rabson     if(ret)
403c19800e8SDoug Rabson 	krb5_warn(context, ret, "kadm5_log_foreach");
404c19800e8SDoug Rabson     ret = kadm5_log_end (server_context);
405c19800e8SDoug Rabson     if (ret)
406c19800e8SDoug Rabson 	krb5_warn(context, ret, "kadm5_log_end");
407c19800e8SDoug Rabson     ret = server_context->db->hdb_close (context, server_context->db);
408c19800e8SDoug Rabson     if (ret)
409c19800e8SDoug Rabson 	krb5_err (context, 1, ret, "db->close");
410c19800e8SDoug Rabson 
411c19800e8SDoug Rabson     return 0;
412c19800e8SDoug Rabson }
413c19800e8SDoug Rabson 
414c19800e8SDoug Rabson static int help_flag;
415c19800e8SDoug Rabson static int version_flag;
416c19800e8SDoug Rabson 
417c19800e8SDoug Rabson static struct getargs args[] = {
418c19800e8SDoug Rabson     { "version", 	0,	arg_flag, 	&version_flag,
419c19800e8SDoug Rabson       NULL,		NULL
420c19800e8SDoug Rabson     },
421c19800e8SDoug Rabson     { "help", 	'h', 	arg_flag, 	&help_flag,
422c19800e8SDoug Rabson       NULL, NULL
423c19800e8SDoug Rabson     }
424c19800e8SDoug Rabson };
425c19800e8SDoug Rabson 
426c19800e8SDoug Rabson static int num_args = sizeof(args) / sizeof(args[0]);
427c19800e8SDoug Rabson 
428c19800e8SDoug Rabson int
help(void * opt,int argc,char ** argv)429c19800e8SDoug Rabson help(void *opt, int argc, char **argv)
430c19800e8SDoug Rabson {
431c19800e8SDoug Rabson     if(argc == 0) {
432c19800e8SDoug Rabson 	sl_help(commands, 1, argv - 1 /* XXX */);
433c19800e8SDoug Rabson     } else {
434c19800e8SDoug Rabson 	SL_cmd *c = sl_match (commands, argv[0], 0);
435c19800e8SDoug Rabson  	if(c == NULL) {
436c19800e8SDoug Rabson 	    fprintf (stderr, "No such command: %s. "
437c19800e8SDoug Rabson 		     "Try \"help\" for a list of commands\n",
438c19800e8SDoug Rabson 		     argv[0]);
439c19800e8SDoug Rabson 	} else {
440c19800e8SDoug Rabson 	    if(c->func) {
441ae771770SStanislav Sedov 		static char shelp[] = "--help";
442ae771770SStanislav Sedov 		char *fake[3];
443c19800e8SDoug Rabson 		fake[0] = argv[0];
444ae771770SStanislav Sedov 		fake[1] = shelp;
445ae771770SStanislav Sedov 		fake[2] = NULL;
446c19800e8SDoug Rabson 		(*c->func)(2, fake);
447c19800e8SDoug Rabson 		fprintf(stderr, "\n");
448c19800e8SDoug Rabson 	    }
449c19800e8SDoug Rabson 	    if(c->help && *c->help)
450c19800e8SDoug Rabson 		fprintf (stderr, "%s\n", c->help);
451c19800e8SDoug Rabson 	    if((++c)->name && c->func == NULL) {
452c19800e8SDoug Rabson 		int f = 0;
453c19800e8SDoug Rabson 		fprintf (stderr, "Synonyms:");
454c19800e8SDoug Rabson 		while (c->name && c->func == NULL) {
455c19800e8SDoug Rabson 		    fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name);
456c19800e8SDoug Rabson 		    f = 1;
457c19800e8SDoug Rabson 		}
458c19800e8SDoug Rabson 		fprintf (stderr, "\n");
459c19800e8SDoug Rabson 	    }
460c19800e8SDoug Rabson 	}
461c19800e8SDoug Rabson     }
462c19800e8SDoug Rabson     return 0;
463c19800e8SDoug Rabson }
464c19800e8SDoug Rabson 
465c19800e8SDoug Rabson static void
usage(int status)466c19800e8SDoug Rabson usage(int status)
467c19800e8SDoug Rabson {
468c19800e8SDoug Rabson     arg_printusage(args, num_args, NULL, "command");
469c19800e8SDoug Rabson     exit(status);
470c19800e8SDoug Rabson }
471c19800e8SDoug Rabson 
472c19800e8SDoug Rabson int
main(int argc,char ** argv)473c19800e8SDoug Rabson main(int argc, char **argv)
474c19800e8SDoug Rabson {
475c19800e8SDoug Rabson     int optidx = 0;
476c19800e8SDoug Rabson     krb5_error_code ret;
477c19800e8SDoug Rabson 
478c19800e8SDoug Rabson     setprogname(argv[0]);
479c19800e8SDoug Rabson 
480c19800e8SDoug Rabson     if(getarg(args, num_args, argc, argv, &optidx))
481c19800e8SDoug Rabson 	usage(1);
482c19800e8SDoug Rabson     if(help_flag)
483c19800e8SDoug Rabson 	usage(0);
484c19800e8SDoug Rabson     if(version_flag) {
485c19800e8SDoug Rabson 	print_version(NULL);
486c19800e8SDoug Rabson 	exit(0);
487c19800e8SDoug Rabson     }
488c19800e8SDoug Rabson     argc -= optidx;
489c19800e8SDoug Rabson     argv += optidx;
490c19800e8SDoug Rabson     if(argc == 0)
491c19800e8SDoug Rabson 	usage(1);
492c19800e8SDoug Rabson 
493c19800e8SDoug Rabson     ret = krb5_init_context(&context);
494c19800e8SDoug Rabson     if (ret)
495c19800e8SDoug Rabson 	errx(1, "krb5_init_context failed with: %d\n", ret);
496c19800e8SDoug Rabson 
497c19800e8SDoug Rabson     ret = sl_command(commands, argc, argv);
498c19800e8SDoug Rabson     if(ret == -1)
499c19800e8SDoug Rabson 	warnx ("unrecognized command: %s", argv[0]);
500c19800e8SDoug Rabson     return ret;
501c19800e8SDoug Rabson }
502