1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * This module will parse the update logs on the master or slave servers. 8 */ 9 10 #include <stdio.h> 11 #include <libintl.h> 12 #include <sys/types.h> 13 #include <time.h> 14 #include <limits.h> 15 #include <locale.h> 16 #include <syslog.h> 17 #include <kdb/kdb_log.h> 18 #include <kadm5/admin.h> 19 20 static char *progname; 21 22 static void 23 usage() 24 { 25 (void) fprintf(stderr, gettext("\nUsage: %s [-h] [-v] [-e num]\n\n"), 26 progname); 27 exit(1); 28 } 29 30 /* 31 * Print the individual types if verbose mode was specified. 32 */ 33 static void 34 print_attr(kdbe_attr_type_t type) 35 { 36 switch (type) { 37 case AT_ATTRFLAGS: 38 (void) printf(gettext("\t\tAttribute flags\n")); 39 break; 40 case AT_MAX_LIFE: 41 (void) printf(gettext("\t\tMaximum ticket life\n")); 42 break; 43 case AT_MAX_RENEW_LIFE: 44 (void) printf(gettext("\t\tMaximum renewable life\n")); 45 break; 46 case AT_EXP: 47 (void) printf(gettext("\t\tPrincipal expiration\n")); 48 break; 49 case AT_PW_EXP: 50 (void) printf(gettext("\t\tPassword expiration\n")); 51 break; 52 case AT_LAST_SUCCESS: 53 (void) printf(gettext("\t\tLast successful auth\n")); 54 break; 55 case AT_LAST_FAILED: 56 (void) printf(gettext("\t\tLast failed auth\n")); 57 break; 58 case AT_FAIL_AUTH_COUNT: 59 (void) printf(gettext("\t\tFailed passwd attempt\n")); 60 break; 61 case AT_PRINC: 62 (void) printf(gettext("\t\tPrincipal\n")); 63 break; 64 case AT_KEYDATA: 65 (void) printf(gettext("\t\tKey data\n")); 66 break; 67 case AT_TL_DATA: 68 (void) printf(gettext("\t\tTL data\n")); 69 break; 70 case AT_LEN: 71 (void) printf(gettext("\t\tLength\n")); 72 break; 73 case AT_MOD_PRINC: 74 (void) printf(gettext("\t\tModifying principal\n")); 75 break; 76 case AT_MOD_TIME: 77 (void) printf(gettext("\t\tModification time\n")); 78 break; 79 case AT_MOD_WHERE: 80 (void) printf(gettext("\t\tModified where\n")); 81 break; 82 case AT_PW_LAST_CHANGE: 83 (void) printf(gettext("\t\tPassword last changed\n")); 84 break; 85 case AT_PW_POLICY: 86 (void) printf(gettext("\t\tPassword policy\n")); 87 break; 88 case AT_PW_POLICY_SWITCH: 89 (void) printf(gettext("\t\tPassword policy switch\n")); 90 break; 91 case AT_PW_HIST_KVNO: 92 (void) printf(gettext("\t\tPassword history KVNO\n")); 93 break; 94 case AT_PW_HIST: 95 (void) printf(gettext("\t\tPassword history\n")); 96 break; 97 } /* switch */ 98 99 } 100 /* 101 * Print the update entry information 102 */ 103 static void 104 print_update(kdb_hlog_t *ulog, uint32_t entry, bool_t verbose) 105 { 106 XDR xdrs; 107 uint32_t start_sno, i, j, indx; 108 char *dbprinc; 109 kdb_ent_header_t *indx_log; 110 kdb_incr_update_t upd; 111 112 if (entry && (entry < ulog->kdb_num)) 113 start_sno = ulog->kdb_last_sno - entry; 114 else 115 start_sno = ulog->kdb_first_sno - 1; 116 117 for (i = start_sno; i < ulog->kdb_last_sno; i++) { 118 indx = i % ulog->kdb_num; 119 120 indx_log = (kdb_ent_header_t *)INDEX(ulog, indx); 121 122 /* 123 * Check for corrupt update entry 124 */ 125 if (indx_log->kdb_umagic != KDB_UMAGIC) { 126 (void) fprintf(stderr, 127 gettext("Corrupt update entry\n\n")); 128 exit(1); 129 } 130 131 (void) memset((char *)&upd, 0, sizeof (kdb_incr_update_t)); 132 xdrmem_create(&xdrs, (char *)indx_log->entry_data, 133 indx_log->kdb_entry_size, XDR_DECODE); 134 if (!xdr_kdb_incr_update_t(&xdrs, &upd)) { 135 (void) printf(gettext("Entry data decode failure\n\n")); 136 exit(1); 137 } 138 139 (void) printf("---\n"); 140 (void) printf(gettext("Update Entry\n")); 141 142 (void) printf(gettext("\tUpdate serial # : %u\n"), 143 indx_log->kdb_entry_sno); 144 145 (void) printf(gettext("\tUpdate operation : ")); 146 if (upd.kdb_deleted) 147 (void) printf(gettext("Delete\n")); 148 else 149 (void) printf(gettext("Add\n")); 150 151 dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1); 152 if (dbprinc == NULL) { 153 (void) printf(gettext("Could not allocate " 154 "principal name\n\n")); 155 exit(1); 156 } 157 (void) strlcpy(dbprinc, upd.kdb_princ_name.utf8str_t_val, 158 (upd.kdb_princ_name.utf8str_t_len + 1)); 159 (void) printf(gettext("\tUpdate principal : %s\n"), dbprinc); 160 161 (void) printf(gettext("\tUpdate size : %u\n"), 162 indx_log->kdb_entry_size); 163 164 (void) printf(gettext("\tUpdate committed : %s\n"), 165 indx_log->kdb_commit ? "True" : "False"); 166 167 if (indx_log->kdb_time.seconds == 0L) 168 (void) printf(gettext("\tUpdate time stamp : None\n")); 169 else 170 (void) printf(gettext("\tUpdate time stamp : %s"), 171 ctime((time_t *)&(indx_log->kdb_time.seconds))); 172 173 (void) printf(gettext("\tAttributes changed : %d\n"), 174 upd.kdb_update.kdbe_t_len); 175 176 if (verbose) 177 for (j = 0; j < upd.kdb_update.kdbe_t_len; j++) 178 print_attr( 179 upd.kdb_update.kdbe_t_val[j].av_type); 180 181 xdr_free(xdr_kdb_incr_update_t, (char *)&upd); 182 if (dbprinc) 183 free(dbprinc); 184 } /* for */ 185 } 186 187 int 188 main(int argc, char **argv) 189 { 190 int c; 191 bool_t verbose = FALSE; 192 bool_t headeronly = FALSE; 193 uint32_t entry = 0; 194 krb5_context context; 195 kadm5_config_params params; 196 kdb_log_context *log_ctx; 197 kdb_hlog_t *ulog = NULL; 198 199 (void) setlocale(LC_ALL, ""); 200 201 #if !defined(TEXT_DOMAIN) 202 #define TEXT_DOMAIN "SYS_TEST" 203 #endif /* TEXT_DOMAIN */ 204 205 (void) textdomain(TEXT_DOMAIN); 206 207 if (geteuid() != (uid_t)0) { 208 (void) fprintf(stderr, 209 gettext("kproplog must be run as root\n\n")); 210 exit(1); 211 } 212 213 progname = argv[0]; 214 215 while ((c = getopt(argc, argv, "vhe:")) != -1) { 216 switch (c) { 217 case 'h': 218 headeronly = TRUE; 219 break; 220 case 'e': 221 entry = atoi(optarg); 222 break; 223 case 'v': 224 verbose = TRUE; 225 break; 226 default: 227 usage(); 228 } 229 } 230 231 if (krb5_init_context(&context)) { 232 (void) fprintf(stderr, 233 gettext("Unable to initialize Kerberos\n\n")); 234 exit(1); 235 } 236 237 (void) memset((char *)¶ms, 0, sizeof (params)); 238 239 if (kadm5_get_config_params(context, NULL, NULL, ¶ms, ¶ms)) { 240 (void) fprintf(stderr, 241 gettext("Couldn't read database_name\n\n")); 242 exit(1); 243 } 244 245 (void) printf(gettext("\nKerberos update log (%s.ulog)\n"), 246 params.dbname); 247 248 if (ulog_map(context, ¶ms, FKPROPLOG)) { 249 (void) fprintf(stderr, gettext("Unable to map log file " 250 "%s.ulog\n\n"), params.dbname); 251 exit(1); 252 } 253 254 log_ctx = context->kdblog_context; 255 if (log_ctx) 256 ulog = log_ctx->ulog; 257 else { 258 (void) fprintf(stderr, gettext("Unable to map log file " 259 "%s.ulog\n\n"), params.dbname); 260 exit(1); 261 } 262 263 if (ulog->kdb_hmagic != KDB_HMAGIC) { 264 (void) fprintf(stderr, 265 gettext("Corrupt header log, exiting\n\n")); 266 exit(1); 267 } 268 269 (void) printf(gettext("Update log dump :\n")); 270 (void) printf(gettext("\tLog version # : %u\n"), ulog->db_version_num); 271 (void) printf(gettext("\tLog state : ")); 272 switch (ulog->kdb_state) { 273 case KDB_STABLE: 274 (void) printf(gettext("Stable\n")); 275 break; 276 case KDB_UNSTABLE: 277 (void) printf(gettext("Unstable\n")); 278 break; 279 case KDB_CORRUPT: 280 (void) printf(gettext("Corrupt\n")); 281 break; 282 default: 283 (void) printf(gettext("Unknown state: %d\n"), 284 ulog->kdb_state); 285 break; 286 } 287 (void) printf(gettext("\tEntry block size : %u\n"), ulog->kdb_block); 288 (void) printf(gettext("\tNumber of entries : %u\n"), ulog->kdb_num); 289 290 if (ulog->kdb_last_sno == 0) 291 (void) printf(gettext("\tLast serial # : None\n")); 292 else { 293 if (ulog->kdb_first_sno == 0) 294 (void) printf(gettext("\tFirst serial # : None\n")); 295 else { 296 (void) printf(gettext("\tFirst serial # : ")); 297 (void) printf("%u\n", ulog->kdb_first_sno); 298 } 299 300 (void) printf(gettext("\tLast serial # : ")); 301 (void) printf("%u\n", ulog->kdb_last_sno); 302 } 303 304 if (ulog->kdb_last_time.seconds == 0L) { 305 (void) printf(gettext("\tLast time stamp : None\n")); 306 } else { 307 if (ulog->kdb_first_time.seconds == 0L) 308 (void) printf(gettext("\tFirst time stamp : None\n")); 309 else { 310 (void) printf(gettext("\tFirst time stamp : %s"), 311 ctime((time_t *) 312 &(ulog->kdb_first_time.seconds))); 313 } 314 315 (void) printf(gettext("\tLast time stamp : %s\n"), 316 ctime((time_t *)&(ulog->kdb_last_time.seconds))); 317 } 318 319 if ((!headeronly) && ulog->kdb_num) { 320 print_update(ulog, entry, verbose); 321 } 322 323 (void) printf("\n"); 324 325 return (0); 326 } 327