1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4*7f2fe78bSCy Schubert * Use is subject to license terms.
5*7f2fe78bSCy Schubert */
6*7f2fe78bSCy Schubert
7*7f2fe78bSCy Schubert /*
8*7f2fe78bSCy Schubert * This module will parse the update logs on the primary or replica servers.
9*7f2fe78bSCy Schubert */
10*7f2fe78bSCy Schubert
11*7f2fe78bSCy Schubert #include "k5-int.h"
12*7f2fe78bSCy Schubert #include "k5-hex.h"
13*7f2fe78bSCy Schubert #include <locale.h>
14*7f2fe78bSCy Schubert #include <sys/types.h>
15*7f2fe78bSCy Schubert #include <sys/mman.h>
16*7f2fe78bSCy Schubert #include <time.h>
17*7f2fe78bSCy Schubert #include <limits.h>
18*7f2fe78bSCy Schubert #include <locale.h>
19*7f2fe78bSCy Schubert #include <syslog.h>
20*7f2fe78bSCy Schubert #include <kdb_log.h>
21*7f2fe78bSCy Schubert #include <kadm5/admin.h>
22*7f2fe78bSCy Schubert #include <adm_proto.h>
23*7f2fe78bSCy Schubert
24*7f2fe78bSCy Schubert static char *progname;
25*7f2fe78bSCy Schubert
26*7f2fe78bSCy Schubert static void
usage()27*7f2fe78bSCy Schubert usage()
28*7f2fe78bSCy Schubert {
29*7f2fe78bSCy Schubert fprintf(stderr, _("\nUsage: %s [-h] [-v] [-v] [-e num]\n\t%s -R\n\n"),
30*7f2fe78bSCy Schubert progname, progname);
31*7f2fe78bSCy Schubert exit(1);
32*7f2fe78bSCy Schubert }
33*7f2fe78bSCy Schubert
34*7f2fe78bSCy Schubert /*
35*7f2fe78bSCy Schubert * Print the attribute flags of principal in human readable form.
36*7f2fe78bSCy Schubert */
37*7f2fe78bSCy Schubert static void
print_flags(unsigned int flags)38*7f2fe78bSCy Schubert print_flags(unsigned int flags)
39*7f2fe78bSCy Schubert {
40*7f2fe78bSCy Schubert char **attrstrs, **sp;
41*7f2fe78bSCy Schubert
42*7f2fe78bSCy Schubert if (krb5_flags_to_strings(flags, &attrstrs) != 0) {
43*7f2fe78bSCy Schubert printf("\t\t\t(error)\n");
44*7f2fe78bSCy Schubert return;
45*7f2fe78bSCy Schubert }
46*7f2fe78bSCy Schubert for (sp = attrstrs; sp != NULL && *sp != NULL; sp++) {
47*7f2fe78bSCy Schubert printf("\t\t\t%s\n", *sp);
48*7f2fe78bSCy Schubert free(*sp);
49*7f2fe78bSCy Schubert }
50*7f2fe78bSCy Schubert free(attrstrs);
51*7f2fe78bSCy Schubert }
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert /* ctime() for uint32_t* */
54*7f2fe78bSCy Schubert static const char *
ctime_uint32(uint32_t * time32)55*7f2fe78bSCy Schubert ctime_uint32(uint32_t *time32)
56*7f2fe78bSCy Schubert {
57*7f2fe78bSCy Schubert time_t tmp;
58*7f2fe78bSCy Schubert const char *r;
59*7f2fe78bSCy Schubert
60*7f2fe78bSCy Schubert tmp = *time32;
61*7f2fe78bSCy Schubert r = ctime(&tmp);
62*7f2fe78bSCy Schubert return (r == NULL) ? "(error)" : r;
63*7f2fe78bSCy Schubert }
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert /* Display time information. */
66*7f2fe78bSCy Schubert static void
print_time(uint32_t * timep)67*7f2fe78bSCy Schubert print_time(uint32_t *timep)
68*7f2fe78bSCy Schubert {
69*7f2fe78bSCy Schubert if (*timep == 0L)
70*7f2fe78bSCy Schubert printf("\t\t\tNone\n");
71*7f2fe78bSCy Schubert else
72*7f2fe78bSCy Schubert printf("\t\t\t%s", ctime_uint32(timep));
73*7f2fe78bSCy Schubert }
74*7f2fe78bSCy Schubert
75*7f2fe78bSCy Schubert static void
print_deltat(uint32_t * deltat)76*7f2fe78bSCy Schubert print_deltat(uint32_t *deltat)
77*7f2fe78bSCy Schubert {
78*7f2fe78bSCy Schubert krb5_error_code ret;
79*7f2fe78bSCy Schubert static char buf[30];
80*7f2fe78bSCy Schubert
81*7f2fe78bSCy Schubert ret = krb5_deltat_to_string(*deltat, buf, sizeof(buf));
82*7f2fe78bSCy Schubert if (ret)
83*7f2fe78bSCy Schubert printf("\t\t\t(error)\n");
84*7f2fe78bSCy Schubert else
85*7f2fe78bSCy Schubert printf("\t\t\t%s\n", buf);
86*7f2fe78bSCy Schubert }
87*7f2fe78bSCy Schubert
88*7f2fe78bSCy Schubert /* Display string in hex primitive. */
89*7f2fe78bSCy Schubert static void
print_hex(const char * tag,utf8str_t * str)90*7f2fe78bSCy Schubert print_hex(const char *tag, utf8str_t *str)
91*7f2fe78bSCy Schubert {
92*7f2fe78bSCy Schubert unsigned int len;
93*7f2fe78bSCy Schubert char *hex;
94*7f2fe78bSCy Schubert
95*7f2fe78bSCy Schubert len = str->utf8str_t_len;
96*7f2fe78bSCy Schubert
97*7f2fe78bSCy Schubert if (k5_hex_encode(str->utf8str_t_val, len, FALSE, &hex) != 0)
98*7f2fe78bSCy Schubert abort();
99*7f2fe78bSCy Schubert printf("\t\t\t%s(%d): 0x%s\n", tag, len, hex);
100*7f2fe78bSCy Schubert free(hex);
101*7f2fe78bSCy Schubert }
102*7f2fe78bSCy Schubert
103*7f2fe78bSCy Schubert /* Display string primitive. */
104*7f2fe78bSCy Schubert static void
print_str(const char * tag,utf8str_t * str)105*7f2fe78bSCy Schubert print_str(const char *tag, utf8str_t *str)
106*7f2fe78bSCy Schubert {
107*7f2fe78bSCy Schubert krb5_error_code ret;
108*7f2fe78bSCy Schubert char *s;
109*7f2fe78bSCy Schubert
110*7f2fe78bSCy Schubert s = k5memdup0(str->utf8str_t_val, str->utf8str_t_len, &ret);
111*7f2fe78bSCy Schubert if (s == NULL) {
112*7f2fe78bSCy Schubert fprintf(stderr, _("\nCouldn't allocate memory"));
113*7f2fe78bSCy Schubert exit(1);
114*7f2fe78bSCy Schubert }
115*7f2fe78bSCy Schubert printf("\t\t\t%s(%d): %s\n", tag, str->utf8str_t_len, s);
116*7f2fe78bSCy Schubert free(s);
117*7f2fe78bSCy Schubert }
118*7f2fe78bSCy Schubert
119*7f2fe78bSCy Schubert /* Display data components. */
120*7f2fe78bSCy Schubert static void
print_data(const char * tag,kdbe_data_t * data)121*7f2fe78bSCy Schubert print_data(const char *tag, kdbe_data_t *data)
122*7f2fe78bSCy Schubert {
123*7f2fe78bSCy Schubert printf("\t\t\tmagic: 0x%x\n", data->k_magic);
124*7f2fe78bSCy Schubert print_str(tag, &data->k_data);
125*7f2fe78bSCy Schubert }
126*7f2fe78bSCy Schubert
127*7f2fe78bSCy Schubert /* Display the principal components. */
128*7f2fe78bSCy Schubert static void
print_princ(kdbe_princ_t * princ)129*7f2fe78bSCy Schubert print_princ(kdbe_princ_t *princ)
130*7f2fe78bSCy Schubert {
131*7f2fe78bSCy Schubert int i, len;
132*7f2fe78bSCy Schubert kdbe_data_t *data;
133*7f2fe78bSCy Schubert
134*7f2fe78bSCy Schubert print_str("realm", &princ->k_realm);
135*7f2fe78bSCy Schubert
136*7f2fe78bSCy Schubert len = princ->k_components.k_components_len;
137*7f2fe78bSCy Schubert data = princ->k_components.k_components_val;
138*7f2fe78bSCy Schubert for (i = 0; i < len; i++, data++)
139*7f2fe78bSCy Schubert print_data("princ", data);
140*7f2fe78bSCy Schubert }
141*7f2fe78bSCy Schubert
142*7f2fe78bSCy Schubert /* Display individual key. */
143*7f2fe78bSCy Schubert static void
print_key(kdbe_key_t * k)144*7f2fe78bSCy Schubert print_key(kdbe_key_t *k)
145*7f2fe78bSCy Schubert {
146*7f2fe78bSCy Schubert unsigned int i;
147*7f2fe78bSCy Schubert utf8str_t *str;
148*7f2fe78bSCy Schubert
149*7f2fe78bSCy Schubert printf("\t\t\tver: %d\n", k->k_ver);
150*7f2fe78bSCy Schubert printf("\t\t\tkvno: %d\n", k->k_kvno);
151*7f2fe78bSCy Schubert
152*7f2fe78bSCy Schubert for (i = 0; i < k->k_enctype.k_enctype_len; i++)
153*7f2fe78bSCy Schubert printf("\t\t\tenc type: 0x%x\n", k->k_enctype.k_enctype_val[i]);
154*7f2fe78bSCy Schubert
155*7f2fe78bSCy Schubert str = k->k_contents.k_contents_val;
156*7f2fe78bSCy Schubert for (i = 0; i < k->k_contents.k_contents_len; i++, str++)
157*7f2fe78bSCy Schubert print_hex("key", str);
158*7f2fe78bSCy Schubert }
159*7f2fe78bSCy Schubert
160*7f2fe78bSCy Schubert /* Display all key data. */
161*7f2fe78bSCy Schubert static void
print_keydata(kdbe_key_t * keys,unsigned int len)162*7f2fe78bSCy Schubert print_keydata(kdbe_key_t *keys, unsigned int len)
163*7f2fe78bSCy Schubert {
164*7f2fe78bSCy Schubert unsigned int i;
165*7f2fe78bSCy Schubert
166*7f2fe78bSCy Schubert for (i = 0; i < len; i++, keys++)
167*7f2fe78bSCy Schubert print_key(keys);
168*7f2fe78bSCy Schubert }
169*7f2fe78bSCy Schubert
170*7f2fe78bSCy Schubert /* Display TL item. */
171*7f2fe78bSCy Schubert static void
print_tl(kdbe_tl_t * tl)172*7f2fe78bSCy Schubert print_tl(kdbe_tl_t *tl)
173*7f2fe78bSCy Schubert {
174*7f2fe78bSCy Schubert int i, len;
175*7f2fe78bSCy Schubert
176*7f2fe78bSCy Schubert printf("\t\t\ttype: 0x%x\n", tl->tl_type);
177*7f2fe78bSCy Schubert
178*7f2fe78bSCy Schubert len = tl->tl_data.tl_data_len;
179*7f2fe78bSCy Schubert
180*7f2fe78bSCy Schubert printf("\t\t\tvalue(%d): 0x", len);
181*7f2fe78bSCy Schubert for (i = 0; i < len; i++)
182*7f2fe78bSCy Schubert printf("%02x", (krb5_octet)tl->tl_data.tl_data_val[i]);
183*7f2fe78bSCy Schubert printf("\n");
184*7f2fe78bSCy Schubert }
185*7f2fe78bSCy Schubert
186*7f2fe78bSCy Schubert /* Display TL data items. */
187*7f2fe78bSCy Schubert static void
print_tldata(kdbe_tl_t * tldata,int len)188*7f2fe78bSCy Schubert print_tldata(kdbe_tl_t *tldata, int len)
189*7f2fe78bSCy Schubert {
190*7f2fe78bSCy Schubert int i;
191*7f2fe78bSCy Schubert
192*7f2fe78bSCy Schubert printf("\t\t\titems: %d\n", len);
193*7f2fe78bSCy Schubert for (i = 0; i < len; i++, tldata++)
194*7f2fe78bSCy Schubert print_tl(tldata);
195*7f2fe78bSCy Schubert }
196*7f2fe78bSCy Schubert
197*7f2fe78bSCy Schubert /*
198*7f2fe78bSCy Schubert * Print the individual types if verbose mode was specified.
199*7f2fe78bSCy Schubert * If verbose-verbose then print types along with respective values.
200*7f2fe78bSCy Schubert */
201*7f2fe78bSCy Schubert static void
print_attr(kdbe_val_t * val,int vverbose)202*7f2fe78bSCy Schubert print_attr(kdbe_val_t *val, int vverbose)
203*7f2fe78bSCy Schubert {
204*7f2fe78bSCy Schubert switch (val->av_type) {
205*7f2fe78bSCy Schubert case AT_ATTRFLAGS:
206*7f2fe78bSCy Schubert printf(_("\t\tAttribute flags\n"));
207*7f2fe78bSCy Schubert if (vverbose)
208*7f2fe78bSCy Schubert print_flags(val->kdbe_val_t_u.av_attrflags);
209*7f2fe78bSCy Schubert break;
210*7f2fe78bSCy Schubert case AT_MAX_LIFE:
211*7f2fe78bSCy Schubert printf(_("\t\tMaximum ticket life\n"));
212*7f2fe78bSCy Schubert if (vverbose)
213*7f2fe78bSCy Schubert print_deltat(&val->kdbe_val_t_u.av_max_life);
214*7f2fe78bSCy Schubert break;
215*7f2fe78bSCy Schubert case AT_MAX_RENEW_LIFE:
216*7f2fe78bSCy Schubert printf(_("\t\tMaximum renewable life\n"));
217*7f2fe78bSCy Schubert if (vverbose)
218*7f2fe78bSCy Schubert print_deltat(&val->kdbe_val_t_u.av_max_renew_life);
219*7f2fe78bSCy Schubert break;
220*7f2fe78bSCy Schubert case AT_EXP:
221*7f2fe78bSCy Schubert printf(_("\t\tPrincipal expiration\n"));
222*7f2fe78bSCy Schubert if (vverbose)
223*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_exp);
224*7f2fe78bSCy Schubert break;
225*7f2fe78bSCy Schubert case AT_PW_EXP:
226*7f2fe78bSCy Schubert printf(_("\t\tPassword expiration\n"));
227*7f2fe78bSCy Schubert if (vverbose)
228*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_pw_exp);
229*7f2fe78bSCy Schubert break;
230*7f2fe78bSCy Schubert case AT_LAST_SUCCESS:
231*7f2fe78bSCy Schubert printf(_("\t\tLast successful auth\n"));
232*7f2fe78bSCy Schubert if (vverbose)
233*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_last_success);
234*7f2fe78bSCy Schubert break;
235*7f2fe78bSCy Schubert case AT_LAST_FAILED:
236*7f2fe78bSCy Schubert printf(_("\t\tLast failed auth\n"));
237*7f2fe78bSCy Schubert if (vverbose)
238*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_last_failed);
239*7f2fe78bSCy Schubert break;
240*7f2fe78bSCy Schubert case AT_FAIL_AUTH_COUNT:
241*7f2fe78bSCy Schubert printf(_("\t\tFailed passwd attempt\n"));
242*7f2fe78bSCy Schubert if (vverbose)
243*7f2fe78bSCy Schubert printf("\t\t\t%d\n", val->kdbe_val_t_u.av_fail_auth_count);
244*7f2fe78bSCy Schubert break;
245*7f2fe78bSCy Schubert case AT_PRINC:
246*7f2fe78bSCy Schubert printf(_("\t\tPrincipal\n"));
247*7f2fe78bSCy Schubert if (vverbose)
248*7f2fe78bSCy Schubert print_princ(&val->kdbe_val_t_u.av_princ);
249*7f2fe78bSCy Schubert break;
250*7f2fe78bSCy Schubert case AT_KEYDATA:
251*7f2fe78bSCy Schubert printf(_("\t\tKey data\n"));
252*7f2fe78bSCy Schubert if (vverbose) {
253*7f2fe78bSCy Schubert print_keydata(val->kdbe_val_t_u.av_keydata.av_keydata_val,
254*7f2fe78bSCy Schubert val->kdbe_val_t_u.av_keydata.av_keydata_len);
255*7f2fe78bSCy Schubert }
256*7f2fe78bSCy Schubert break;
257*7f2fe78bSCy Schubert case AT_TL_DATA:
258*7f2fe78bSCy Schubert printf(_("\t\tTL data\n"));
259*7f2fe78bSCy Schubert if (vverbose) {
260*7f2fe78bSCy Schubert print_tldata(val->kdbe_val_t_u.av_tldata.av_tldata_val,
261*7f2fe78bSCy Schubert val->kdbe_val_t_u.av_tldata.av_tldata_len);
262*7f2fe78bSCy Schubert }
263*7f2fe78bSCy Schubert break;
264*7f2fe78bSCy Schubert case AT_LEN:
265*7f2fe78bSCy Schubert printf(_("\t\tLength\n"));
266*7f2fe78bSCy Schubert if (vverbose)
267*7f2fe78bSCy Schubert printf("\t\t\t%d\n", val->kdbe_val_t_u.av_len);
268*7f2fe78bSCy Schubert break;
269*7f2fe78bSCy Schubert case AT_PW_LAST_CHANGE:
270*7f2fe78bSCy Schubert printf(_("\t\tPassword last changed\n"));
271*7f2fe78bSCy Schubert if (vverbose)
272*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_pw_last_change);
273*7f2fe78bSCy Schubert break;
274*7f2fe78bSCy Schubert case AT_MOD_PRINC:
275*7f2fe78bSCy Schubert printf(_("\t\tModifying principal\n"));
276*7f2fe78bSCy Schubert if (vverbose)
277*7f2fe78bSCy Schubert print_princ(&val->kdbe_val_t_u.av_mod_princ);
278*7f2fe78bSCy Schubert break;
279*7f2fe78bSCy Schubert case AT_MOD_TIME:
280*7f2fe78bSCy Schubert printf(_("\t\tModification time\n"));
281*7f2fe78bSCy Schubert if (vverbose)
282*7f2fe78bSCy Schubert print_time(&val->kdbe_val_t_u.av_mod_time);
283*7f2fe78bSCy Schubert break;
284*7f2fe78bSCy Schubert case AT_MOD_WHERE:
285*7f2fe78bSCy Schubert printf(_("\t\tModified where\n"));
286*7f2fe78bSCy Schubert if (vverbose)
287*7f2fe78bSCy Schubert print_str("where", &val->kdbe_val_t_u.av_mod_where);
288*7f2fe78bSCy Schubert break;
289*7f2fe78bSCy Schubert case AT_PW_POLICY:
290*7f2fe78bSCy Schubert printf(_("\t\tPassword policy\n"));
291*7f2fe78bSCy Schubert if (vverbose)
292*7f2fe78bSCy Schubert print_str("policy", &val->kdbe_val_t_u.av_pw_policy);
293*7f2fe78bSCy Schubert break;
294*7f2fe78bSCy Schubert case AT_PW_POLICY_SWITCH:
295*7f2fe78bSCy Schubert printf(_("\t\tPassword policy switch\n"));
296*7f2fe78bSCy Schubert if (vverbose)
297*7f2fe78bSCy Schubert printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_policy_switch);
298*7f2fe78bSCy Schubert break;
299*7f2fe78bSCy Schubert case AT_PW_HIST_KVNO:
300*7f2fe78bSCy Schubert printf(_("\t\tPassword history KVNO\n"));
301*7f2fe78bSCy Schubert if (vverbose)
302*7f2fe78bSCy Schubert printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_hist_kvno);
303*7f2fe78bSCy Schubert break;
304*7f2fe78bSCy Schubert case AT_PW_HIST:
305*7f2fe78bSCy Schubert printf(_("\t\tPassword history\n"));
306*7f2fe78bSCy Schubert if (vverbose)
307*7f2fe78bSCy Schubert printf("\t\t\tPW history elided\n");
308*7f2fe78bSCy Schubert break;
309*7f2fe78bSCy Schubert } /* switch */
310*7f2fe78bSCy Schubert
311*7f2fe78bSCy Schubert }
312*7f2fe78bSCy Schubert /*
313*7f2fe78bSCy Schubert * Print the update entry information
314*7f2fe78bSCy Schubert */
315*7f2fe78bSCy Schubert static void
print_update(kdb_hlog_t * ulog,uint32_t entry,uint32_t ulogentries,unsigned int verbose)316*7f2fe78bSCy Schubert print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries,
317*7f2fe78bSCy Schubert unsigned int verbose)
318*7f2fe78bSCy Schubert {
319*7f2fe78bSCy Schubert XDR xdrs;
320*7f2fe78bSCy Schubert uint32_t start_sno, i, j, indx;
321*7f2fe78bSCy Schubert char *dbprinc;
322*7f2fe78bSCy Schubert kdb_ent_header_t *indx_log;
323*7f2fe78bSCy Schubert kdb_incr_update_t upd;
324*7f2fe78bSCy Schubert
325*7f2fe78bSCy Schubert if (entry && (entry < ulog->kdb_num))
326*7f2fe78bSCy Schubert start_sno = ulog->kdb_last_sno - entry;
327*7f2fe78bSCy Schubert else
328*7f2fe78bSCy Schubert start_sno = ulog->kdb_first_sno - 1;
329*7f2fe78bSCy Schubert
330*7f2fe78bSCy Schubert for (i = start_sno; i < ulog->kdb_last_sno; i++) {
331*7f2fe78bSCy Schubert indx = i % ulogentries;
332*7f2fe78bSCy Schubert
333*7f2fe78bSCy Schubert indx_log = INDEX(ulog, indx);
334*7f2fe78bSCy Schubert
335*7f2fe78bSCy Schubert /*
336*7f2fe78bSCy Schubert * Check for corrupt update entry
337*7f2fe78bSCy Schubert */
338*7f2fe78bSCy Schubert if (indx_log->kdb_umagic != KDB_ULOG_MAGIC) {
339*7f2fe78bSCy Schubert fprintf(stderr, _("Corrupt update entry\n\n"));
340*7f2fe78bSCy Schubert exit(1);
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert
343*7f2fe78bSCy Schubert printf("---\n");
344*7f2fe78bSCy Schubert printf(_("Update Entry\n"));
345*7f2fe78bSCy Schubert
346*7f2fe78bSCy Schubert printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno);
347*7f2fe78bSCy Schubert
348*7f2fe78bSCy Schubert /* The initial entry after a reset is a dummy entry; skip it. */
349*7f2fe78bSCy Schubert if (indx_log->kdb_entry_size == 0) {
350*7f2fe78bSCy Schubert printf(_("\tDummy entry\n"));
351*7f2fe78bSCy Schubert continue;
352*7f2fe78bSCy Schubert }
353*7f2fe78bSCy Schubert
354*7f2fe78bSCy Schubert memset(&upd, 0, sizeof(kdb_incr_update_t));
355*7f2fe78bSCy Schubert xdrmem_create(&xdrs, (char *)indx_log->entry_data,
356*7f2fe78bSCy Schubert indx_log->kdb_entry_size, XDR_DECODE);
357*7f2fe78bSCy Schubert if (!xdr_kdb_incr_update_t(&xdrs, &upd)) {
358*7f2fe78bSCy Schubert printf(_("Entry data decode failure\n\n"));
359*7f2fe78bSCy Schubert exit(1);
360*7f2fe78bSCy Schubert }
361*7f2fe78bSCy Schubert
362*7f2fe78bSCy Schubert printf(_("\tUpdate operation : "));
363*7f2fe78bSCy Schubert if (upd.kdb_deleted)
364*7f2fe78bSCy Schubert printf(_("Delete\n"));
365*7f2fe78bSCy Schubert else
366*7f2fe78bSCy Schubert printf(_("Add\n"));
367*7f2fe78bSCy Schubert
368*7f2fe78bSCy Schubert dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1);
369*7f2fe78bSCy Schubert if (dbprinc == NULL) {
370*7f2fe78bSCy Schubert printf(_("Could not allocate principal name\n\n"));
371*7f2fe78bSCy Schubert exit(1);
372*7f2fe78bSCy Schubert }
373*7f2fe78bSCy Schubert strncpy(dbprinc, upd.kdb_princ_name.utf8str_t_val,
374*7f2fe78bSCy Schubert upd.kdb_princ_name.utf8str_t_len);
375*7f2fe78bSCy Schubert dbprinc[upd.kdb_princ_name.utf8str_t_len] = 0;
376*7f2fe78bSCy Schubert printf(_("\tUpdate principal : %s\n"), dbprinc);
377*7f2fe78bSCy Schubert
378*7f2fe78bSCy Schubert printf(_("\tUpdate size : %u\n"), indx_log->kdb_entry_size);
379*7f2fe78bSCy Schubert printf(_("\tUpdate committed : %s\n"),
380*7f2fe78bSCy Schubert indx_log->kdb_commit ? "True" : "False");
381*7f2fe78bSCy Schubert
382*7f2fe78bSCy Schubert if (indx_log->kdb_time.seconds == 0L) {
383*7f2fe78bSCy Schubert printf(_("\tUpdate time stamp : None\n"));
384*7f2fe78bSCy Schubert } else{
385*7f2fe78bSCy Schubert printf(_("\tUpdate time stamp : %s"),
386*7f2fe78bSCy Schubert ctime_uint32(&indx_log->kdb_time.seconds));
387*7f2fe78bSCy Schubert }
388*7f2fe78bSCy Schubert
389*7f2fe78bSCy Schubert printf(_("\tAttributes changed : %d\n"), upd.kdb_update.kdbe_t_len);
390*7f2fe78bSCy Schubert
391*7f2fe78bSCy Schubert if (verbose) {
392*7f2fe78bSCy Schubert for (j = 0; j < upd.kdb_update.kdbe_t_len; j++)
393*7f2fe78bSCy Schubert print_attr(&upd.kdb_update.kdbe_t_val[j], verbose > 1 ? 1 : 0);
394*7f2fe78bSCy Schubert }
395*7f2fe78bSCy Schubert
396*7f2fe78bSCy Schubert xdr_free(xdr_kdb_incr_update_t, (char *)&upd);
397*7f2fe78bSCy Schubert free(dbprinc);
398*7f2fe78bSCy Schubert }
399*7f2fe78bSCy Schubert }
400*7f2fe78bSCy Schubert
401*7f2fe78bSCy Schubert /* Return a read-only mmap of the ulog, or NULL on failure. */
402*7f2fe78bSCy Schubert static kdb_hlog_t *
map_ulog(const char * filename,int * fd_out)403*7f2fe78bSCy Schubert map_ulog(const char *filename, int *fd_out)
404*7f2fe78bSCy Schubert {
405*7f2fe78bSCy Schubert int fd;
406*7f2fe78bSCy Schubert struct stat st;
407*7f2fe78bSCy Schubert kdb_hlog_t *ulog = MAP_FAILED;
408*7f2fe78bSCy Schubert
409*7f2fe78bSCy Schubert *fd_out = -1;
410*7f2fe78bSCy Schubert
411*7f2fe78bSCy Schubert fd = open(filename, O_RDONLY);
412*7f2fe78bSCy Schubert if (fd == -1)
413*7f2fe78bSCy Schubert return NULL;
414*7f2fe78bSCy Schubert if (fstat(fd, &st) < 0) {
415*7f2fe78bSCy Schubert close(fd);
416*7f2fe78bSCy Schubert return NULL;
417*7f2fe78bSCy Schubert }
418*7f2fe78bSCy Schubert ulog = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
419*7f2fe78bSCy Schubert if (ulog == MAP_FAILED) {
420*7f2fe78bSCy Schubert close(fd);
421*7f2fe78bSCy Schubert return NULL;
422*7f2fe78bSCy Schubert }
423*7f2fe78bSCy Schubert *fd_out = fd;
424*7f2fe78bSCy Schubert return ulog;
425*7f2fe78bSCy Schubert }
426*7f2fe78bSCy Schubert
427*7f2fe78bSCy Schubert int
main(int argc,char ** argv)428*7f2fe78bSCy Schubert main(int argc, char **argv)
429*7f2fe78bSCy Schubert {
430*7f2fe78bSCy Schubert int c, ulog_fd = -1;
431*7f2fe78bSCy Schubert unsigned int verbose = 0;
432*7f2fe78bSCy Schubert bool_t headeronly = FALSE, reset = FALSE;
433*7f2fe78bSCy Schubert uint32_t entry = 0;
434*7f2fe78bSCy Schubert krb5_context context;
435*7f2fe78bSCy Schubert kadm5_config_params params;
436*7f2fe78bSCy Schubert kdb_hlog_t *ulog = NULL;
437*7f2fe78bSCy Schubert
438*7f2fe78bSCy Schubert setlocale(LC_ALL, "");
439*7f2fe78bSCy Schubert
440*7f2fe78bSCy Schubert progname = argv[0];
441*7f2fe78bSCy Schubert
442*7f2fe78bSCy Schubert while ((c = getopt(argc, argv, "Rvhe:")) != -1) {
443*7f2fe78bSCy Schubert switch (c) {
444*7f2fe78bSCy Schubert case 'h':
445*7f2fe78bSCy Schubert headeronly = TRUE;
446*7f2fe78bSCy Schubert break;
447*7f2fe78bSCy Schubert case 'e':
448*7f2fe78bSCy Schubert entry = atoi(optarg);
449*7f2fe78bSCy Schubert break;
450*7f2fe78bSCy Schubert case 'R':
451*7f2fe78bSCy Schubert reset = TRUE;
452*7f2fe78bSCy Schubert break;
453*7f2fe78bSCy Schubert case 'v':
454*7f2fe78bSCy Schubert verbose++;
455*7f2fe78bSCy Schubert break;
456*7f2fe78bSCy Schubert default:
457*7f2fe78bSCy Schubert usage();
458*7f2fe78bSCy Schubert }
459*7f2fe78bSCy Schubert }
460*7f2fe78bSCy Schubert
461*7f2fe78bSCy Schubert if (kadm5_init_krb5_context(&context)) {
462*7f2fe78bSCy Schubert fprintf(stderr, _("Unable to initialize Kerberos\n\n"));
463*7f2fe78bSCy Schubert exit(1);
464*7f2fe78bSCy Schubert }
465*7f2fe78bSCy Schubert
466*7f2fe78bSCy Schubert memset(¶ms, 0, sizeof(params));
467*7f2fe78bSCy Schubert
468*7f2fe78bSCy Schubert if (kadm5_get_config_params(context, 1, ¶ms, ¶ms)) {
469*7f2fe78bSCy Schubert fprintf(stderr, _("Couldn't read database_name\n\n"));
470*7f2fe78bSCy Schubert exit(1);
471*7f2fe78bSCy Schubert }
472*7f2fe78bSCy Schubert
473*7f2fe78bSCy Schubert printf(_("\nKerberos update log (%s)\n"), params.iprop_logfile);
474*7f2fe78bSCy Schubert
475*7f2fe78bSCy Schubert if (reset) {
476*7f2fe78bSCy Schubert if (ulog_map(context, params.iprop_logfile, params.iprop_ulogsize)) {
477*7f2fe78bSCy Schubert fprintf(stderr, _("Unable to map log file %s\n\n"),
478*7f2fe78bSCy Schubert params.iprop_logfile);
479*7f2fe78bSCy Schubert exit(1);
480*7f2fe78bSCy Schubert }
481*7f2fe78bSCy Schubert if (ulog_init_header(context) != 0) {
482*7f2fe78bSCy Schubert fprintf(stderr, _("Couldn't reinitialize ulog file %s\n\n"),
483*7f2fe78bSCy Schubert params.iprop_logfile);
484*7f2fe78bSCy Schubert exit(1);
485*7f2fe78bSCy Schubert }
486*7f2fe78bSCy Schubert printf(_("Reinitialized the ulog.\n"));
487*7f2fe78bSCy Schubert ulog_fini(context);
488*7f2fe78bSCy Schubert goto done;
489*7f2fe78bSCy Schubert }
490*7f2fe78bSCy Schubert
491*7f2fe78bSCy Schubert ulog = map_ulog(params.iprop_logfile, &ulog_fd);
492*7f2fe78bSCy Schubert if (ulog == NULL) {
493*7f2fe78bSCy Schubert fprintf(stderr, _("Unable to map log file %s\n\n"),
494*7f2fe78bSCy Schubert params.iprop_logfile);
495*7f2fe78bSCy Schubert exit(1);
496*7f2fe78bSCy Schubert }
497*7f2fe78bSCy Schubert
498*7f2fe78bSCy Schubert if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC) {
499*7f2fe78bSCy Schubert fprintf(stderr, _("Corrupt header log, exiting\n\n"));
500*7f2fe78bSCy Schubert exit(1);
501*7f2fe78bSCy Schubert }
502*7f2fe78bSCy Schubert
503*7f2fe78bSCy Schubert printf(_("Update log dump :\n"));
504*7f2fe78bSCy Schubert printf(_("\tLog version # : %u\n"), ulog->db_version_num);
505*7f2fe78bSCy Schubert printf(_("\tLog state : "));
506*7f2fe78bSCy Schubert switch (ulog->kdb_state) {
507*7f2fe78bSCy Schubert case KDB_STABLE:
508*7f2fe78bSCy Schubert printf(_("Stable\n"));
509*7f2fe78bSCy Schubert break;
510*7f2fe78bSCy Schubert case KDB_UNSTABLE:
511*7f2fe78bSCy Schubert printf(_("Unstable\n"));
512*7f2fe78bSCy Schubert break;
513*7f2fe78bSCy Schubert case KDB_CORRUPT:
514*7f2fe78bSCy Schubert printf(_("Corrupt\n"));
515*7f2fe78bSCy Schubert break;
516*7f2fe78bSCy Schubert default:
517*7f2fe78bSCy Schubert printf(_("Unknown state: %d\n"), ulog->kdb_state);
518*7f2fe78bSCy Schubert break;
519*7f2fe78bSCy Schubert }
520*7f2fe78bSCy Schubert printf(_("\tEntry block size : %u\n"), ulog->kdb_block);
521*7f2fe78bSCy Schubert printf(_("\tNumber of entries : %u\n"), ulog->kdb_num);
522*7f2fe78bSCy Schubert
523*7f2fe78bSCy Schubert if (ulog->kdb_last_sno == 0) {
524*7f2fe78bSCy Schubert printf(_("\tLast serial # : None\n"));
525*7f2fe78bSCy Schubert } else {
526*7f2fe78bSCy Schubert if (ulog->kdb_first_sno == 0) {
527*7f2fe78bSCy Schubert printf(_("\tFirst serial # : None\n"));
528*7f2fe78bSCy Schubert } else {
529*7f2fe78bSCy Schubert printf(_("\tFirst serial # : "));
530*7f2fe78bSCy Schubert printf("%u\n", ulog->kdb_first_sno);
531*7f2fe78bSCy Schubert }
532*7f2fe78bSCy Schubert
533*7f2fe78bSCy Schubert printf(_("\tLast serial # : "));
534*7f2fe78bSCy Schubert printf("%u\n", ulog->kdb_last_sno);
535*7f2fe78bSCy Schubert }
536*7f2fe78bSCy Schubert
537*7f2fe78bSCy Schubert if (ulog->kdb_last_time.seconds == 0L) {
538*7f2fe78bSCy Schubert printf(_("\tLast time stamp : None\n"));
539*7f2fe78bSCy Schubert } else {
540*7f2fe78bSCy Schubert if (ulog->kdb_first_time.seconds == 0L) {
541*7f2fe78bSCy Schubert printf(_("\tFirst time stamp : None\n"));
542*7f2fe78bSCy Schubert } else {
543*7f2fe78bSCy Schubert printf(_("\tFirst time stamp : %s"),
544*7f2fe78bSCy Schubert ctime_uint32(&ulog->kdb_first_time.seconds));
545*7f2fe78bSCy Schubert }
546*7f2fe78bSCy Schubert
547*7f2fe78bSCy Schubert printf(_("\tLast time stamp : %s\n"),
548*7f2fe78bSCy Schubert ctime_uint32(&ulog->kdb_last_time.seconds));
549*7f2fe78bSCy Schubert }
550*7f2fe78bSCy Schubert
551*7f2fe78bSCy Schubert if (!headeronly && ulog->kdb_num)
552*7f2fe78bSCy Schubert print_update(ulog, entry, params.iprop_ulogsize, verbose);
553*7f2fe78bSCy Schubert
554*7f2fe78bSCy Schubert printf("\n");
555*7f2fe78bSCy Schubert
556*7f2fe78bSCy Schubert done:
557*7f2fe78bSCy Schubert close(ulog_fd);
558*7f2fe78bSCy Schubert kadm5_free_config_params(context, ¶ms);
559*7f2fe78bSCy Schubert krb5_free_context(context);
560*7f2fe78bSCy Schubert return 0;
561*7f2fe78bSCy Schubert }
562