1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/ccache/t_marshal.c - test program for cred marshalling */
3 /*
4 * Copyright (C) 2014 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "cc-int.h"
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <arpa/inet.h>
37 #include <fcntl.h>
38
39 /*
40 * Versions 1 and 2 of the ccache format use native byte order representations
41 * of integers. The test data below is from a little-endian platform. Skip
42 * those tests on big-endian platforms by starting at version 3.
43 */
44 #ifdef K5_BE
45 #define FIRST_VERSION 3
46 #else
47 #define FIRST_VERSION 1
48 #endif
49
50 /* Each test contains the expected binary representation of a credential cache
51 * divided into the header, the default principal, and two credentials. */
52 const struct test {
53 size_t headerlen;
54 const unsigned char header[256];
55 size_t princlen;
56 const unsigned char princ[256];
57 size_t cred1len;
58 const unsigned char cred1[256];
59 size_t cred2len;
60 const unsigned char cred2[256];
61 } tests[4] = {
62 {
63 /* Version 1 header */
64 2,
65 "\x05\x01",
66 /* Version 1 principal */
67 33,
68 "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E"
69 "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E"
70 "\x74",
71 /* Version 1 cred 1 */
72 165,
73 "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E"
74 "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E"
75 "\x74\x03\x00\x00\x00\x0B\x00\x00\x00\x45\x58\x41\x4D\x50\x4C\x45"
76 "\x2E\x43\x4F\x4D\x04\x00\x00\x00\x74\x65\x73\x74\x04\x00\x00\x00"
77 "\x68\x6F\x73\x74\x11\x00\x10\x00\x00\x00\x00\x01\x02\x03\x04\x05"
78 "\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x0B\x00\x00\x00\xDE\x00"
79 "\x00\x00\x05\x0D\x00\x00\x00\xCA\x9A\x3B\x00\x00\x00\x80\x40\x01"
80 "\x00\x00\x00\x02\x00\x04\x00\x00\x00\x0A\x00\x00\x01\x02\x00\x00"
81 "\x00\x00\x02\x0A\x00\x00\x00\x73\x69\x67\x6E\x74\x69\x63\x6B\x65"
82 "\x74\x9C\xFF\x00\x00\x00\x00\x06\x00\x00\x00\x74\x69\x63\x6B\x65"
83 "\x74\x00\x00\x00\x00",
84 /* Version 1 cred 2 */
85 113,
86 "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E"
87 "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E"
88 "\x74\x01\x00\x00\x00\x00\x00\x00\x00\x17\x00\x10\x00\x00\x00\x0F"
89 "\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00"
90 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
91 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00"
92 "\x74\x69\x63\x6B\x65\x74\x07\x00\x00\x00\x32\x74\x69\x63\x6B\x65"
93 "\x74"
94 },
95 {
96 /* Version 2 header */
97 2,
98 "\x05\x02",
99 /* Version 2 principal */
100 37,
101 "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54"
102 "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63"
103 "\x6C\x69\x65\x6E\x74",
104 /* Version 2 cred 1 */
105 173,
106 "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54"
107 "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63"
108 "\x6C\x69\x65\x6E\x74\x01\x00\x00\x00\x02\x00\x00\x00\x0B\x00\x00"
109 "\x00\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x04\x00\x00\x00"
110 "\x74\x65\x73\x74\x04\x00\x00\x00\x68\x6F\x73\x74\x11\x00\x10\x00"
111 "\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D"
112 "\x0E\x0F\x0B\x00\x00\x00\xDE\x00\x00\x00\x05\x0D\x00\x00\x00\xCA"
113 "\x9A\x3B\x00\x00\x00\x80\x40\x01\x00\x00\x00\x02\x00\x04\x00\x00"
114 "\x00\x0A\x00\x00\x01\x02\x00\x00\x00\x00\x02\x0A\x00\x00\x00\x73"
115 "\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\x9C\xFF\x00\x00\x00\x00\x06"
116 "\x00\x00\x00\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00",
117 /* Version 2 cred 2 */
118 121,
119 "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54"
120 "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63"
121 "\x6C\x69\x65\x6E\x74\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
122 "\x00\x17\x00\x10\x00\x00\x00\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07"
123 "\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
124 "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
125 "\x00\x00\x00\x00\x06\x00\x00\x00\x74\x69\x63\x6B\x65\x74\x07\x00"
126 "\x00\x00\x32\x74\x69\x63\x6B\x65\x74"
127 },
128 {
129 /* Version 3 header */
130 2,
131 "\x05\x03",
132 /* Version 3 principal */
133 37,
134 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
135 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
136 "\x6C\x69\x65\x6E\x74",
137 /* Version 3 cred 1 */
138 175,
139 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
140 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
141 "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00"
142 "\x0B\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x00\x00\x00\x04"
143 "\x74\x65\x73\x74\x00\x00\x00\x04\x68\x6F\x73\x74\x00\x11\x00\x11"
144 "\x00\x00\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"
145 "\x0C\x0D\x0E\x0F\x00\x00\x00\x0B\x00\x00\x00\xDE\x00\x00\x0D\x05"
146 "\x3B\x9A\xCA\x00\x00\x40\x80\x00\x00\x00\x00\x00\x01\x00\x02\x00"
147 "\x00\x00\x04\x0A\x00\x00\x01\x00\x00\x00\x02\x02\x00\x00\x00\x00"
148 "\x0A\x73\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\xFF\x9C\x00\x00\x00"
149 "\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00",
150 /* Version 3 cred 2 */
151 123,
152 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
153 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
154 "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
155 "\x00\x00\x17\x00\x17\x00\x00\x00\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09"
156 "\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00"
157 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
158 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74"
159 "\x00\x00\x00\x07\x32\x74\x69\x63\x6B\x65\x74"
160 },
161 {
162 /* Version 4 header */
163 16,
164 "\x05\x04\x00\x0C\x00\x01\x00\x08\x00\x00\x01\x2C\x00\x00\xD4\x31",
165 /* Version 4 principal */
166 37,
167 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
168 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
169 "\x6C\x69\x65\x6E\x74",
170 /* Version 4 cred 1 */
171 173,
172 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
173 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
174 "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00"
175 "\x0B\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x00\x00\x00\x04"
176 "\x74\x65\x73\x74\x00\x00\x00\x04\x68\x6F\x73\x74\x00\x11\x00\x00"
177 "\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D"
178 "\x0E\x0F\x00\x00\x00\x0B\x00\x00\x00\xDE\x00\x00\x0D\x05\x3B\x9A"
179 "\xCA\x00\x00\x40\x80\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00"
180 "\x04\x0A\x00\x00\x01\x00\x00\x00\x02\x02\x00\x00\x00\x00\x0A\x73"
181 "\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\xFF\x9C\x00\x00\x00\x00\x00"
182 "\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00",
183 /* Version 4 cred 2 */
184 121,
185 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54"
186 "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63"
187 "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
188 "\x00\x00\x17\x00\x00\x00\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07"
189 "\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
190 "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
191 "\x00\x00\x00\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00"
192 "\x00\x07\x32\x74\x69\x63\x6B\x65\x74"
193 }
194 };
195
196 static void
verify_princ(krb5_principal p)197 verify_princ(krb5_principal p)
198 {
199 assert(p->length == 1);
200 assert(data_eq_string(p->realm, "KRBTEST.COM"));
201 assert(data_eq_string(p->data[0], "testclient"));
202 }
203
204 static void
verify_cred1(const krb5_creds * c)205 verify_cred1(const krb5_creds *c)
206 {
207 uint32_t ipaddr = ntohl(0x0A000001);
208
209 verify_princ(c->client);
210 assert(c->server->length == 2);
211 assert(data_eq_string(c->server->realm, "EXAMPLE.COM"));
212 assert(data_eq_string(c->server->data[0], "test"));
213 assert(data_eq_string(c->server->data[1], "host"));
214 assert(c->keyblock.enctype == ENCTYPE_AES128_CTS_HMAC_SHA1_96);
215 assert(c->keyblock.length == 16);
216 assert(memcmp(c->keyblock.contents,
217 "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF",
218 16) == 0);
219 assert(c->times.authtime == 11);
220 assert(c->times.starttime == 222);
221 assert(c->times.endtime == 3333);
222 assert(c->times.renew_till == 1000000000);
223 assert(c->is_skey == FALSE);
224 assert(c->ticket_flags == (TKT_FLG_FORWARDABLE | TKT_FLG_RENEWABLE));
225 assert(c->addresses != NULL && c->addresses[0] != NULL);
226 assert(c->addresses[0]->addrtype == ADDRTYPE_INET);
227 assert(c->addresses[0]->length == 4);
228 assert(memcmp(c->addresses[0]->contents, &ipaddr, 4) == 0);
229 assert(c->addresses[1] == NULL);
230 assert(c->authdata != NULL && c->authdata[0] != NULL);
231 assert(c->authdata[0]->ad_type == KRB5_AUTHDATA_SIGNTICKET);
232 assert(c->authdata[0]->length == 10);
233 assert(memcmp(c->authdata[0]->contents, "signticket", 10) == 0);
234 assert(c->authdata[1] != NULL);
235 assert(c->authdata[1]->ad_type == -100);
236 assert(c->authdata[1]->length == 0);
237 assert(c->authdata[2] == NULL);
238 assert(data_eq_string(c->ticket, "ticket"));
239 assert(c->second_ticket.length == 0);
240 }
241
242 static void
verify_cred2(const krb5_creds * c)243 verify_cred2(const krb5_creds *c)
244 {
245 verify_princ(c->client);
246 assert(c->server->length == 0);
247 assert(c->server->realm.length == 0);
248 assert(c->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC);
249 assert(c->keyblock.length == 16);
250 assert(memcmp(c->keyblock.contents,
251 "\xF\xE\xD\xC\xB\xA\x9\x8\x7\x6\x5\x4\x3\x2\x1\x0",
252 16) == 0);
253 assert(c->times.authtime == 0);
254 assert(c->times.starttime == 0);
255 assert(c->times.endtime == 0);
256 assert(c->times.renew_till == 0);
257 assert(c->is_skey == TRUE);
258 assert(c->ticket_flags == 0);
259 assert(c->addresses == NULL || c->addresses[0] == NULL);
260 assert(c->authdata == NULL || c->authdata[0] == NULL);
261 assert(data_eq_string(c->ticket, "ticket"));
262 assert(data_eq_string(c->second_ticket, "2ticket"));
263 }
264
265 int
main(int argc,char ** argv)266 main(int argc, char **argv)
267 {
268 krb5_context context;
269 krb5_ccache cache;
270 krb5_principal princ;
271 krb5_creds cred1, cred2, *alloc_cred;
272 krb5_cc_cursor cursor;
273 const char *filename;
274 char *ccname, filebuf[256];
275 int version, fd;
276 const struct test *t;
277 struct k5buf buf;
278 krb5_data ser_data, *alloc_data;
279
280 if (argc != 2)
281 abort();
282 filename = argv[1];
283 if (asprintf(&ccname, "FILE:%s", filename) == -1)
284 abort();
285
286 if (krb5_init_context(&context) != 0)
287 abort();
288
289 /* Test public functions for unmarshalling and marshalling. */
290 ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len);
291 if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0)
292 abort();
293 verify_cred1(alloc_cred);
294 if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0)
295 abort();
296 assert(alloc_data->length == tests[3].cred1len);
297 assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0);
298 krb5_free_data(context, alloc_data);
299 krb5_free_creds(context, alloc_cred);
300
301 for (version = FIRST_VERSION; version <= 4; version++) {
302 t = &tests[version - 1];
303
304 /* Test principal unmarshalling and marshalling. */
305 if (k5_unmarshal_princ(t->princ, t->princlen, version, &princ) != 0)
306 abort();
307 verify_princ(princ);
308 k5_buf_init_dynamic(&buf);
309 k5_marshal_princ(&buf, version, princ);
310 assert(buf.len == t->princlen);
311 assert(memcmp(t->princ, buf.data, buf.len) == 0);
312 k5_buf_free(&buf);
313
314 /* Test cred1 unmarshalling and marshalling. */
315 if (k5_unmarshal_cred(t->cred1, t->cred1len, version, &cred1) != 0)
316 abort();
317 verify_cred1(&cred1);
318 k5_buf_init_dynamic(&buf);
319 k5_marshal_cred(&buf, version, &cred1);
320 assert(buf.len == t->cred1len);
321 assert(memcmp(t->cred1, buf.data, buf.len) == 0);
322 k5_buf_free(&buf);
323
324 /* Test cred2 unmarshalling and marshalling. */
325 if (k5_unmarshal_cred(t->cred2, t->cred2len, version, &cred2) != 0)
326 abort();
327 verify_cred2(&cred2);
328 k5_buf_init_dynamic(&buf);
329 k5_marshal_cred(&buf, version, &cred2);
330 assert(buf.len == t->cred2len);
331 assert(memcmp(t->cred2, buf.data, buf.len) == 0);
332 k5_buf_free(&buf);
333
334 /* Write a ccache containing the principal and creds. Use the same
335 * time offset as the version 4 test data used. */
336 context->fcc_default_format = 0x0500 + version;
337 context->os_context.time_offset = 300;
338 context->os_context.usec_offset = 54321;
339 context->os_context.os_flags = KRB5_OS_TOFFSET_VALID;
340 if (krb5_cc_resolve(context, ccname, &cache) != 0)
341 abort();
342 if (krb5_cc_initialize(context, cache, princ) != 0)
343 abort();
344 if (krb5_cc_store_cred(context, cache, &cred1) != 0)
345 abort();
346 if (krb5_cc_store_cred(context, cache, &cred2) != 0)
347 abort();
348 if (krb5_cc_close(context, cache) != 0)
349 abort();
350
351 /* Verify the cache representation against the test data. */
352 fd = open(filename, O_RDONLY);
353 if (fd == -1)
354 abort();
355 if (read(fd, filebuf, t->headerlen) != (ssize_t)t->headerlen)
356 abort();
357 assert(memcmp(filebuf, t->header, t->headerlen) == 0);
358 if (read(fd, filebuf, t->princlen) != (ssize_t)t->princlen)
359 abort();
360 assert(memcmp(filebuf, t->princ, t->princlen) == 0);
361 if (read(fd, filebuf, t->cred1len) != (ssize_t)t->cred1len)
362 abort();
363 assert(memcmp(filebuf, t->cred1, t->cred1len) == 0);
364 if (read(fd, filebuf, t->cred2len) != (ssize_t)t->cred2len)
365 abort();
366 assert(memcmp(filebuf, t->cred2, t->cred2len) == 0);
367 close(fd);
368
369 krb5_free_principal(context, princ);
370 krb5_free_cred_contents(context, &cred1);
371 krb5_free_cred_contents(context, &cred2);
372
373 /* Write a cache containing the test data. */
374 fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0700);
375 if (fd == -1)
376 abort();
377 if (write(fd, t->header, t->headerlen) != (ssize_t)t->headerlen)
378 abort();
379 if (write(fd, t->princ, t->princlen) != (ssize_t)t->princlen)
380 abort();
381 if (write(fd, t->cred1, t->cred1len) != (ssize_t)t->cred1len)
382 abort();
383 if (write(fd, t->cred2, t->cred2len) != (ssize_t)t->cred2len)
384 abort();
385 close(fd);
386
387 /* Read the cache and verify that it matches. */
388 if (krb5_cc_resolve(context, ccname, &cache) != 0)
389 abort();
390 if (krb5_cc_get_principal(context, cache, &princ) != 0)
391 abort();
392 /* Not every version stores the time offset, but at least it shouldn't
393 * have changed from when we set it before. */
394 assert(context->os_context.time_offset == 300);
395 assert(context->os_context.usec_offset == 54321);
396 verify_princ(princ);
397 if (krb5_cc_start_seq_get(context, cache, &cursor) != 0)
398 abort();
399 if (krb5_cc_next_cred(context, cache, &cursor, &cred1) != 0)
400 abort();
401 verify_cred1(&cred1);
402 krb5_free_cred_contents(context, &cred1);
403 if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != 0)
404 abort();
405 verify_cred2(&cred2);
406 krb5_free_cred_contents(context, &cred2);
407 if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != KRB5_CC_END)
408 abort();
409 if (krb5_cc_end_seq_get(context, cache, &cursor) != 0)
410 abort();
411 if (krb5_cc_close(context, cache) != 0)
412 abort();
413 krb5_free_principal(context, princ);
414 }
415
416 (void)unlink(filename);
417 free(ccname);
418 krb5_free_context(context);
419 return 0;
420 }
421