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"
41 static krb5_context context
;
43 static kadm5_server_context
*
44 get_kadmin_context(const char *config_file
, char *realm
)
46 kadm5_config_params conf
;
51 if (config_file
== NULL
) {
53 asprintf(&file
, "%s/kdc.conf", hdb_db_dir(context
));
55 errx(1, "out of memory");
59 ret
= krb5_prepend_config_files_default(config_file
, &files
);
61 krb5_err(context
, 1, ret
, "getting configuration files");
63 ret
= krb5_set_config_files(context
, files
);
64 krb5_free_config_files(files
);
66 krb5_err(context
, 1, ret
, "reading configuration files");
68 memset(&conf
, 0, sizeof(conf
));
70 conf
.mask
|= KADM5_CONFIG_REALM
;
74 ret
= kadm5_init_with_password_ctx (context
,
81 krb5_err (context
, 1, ret
, "kadm5_init_with_password_ctx");
83 return (kadm5_server_context
*)kadm_handle
;
90 static const char *op_names
[] = {
105 print_entry(kadm5_server_context
*server_context
,
116 krb5_principal source
;
119 krb5_context scontext
= server_context
->context
;
121 off_t end
= krb5_storage_seek(sp
, 0, SEEK_CUR
) + len
;
125 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S", localtime(×tamp
));
127 if(op
< kadm_get
|| op
> kadm_nop
) {
128 printf("unknown op: %d\n", op
);
129 krb5_storage_seek(sp
, end
, SEEK_SET
);
133 printf ("%s: ver = %u, timestamp = %s, len = %u\n",
134 op_names
[op
], ver
, t
, len
);
137 krb5_ret_principal(sp
, &source
);
138 krb5_unparse_name(scontext
, source
, &name1
);
139 printf(" %s\n", name1
);
141 krb5_free_principal(scontext
, source
);
144 ret
= krb5_data_alloc(&data
, len
);
146 krb5_err (scontext
, 1, ret
, "kadm_rename: data alloc: %d", len
);
147 krb5_ret_principal(sp
, &source
);
148 krb5_storage_read(sp
, data
.data
, data
.length
);
149 hdb_value2entry(scontext
, &data
, &ent
);
150 krb5_unparse_name(scontext
, source
, &name1
);
151 krb5_unparse_name(scontext
, ent
.principal
, &name2
);
152 printf(" %s -> %s\n", name1
, name2
);
155 krb5_free_principal(scontext
, source
);
156 free_hdb_entry(&ent
);
159 ret
= krb5_data_alloc(&data
, len
);
161 krb5_err (scontext
, 1, ret
, "kadm_create: data alloc: %d", len
);
162 krb5_storage_read(sp
, data
.data
, data
.length
);
163 ret
= hdb_value2entry(scontext
, &data
, &ent
);
169 ret
= krb5_data_alloc(&data
, len
);
171 krb5_err (scontext
, 1, ret
, "kadm_modify: data alloc: %d", len
);
172 krb5_ret_int32(sp
, &mask
);
173 krb5_storage_read(sp
, data
.data
, data
.length
);
174 ret
= hdb_value2entry(scontext
, &data
, &ent
);
178 if(ent
.principal
/* mask & KADM5_PRINCIPAL */) {
179 krb5_unparse_name(scontext
, ent
.principal
, &name1
);
180 printf(" principal = %s\n", name1
);
183 if(mask
& KADM5_PRINC_EXPIRE_TIME
) {
184 if(ent
.valid_end
== NULL
) {
185 strlcpy(t
, "never", sizeof(t
));
187 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S",
188 localtime(ent
.valid_end
));
190 printf(" expires = %s\n", t
);
192 if(mask
& KADM5_PW_EXPIRATION
) {
193 if(ent
.pw_end
== NULL
) {
194 strlcpy(t
, "never", sizeof(t
));
196 strftime(t
, sizeof(t
), "%Y-%m-%d %H:%M:%S",
197 localtime(ent
.pw_end
));
199 printf(" password exp = %s\n", t
);
201 if(mask
& KADM5_LAST_PWD_CHANGE
) {
203 if(mask
& KADM5_ATTRIBUTES
) {
204 unparse_flags(HDBFlags2int(ent
.flags
),
205 asn1_HDBFlags_units(), t
, sizeof(t
));
206 printf(" attributes = %s\n", t
);
208 if(mask
& KADM5_MAX_LIFE
) {
209 if(ent
.max_life
== NULL
)
210 strlcpy(t
, "for ever", sizeof(t
));
212 unparse_time(*ent
.max_life
, t
, sizeof(t
));
213 printf(" max life = %s\n", t
);
215 if(mask
& KADM5_MAX_RLIFE
) {
216 if(ent
.max_renew
== NULL
)
217 strlcpy(t
, "for ever", sizeof(t
));
219 unparse_time(*ent
.max_renew
, t
, sizeof(t
));
220 printf(" max rlife = %s\n", t
);
222 if(mask
& KADM5_MOD_TIME
) {
223 printf(" mod time\n");
225 if(mask
& KADM5_MOD_NAME
) {
226 printf(" mod name\n");
228 if(mask
& KADM5_KVNO
) {
229 printf(" kvno = %d\n", ent
.kvno
);
231 if(mask
& KADM5_MKVNO
) {
234 if(mask
& KADM5_AUX_ATTRIBUTES
) {
235 printf(" aux attributes\n");
237 if(mask
& KADM5_POLICY
) {
240 if(mask
& KADM5_POLICY_CLR
) {
241 printf(" mod time\n");
243 if(mask
& KADM5_LAST_SUCCESS
) {
244 printf(" last success\n");
246 if(mask
& KADM5_LAST_FAILED
) {
247 printf(" last failed\n");
249 if(mask
& KADM5_FAIL_AUTH_COUNT
) {
250 printf(" fail auth count\n");
252 if(mask
& KADM5_KEY_DATA
) {
253 printf(" key data\n");
255 if(mask
& KADM5_TL_DATA
) {
256 printf(" tl data\n");
258 free_hdb_entry(&ent
);
265 krb5_storage_seek(sp
, end
, SEEK_SET
);
269 iprop_dump(struct dump_options
*opt
, int argc
, char **argv
)
271 kadm5_server_context
*server_context
;
274 server_context
= get_kadmin_context(opt
->config_file_string
,
277 ret
= kadm5_log_init (server_context
);
279 krb5_err (context
, 1, ret
, "kadm5_log_init");
281 ret
= kadm5_log_foreach (server_context
, print_entry
, NULL
);
283 krb5_warn(context
, ret
, "kadm5_log_foreach");
285 ret
= kadm5_log_end (server_context
);
287 krb5_warn(context
, ret
, "kadm5_log_end");
292 iprop_truncate(struct truncate_options
*opt
, int argc
, char **argv
)
294 kadm5_server_context
*server_context
;
297 server_context
= get_kadmin_context(opt
->config_file_string
,
300 ret
= kadm5_log_truncate (server_context
);
302 krb5_err (context
, 1, ret
, "kadm5_log_truncate");
308 last_version(struct last_version_options
*opt
, int argc
, char **argv
)
310 kadm5_server_context
*server_context
;
314 server_context
= get_kadmin_context(opt
->config_file_string
,
317 ret
= kadm5_log_init (server_context
);
319 krb5_err (context
, 1, ret
, "kadm5_log_init");
321 ret
= kadm5_log_get_version (server_context
, &version
);
323 krb5_err (context
, 1, ret
, "kadm5_log_get_version");
325 ret
= kadm5_log_end (server_context
);
327 krb5_warn(context
, ret
, "kadm5_log_end");
329 printf("version: %lu\n", (unsigned long)version
);
338 int start_version
= -1;
339 int end_version
= -1;
342 apply_entry(kadm5_server_context
*server_context
,
350 struct replay_options
*opt
= ctx
;
353 if((opt
->start_version_integer
!= -1 && ver
< opt
->start_version_integer
) ||
354 (opt
->end_version_integer
!= -1 && ver
> opt
->end_version_integer
)) {
355 /* XXX skip this entry */
356 krb5_storage_seek(sp
, len
, SEEK_CUR
);
359 printf ("ver %u... ", ver
);
362 ret
= kadm5_log_replay (server_context
,
365 krb5_warn (server_context
->context
, ret
, "kadm5_log_replay");
371 iprop_replay(struct replay_options
*opt
, int argc
, char **argv
)
373 kadm5_server_context
*server_context
;
376 server_context
= get_kadmin_context(opt
->config_file_string
,
379 ret
= server_context
->db
->hdb_open(context
,
381 O_RDWR
| O_CREAT
, 0600);
383 krb5_err (context
, 1, ret
, "db->open");
385 ret
= kadm5_log_init (server_context
);
387 krb5_err (context
, 1, ret
, "kadm5_log_init");
389 ret
= kadm5_log_foreach (server_context
, apply_entry
, opt
);
391 krb5_warn(context
, ret
, "kadm5_log_foreach");
392 ret
= kadm5_log_end (server_context
);
394 krb5_warn(context
, ret
, "kadm5_log_end");
395 ret
= server_context
->db
->hdb_close (context
, server_context
->db
);
397 krb5_err (context
, 1, ret
, "db->close");
402 static int help_flag
;
403 static int version_flag
;
405 static struct getargs args
[] = {
406 { "version", 0, arg_flag
, &version_flag
,
409 { "help", 'h', arg_flag
, &help_flag
,
414 static int num_args
= sizeof(args
) / sizeof(args
[0]);
417 help(void *opt
, int argc
, char **argv
)
420 sl_help(commands
, 1, argv
- 1 /* XXX */);
422 SL_cmd
*c
= sl_match (commands
, argv
[0], 0);
424 fprintf (stderr
, "No such command: %s. "
425 "Try \"help\" for a list of commands\n",
429 char *fake
[] = { NULL
, "--help", NULL
};
432 fprintf(stderr
, "\n");
434 if(c
->help
&& *c
->help
)
435 fprintf (stderr
, "%s\n", c
->help
);
436 if((++c
)->name
&& c
->func
== NULL
) {
438 fprintf (stderr
, "Synonyms:");
439 while (c
->name
&& c
->func
== NULL
) {
440 fprintf (stderr
, "%s%s", f
? ", " : " ", (c
++)->name
);
443 fprintf (stderr
, "\n");
453 arg_printusage(args
, num_args
, NULL
, "command");
458 main(int argc
, char **argv
)
463 setprogname(argv
[0]);
465 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
478 ret
= krb5_init_context(&context
);
480 errx(1, "krb5_init_context failed with: %d\n", ret
);
482 ret
= sl_command(commands
, argc
, argv
);
484 warnx ("unrecognized command: %s", argv
[0]);