/* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * This module will parse the update logs on the master or slave servers. */ #include #include #include #include #include #include #include #include #include static char *progname; static void usage() { (void) fprintf(stderr, gettext("\nUsage: %s [-h] [-v] [-e num]\n\n"), progname); exit(1); } /* * Print the individual types if verbose mode was specified. */ static void print_attr(kdbe_attr_type_t type) { switch (type) { case AT_ATTRFLAGS: (void) printf(gettext("\t\tAttribute flags\n")); break; case AT_MAX_LIFE: (void) printf(gettext("\t\tMaximum ticket life\n")); break; case AT_MAX_RENEW_LIFE: (void) printf(gettext("\t\tMaximum renewable life\n")); break; case AT_EXP: (void) printf(gettext("\t\tPrincipal expiration\n")); break; case AT_PW_EXP: (void) printf(gettext("\t\tPassword expiration\n")); break; case AT_LAST_SUCCESS: (void) printf(gettext("\t\tLast successful auth\n")); break; case AT_LAST_FAILED: (void) printf(gettext("\t\tLast failed auth\n")); break; case AT_FAIL_AUTH_COUNT: (void) printf(gettext("\t\tFailed passwd attempt\n")); break; case AT_PRINC: (void) printf(gettext("\t\tPrincipal\n")); break; case AT_KEYDATA: (void) printf(gettext("\t\tKey data\n")); break; case AT_TL_DATA: (void) printf(gettext("\t\tTL data\n")); break; case AT_LEN: (void) printf(gettext("\t\tLength\n")); break; case AT_MOD_PRINC: (void) printf(gettext("\t\tModifying principal\n")); break; case AT_MOD_TIME: (void) printf(gettext("\t\tModification time\n")); break; case AT_MOD_WHERE: (void) printf(gettext("\t\tModified where\n")); break; case AT_PW_LAST_CHANGE: (void) printf(gettext("\t\tPassword last changed\n")); break; case AT_PW_POLICY: (void) printf(gettext("\t\tPassword policy\n")); break; case AT_PW_POLICY_SWITCH: (void) printf(gettext("\t\tPassword policy switch\n")); break; case AT_PW_HIST_KVNO: (void) printf(gettext("\t\tPassword history KVNO\n")); break; case AT_PW_HIST: (void) printf(gettext("\t\tPassword history\n")); break; } /* switch */ } /* * Print the update entry information */ static void print_update(kdb_hlog_t *ulog, uint32_t entry, bool_t verbose) { XDR xdrs; uint32_t start_sno, i, j, indx; char *dbprinc; kdb_ent_header_t *indx_log; kdb_incr_update_t upd; if (entry && (entry < ulog->kdb_num)) start_sno = ulog->kdb_last_sno - entry; else start_sno = ulog->kdb_first_sno - 1; for (i = start_sno; i < ulog->kdb_last_sno; i++) { indx = i % ulog->kdb_num; indx_log = (kdb_ent_header_t *)INDEX(ulog, indx); /* * Check for corrupt update entry */ if (indx_log->kdb_umagic != KDB_UMAGIC) { (void) fprintf(stderr, gettext("Corrupt update entry\n\n")); exit(1); } (void) memset((char *)&upd, 0, sizeof (kdb_incr_update_t)); xdrmem_create(&xdrs, (char *)indx_log->entry_data, indx_log->kdb_entry_size, XDR_DECODE); if (!xdr_kdb_incr_update_t(&xdrs, &upd)) { (void) printf(gettext("Entry data decode failure\n\n")); exit(1); } (void) printf("---\n"); (void) printf(gettext("Update Entry\n")); (void) printf(gettext("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno); (void) printf(gettext("\tUpdate operation : ")); if (upd.kdb_deleted) (void) printf(gettext("Delete\n")); else (void) printf(gettext("Add\n")); dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1); if (dbprinc == NULL) { (void) printf(gettext("Could not allocate " "principal name\n\n")); exit(1); } (void) strlcpy(dbprinc, upd.kdb_princ_name.utf8str_t_val, (upd.kdb_princ_name.utf8str_t_len + 1)); (void) printf(gettext("\tUpdate principal : %s\n"), dbprinc); (void) printf(gettext("\tUpdate size : %u\n"), indx_log->kdb_entry_size); (void) printf(gettext("\tUpdate committed : %s\n"), indx_log->kdb_commit ? "True" : "False"); if (indx_log->kdb_time.seconds == 0L) (void) printf(gettext("\tUpdate time stamp : None\n")); else (void) printf(gettext("\tUpdate time stamp : %s"), ctime((time_t *)&(indx_log->kdb_time.seconds))); (void) printf(gettext("\tAttributes changed : %d\n"), upd.kdb_update.kdbe_t_len); if (verbose) for (j = 0; j < upd.kdb_update.kdbe_t_len; j++) print_attr( upd.kdb_update.kdbe_t_val[j].av_type); xdr_free(xdr_kdb_incr_update_t, (char *)&upd); if (dbprinc) free(dbprinc); } /* for */ } int main(int argc, char **argv) { int c; bool_t verbose = FALSE; bool_t headeronly = FALSE; uint32_t entry = 0; krb5_context context; kadm5_config_params params; kdb_log_context *log_ctx; kdb_hlog_t *ulog = NULL; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif /* TEXT_DOMAIN */ (void) textdomain(TEXT_DOMAIN); if (geteuid() != (uid_t)0) { (void) fprintf(stderr, gettext("kproplog must be run as root\n\n")); exit(1); } progname = argv[0]; while ((c = getopt(argc, argv, "vhe:")) != -1) { switch (c) { case 'h': headeronly = TRUE; break; case 'e': entry = atoi(optarg); break; case 'v': verbose = TRUE; break; default: usage(); } } if (krb5_init_context(&context)) { (void) fprintf(stderr, gettext("Unable to initialize Kerberos\n\n")); exit(1); } (void) memset((char *)¶ms, 0, sizeof (params)); if (kadm5_get_config_params(context, NULL, NULL, ¶ms, ¶ms)) { (void) fprintf(stderr, gettext("Couldn't read database_name\n\n")); exit(1); } (void) printf(gettext("\nKerberos update log (%s.ulog)\n"), params.dbname); if (ulog_map(context, ¶ms, FKPROPLOG)) { (void) fprintf(stderr, gettext("Unable to map log file " "%s.ulog\n\n"), params.dbname); exit(1); } log_ctx = context->kdblog_context; if (log_ctx) ulog = log_ctx->ulog; else { (void) fprintf(stderr, gettext("Unable to map log file " "%s.ulog\n\n"), params.dbname); exit(1); } if (ulog->kdb_hmagic != KDB_HMAGIC) { (void) fprintf(stderr, gettext("Corrupt header log, exiting\n\n")); exit(1); } (void) printf(gettext("Update log dump :\n")); (void) printf(gettext("\tLog version # : %u\n"), ulog->db_version_num); (void) printf(gettext("\tLog state : ")); switch (ulog->kdb_state) { case KDB_STABLE: (void) printf(gettext("Stable\n")); break; case KDB_UNSTABLE: (void) printf(gettext("Unstable\n")); break; case KDB_CORRUPT: (void) printf(gettext("Corrupt\n")); break; default: (void) printf(gettext("Unknown state: %d\n"), ulog->kdb_state); break; } (void) printf(gettext("\tEntry block size : %u\n"), ulog->kdb_block); (void) printf(gettext("\tNumber of entries : %u\n"), ulog->kdb_num); if (ulog->kdb_last_sno == 0) (void) printf(gettext("\tLast serial # : None\n")); else { if (ulog->kdb_first_sno == 0) (void) printf(gettext("\tFirst serial # : None\n")); else { (void) printf(gettext("\tFirst serial # : ")); (void) printf("%u\n", ulog->kdb_first_sno); } (void) printf(gettext("\tLast serial # : ")); (void) printf("%u\n", ulog->kdb_last_sno); } if (ulog->kdb_last_time.seconds == 0L) { (void) printf(gettext("\tLast time stamp : None\n")); } else { if (ulog->kdb_first_time.seconds == 0L) (void) printf(gettext("\tFirst time stamp : None\n")); else { (void) printf(gettext("\tFirst time stamp : %s"), ctime((time_t *) &(ulog->kdb_first_time.seconds))); } (void) printf(gettext("\tLast time stamp : %s\n"), ctime((time_t *)&(ulog->kdb_last_time.seconds))); } if ((!headeronly) && ulog->kdb_num) { print_update(ulog, entry, verbose); } (void) printf("\n"); return (0); }