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
usage()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
print_attr(kdbe_attr_type_t type)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
print_update(kdb_hlog_t * ulog,uint32_t entry,bool_t verbose)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
main(int argc,char ** argv)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