2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 /* This modified from the code in kerberos/src/lib/krb/tf_util.c. */
17 * This file contains routines for manipulating the ticket cache file.
19 * The ticket file is in the following format:
21 * principal's name (null-terminated string)
22 * principal's instance (null-terminated string)
29 * Where "CREDENTIAL_x" consists of the following fixed-length
30 * fields from the CREDENTIALS structure (see "krb.h"):
32 * char service[ANAME_SZ]
33 * char instance[INST_SZ]
34 * char realm[REALM_SZ]
39 * afs_int32 issue_date
44 /* Inspite of what the above comment suggests the fields are not fixed length
45 but null terminated as you might figure, except for the ticket which is
46 preceded by a 4 byte length. All fields in host order. 890306 */
47 #include <afsconfig.h>
48 #include <afs/param.h>
62 #include <sys/types.h>
69 #ifndef WORDS_BIGENDIAN
70 /* This was taken from jhutz's patch for heimdal krb4. It only
71 * applies to little endian systems. Big endian systems have a
72 * less elegant solution documented below.
74 * This record is written after every real ticket, to ensure that
75 * both 32- and 64-bit readers will perceive the next real ticket
76 * as starting in the same place. This record looks like a ticket
77 * with the following properties:
79 * ============ ================= =================
83 * session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
86 * ticket 12 nulls 4 nulls
89 static unsigned char align_rec[] = {
90 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x2e,
91 0x2e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
93 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 #else /* AFSLITTLE_ENDIAN */
100 /* This was taken from asedeno's patch for MIT Kerberos. These
101 * alignment records are for big endian systems. We need more of them
102 * because the portion of the 64-bit issue_date that overlaps with the
103 * start of a ticket on 32-bit systems contains an unpredictable
104 * number of NULL bytes. Preceeding these records is a second copy of
105 * the 32-bit issue_date. The srealm for the alignment records is
106 * always one of ".." or "?.."
110 * This is actually two alignment records since both 32- and 64-bit
111 * readers will agree on everything in the first record up through the
112 * issue_date size, except where sname starts.
113 * Field (1) 32-bit 64-bit
114 * ============ ================= =================
118 * session key 00000000 xxxxxxxx 00000000 xxxxxxxx
121 * ticket 4 nulls 4 nulls
124 * Field (2) 32-bit 64-bit
125 * ============ ================= =================
129 * session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
132 * ticket 12 nulls 4 nulls
136 static unsigned char align_rec_0[] = {
137 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00,
142 0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff, 0xff, 0xff,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00
150 * Field 32-bit 64-bit
151 * ============ ================= =================
152 * sname "x" |"xx"|"xxx" "."
153 * sinst "xx."|"x."|"." ".."
155 * session key 2E2E2E00 xxxxxxxx xxxxxxxx 00000000
158 * ticket 12 nulls 4 nulls
161 static unsigned char align_rec_1[] = {
162 0x2e, 0x00, 0x2e, 0x2e, 0x00, 0x2e, 0x2e, 0x2e,
163 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 * Field 32-bit 64-bit
172 * ============ ================= =================
173 * sname "x" |"x" |"xx" ".."
174 * sinst "" |"x" |"" ""
175 * srealm "x.."|".."|".." ".."
176 * session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
179 * ticket 12 nulls 4 nulls
182 static unsigned char align_rec_2[] = {
183 0x2e, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff,
184 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
186 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
191 * Things break here for 32-bit krb4 libraries that don't
192 * understand this alignment record. We can't really do
193 * anything about the fact that the three strings ended
194 * in the duplicate timestamp. The good news is that this
195 * only happens once every 0x1000000 seconds, once roughly
196 * every six and a half months. We'll live.
198 * Discussion on the krbdev list has suggested the
199 * issue_date be incremented by one in this case to avoid
200 * the problem. I'm leaving this here just in case.
202 * Field 32-bit 64-bit
203 * ============ ================= =================
207 * session key 2E00002E 2E00FFFF xxxx0000 0000xxxx
209 * kvno 4294901760 917504
210 * ticket 14 nulls 4 nulls
214 static unsigned char align_rec_3[] = {
215 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff,
216 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
222 #endif /* AFSLITTLE_ENDIAN */
225 krb_write_ticket_file(realm)
228 char ticket_file[AFSDIR_PATH_MAX];
234 struct ktc_principal client, server;
235 struct ktc_token token;
237 if ((strlen(realm) >= sizeof(client.cell)))
239 strcpy(server.name, KA_TGS_NAME);
240 strcpy(server.instance, realm);
241 lcstring(server.cell, realm, sizeof(server.cell));
243 code = ktc_GetToken(&server, &token, sizeof(struct ktc_token), &client);
247 /* Use the KRBTKFILE environment variable if it exists, otherwise fall
248 * back upon /tmp/tkt(uid}.
250 if (tf_name = (char *)getenv("KRBTKFILE"))
251 (void)sprintf(ticket_file, "%s", tf_name);
253 (void)sprintf(ticket_file, "%s/tkt%d", gettmpdir(), getuid());
254 fd = open(ticket_file, O_WRONLY + O_CREAT + O_TRUNC, 0700);
258 /* write client name as file header */
260 count = strlen(client.name) + 1;
261 if (write(fd, client.name, count) != count)
264 count = strlen(client.instance) + 1;
265 if (write(fd, client.instance, count) != count)
268 /* Write the ticket and associated data */
270 count = strlen(server.name) + 1;
271 if (write(fd, server.name, count) != count)
274 count = strlen(server.instance) + 1;
275 if (write(fd, server.instance, count) != count)
278 ucstring(server.cell, server.cell, sizeof(server.cell));
279 count = strlen(server.cell) + 1;
280 if (write(fd, server.cell, count) != count)
283 if (write(fd, (char *)&token.sessionKey, 8) != 8)
286 lifetime = time_to_life(token.startTime, token.endTime);
287 if (write(fd, (char *)&lifetime, sizeof(int)) != sizeof(int))
291 if (write(fd, (char *)&kvno, sizeof(int)) != sizeof(int))
294 if (write(fd, (char *)&(token.ticketLen), sizeof(int)) != sizeof(int))
297 count = token.ticketLen;
298 if (write(fd, (char *)(token.ticket), count) != count)
301 if (write(fd, (char *)&(token.startTime), sizeof(afs_int32))
302 != sizeof(afs_int32))
307 /* Alignment Record, from MIT Kerberos */
308 #ifndef WORDS_BIGENDIAN
309 if (write(fd, align_rec, sizeof(align_rec)) != sizeof(align_rec))
311 #else /* AFSLITTLE_ENDIAN */
314 if (0 == (token.startTime & 0xff000000))
316 if (0 == (token.startTime & 0x00ff0000))
318 if (0 == (token.startTime & 0x0000ff00))
320 if (0 == (token.startTime & 0x000000ff))
326 if (write(fd, (char *) token.startTime, sizeof(afs_int32))
327 != sizeof(afs_int32))
329 if (write(fd, align_rec_0, sizeof(align_rec_0))
330 != sizeof(align_rec_0))
336 if (write(fd, (char *) &token.startTime, sizeof(afs_int32))
337 != sizeof(afs_int32))
339 if (write(fd, align_rec_1, sizeof(align_rec_1))
340 != sizeof(align_rec_1))
345 /* Three NULLS are troublesome but rare. We'll just pretend
346 * they don't exist by decrementing the token.startTime.
351 if (write(fd, (char *) &token.startTime, sizeof(afs_int32))
352 != sizeof(afs_int32))
354 if (write(fd, align_rec_2, sizeof(align_rec_2))
355 != sizeof(align_rec_2))
363 #endif /* AFSLITTLE_ENDIAN */