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(×tamp));
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:
137*5040a7a9SCy Schubert ret = krb5_unparse_name(scontext, source, &name1);
138*5040a7a9SCy Schubert if (ret == 0)
139*5040a7a9SCy Schubert ret = krb5_ret_principal(sp, &source);
140*5040a7a9SCy Schubert if (ret)
141*5040a7a9SCy 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);
148*5040a7a9SCy Schubert if (ret == 0)
149*5040a7a9SCy Schubert krb5_ret_principal(sp, &source);
150*5040a7a9SCy Schubert if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
151*5040a7a9SCy Schubert ret = errno;
152*5040a7a9SCy Schubert if (ret == 0)
153*5040a7a9SCy Schubert ret = hdb_value2entry(scontext, &data, &ent);
154*5040a7a9SCy Schubert if (ret == 0)
155*5040a7a9SCy Schubert ret = krb5_unparse_name(scontext, source, &name1);
156*5040a7a9SCy Schubert if (ret == 0)
157*5040a7a9SCy 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);
168*5040a7a9SCy Schubert if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
169*5040a7a9SCy Schubert ret = errno;
170*5040a7a9SCy Schubert if (ret == 0)
171c19800e8SDoug Rabson ret = hdb_value2entry(scontext, &data, &ent);
172c19800e8SDoug Rabson if (ret)
173*5040a7a9SCy 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);
178*5040a7a9SCy Schubert if (ret == 0)
179*5040a7a9SCy Schubert ret = krb5_ret_int32(sp, &mask);
180*5040a7a9SCy Schubert if (ret == 0 && krb5_storage_read(sp, data.data, data.length))
181*5040a7a9SCy Schubert ret = errno;
182*5040a7a9SCy Schubert if (ret == 0)
183c19800e8SDoug Rabson ret = hdb_value2entry(scontext, &data, &ent);
184c19800e8SDoug Rabson if (ret)
185*5040a7a9SCy Schubert krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);
186c19800e8SDoug Rabson foo:
187c19800e8SDoug Rabson if(ent.principal /* mask & KADM5_PRINCIPAL */) {
188*5040a7a9SCy Schubert ret = krb5_unparse_name(scontext, ent.principal, &name1);
189*5040a7a9SCy Schubert if (ret)
190*5040a7a9SCy Schubert krb5_err(scontext, 1, ret,
191*5040a7a9SCy 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:
275*5040a7a9SCy 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