1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4 * Use is subject to license terms.
8 * This module will parse the update logs on the master or replica servers.
14 #include <sys/types.h>
21 #include <kadm5/admin.h>
23 static char *progname;
28 fprintf(stderr, _("\nUsage: %s [-h] [-v] [-v] [-e num]\n\t%s -R\n\n"),
34 * Print the attribute flags of principal in human readable form.
37 print_flags(unsigned int flags)
40 static char *prflags[] = {
41 "DISALLOW_POSTDATED", /* 0x00000001 */
42 "DISALLOW_FORWARDABLE", /* 0x00000002 */
43 "DISALLOW_TGT_BASED", /* 0x00000004 */
44 "DISALLOW_RENEWABLE", /* 0x00000008 */
45 "DISALLOW_PROXIABLE", /* 0x00000010 */
46 "DISALLOW_DUP_SKEY", /* 0x00000020 */
47 "DISALLOW_ALL_TIX", /* 0x00000040 */
48 "REQUIRES_PRE_AUTH", /* 0x00000080 */
49 "REQUIRES_HW_AUTH", /* 0x00000100 */
50 "REQUIRES_PWCHANGE", /* 0x00000200 */
51 "UNKNOWN_0x00000400", /* 0x00000400 */
52 "UNKNOWN_0x00000800", /* 0x00000800 */
53 "DISALLOW_SVR", /* 0x00001000 */
54 "PWCHANGE_SERVICE", /* 0x00002000 */
55 "SUPPORT_DESMD5", /* 0x00004000 */
56 "NEW_PRINC", /* 0x00008000 */
57 "UNKNOWN_0x00010000", /* 0x00010000 */
58 "UNKNOWN_0x00020000", /* 0x00020000 */
59 "UNKNOWN_0x00040000", /* 0x00040000 */
60 "UNKNOWN_0x00080000", /* 0x00080000 */
61 "OK_AS_DELEGATE", /* 0x00100000 */
62 "OK_TO_AUTH_AS_DELEGATE", /* 0x00200000 */
63 "NO_AUTH_DATA_REQUIRED", /* 0x00400000 */
67 for (i = 0; i < sizeof(prflags) / sizeof(*prflags); i++) {
68 if (flags & (krb5_flags)(1 << i))
69 printf("\t\t\t%s\n", prflags[i]);
73 /* ctime() for uint32_t* */
75 ctime_uint32(uint32_t *time32)
82 return (r == NULL) ? "(error)" : r;
85 /* Display time information. */
87 print_time(uint32_t *timep)
90 printf("\t\t\tNone\n");
92 printf("\t\t\t%s", ctime_uint32(timep));
96 print_deltat(uint32_t *deltat)
101 ret = krb5_deltat_to_string(*deltat, buf, sizeof(buf));
103 printf("\t\t\t(error)\n");
105 printf("\t\t\t%s\n", buf);
108 /* Display string in hex primitive. */
110 print_hex(const char *tag, utf8str_t *str)
115 len = str->utf8str_t_len;
117 if (k5_hex_encode(str->utf8str_t_val, len, FALSE, &hex) != 0)
119 printf("\t\t\t%s(%d): 0x%s\n", tag, len, hex);
123 /* Display string primitive. */
125 print_str(const char *tag, utf8str_t *str)
130 s = k5memdup0(str->utf8str_t_val, str->utf8str_t_len, &ret);
132 fprintf(stderr, _("\nCouldn't allocate memory"));
135 printf("\t\t\t%s(%d): %s\n", tag, str->utf8str_t_len, s);
139 /* Display data components. */
141 print_data(const char *tag, kdbe_data_t *data)
143 printf("\t\t\tmagic: 0x%x\n", data->k_magic);
144 print_str(tag, &data->k_data);
147 /* Display the principal components. */
149 print_princ(kdbe_princ_t *princ)
154 print_str("realm", &princ->k_realm);
156 len = princ->k_components.k_components_len;
157 data = princ->k_components.k_components_val;
158 for (i = 0; i < len; i++, data++)
159 print_data("princ", data);
162 /* Display individual key. */
164 print_key(kdbe_key_t *k)
169 printf("\t\t\tver: %d\n", k->k_ver);
170 printf("\t\t\tkvno: %d\n", k->k_kvno);
172 for (i = 0; i < k->k_enctype.k_enctype_len; i++)
173 printf("\t\t\tenc type: 0x%x\n", k->k_enctype.k_enctype_val[i]);
175 str = k->k_contents.k_contents_val;
176 for (i = 0; i < k->k_contents.k_contents_len; i++, str++)
177 print_hex("key", str);
180 /* Display all key data. */
182 print_keydata(kdbe_key_t *keys, unsigned int len)
186 for (i = 0; i < len; i++, keys++)
190 /* Display TL item. */
192 print_tl(kdbe_tl_t *tl)
196 printf("\t\t\ttype: 0x%x\n", tl->tl_type);
198 len = tl->tl_data.tl_data_len;
200 printf("\t\t\tvalue(%d): 0x", len);
201 for (i = 0; i < len; i++)
202 printf("%02x", (krb5_octet)tl->tl_data.tl_data_val[i]);
206 /* Display TL data items. */
208 print_tldata(kdbe_tl_t *tldata, int len)
212 printf("\t\t\titems: %d\n", len);
213 for (i = 0; i < len; i++, tldata++)
218 * Print the individual types if verbose mode was specified.
219 * If verbose-verbose then print types along with respective values.
222 print_attr(kdbe_val_t *val, int vverbose)
224 switch (val->av_type) {
226 printf(_("\t\tAttribute flags\n"));
228 print_flags(val->kdbe_val_t_u.av_attrflags);
231 printf(_("\t\tMaximum ticket life\n"));
233 print_deltat(&val->kdbe_val_t_u.av_max_life);
235 case AT_MAX_RENEW_LIFE:
236 printf(_("\t\tMaximum renewable life\n"));
238 print_deltat(&val->kdbe_val_t_u.av_max_renew_life);
241 printf(_("\t\tPrincipal expiration\n"));
243 print_time(&val->kdbe_val_t_u.av_exp);
246 printf(_("\t\tPassword expiration\n"));
248 print_time(&val->kdbe_val_t_u.av_pw_exp);
250 case AT_LAST_SUCCESS:
251 printf(_("\t\tLast successful auth\n"));
253 print_time(&val->kdbe_val_t_u.av_last_success);
256 printf(_("\t\tLast failed auth\n"));
258 print_time(&val->kdbe_val_t_u.av_last_failed);
260 case AT_FAIL_AUTH_COUNT:
261 printf(_("\t\tFailed passwd attempt\n"));
263 printf("\t\t\t%d\n", val->kdbe_val_t_u.av_fail_auth_count);
266 printf(_("\t\tPrincipal\n"));
268 print_princ(&val->kdbe_val_t_u.av_princ);
271 printf(_("\t\tKey data\n"));
273 print_keydata(val->kdbe_val_t_u.av_keydata.av_keydata_val,
274 val->kdbe_val_t_u.av_keydata.av_keydata_len);
278 printf(_("\t\tTL data\n"));
280 print_tldata(val->kdbe_val_t_u.av_tldata.av_tldata_val,
281 val->kdbe_val_t_u.av_tldata.av_tldata_len);
285 printf(_("\t\tLength\n"));
287 printf("\t\t\t%d\n", val->kdbe_val_t_u.av_len);
289 case AT_PW_LAST_CHANGE:
290 printf(_("\t\tPassword last changed\n"));
292 print_time(&val->kdbe_val_t_u.av_pw_last_change);
295 printf(_("\t\tModifying principal\n"));
297 print_princ(&val->kdbe_val_t_u.av_mod_princ);
300 printf(_("\t\tModification time\n"));
302 print_time(&val->kdbe_val_t_u.av_mod_time);
305 printf(_("\t\tModified where\n"));
307 print_str("where", &val->kdbe_val_t_u.av_mod_where);
310 printf(_("\t\tPassword policy\n"));
312 print_str("policy", &val->kdbe_val_t_u.av_pw_policy);
314 case AT_PW_POLICY_SWITCH:
315 printf(_("\t\tPassword policy switch\n"));
317 printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_policy_switch);
319 case AT_PW_HIST_KVNO:
320 printf(_("\t\tPassword history KVNO\n"));
322 printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_hist_kvno);
325 printf(_("\t\tPassword history\n"));
327 printf("\t\t\tPW history elided\n");
333 * Print the update entry information
336 print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries,
337 unsigned int verbose)
340 uint32_t start_sno, i, j, indx;
342 kdb_ent_header_t *indx_log;
343 kdb_incr_update_t upd;
345 if (entry && (entry < ulog->kdb_num))
346 start_sno = ulog->kdb_last_sno - entry;
348 start_sno = ulog->kdb_first_sno - 1;
350 for (i = start_sno; i < ulog->kdb_last_sno; i++) {
351 indx = i % ulogentries;
353 indx_log = INDEX(ulog, indx);
356 * Check for corrupt update entry
358 if (indx_log->kdb_umagic != KDB_ULOG_MAGIC) {
359 fprintf(stderr, _("Corrupt update entry\n\n"));
364 printf(_("Update Entry\n"));
366 printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno);
368 /* The initial entry after a reset is a dummy entry; skip it. */
369 if (indx_log->kdb_entry_size == 0) {
370 printf(_("\tDummy entry\n"));
374 memset(&upd, 0, sizeof(kdb_incr_update_t));
375 xdrmem_create(&xdrs, (char *)indx_log->entry_data,
376 indx_log->kdb_entry_size, XDR_DECODE);
377 if (!xdr_kdb_incr_update_t(&xdrs, &upd)) {
378 printf(_("Entry data decode failure\n\n"));
382 printf(_("\tUpdate operation : "));
384 printf(_("Delete\n"));
388 dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1);
389 if (dbprinc == NULL) {
390 printf(_("Could not allocate principal name\n\n"));
393 strncpy(dbprinc, upd.kdb_princ_name.utf8str_t_val,
394 upd.kdb_princ_name.utf8str_t_len);
395 dbprinc[upd.kdb_princ_name.utf8str_t_len] = 0;
396 printf(_("\tUpdate principal : %s\n"), dbprinc);
398 printf(_("\tUpdate size : %u\n"), indx_log->kdb_entry_size);
399 printf(_("\tUpdate committed : %s\n"),
400 indx_log->kdb_commit ? "True" : "False");
402 if (indx_log->kdb_time.seconds == 0L) {
403 printf(_("\tUpdate time stamp : None\n"));
405 printf(_("\tUpdate time stamp : %s"),
406 ctime_uint32(&indx_log->kdb_time.seconds));
409 printf(_("\tAttributes changed : %d\n"), upd.kdb_update.kdbe_t_len);
412 for (j = 0; j < upd.kdb_update.kdbe_t_len; j++)
413 print_attr(&upd.kdb_update.kdbe_t_val[j], verbose > 1 ? 1 : 0);
416 xdr_free(xdr_kdb_incr_update_t, (char *)&upd);
421 /* Return a read-only mmap of the ulog, or NULL on failure. Assumes fd is
422 * released on process exit. */
424 map_ulog(const char *filename)
430 fd = open(filename, O_RDONLY);
433 if (fstat(fd, &st) < 0)
435 ulog = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
436 return (ulog == MAP_FAILED) ? NULL : ulog;
440 main(int argc, char **argv)
443 unsigned int verbose = 0;
444 bool_t headeronly = FALSE, reset = FALSE;
446 krb5_context context;
447 kadm5_config_params params;
448 kdb_hlog_t *ulog = NULL;
450 setlocale(LC_ALL, "");
454 while ((c = getopt(argc, argv, "Rvhe:")) != -1) {
460 entry = atoi(optarg);
473 if (krb5_init_context(&context)) {
474 fprintf(stderr, _("Unable to initialize Kerberos\n\n"));
478 memset(¶ms, 0, sizeof(params));
480 if (kadm5_get_config_params(context, 1, ¶ms, ¶ms)) {
481 fprintf(stderr, _("Couldn't read database_name\n\n"));
485 printf(_("\nKerberos update log (%s)\n"), params.iprop_logfile);
488 if (ulog_map(context, params.iprop_logfile, params.iprop_ulogsize)) {
489 fprintf(stderr, _("Unable to map log file %s\n\n"),
490 params.iprop_logfile);
493 if (ulog_init_header(context) != 0) {
494 fprintf(stderr, _("Couldn't reinitialize ulog file %s\n\n"),
495 params.iprop_logfile);
498 printf(_("Reinitialized the ulog.\n"));
503 ulog = map_ulog(params.iprop_logfile);
505 fprintf(stderr, _("Unable to map log file %s\n\n"),
506 params.iprop_logfile);
510 if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC) {
511 fprintf(stderr, _("Corrupt header log, exiting\n\n"));
515 printf(_("Update log dump :\n"));
516 printf(_("\tLog version # : %u\n"), ulog->db_version_num);
517 printf(_("\tLog state : "));
518 switch (ulog->kdb_state) {
520 printf(_("Stable\n"));
523 printf(_("Unstable\n"));
526 printf(_("Corrupt\n"));
529 printf(_("Unknown state: %d\n"), ulog->kdb_state);
532 printf(_("\tEntry block size : %u\n"), ulog->kdb_block);
533 printf(_("\tNumber of entries : %u\n"), ulog->kdb_num);
535 if (ulog->kdb_last_sno == 0) {
536 printf(_("\tLast serial # : None\n"));
538 if (ulog->kdb_first_sno == 0) {
539 printf(_("\tFirst serial # : None\n"));
541 printf(_("\tFirst serial # : "));
542 printf("%u\n", ulog->kdb_first_sno);
545 printf(_("\tLast serial # : "));
546 printf("%u\n", ulog->kdb_last_sno);
549 if (ulog->kdb_last_time.seconds == 0L) {
550 printf(_("\tLast time stamp : None\n"));
552 if (ulog->kdb_first_time.seconds == 0L) {
553 printf(_("\tFirst time stamp : None\n"));
555 printf(_("\tFirst time stamp : %s"),
556 ctime_uint32(&ulog->kdb_first_time.seconds));
559 printf(_("\tLast time stamp : %s\n"),
560 ctime_uint32(&ulog->kdb_last_time.seconds));
563 if (!headeronly && ulog->kdb_num)
564 print_update(ulog, entry, params.iprop_ulogsize, verbose);
569 kadm5_free_config_params(context, ¶ms);
570 krb5_free_context(context);