2 * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <parse_time.h>
37 #include "iprop-commands.h"
39 __RCSID("$Heimdal: iprop-log.c 22211 2007-12-07 19:27:27Z lha $"
42 static krb5_context context
;
44 static kadm5_server_context
*
45 get_kadmin_context(const char *config_file
, char *realm
)
47 kadm5_config_params conf
;
52 if (config_file
== NULL
) {
54 asprintf(&file
, "%s/kdc.conf", hdb_db_dir(context
));
56 errx(1, "out of memory");
60 ret
= krb5_prepend_config_files_default(config_file
, &files
);
62 krb5_err(context
, 1, ret
, "getting configuration files");
64 ret
= krb5_set_config_files(context
, files
);
65 krb5_free_config_files(files
);
67 krb5_err(context
, 1, ret
, "reading configuration files");
69 memset(&conf
, 0, sizeof(conf
));
71 conf
.mask
|= KADM5_CONFIG_REALM
;
75 ret
= kadm5_init_with_password_ctx (context
,
82 krb5_err (context
, 1, ret
, "kadm5_init_with_password_ctx");
84 return (kadm5_server_context
*)kadm_handle
;
91 static const char *op_names
[] = {
106 print_entry(kadm5_server_context
*server_context
,
117 krb5_principal source
;
120 krb5_context scontext
= server_context
->context
;
122 off_t end
= krb5_storage_seek(sp
, 0, SEEK_CUR
) + len
;
126 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S", localtime(×tamp
));
128 if(op
< kadm_get
|| op
> kadm_nop
) {
129 printf("unknown op: %d\n", op
);
130 krb5_storage_seek(sp
, end
, SEEK_SET
);
134 printf ("%s: ver = %u, timestamp = %s, len = %u\n",
135 op_names
[op
], ver
, t
, len
);
138 krb5_ret_principal(sp
, &source
);
139 krb5_unparse_name(scontext
, source
, &name1
);
140 printf(" %s\n", name1
);
142 krb5_free_principal(scontext
, source
);
145 ret
= krb5_data_alloc(&data
, len
);
147 krb5_err (scontext
, 1, ret
, "kadm_rename: data alloc: %d", len
);
148 krb5_ret_principal(sp
, &source
);
149 krb5_storage_read(sp
, data
.data
, data
.length
);
150 hdb_value2entry(scontext
, &data
, &ent
);
151 krb5_unparse_name(scontext
, source
, &name1
);
152 krb5_unparse_name(scontext
, ent
.principal
, &name2
);
153 printf(" %s -> %s\n", name1
, name2
);
156 krb5_free_principal(scontext
, source
);
157 free_hdb_entry(&ent
);
160 ret
= krb5_data_alloc(&data
, len
);
162 krb5_err (scontext
, 1, ret
, "kadm_create: data alloc: %d", len
);
163 krb5_storage_read(sp
, data
.data
, data
.length
);
164 ret
= hdb_value2entry(scontext
, &data
, &ent
);
170 ret
= krb5_data_alloc(&data
, len
);
172 krb5_err (scontext
, 1, ret
, "kadm_modify: data alloc: %d", len
);
173 krb5_ret_int32(sp
, &mask
);
174 krb5_storage_read(sp
, data
.data
, data
.length
);
175 ret
= hdb_value2entry(scontext
, &data
, &ent
);
179 if(ent
.principal
/* mask & KADM5_PRINCIPAL */) {
180 krb5_unparse_name(scontext
, ent
.principal
, &name1
);
181 printf(" principal = %s\n", name1
);
184 if(mask
& KADM5_PRINC_EXPIRE_TIME
) {
185 if(ent
.valid_end
== NULL
) {
186 strlcpy(t
, "never", sizeof(t
));
188 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S",
189 localtime(ent
.valid_end
));
191 printf(" expires = %s\n", t
);
193 if(mask
& KADM5_PW_EXPIRATION
) {
194 if(ent
.pw_end
== NULL
) {
195 strlcpy(t
, "never", sizeof(t
));
197 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S",
198 localtime(ent
.pw_end
));
200 printf(" password exp = %s\n", t
);
202 if(mask
& KADM5_LAST_PWD_CHANGE
) {
204 if(mask
& KADM5_ATTRIBUTES
) {
205 unparse_flags(HDBFlags2int(ent
.flags
),
206 asn1_HDBFlags_units(), t
, sizeof(t
));
207 printf(" attributes = %s\n", t
);
209 if(mask
& KADM5_MAX_LIFE
) {
210 if(ent
.max_life
== NULL
)
211 strlcpy(t
, "for ever", sizeof(t
));
213 unparse_time(*ent
.max_life
, t
, sizeof(t
));
214 printf(" max life = %s\n", t
);
216 if(mask
& KADM5_MAX_RLIFE
) {
217 if(ent
.max_renew
== NULL
)
218 strlcpy(t
, "for ever", sizeof(t
));
220 unparse_time(*ent
.max_renew
, t
, sizeof(t
));
221 printf(" max rlife = %s\n", t
);
223 if(mask
& KADM5_MOD_TIME
) {
224 printf(" mod time\n");
226 if(mask
& KADM5_MOD_NAME
) {
227 printf(" mod name\n");
229 if(mask
& KADM5_KVNO
) {
230 printf(" kvno = %d\n", ent
.kvno
);
232 if(mask
& KADM5_MKVNO
) {
235 if(mask
& KADM5_AUX_ATTRIBUTES
) {
236 printf(" aux attributes\n");
238 if(mask
& KADM5_POLICY
) {
241 if(mask
& KADM5_POLICY_CLR
) {
242 printf(" mod time\n");
244 if(mask
& KADM5_LAST_SUCCESS
) {
245 printf(" last success\n");
247 if(mask
& KADM5_LAST_FAILED
) {
248 printf(" last failed\n");
250 if(mask
& KADM5_FAIL_AUTH_COUNT
) {
251 printf(" fail auth count\n");
253 if(mask
& KADM5_KEY_DATA
) {
254 printf(" key data\n");
256 if(mask
& KADM5_TL_DATA
) {
257 printf(" tl data\n");
259 free_hdb_entry(&ent
);
266 krb5_storage_seek(sp
, end
, SEEK_SET
);
270 iprop_dump(struct dump_options
*opt
, int argc
, char **argv
)
272 kadm5_server_context
*server_context
;
275 server_context
= get_kadmin_context(opt
->config_file_string
,
278 ret
= kadm5_log_init (server_context
);
280 krb5_err (context
, 1, ret
, "kadm5_log_init");
282 ret
= kadm5_log_foreach (server_context
, print_entry
, NULL
);
284 krb5_warn(context
, ret
, "kadm5_log_foreach");
286 ret
= kadm5_log_end (server_context
);
288 krb5_warn(context
, ret
, "kadm5_log_end");
293 iprop_truncate(struct truncate_options
*opt
, int argc
, char **argv
)
295 kadm5_server_context
*server_context
;
298 server_context
= get_kadmin_context(opt
->config_file_string
,
301 ret
= kadm5_log_truncate (server_context
);
303 krb5_err (context
, 1, ret
, "kadm5_log_truncate");
309 last_version(struct last_version_options
*opt
, int argc
, char **argv
)
311 kadm5_server_context
*server_context
;
315 server_context
= get_kadmin_context(opt
->config_file_string
,
318 ret
= kadm5_log_init (server_context
);
320 krb5_err (context
, 1, ret
, "kadm5_log_init");
322 ret
= kadm5_log_get_version (server_context
, &version
);
324 krb5_err (context
, 1, ret
, "kadm5_log_get_version");
326 ret
= kadm5_log_end (server_context
);
328 krb5_warn(context
, ret
, "kadm5_log_end");
330 printf("version: %lu\n", (unsigned long)version
);
339 int start_version
= -1;
340 int end_version
= -1;
343 apply_entry(kadm5_server_context
*server_context
,
351 struct replay_options
*opt
= ctx
;
354 if((opt
->start_version_integer
!= -1 && ver
< opt
->start_version_integer
) ||
355 (opt
->end_version_integer
!= -1 && ver
> opt
->end_version_integer
)) {
356 /* XXX skip this entry */
357 krb5_storage_seek(sp
, len
, SEEK_CUR
);
360 printf ("ver %u... ", ver
);
363 ret
= kadm5_log_replay (server_context
,
366 krb5_warn (server_context
->context
, ret
, "kadm5_log_replay");
372 iprop_replay(struct replay_options
*opt
, int argc
, char **argv
)
374 kadm5_server_context
*server_context
;
377 server_context
= get_kadmin_context(opt
->config_file_string
,
380 ret
= server_context
->db
->hdb_open(context
,
382 O_RDWR
| O_CREAT
, 0600);
384 krb5_err (context
, 1, ret
, "db->open");
386 ret
= kadm5_log_init (server_context
);
388 krb5_err (context
, 1, ret
, "kadm5_log_init");
390 ret
= kadm5_log_foreach (server_context
, apply_entry
, opt
);
392 krb5_warn(context
, ret
, "kadm5_log_foreach");
393 ret
= kadm5_log_end (server_context
);
395 krb5_warn(context
, ret
, "kadm5_log_end");
396 ret
= server_context
->db
->hdb_close (context
, server_context
->db
);
398 krb5_err (context
, 1, ret
, "db->close");
403 static int help_flag
;
404 static int version_flag
;
406 static struct getargs args
[] = {
407 { "version", 0, arg_flag
, &version_flag
,
410 { "help", 'h', arg_flag
, &help_flag
,
415 static int num_args
= sizeof(args
) / sizeof(args
[0]);
418 help(void *opt
, int argc
, char **argv
)
421 sl_help(commands
, 1, argv
- 1 /* XXX */);
423 SL_cmd
*c
= sl_match (commands
, argv
[0], 0);
425 fprintf (stderr
, "No such command: %s. "
426 "Try \"help\" for a list of commands\n",
430 char *fake
[] = { NULL
, "--help", NULL
};
433 fprintf(stderr
, "\n");
435 if(c
->help
&& *c
->help
)
436 fprintf (stderr
, "%s\n", c
->help
);
437 if((++c
)->name
&& c
->func
== NULL
) {
439 fprintf (stderr
, "Synonyms:");
440 while (c
->name
&& c
->func
== NULL
) {
441 fprintf (stderr
, "%s%s", f
? ", " : " ", (c
++)->name
);
444 fprintf (stderr
, "\n");
454 arg_printusage(args
, num_args
, NULL
, "command");
459 main(int argc
, char **argv
)
464 setprogname(argv
[0]);
466 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
479 ret
= krb5_init_context(&context
);
481 errx(1, "krb5_init_context failed with: %d\n", ret
);
483 ret
= sl_command(commands
, argc
, argv
);
485 warnx ("unrecognized command: %s", argv
[0]);