1*d3273b5bSchristos /* $NetBSD: iprop-log.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */
2ca1c9b0cSelric
3ca1c9b0cSelric /*
4ca1c9b0cSelric * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
5ca1c9b0cSelric * (Royal Institute of Technology, Stockholm, Sweden).
6ca1c9b0cSelric * All rights reserved.
7ca1c9b0cSelric *
8ca1c9b0cSelric * Redistribution and use in source and binary forms, with or without
9ca1c9b0cSelric * modification, are permitted provided that the following conditions
10ca1c9b0cSelric * are met:
11ca1c9b0cSelric *
12ca1c9b0cSelric * 1. Redistributions of source code must retain the above copyright
13ca1c9b0cSelric * notice, this list of conditions and the following disclaimer.
14ca1c9b0cSelric *
15ca1c9b0cSelric * 2. Redistributions in binary form must reproduce the above copyright
16ca1c9b0cSelric * notice, this list of conditions and the following disclaimer in the
17ca1c9b0cSelric * documentation and/or other materials provided with the distribution.
18ca1c9b0cSelric *
19ca1c9b0cSelric * 3. Neither the name of the Institute nor the names of its contributors
20ca1c9b0cSelric * may be used to endorse or promote products derived from this software
21ca1c9b0cSelric * without specific prior written permission.
22ca1c9b0cSelric *
23ca1c9b0cSelric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ca1c9b0cSelric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ca1c9b0cSelric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ca1c9b0cSelric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ca1c9b0cSelric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ca1c9b0cSelric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ca1c9b0cSelric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ca1c9b0cSelric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ca1c9b0cSelric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ca1c9b0cSelric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ca1c9b0cSelric * SUCH DAMAGE.
34ca1c9b0cSelric */
35ca1c9b0cSelric
36ca1c9b0cSelric #include "iprop.h"
37ca1c9b0cSelric #include <krb5/sl.h>
38ca1c9b0cSelric #include <krb5/parse_time.h>
39ca1c9b0cSelric #include "iprop-commands.h"
40ca1c9b0cSelric
41*d3273b5bSchristos __RCSID("$NetBSD: iprop-log.c,v 1.2 2017/01/28 21:31:49 christos Exp $");
42ca1c9b0cSelric
43ca1c9b0cSelric static krb5_context context;
44ca1c9b0cSelric
45ca1c9b0cSelric static kadm5_server_context *
get_kadmin_context(const char * config_file,char * realm)46ca1c9b0cSelric get_kadmin_context(const char *config_file, char *realm)
47ca1c9b0cSelric {
48ca1c9b0cSelric kadm5_config_params conf;
49ca1c9b0cSelric krb5_error_code ret;
50ca1c9b0cSelric void *kadm_handle;
51b9d004c6Schristos char *file = NULL;
52ca1c9b0cSelric char **files;
53b9d004c6Schristos int aret;
54ca1c9b0cSelric
55ca1c9b0cSelric if (config_file == NULL) {
56b9d004c6Schristos aret = asprintf(&file, "%s/kdc.conf", hdb_db_dir(context));
57b9d004c6Schristos if (aret == -1 || file == NULL)
58ca1c9b0cSelric errx(1, "out of memory");
59ca1c9b0cSelric config_file = file;
60ca1c9b0cSelric }
61ca1c9b0cSelric
62ca1c9b0cSelric ret = krb5_prepend_config_files_default(config_file, &files);
63b9d004c6Schristos free(file);
64ca1c9b0cSelric if (ret)
65ca1c9b0cSelric krb5_err(context, 1, ret, "getting configuration files");
66ca1c9b0cSelric
67ca1c9b0cSelric ret = krb5_set_config_files(context, files);
68ca1c9b0cSelric krb5_free_config_files(files);
69ca1c9b0cSelric if (ret)
70ca1c9b0cSelric krb5_err(context, 1, ret, "reading configuration files");
71ca1c9b0cSelric
72ca1c9b0cSelric memset(&conf, 0, sizeof(conf));
73ca1c9b0cSelric if(realm) {
74ca1c9b0cSelric conf.mask |= KADM5_CONFIG_REALM;
75ca1c9b0cSelric conf.realm = realm;
76ca1c9b0cSelric }
77ca1c9b0cSelric
78ca1c9b0cSelric ret = kadm5_init_with_password_ctx (context,
79ca1c9b0cSelric KADM5_ADMIN_SERVICE,
80ca1c9b0cSelric NULL,
81ca1c9b0cSelric KADM5_ADMIN_SERVICE,
82ca1c9b0cSelric &conf, 0, 0,
83ca1c9b0cSelric &kadm_handle);
84ca1c9b0cSelric if (ret)
85ca1c9b0cSelric krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
86ca1c9b0cSelric
87ca1c9b0cSelric return (kadm5_server_context *)kadm_handle;
88ca1c9b0cSelric }
89ca1c9b0cSelric
90ca1c9b0cSelric /*
91ca1c9b0cSelric * dump log
92ca1c9b0cSelric */
93ca1c9b0cSelric
94ca1c9b0cSelric static const char *op_names[] = {
95ca1c9b0cSelric "get",
96ca1c9b0cSelric "delete",
97ca1c9b0cSelric "create",
98ca1c9b0cSelric "rename",
99ca1c9b0cSelric "chpass",
100ca1c9b0cSelric "modify",
101ca1c9b0cSelric "randkey",
102ca1c9b0cSelric "get_privs",
103ca1c9b0cSelric "get_princs",
104ca1c9b0cSelric "chpass_with_key",
105ca1c9b0cSelric "nop"
106ca1c9b0cSelric };
107ca1c9b0cSelric
108b9d004c6Schristos static kadm5_ret_t
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)109ca1c9b0cSelric print_entry(kadm5_server_context *server_context,
110ca1c9b0cSelric uint32_t ver,
111ca1c9b0cSelric time_t timestamp,
112ca1c9b0cSelric enum kadm_ops op,
113ca1c9b0cSelric uint32_t len,
114ca1c9b0cSelric krb5_storage *sp,
115ca1c9b0cSelric void *ctx)
116ca1c9b0cSelric {
117ca1c9b0cSelric char t[256];
118b9d004c6Schristos const char *entry_kind = ctx;
119ca1c9b0cSelric int32_t mask;
120b9d004c6Schristos int32_t nop_time;
121b9d004c6Schristos uint32_t nop_ver;
122ca1c9b0cSelric hdb_entry ent;
123ca1c9b0cSelric krb5_principal source;
124ca1c9b0cSelric char *name1, *name2;
125ca1c9b0cSelric krb5_data data;
126ca1c9b0cSelric krb5_context scontext = server_context->context;
127ca1c9b0cSelric krb5_error_code ret;
128ca1c9b0cSelric
129b9d004c6Schristos krb5_data_zero(&data);
130b9d004c6Schristos
131ca1c9b0cSelric strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(×tamp));
132ca1c9b0cSelric
1334f77a458Spettai if((int)op < (int)kadm_get || (int)op > (int)kadm_nop) {
134ca1c9b0cSelric printf("unknown op: %d\n", op);
135b9d004c6Schristos return 0;
136ca1c9b0cSelric }
137ca1c9b0cSelric
138b9d004c6Schristos printf ("%s%s: ver = %u, timestamp = %s, len = %u\n",
139b9d004c6Schristos entry_kind, op_names[op], ver, t, len);
140ca1c9b0cSelric switch(op) {
141ca1c9b0cSelric case kadm_delete:
142ca1c9b0cSelric krb5_ret_principal(sp, &source);
143ca1c9b0cSelric krb5_unparse_name(scontext, source, &name1);
144ca1c9b0cSelric printf(" %s\n", name1);
145ca1c9b0cSelric free(name1);
146ca1c9b0cSelric krb5_free_principal(scontext, source);
147ca1c9b0cSelric break;
148ca1c9b0cSelric case kadm_rename:
149ca1c9b0cSelric ret = krb5_data_alloc(&data, len);
150ca1c9b0cSelric if (ret)
151ca1c9b0cSelric krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len);
152ca1c9b0cSelric krb5_ret_principal(sp, &source);
153ca1c9b0cSelric krb5_storage_read(sp, data.data, data.length);
154ca1c9b0cSelric hdb_value2entry(scontext, &data, &ent);
155ca1c9b0cSelric krb5_unparse_name(scontext, source, &name1);
156ca1c9b0cSelric krb5_unparse_name(scontext, ent.principal, &name2);
157ca1c9b0cSelric printf(" %s -> %s\n", name1, name2);
158ca1c9b0cSelric free(name1);
159ca1c9b0cSelric free(name2);
160ca1c9b0cSelric krb5_free_principal(scontext, source);
161ca1c9b0cSelric free_hdb_entry(&ent);
162ca1c9b0cSelric break;
163ca1c9b0cSelric case kadm_create:
164ca1c9b0cSelric ret = krb5_data_alloc(&data, len);
165ca1c9b0cSelric if (ret)
166ca1c9b0cSelric krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len);
167ca1c9b0cSelric krb5_storage_read(sp, data.data, data.length);
168ca1c9b0cSelric ret = hdb_value2entry(scontext, &data, &ent);
169ca1c9b0cSelric if(ret)
170ca1c9b0cSelric abort();
171ca1c9b0cSelric mask = ~0;
172ca1c9b0cSelric goto foo;
173ca1c9b0cSelric case kadm_modify:
174ca1c9b0cSelric ret = krb5_data_alloc(&data, len);
175ca1c9b0cSelric if (ret)
176ca1c9b0cSelric krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);
177ca1c9b0cSelric krb5_ret_int32(sp, &mask);
178ca1c9b0cSelric krb5_storage_read(sp, data.data, data.length);
179ca1c9b0cSelric ret = hdb_value2entry(scontext, &data, &ent);
180ca1c9b0cSelric if(ret)
181ca1c9b0cSelric abort();
182ca1c9b0cSelric foo:
183ca1c9b0cSelric if(ent.principal /* mask & KADM5_PRINCIPAL */) {
184ca1c9b0cSelric krb5_unparse_name(scontext, ent.principal, &name1);
185ca1c9b0cSelric printf(" principal = %s\n", name1);
186ca1c9b0cSelric free(name1);
187ca1c9b0cSelric }
188ca1c9b0cSelric if(mask & KADM5_PRINC_EXPIRE_TIME) {
189ca1c9b0cSelric if(ent.valid_end == NULL) {
190ca1c9b0cSelric strlcpy(t, "never", sizeof(t));
191ca1c9b0cSelric } else {
192ca1c9b0cSelric strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
193ca1c9b0cSelric localtime(ent.valid_end));
194ca1c9b0cSelric }
195ca1c9b0cSelric printf(" expires = %s\n", t);
196ca1c9b0cSelric }
197ca1c9b0cSelric if(mask & KADM5_PW_EXPIRATION) {
198ca1c9b0cSelric if(ent.pw_end == NULL) {
199ca1c9b0cSelric strlcpy(t, "never", sizeof(t));
200ca1c9b0cSelric } else {
201ca1c9b0cSelric strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
202ca1c9b0cSelric localtime(ent.pw_end));
203ca1c9b0cSelric }
204ca1c9b0cSelric printf(" password exp = %s\n", t);
205ca1c9b0cSelric }
206ca1c9b0cSelric if(mask & KADM5_LAST_PWD_CHANGE) {
207ca1c9b0cSelric }
208ca1c9b0cSelric if(mask & KADM5_ATTRIBUTES) {
209ca1c9b0cSelric unparse_flags(HDBFlags2int(ent.flags),
210ca1c9b0cSelric asn1_HDBFlags_units(), t, sizeof(t));
211ca1c9b0cSelric printf(" attributes = %s\n", t);
212ca1c9b0cSelric }
213ca1c9b0cSelric if(mask & KADM5_MAX_LIFE) {
214ca1c9b0cSelric if(ent.max_life == NULL)
215ca1c9b0cSelric strlcpy(t, "for ever", sizeof(t));
216ca1c9b0cSelric else
217ca1c9b0cSelric unparse_time(*ent.max_life, t, sizeof(t));
218ca1c9b0cSelric printf(" max life = %s\n", t);
219ca1c9b0cSelric }
220ca1c9b0cSelric if(mask & KADM5_MAX_RLIFE) {
221ca1c9b0cSelric if(ent.max_renew == NULL)
222ca1c9b0cSelric strlcpy(t, "for ever", sizeof(t));
223ca1c9b0cSelric else
224ca1c9b0cSelric unparse_time(*ent.max_renew, t, sizeof(t));
225ca1c9b0cSelric printf(" max rlife = %s\n", t);
226ca1c9b0cSelric }
227ca1c9b0cSelric if(mask & KADM5_MOD_TIME) {
228ca1c9b0cSelric printf(" mod time\n");
229ca1c9b0cSelric }
230ca1c9b0cSelric if(mask & KADM5_MOD_NAME) {
231ca1c9b0cSelric printf(" mod name\n");
232ca1c9b0cSelric }
233ca1c9b0cSelric if(mask & KADM5_KVNO) {
234ca1c9b0cSelric printf(" kvno = %d\n", ent.kvno);
235ca1c9b0cSelric }
236ca1c9b0cSelric if(mask & KADM5_MKVNO) {
237ca1c9b0cSelric printf(" mkvno\n");
238ca1c9b0cSelric }
239ca1c9b0cSelric if(mask & KADM5_AUX_ATTRIBUTES) {
240ca1c9b0cSelric printf(" aux attributes\n");
241ca1c9b0cSelric }
242ca1c9b0cSelric if(mask & KADM5_POLICY) {
243ca1c9b0cSelric printf(" policy\n");
244ca1c9b0cSelric }
245ca1c9b0cSelric if(mask & KADM5_POLICY_CLR) {
246ca1c9b0cSelric printf(" mod time\n");
247ca1c9b0cSelric }
248ca1c9b0cSelric if(mask & KADM5_LAST_SUCCESS) {
249ca1c9b0cSelric printf(" last success\n");
250ca1c9b0cSelric }
251ca1c9b0cSelric if(mask & KADM5_LAST_FAILED) {
252ca1c9b0cSelric printf(" last failed\n");
253ca1c9b0cSelric }
254ca1c9b0cSelric if(mask & KADM5_FAIL_AUTH_COUNT) {
255ca1c9b0cSelric printf(" fail auth count\n");
256ca1c9b0cSelric }
257ca1c9b0cSelric if(mask & KADM5_KEY_DATA) {
258ca1c9b0cSelric printf(" key data\n");
259ca1c9b0cSelric }
260ca1c9b0cSelric if(mask & KADM5_TL_DATA) {
261ca1c9b0cSelric printf(" tl data\n");
262ca1c9b0cSelric }
263ca1c9b0cSelric free_hdb_entry(&ent);
264ca1c9b0cSelric break;
265ca1c9b0cSelric case kadm_nop :
266b9d004c6Schristos if (len == 16) {
267b9d004c6Schristos uint64_t off;
268b9d004c6Schristos krb5_ret_uint64(sp, &off);
269b9d004c6Schristos printf("uberblock offset %llu ", (unsigned long long)off);
270b9d004c6Schristos } else {
271b9d004c6Schristos printf("nop");
272b9d004c6Schristos }
273b9d004c6Schristos if (len == 16 || len == 8) {
274b9d004c6Schristos krb5_ret_int32(sp, &nop_time);
275b9d004c6Schristos krb5_ret_uint32(sp, &nop_ver);
276b9d004c6Schristos
277b9d004c6Schristos timestamp = nop_time;
278b9d004c6Schristos strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(×tamp));
279b9d004c6Schristos printf("timestamp %s version %u", t, nop_ver);
280b9d004c6Schristos }
281b9d004c6Schristos printf("\n");
282ca1c9b0cSelric break;
283ca1c9b0cSelric default:
284ca1c9b0cSelric abort();
285ca1c9b0cSelric }
286b9d004c6Schristos krb5_data_free(&data);
287b9d004c6Schristos
288b9d004c6Schristos return 0;
289ca1c9b0cSelric }
290ca1c9b0cSelric
291ca1c9b0cSelric int
iprop_dump(struct dump_options * opt,int argc,char ** argv)292ca1c9b0cSelric iprop_dump(struct dump_options *opt, int argc, char **argv)
293ca1c9b0cSelric {
294ca1c9b0cSelric kadm5_server_context *server_context;
295ca1c9b0cSelric krb5_error_code ret;
296b9d004c6Schristos enum kadm_iter_opts iter_opts_1st = 0;
297b9d004c6Schristos enum kadm_iter_opts iter_opts_2nd = 0;
298b9d004c6Schristos char *desc_1st = "";
299b9d004c6Schristos char *desc_2nd = "";
300ca1c9b0cSelric
301ca1c9b0cSelric server_context = get_kadmin_context(opt->config_file_string,
302ca1c9b0cSelric opt->realm_string);
303ca1c9b0cSelric
304b9d004c6Schristos if (argc > 0) {
305b9d004c6Schristos free(server_context->log_context.log_file);
306b9d004c6Schristos server_context->log_context.log_file = strdup(argv[0]);
307b9d004c6Schristos if (server_context->log_context.log_file == NULL)
308b9d004c6Schristos krb5_err(context, 1, errno, "strdup");
309b9d004c6Schristos }
310ca1c9b0cSelric
311b9d004c6Schristos if (opt->reverse_flag) {
312b9d004c6Schristos iter_opts_1st = kadm_backward | kadm_unconfirmed;
313b9d004c6Schristos iter_opts_2nd = kadm_backward | kadm_confirmed;
314b9d004c6Schristos desc_1st = "unconfirmed ";
315b9d004c6Schristos } else {
316b9d004c6Schristos iter_opts_1st = kadm_forward | kadm_confirmed;
317b9d004c6Schristos iter_opts_2nd = kadm_forward | kadm_unconfirmed;
318b9d004c6Schristos desc_2nd = "unconfirmed";
319b9d004c6Schristos }
320b9d004c6Schristos
321b9d004c6Schristos if (opt->no_lock_flag) {
322b9d004c6Schristos ret = kadm5_log_init_sharedlock(server_context, LOCK_NB);
323b9d004c6Schristos if (ret == EAGAIN || ret == EWOULDBLOCK) {
324b9d004c6Schristos warnx("Not locking the iprop log");
325b9d004c6Schristos ret = kadm5_log_init_nolock(server_context);
326b9d004c6Schristos if (ret)
327b9d004c6Schristos krb5_err(context, 1, ret, "kadm5_log_init_nolock");
328b9d004c6Schristos }
329b9d004c6Schristos } else {
330b9d004c6Schristos warnx("If this command appears to block, try the --no-lock option");
331b9d004c6Schristos ret = kadm5_log_init_sharedlock(server_context, 0);
332b9d004c6Schristos if (ret)
333b9d004c6Schristos krb5_err(context, 1, ret, "kadm5_log_init_sharedlock");
334b9d004c6Schristos }
335b9d004c6Schristos
336b9d004c6Schristos ret = kadm5_log_foreach(server_context, iter_opts_1st,
337b9d004c6Schristos NULL, print_entry, desc_1st);
338b9d004c6Schristos if (ret)
339b9d004c6Schristos krb5_warn(context, ret, "kadm5_log_foreach");
340b9d004c6Schristos
341b9d004c6Schristos ret = kadm5_log_foreach(server_context, iter_opts_2nd,
342b9d004c6Schristos NULL, print_entry, desc_2nd);
343ca1c9b0cSelric if (ret)
344ca1c9b0cSelric krb5_warn(context, ret, "kadm5_log_foreach");
345ca1c9b0cSelric
346ca1c9b0cSelric ret = kadm5_log_end (server_context);
347ca1c9b0cSelric if (ret)
348ca1c9b0cSelric krb5_warn(context, ret, "kadm5_log_end");
349b9d004c6Schristos
350b9d004c6Schristos kadm5_destroy(server_context);
351ca1c9b0cSelric return 0;
352ca1c9b0cSelric }
353ca1c9b0cSelric
354ca1c9b0cSelric int
iprop_truncate(struct truncate_options * opt,int argc,char ** argv)355ca1c9b0cSelric iprop_truncate(struct truncate_options *opt, int argc, char **argv)
356ca1c9b0cSelric {
357ca1c9b0cSelric kadm5_server_context *server_context;
358ca1c9b0cSelric krb5_error_code ret;
359ca1c9b0cSelric
360ca1c9b0cSelric server_context = get_kadmin_context(opt->config_file_string,
361ca1c9b0cSelric opt->realm_string);
362ca1c9b0cSelric
363b9d004c6Schristos if (argc > 0) {
364b9d004c6Schristos free(server_context->log_context.log_file);
365b9d004c6Schristos server_context->log_context.log_file = strdup(argv[0]);
366b9d004c6Schristos if (server_context->log_context.log_file == NULL)
367b9d004c6Schristos krb5_err(context, 1, errno, "strdup");
368b9d004c6Schristos }
369b9d004c6Schristos
370b9d004c6Schristos if (opt->keep_entries_integer < 0 &&
371b9d004c6Schristos opt->max_bytes_integer < 0) {
372b9d004c6Schristos opt->keep_entries_integer = 100;
373b9d004c6Schristos opt->max_bytes_integer = 0;
374b9d004c6Schristos }
375b9d004c6Schristos if (opt->keep_entries_integer < 0)
376b9d004c6Schristos opt->keep_entries_integer = 0;
377b9d004c6Schristos if (opt->max_bytes_integer < 0)
378b9d004c6Schristos opt->max_bytes_integer = 0;
379b9d004c6Schristos
380b9d004c6Schristos if (opt->reset_flag) {
381b9d004c6Schristos /* First recover unconfirmed records */
382b9d004c6Schristos ret = kadm5_log_init(server_context);
383b9d004c6Schristos if (ret == 0)
384b9d004c6Schristos ret = kadm5_log_reinit(server_context, 0);
385b9d004c6Schristos } else {
386b9d004c6Schristos ret = kadm5_log_init(server_context);
387b9d004c6Schristos if (ret)
388b9d004c6Schristos krb5_err(context, 1, ret, "kadm5_log_init");
389b9d004c6Schristos ret = kadm5_log_truncate(server_context, opt->keep_entries_integer,
390b9d004c6Schristos opt->max_bytes_integer);
391b9d004c6Schristos }
392ca1c9b0cSelric if (ret)
393ca1c9b0cSelric krb5_err(context, 1, ret, "kadm5_log_truncate");
394ca1c9b0cSelric
395b9d004c6Schristos kadm5_log_signal_master(server_context);
396b9d004c6Schristos
397b9d004c6Schristos kadm5_destroy(server_context);
398ca1c9b0cSelric return 0;
399ca1c9b0cSelric }
400ca1c9b0cSelric
401ca1c9b0cSelric int
last_version(struct last_version_options * opt,int argc,char ** argv)402ca1c9b0cSelric last_version(struct last_version_options *opt, int argc, char **argv)
403ca1c9b0cSelric {
404ca1c9b0cSelric kadm5_server_context *server_context;
405b9d004c6Schristos char *alt_argv[2] = { NULL, NULL };
406ca1c9b0cSelric krb5_error_code ret;
407ca1c9b0cSelric uint32_t version;
408b9d004c6Schristos size_t i;
409ca1c9b0cSelric
410ca1c9b0cSelric server_context = get_kadmin_context(opt->config_file_string,
411ca1c9b0cSelric opt->realm_string);
412ca1c9b0cSelric
413b9d004c6Schristos if (argc == 0) {
414b9d004c6Schristos alt_argv[0] = strdup(server_context->log_context.log_file);
415b9d004c6Schristos if (alt_argv[0] == NULL)
416b9d004c6Schristos krb5_err(context, 1, errno, "strdup");
417b9d004c6Schristos argv = alt_argv;
418b9d004c6Schristos argc = 1;
419b9d004c6Schristos }
420b9d004c6Schristos
421b9d004c6Schristos for (i = 0; i < argc; i++) {
422b9d004c6Schristos free(server_context->log_context.log_file);
423b9d004c6Schristos server_context->log_context.log_file = strdup(argv[i]);
424b9d004c6Schristos if (server_context->log_context.log_file == NULL)
425b9d004c6Schristos krb5_err(context, 1, errno, "strdup");
426b9d004c6Schristos
427b9d004c6Schristos if (opt->no_lock_flag) {
428b9d004c6Schristos ret = kadm5_log_init_sharedlock(server_context, LOCK_NB);
429b9d004c6Schristos if (ret == EAGAIN || ret == EWOULDBLOCK) {
430b9d004c6Schristos warnx("Not locking the iprop log");
431b9d004c6Schristos ret = kadm5_log_init_nolock(server_context);
432ca1c9b0cSelric if (ret)
433b9d004c6Schristos krb5_err(context, 1, ret, "kadm5_log_init_nolock");
434b9d004c6Schristos }
435b9d004c6Schristos } else {
436b9d004c6Schristos warnx("If this command appears to block, try the "
437b9d004c6Schristos "--no-lock option");
438b9d004c6Schristos ret = kadm5_log_init_sharedlock(server_context, 0);
439b9d004c6Schristos if (ret)
440b9d004c6Schristos krb5_err(context, 1, ret, "kadm5_log_init_sharedlock");
441b9d004c6Schristos }
442ca1c9b0cSelric
443ca1c9b0cSelric ret = kadm5_log_get_version (server_context, &version);
444ca1c9b0cSelric if (ret)
445ca1c9b0cSelric krb5_err (context, 1, ret, "kadm5_log_get_version");
446ca1c9b0cSelric
447ca1c9b0cSelric ret = kadm5_log_end (server_context);
448ca1c9b0cSelric if (ret)
449ca1c9b0cSelric krb5_warn(context, ret, "kadm5_log_end");
450ca1c9b0cSelric
451ca1c9b0cSelric printf("version: %lu\n", (unsigned long)version);
452b9d004c6Schristos }
453ca1c9b0cSelric
454b9d004c6Schristos kadm5_destroy(server_context);
455b9d004c6Schristos free(alt_argv[0]);
456b9d004c6Schristos return 0;
457b9d004c6Schristos }
458b9d004c6Schristos
459b9d004c6Schristos int
signal_master(struct signal_options * opt,int argc,char ** argv)460b9d004c6Schristos signal_master(struct signal_options *opt, int argc, char **argv)
461b9d004c6Schristos {
462b9d004c6Schristos kadm5_server_context *server_context;
463b9d004c6Schristos
464b9d004c6Schristos server_context = get_kadmin_context(opt->config_file_string,
465b9d004c6Schristos opt->realm_string);
466b9d004c6Schristos
467b9d004c6Schristos kadm5_log_signal_master(server_context);
468b9d004c6Schristos
469b9d004c6Schristos kadm5_destroy(server_context);
470ca1c9b0cSelric return 0;
471ca1c9b0cSelric }
472ca1c9b0cSelric
473ca1c9b0cSelric /*
474ca1c9b0cSelric * Replay log
475ca1c9b0cSelric */
476ca1c9b0cSelric
477ca1c9b0cSelric int start_version = -1;
478ca1c9b0cSelric int end_version = -1;
479ca1c9b0cSelric
480b9d004c6Schristos static kadm5_ret_t
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)481ca1c9b0cSelric apply_entry(kadm5_server_context *server_context,
482ca1c9b0cSelric uint32_t ver,
483ca1c9b0cSelric time_t timestamp,
484ca1c9b0cSelric enum kadm_ops op,
485ca1c9b0cSelric uint32_t len,
486ca1c9b0cSelric krb5_storage *sp,
487ca1c9b0cSelric void *ctx)
488ca1c9b0cSelric {
489ca1c9b0cSelric struct replay_options *opt = ctx;
490ca1c9b0cSelric krb5_error_code ret;
491ca1c9b0cSelric
4924f77a458Spettai if((opt->start_version_integer != -1 && ver < (uint32_t)opt->start_version_integer) ||
4934f77a458Spettai (opt->end_version_integer != -1 && ver > (uint32_t)opt->end_version_integer)) {
494ca1c9b0cSelric /* XXX skip this entry */
495b9d004c6Schristos return 0;
496ca1c9b0cSelric }
497ca1c9b0cSelric printf ("ver %u... ", ver);
498ca1c9b0cSelric fflush (stdout);
499ca1c9b0cSelric
500b9d004c6Schristos ret = kadm5_log_replay(server_context, op, ver, len, sp);
501ca1c9b0cSelric if (ret)
502ca1c9b0cSelric krb5_warn (server_context->context, ret, "kadm5_log_replay");
503ca1c9b0cSelric
504ca1c9b0cSelric printf ("done\n");
505b9d004c6Schristos
506b9d004c6Schristos return 0;
507ca1c9b0cSelric }
508ca1c9b0cSelric
509ca1c9b0cSelric int
iprop_replay(struct replay_options * opt,int argc,char ** argv)510ca1c9b0cSelric iprop_replay(struct replay_options *opt, int argc, char **argv)
511ca1c9b0cSelric {
512ca1c9b0cSelric kadm5_server_context *server_context;
513ca1c9b0cSelric krb5_error_code ret;
514ca1c9b0cSelric
515ca1c9b0cSelric server_context = get_kadmin_context(opt->config_file_string,
516ca1c9b0cSelric opt->realm_string);
517ca1c9b0cSelric
518b9d004c6Schristos if (argc > 0) {
519b9d004c6Schristos free(server_context->log_context.log_file);
520b9d004c6Schristos server_context->log_context.log_file = strdup(argv[0]);
521b9d004c6Schristos if (server_context->log_context.log_file == NULL)
522b9d004c6Schristos krb5_err(context, 1, errno, "strdup");
523b9d004c6Schristos }
524b9d004c6Schristos
525ca1c9b0cSelric ret = server_context->db->hdb_open(context,
526ca1c9b0cSelric server_context->db,
527ca1c9b0cSelric O_RDWR | O_CREAT, 0600);
528ca1c9b0cSelric if (ret)
529ca1c9b0cSelric krb5_err (context, 1, ret, "db->open");
530ca1c9b0cSelric
531ca1c9b0cSelric ret = kadm5_log_init (server_context);
532ca1c9b0cSelric if (ret)
533ca1c9b0cSelric krb5_err (context, 1, ret, "kadm5_log_init");
534ca1c9b0cSelric
535b9d004c6Schristos ret = kadm5_log_foreach(server_context,
536b9d004c6Schristos kadm_forward | kadm_confirmed | kadm_unconfirmed,
537b9d004c6Schristos NULL, apply_entry, opt);
538ca1c9b0cSelric if(ret)
539ca1c9b0cSelric krb5_warn(context, ret, "kadm5_log_foreach");
540ca1c9b0cSelric ret = kadm5_log_end (server_context);
541ca1c9b0cSelric if (ret)
542ca1c9b0cSelric krb5_warn(context, ret, "kadm5_log_end");
543ca1c9b0cSelric ret = server_context->db->hdb_close (context, server_context->db);
544ca1c9b0cSelric if (ret)
545ca1c9b0cSelric krb5_err (context, 1, ret, "db->close");
546ca1c9b0cSelric
547b9d004c6Schristos kadm5_destroy(server_context);
548ca1c9b0cSelric return 0;
549ca1c9b0cSelric }
550ca1c9b0cSelric
551ca1c9b0cSelric static int help_flag;
552ca1c9b0cSelric static int version_flag;
553ca1c9b0cSelric
554ca1c9b0cSelric static struct getargs args[] = {
555ca1c9b0cSelric { "version", 0, arg_flag, &version_flag,
556ca1c9b0cSelric NULL, NULL
557ca1c9b0cSelric },
558ca1c9b0cSelric { "help", 'h', arg_flag, &help_flag,
559ca1c9b0cSelric NULL, NULL
560ca1c9b0cSelric }
561ca1c9b0cSelric };
562ca1c9b0cSelric
563ca1c9b0cSelric static int num_args = sizeof(args) / sizeof(args[0]);
564ca1c9b0cSelric
565ca1c9b0cSelric int
help(void * opt,int argc,char ** argv)566ca1c9b0cSelric help(void *opt, int argc, char **argv)
567ca1c9b0cSelric {
568ca1c9b0cSelric if(argc == 0) {
569ca1c9b0cSelric sl_help(commands, 1, argv - 1 /* XXX */);
570ca1c9b0cSelric } else {
571ca1c9b0cSelric SL_cmd *c = sl_match (commands, argv[0], 0);
572ca1c9b0cSelric if(c == NULL) {
573ca1c9b0cSelric fprintf (stderr, "No such command: %s. "
574ca1c9b0cSelric "Try \"help\" for a list of commands\n",
575ca1c9b0cSelric argv[0]);
576ca1c9b0cSelric } else {
577ca1c9b0cSelric if(c->func) {
5784f77a458Spettai static char shelp[] = "--help";
5794f77a458Spettai char *fake[3];
580ca1c9b0cSelric fake[0] = argv[0];
5814f77a458Spettai fake[1] = shelp;
5824f77a458Spettai fake[2] = NULL;
583ca1c9b0cSelric (*c->func)(2, fake);
584ca1c9b0cSelric fprintf(stderr, "\n");
585ca1c9b0cSelric }
586ca1c9b0cSelric if(c->help && *c->help)
587ca1c9b0cSelric fprintf (stderr, "%s\n", c->help);
588ca1c9b0cSelric if((++c)->name && c->func == NULL) {
589ca1c9b0cSelric int f = 0;
590ca1c9b0cSelric fprintf (stderr, "Synonyms:");
591ca1c9b0cSelric while (c->name && c->func == NULL) {
592ca1c9b0cSelric fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name);
593ca1c9b0cSelric f = 1;
594ca1c9b0cSelric }
595ca1c9b0cSelric fprintf (stderr, "\n");
596ca1c9b0cSelric }
597ca1c9b0cSelric }
598ca1c9b0cSelric }
599ca1c9b0cSelric return 0;
600ca1c9b0cSelric }
601ca1c9b0cSelric
602ca1c9b0cSelric static void
usage(int status)603ca1c9b0cSelric usage(int status)
604ca1c9b0cSelric {
605ca1c9b0cSelric arg_printusage(args, num_args, NULL, "command");
606ca1c9b0cSelric exit(status);
607ca1c9b0cSelric }
608ca1c9b0cSelric
609ca1c9b0cSelric int
main(int argc,char ** argv)610ca1c9b0cSelric main(int argc, char **argv)
611ca1c9b0cSelric {
612ca1c9b0cSelric int optidx = 0;
613ca1c9b0cSelric krb5_error_code ret;
614ca1c9b0cSelric
615ca1c9b0cSelric setprogname(argv[0]);
616ca1c9b0cSelric
617ca1c9b0cSelric if(getarg(args, num_args, argc, argv, &optidx))
618ca1c9b0cSelric usage(1);
619ca1c9b0cSelric if(help_flag)
620ca1c9b0cSelric usage(0);
621ca1c9b0cSelric if(version_flag) {
622ca1c9b0cSelric print_version(NULL);
623ca1c9b0cSelric exit(0);
624ca1c9b0cSelric }
625ca1c9b0cSelric argc -= optidx;
626ca1c9b0cSelric argv += optidx;
627ca1c9b0cSelric if(argc == 0)
628ca1c9b0cSelric usage(1);
629ca1c9b0cSelric
630ca1c9b0cSelric ret = krb5_init_context(&context);
631ca1c9b0cSelric if (ret)
632ca1c9b0cSelric errx(1, "krb5_init_context failed with: %d\n", ret);
633ca1c9b0cSelric
634ca1c9b0cSelric ret = sl_command(commands, argc, argv);
635ca1c9b0cSelric if(ret == -1)
636ca1c9b0cSelric warnx ("unrecognized command: %s", argv[0]);
637ca1c9b0cSelric return ret;
638ca1c9b0cSelric }
639