2 * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of KTH nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
34 * If this test fails with
36 * krb5_cc_gen_new: KEYRING: Key has been revoked
43 #include "krb5_locl.h"
47 #ifdef HAVE_KEYUTILS_H
51 static const char *unlink_this
;
52 static const char *unlink_this2
;
54 static int debug_flag
= 0;
55 static int version_flag
= 0;
56 static int help_flag
= 0;
58 #define TEST_CC_TEMPLATE "%{TEMP}/krb5-cc-test-XXXXXX"
65 if (asprintf(&s
, "%s/cc", tmpdir
) > -1 && s
!= NULL
)
69 if (asprintf(&s
, "%s/scc", tmpdir
) > -1 && s
!= NULL
)
73 if (asprintf(&s
, "%s/cccol/foobar+lha@H5L.SE", tmpdir
) > -1 && s
!= NULL
)
77 if (asprintf(&s
, "%s/cccol/foobar+lha@SU.SE", tmpdir
) > -1 && s
!= NULL
)
81 if (asprintf(&s
, "%s/cccol/foobar", tmpdir
) > -1 && s
!= NULL
)
85 if (asprintf(&s
, "%s/cccol", tmpdir
) > -1 && s
!= NULL
)
89 if (asprintf(&s
, "%s/dcc/tkt.lha@H5L.SE", tmpdir
) > -1 && s
!= NULL
)
93 if (asprintf(&s
, "%s/dcc/tkt.lha@SU.SE", tmpdir
) > -1 && s
!= NULL
)
97 if (asprintf(&s
, "%s/dcc/tkt", tmpdir
) > -1 && s
!= NULL
)
101 if (asprintf(&s
, "%s/dcc/primary", tmpdir
) > -1 && s
!= NULL
)
105 if (asprintf(&s
, "%s/dcc", tmpdir
) > -1 && s
!= NULL
)
113 unlink(unlink_this2
);
120 make_dir(krb5_context context
)
123 char *template = NULL
;
126 ret
= _krb5_expand_path_tokens(context
, TEST_CC_TEMPLATE
, 1, &template);
128 krb5_err(context
, 1, ret
, "_krb5_expand_path_tokens(%s) failed",
130 if ((tmpdir
= mkdtemp(template)) == NULL
)
131 krb5_err(context
, 1, errno
, "mkdtemp(%s) failed", template);
132 if (asprintf(&dcc
, "%s/dcc", tmpdir
) == -1 || dcc
== NULL
)
133 krb5_err(context
, 1, errno
, "asprintf failed");
139 test_default_name(krb5_context context
)
143 char *test_cc_name
= NULL
;
146 char *exp_test_cc_name
;
148 if (asprintf(&test_cc_name
, "%s/cc", tmpdir
) == -1 || test_cc_name
== NULL
)
149 krb5_err(context
, 1, errno
, "out of memory");
151 /* Convert slashes to backslashes */
152 ret
= _krb5_expand_path_tokens(context
, test_cc_name
, 1,
155 krb5_err(context
, 1, ret
, "_krb5_expand_path_tokens(%s) failed",
160 p
= krb5_cc_default_name(context
);
162 krb5_errx (context
, 1, "krb5_cc_default_name 1 failed");
165 ret
= krb5_cc_set_default_name(context
, NULL
);
167 krb5_err(context
, 1, ret
, "krb5_cc_set_default_name(NULL) failed");
169 p
= krb5_cc_default_name(context
);
171 krb5_errx (context
, 1, "krb5_cc_default_name 2 failed");
174 if (strcmp(p1
, p2
) != 0)
175 krb5_errx (context
, 1, "krb5_cc_default_name no longer same");
177 ret
= krb5_cc_set_default_name(context
, exp_test_cc_name
);
179 krb5_err(context
, 1, ret
, "krb5_cc_set_default_name(%s) failed",
182 p
= krb5_cc_default_name(context
);
184 krb5_errx (context
, 1, "krb5_cc_default_name 2 failed");
186 if (strncmp(p
, "FILE:", sizeof("FILE:") - 1) == 0)
187 p3
= p
+ sizeof("FILE:") - 1;
191 if (strcmp(exp_test_cc_name
, p3
) != 0) {
193 krb5_warnx(context
, 1,
194 "krb5_cc_default_name() returned %s; expected %s",
195 p
, exp_test_cc_name
);
197 krb5_errx(context
, 1,
198 "krb5_cc_default_name() returned %s; expected %s",
199 p
, exp_test_cc_name
);
203 free(exp_test_cc_name
);
209 * Check that a closed cc still keeps it data and that it's no longer
210 * there when it's destroyed.
214 test_mcache(krb5_context context
)
220 krb5_principal p
, p2
;
222 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
224 krb5_err(context
, 1, ret
, "krb5_parse_name");
226 ret
= krb5_cc_new_unique(context
, krb5_cc_type_memory
, NULL
, &id
);
228 krb5_err(context
, 1, ret
, "krb5_cc_new_unique");
230 ret
= krb5_cc_initialize(context
, id
, p
);
232 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
234 nc
= krb5_cc_get_name(context
, id
);
236 krb5_errx(context
, 1, "krb5_cc_get_name");
238 tc
= krb5_cc_get_type(context
, id
);
240 krb5_errx(context
, 1, "krb5_cc_get_name");
242 if (asprintf(&c
, "%s:%s", tc
, nc
) < 0 || c
== NULL
)
245 krb5_cc_close(context
, id
);
247 ret
= krb5_cc_resolve(context
, c
, &id2
);
249 krb5_err(context
, 1, ret
, "krb5_cc_resolve");
251 ret
= krb5_cc_get_principal(context
, id2
, &p2
);
253 krb5_err(context
, 1, ret
, "krb5_cc_get_principal");
255 if (krb5_principal_compare(context
, p
, p2
) == FALSE
)
256 krb5_errx(context
, 1, "p != p2");
258 krb5_cc_destroy(context
, id2
);
259 krb5_free_principal(context
, p
);
260 krb5_free_principal(context
, p2
);
262 ret
= krb5_cc_resolve(context
, c
, &id2
);
264 krb5_err(context
, 1, ret
, "krb5_cc_resolve");
266 ret
= krb5_cc_get_principal(context
, id2
, &p2
);
268 krb5_errx(context
, 1, "krb5_cc_get_principal");
270 krb5_cc_destroy(context
, id2
);
275 * Test that init works on a destroyed cc.
279 test_init_vs_destroy(krb5_context context
, const char *type
)
283 krb5_principal p
, p2
;
286 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
288 krb5_err(context
, 1, ret
, "krb5_parse_name");
290 ret
= krb5_cc_new_unique(context
, type
, NULL
, &id
);
292 krb5_err(context
, 1, ret
, "krb5_cc_new_unique: %s", type
);
294 if (asprintf(&n
, "%s:%s",
295 krb5_cc_get_type(context
, id
),
296 krb5_cc_get_name(context
, id
)) < 0 || n
== NULL
)
299 if (strcmp(krb5_cc_get_type(context
, id
), "FILE") == 0)
300 unlink_this
= krb5_cc_get_name(context
, id
);
302 ret
= krb5_cc_resolve(context
, n
, &id2
);
305 krb5_err(context
, 1, ret
, "krb5_cc_resolve");
307 krb5_cc_destroy(context
, id
);
309 ret
= krb5_cc_initialize(context
, id2
, p
);
311 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
313 ret
= krb5_cc_get_principal(context
, id2
, &p2
);
315 krb5_err(context
, 1, ret
, "krb5_cc_get_principal");
317 krb5_cc_destroy(context
, id2
);
319 krb5_free_principal(context
, p
);
320 krb5_free_principal(context
, p2
);
324 test_cache_remove(krb5_context context
, const char *type
)
329 krb5_creds cred
, found
;
331 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
333 krb5_err(context
, 1, ret
, "krb5_parse_name");
335 ret
= krb5_cc_new_unique(context
, type
, NULL
, &id
);
337 krb5_err(context
, 1, ret
, "krb5_cc_gen_new: %s", type
);
339 if (strcmp(krb5_cc_get_type(context
, id
), "FILE") == 0)
340 unlink_this
= krb5_cc_get_name(context
, id
);
342 ret
= krb5_cc_initialize(context
, id
, p
);
344 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
347 memset(&cred
, 0, sizeof(cred
));
348 ret
= krb5_parse_name(context
, "krbtgt/SU.SE@SU.SE", &cred
.server
);
350 krb5_err(context
, 1, ret
, "krb5_parse_name");
351 ret
= krb5_parse_name(context
, "lha@SU.SE", &cred
.client
);
353 krb5_err(context
, 1, ret
, "krb5_parse_name");
354 cred
.times
.endtime
= time(NULL
) + 300;
356 ret
= krb5_cc_store_cred(context
, id
, &cred
);
358 krb5_err(context
, 1, ret
, "krb5_cc_store_cred");
360 ret
= krb5_cc_remove_cred(context
, id
, 0, &cred
);
362 krb5_err(context
, 1, ret
, "krb5_cc_remove_cred");
364 memset(&found
, 0, sizeof(found
));
365 ret
= krb5_cc_retrieve_cred(context
, id
, KRB5_TC_MATCH_TIMES
,
368 krb5_err(context
, 1, ret
, "krb5_cc_remove_cred didn't");
370 ret
= krb5_cc_destroy(context
, id
);
372 krb5_err(context
, 1, ret
, "krb5_cc_destroy");
375 krb5_free_principal(context
, p
);
376 krb5_free_principal(context
, cred
.server
);
377 krb5_free_principal(context
, cred
.client
);
381 test_mcc_default(void)
383 krb5_context context
;
388 for (i
= 0; i
< 10; i
++) {
390 ret
= krb5_init_context(&context
);
392 krb5_err(context
, 1, ret
, "krb5_init_context");
394 ret
= krb5_cc_set_default_name(context
, "MEMORY:foo");
396 krb5_err(context
, 1, ret
, "krb5_cc_set_default_name");
398 ret
= krb5_cc_default(context
, &id
);
400 krb5_err(context
, 1, ret
, "krb5_cc_default");
402 ret
= krb5_cc_default(context
, &id2
);
404 krb5_err(context
, 1, ret
, "krb5_cc_default");
406 ret
= krb5_cc_close(context
, id
);
408 krb5_err(context
, 1, ret
, "krb5_cc_close");
410 ret
= krb5_cc_close(context
, id2
);
412 krb5_err(context
, 1, ret
, "krb5_cc_close");
414 krb5_free_context(context
);
424 { "foo%}", 0, "foo%}" },
425 { "%{uid}", 0, NULL
},
426 { "%{euid}", 0, NULL
},
427 { "%{username}", 0, NULL
},
428 { "foo%{null}", 0, "foo" },
429 { "foo%{null}bar", 0, "foobar" },
431 { "%{foo %{", 1, NULL
},
434 { "%{nulll}", 1, NULL
},
435 { "%{does not exist}", 1, NULL
},
438 { "%{APPDATA}", 0, NULL
},
439 { "%{COMMON_APPDATA}", 0, NULL
},
440 { "%{LOCAL_APPDATA}", 0, NULL
},
441 { "%{SYSTEM}", 0, NULL
},
442 { "%{WINDOWS}", 0, NULL
},
443 { "%{TEMP}", 0, NULL
},
444 { "%{USERID}", 0, NULL
},
445 { "%{uid}", 0, NULL
},
446 { "%{USERCONFIG}", 0, NULL
},
447 { "%{COMMONCONFIG}", 0, NULL
},
448 { "%{LIBDIR}", 0, NULL
},
449 { "%{BINDIR}", 0, NULL
},
450 { "%{LIBEXEC}", 0, NULL
},
451 { "%{SBINDIR}", 0, NULL
},
456 test_def_cc_name(krb5_context context
)
462 for (i
= 0; i
< sizeof(cc_names
)/sizeof(cc_names
[0]); i
++) {
463 ret
= _krb5_expand_default_cc_name(context
, cc_names
[i
].str
, &str
);
465 if (cc_names
[i
].fail
== 0)
466 krb5_errx(context
, 1, "test %d \"%s\" failed",
469 if (cc_names
[i
].fail
)
470 krb5_errx(context
, 1, "test %d \"%s\" was successful",
472 if (cc_names
[i
].res
&& strcmp(cc_names
[i
].res
, str
) != 0)
473 krb5_errx(context
, 1, "test %d %s != %s",
474 i
, cc_names
[i
].res
, str
);
476 printf("%s => %s\n", cc_names
[i
].str
, str
);
483 test_cache_find(krb5_context context
, const char *principal
, int find
)
485 krb5_principal client
;
487 krb5_ccache id
= NULL
;
489 ret
= krb5_parse_name(context
, principal
, &client
);
491 krb5_err(context
, 1, ret
, "parse_name for %s failed", principal
);
493 ret
= krb5_cc_cache_match(context
, client
, &id
);
495 krb5_err(context
, 1, ret
, "cc_cache_match for %s failed", principal
);
496 if (ret
== 0 && !find
)
497 krb5_err(context
, 1, ret
, "cc_cache_match for %s found", principal
);
500 krb5_cc_close(context
, id
);
501 krb5_free_principal(context
, client
);
506 test_cache_iter(krb5_context context
, const char *type
, int destroy
)
508 krb5_cc_cache_cursor cursor
;
512 ret
= krb5_cc_cache_get_first (context
, type
, &cursor
);
513 if (ret
== KRB5_CC_NOSUPP
)
516 krb5_err(context
, 1, ret
, "krb5_cc_cache_get_first(%s)", type
);
519 while ((ret
= krb5_cc_cache_next (context
, cursor
, &id
)) == 0) {
520 krb5_principal principal
;
523 heim_assert(id
!= NULL
, "credentials cache is non-NULL");
525 printf("name: %s\n", krb5_cc_get_name(context
, id
));
526 ret
= krb5_cc_get_principal(context
, id
, &principal
);
528 ret
= krb5_unparse_name(context
, principal
, &name
);
531 printf("\tprincipal: %s\n", name
);
534 krb5_free_principal(context
, principal
);
537 krb5_cc_destroy(context
, id
);
539 krb5_cc_close(context
, id
);
542 krb5_cc_cache_end_seq_get(context
, cursor
);
546 test_cache_iter_all(krb5_context context
)
548 krb5_cccol_cursor cursor
;
552 ret
= krb5_cccol_cursor_new (context
, &cursor
);
554 krb5_err(context
, 1, ret
, "krb5_cccol_cursor_new");
557 while ((ret
= krb5_cccol_cursor_next (context
, cursor
, &id
)) == 0 && id
!= NULL
) {
558 krb5_principal principal
;
562 printf("name: %s\n", krb5_cc_get_name(context
, id
));
563 ret
= krb5_cc_get_principal(context
, id
, &principal
);
565 ret
= krb5_unparse_name(context
, principal
, &name
);
568 printf("\tprincipal: %s\n", name
);
571 krb5_free_principal(context
, principal
);
573 krb5_cc_close(context
, id
);
576 krb5_cccol_cursor_free(context
, &cursor
);
581 test_copy(krb5_context context
, const char *from
, const char *to
)
583 krb5_ccache fromid
, toid
;
585 krb5_principal p
, p2
;
587 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
589 krb5_err(context
, 1, ret
, "krb5_parse_name");
591 ret
= krb5_cc_new_unique(context
, from
, NULL
, &fromid
);
593 krb5_err(context
, 1, ret
, "krb5_cc_new_unique: %s", from
);
595 if (strcmp(krb5_cc_get_type(context
, fromid
), "FILE") == 0)
596 unlink_this
= krb5_cc_get_name(context
, fromid
);
598 ret
= krb5_cc_initialize(context
, fromid
, p
);
600 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
602 ret
= krb5_cc_new_unique(context
, to
, NULL
, &toid
);
604 krb5_err(context
, 1, ret
, "krb5_cc_gen_new: %s", to
);
606 if (strcmp(krb5_cc_get_type(context
, toid
), "FILE") == 0)
607 unlink_this2
= krb5_cc_get_name(context
, toid
);
609 ret
= krb5_cc_copy_cache(context
, fromid
, toid
);
611 krb5_err(context
, 1, ret
, "krb5_cc_copy_cache");
613 ret
= krb5_cc_get_principal(context
, toid
, &p2
);
615 krb5_err(context
, 1, ret
, "krb5_cc_get_principal");
617 if (krb5_principal_compare(context
, p
, p2
) == FALSE
)
618 krb5_errx(context
, 1, "p != p2");
620 krb5_free_principal(context
, p
);
621 krb5_free_principal(context
, p2
);
623 krb5_cc_destroy(context
, fromid
);
624 krb5_cc_destroy(context
, toid
);
625 unlink_this
= unlink_this2
= NULL
;
629 test_move(krb5_context context
, const char *type
)
631 const krb5_cc_ops
*ops
;
632 krb5_ccache fromid
, toid
;
634 krb5_principal p
, p2
;
635 krb5_creds cred
, tocred
;
637 ops
= krb5_cc_get_prefix_ops(context
, type
);
641 ret
= krb5_cc_new_unique(context
, type
, NULL
, &fromid
);
642 if (ret
== KRB5_CC_NOSUPP
)
645 krb5_err(context
, 1, ret
, "krb5_cc_new_unique: %s", type
);
647 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
649 krb5_err(context
, 1, ret
, "krb5_parse_name");
651 ret
= krb5_cc_initialize(context
, fromid
, p
);
653 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
655 memset(&cred
, 0, sizeof(cred
));
656 ret
= krb5_parse_name(context
, "krbtgt/SU.SE@SU.SE", &cred
.server
);
658 krb5_err(context
, 1, ret
, "krb5_parse_name");
659 ret
= krb5_parse_name(context
, "lha@SU.SE", &cred
.client
);
661 krb5_err(context
, 1, ret
, "krb5_parse_name");
663 ret
= krb5_cc_store_cred(context
, fromid
, &cred
);
665 krb5_err(context
, 1, ret
, "krb5_cc_store_cred");
668 ret
= krb5_cc_new_unique(context
, type
, NULL
, &toid
);
670 krb5_err(context
, 1, ret
, "krb5_cc_new_unique");
672 ret
= krb5_cc_move(context
, fromid
, toid
);
674 krb5_err(context
, 1, ret
, "krb5_cc_move");
676 ret
= krb5_cc_get_principal(context
, toid
, &p2
);
678 krb5_err(context
, 1, ret
, "krb5_cc_get_principal");
680 if (krb5_principal_compare(context
, p
, p2
) == FALSE
)
681 krb5_errx(context
, 1, "p != p2");
683 ret
= krb5_cc_retrieve_cred(context
, toid
, 0, &cred
, &tocred
);
685 krb5_errx(context
, 1, "move failed");
686 krb5_free_cred_contents(context
, &cred
);
687 krb5_free_cred_contents(context
, &tocred
);
689 krb5_free_principal(context
, p
);
690 krb5_free_principal(context
, p2
);
691 krb5_cc_destroy(context
, toid
);
696 test_prefix_ops(krb5_context context
, const char *name
, const krb5_cc_ops
*ops
)
698 const krb5_cc_ops
*o
;
700 o
= krb5_cc_get_prefix_ops(context
, name
);
702 krb5_errx(context
, 1, "found no match for prefix '%s'", name
);
703 if (strcmp(o
->prefix
, ops
->prefix
) != 0)
704 krb5_errx(context
, 1, "ops for prefix '%s' is not "
705 "the expected %s != %s", name
, o
->prefix
, ops
->prefix
);
709 test_cc_config(krb5_context context
, const char *cc_type
,
710 const char *cc_name
, size_t count
)
717 ret
= krb5_cc_new_unique(context
, cc_type
, cc_name
, &id
);
719 krb5_err(context
, 1, ret
, "krb5_cc_new_unique");
721 ret
= krb5_parse_name(context
, "lha@SU.SE", &p
);
723 krb5_err(context
, 1, ret
, "krb5_parse_name");
725 ret
= krb5_cc_initialize(context
, id
, p
);
727 krb5_err(context
, 1, ret
, "krb5_cc_initialize");
729 for (i
= 0; i
< count
; i
++) {
730 krb5_data data
, data2
;
731 const char *name
= "foo";
732 krb5_principal p1
= NULL
;
737 data
.data
= rk_UNCONST(name
);
738 data
.length
= strlen(name
);
741 * Because of how krb5_cc_set_config() this will also test
742 * krb5_cc_remove_cred().
744 ret
= krb5_cc_set_config(context
, id
, p1
, "FriendlyName", &data
);
746 krb5_errx(context
, 1, "krb5_cc_set_config: add");
748 ret
= krb5_cc_get_config(context
, id
, p1
, "FriendlyName", &data2
);
750 krb5_errx(context
, 1, "krb5_cc_get_config: first");
752 if (data
.length
!= data2
.length
||
753 memcmp(data
.data
, data2
.data
, data
.length
) != 0)
754 krb5_errx(context
, 1, "krb5_cc_get_config: did not fetch what was set");
756 krb5_data_free(&data2
);
758 data
.data
= rk_UNCONST("bar");
759 data
.length
= strlen("bar");
761 ret
= krb5_cc_set_config(context
, id
, p1
, "FriendlyName", &data
);
763 krb5_errx(context
, 1, "krb5_cc_set_config: add -second");
765 ret
= krb5_cc_get_config(context
, id
, p1
, "FriendlyName", &data2
);
767 krb5_errx(context
, 1, "krb5_cc_get_config: second");
769 if (data
.length
!= data2
.length
||
770 memcmp(data
.data
, data2
.data
, data
.length
) != 0)
771 krb5_errx(context
, 1, "krb5_cc_get_config: replace failed");
773 krb5_data_free(&data2
);
775 ret
= krb5_cc_set_config(context
, id
, p1
, "FriendlyName", NULL
);
777 krb5_errx(context
, 1, "krb5_cc_set_config: delete");
779 ret
= krb5_cc_get_config(context
, id
, p1
, "FriendlyName", &data2
);
781 krb5_errx(context
, 1, "krb5_cc_get_config: non-existant");
784 krb5_errx(context
, 1, "krb5_cc_get_config: delete failed");
787 krb5_cc_destroy(context
, id
);
788 krb5_free_principal(context
, p
);
791 static krb5_error_code
792 test_cccol(krb5_context context
, const char *def_cccol
, const char **what
)
794 krb5_cc_cache_cursor cursor
;
796 krb5_principal p1
, p2
;
797 krb5_ccache id
, id1
, id2
;
798 krb5_creds cred1
, cred2
;
802 memset(&cred1
, 0, sizeof(cred1
));
803 memset(&cred2
, 0, sizeof(cred2
));
805 *what
= "krb5_parse_name";
806 ret
= krb5_parse_name(context
, "krbtgt/SU.SE@SU.SE", &cred1
.server
);
808 ret
= krb5_parse_name(context
, "lha@SU.SE", &cred1
.client
);
810 ret
= krb5_parse_name(context
, "krbtgt/H5L.SE@H5L.SE", &cred2
.server
);
812 ret
= krb5_parse_name(context
, "lha@H5L.SE", &cred2
.client
);
814 *what
= "krb5_cc_set_default_name";
815 ret
= krb5_cc_set_default_name(context
, def_cccol
);
817 *what
= "krb5_cc_default";
818 ret
= krb5_cc_default(context
, &id1
);
820 *what
= "krb5_cc_initialize";
821 ret
= krb5_cc_initialize(context
, id1
, cred1
.client
);
823 *what
= "krb5_cc_store_cred";
824 ret
= krb5_cc_store_cred(context
, id1
, &cred1
);
826 *what
= "krb5_cc_resolve";
827 ret
= krb5_cc_resolve_for(context
, NULL
, def_cccol
, cred2
.client
, &id2
);
829 *what
= "krb5_cc_initialize";
830 ret
= krb5_cc_initialize(context
, id2
, cred2
.client
);
832 *what
= "krb5_cc_store_cred";
833 ret
= krb5_cc_store_cred(context
, id2
, &cred2
);
836 krb5_cc_close(context
, id1
);
837 krb5_cc_close(context
, id2
);
840 *what
= "krb5_cc_default";
841 ret
= krb5_cc_default(context
, &id1
);
843 *what
= "krb5_cc_resolve";
844 ret
= krb5_cc_resolve_for(context
, NULL
, def_cccol
, cred2
.client
, &id2
);
847 *what
= "krb5_cc_get_principal";
848 ret
= krb5_cc_get_principal(context
, id1
, &p1
);
850 ret
= krb5_cc_get_principal(context
, id2
, &p2
);
853 if (!krb5_principal_compare(context
, p1
, cred1
.client
)) {
857 (void) krb5_unparse_name(context
, p1
, &u1
);
858 (void) krb5_unparse_name(context
, cred1
.client
, &u2
);
859 warnx("Inconsistent principals for ccaches in %s: %s vs %s "
860 "(expected lha@SU.SE)", def_cccol
, u1
, u2
);
863 if (!krb5_principal_compare(context
, p2
, cred2
.client
)) {
867 (void) krb5_unparse_name(context
, p2
, &u1
);
868 (void) krb5_unparse_name(context
, cred2
.client
, &u2
);
869 warnx("Inconsistent principals for ccaches in %s: %s and %s "
870 "(expected lha@H5L.SE)", def_cccol
, u1
, u2
);
873 krb5_free_principal(context
, p1
);
874 krb5_free_principal(context
, p2
);
876 *what
= "krb5_cc_cache_get_first";
877 ret
= krb5_cc_cache_get_first(context
, NULL
, &cursor
);
879 *what
= "krb5_cc_cache_next";
880 while (krb5_cc_cache_next(context
, cursor
, &id
) == 0) {
883 *what
= "krb5_cc_get_principal";
884 ret
= krb5_cc_get_principal(context
, id
, &p
);
886 if (krb5_principal_compare(context
, p
, cred1
.client
))
888 else if (krb5_principal_compare(context
, p
, cred2
.client
))
890 krb5_free_principal(context
, p
);
891 krb5_cc_close(context
, id
);
893 (void) krb5_cc_cache_end_seq_get(context
, cursor
);
895 *what
= "cccol iteration inconsistency";
896 if (match1
!= 1 || match2
!= 1)
899 krb5_cc_close(context
, id1
);
900 krb5_cc_close(context
, id2
);
902 krb5_free_cred_contents(context
, &cred1
);
903 krb5_free_cred_contents(context
, &cred2
);
909 test_cccol_dcache(krb5_context context
)
915 if (asprintf(&dcc
, "DIR:%s/dcc", tmpdir
) == -1 || dcc
== NULL
)
916 krb5_err(context
, 1, errno
, "asprintf");
918 ret
= test_cccol(context
, dcc
, &what
);
921 krb5_err(context
, 1, ret
, "%s", what
);
925 test_cccol_scache(krb5_context context
)
932 if (asprintf(&scache
, "SCC:%s/scache", tmpdir
) == -1 || scache
== NULL
)
933 krb5_err(context
, 1, errno
, "asprintf");
934 if ((fd
= open(scache
+ sizeof("SCC:") - 1, O_CREAT
| O_RDWR
, 0600)) == -1)
935 krb5_err(context
, 1, errno
, "open(%s)", scache
+ sizeof("SCC:") - 1);
938 ret
= test_cccol(context
, scache
, &what
);
939 (void) unlink(scache
+ sizeof("SCC:") - 1);
942 krb5_err(context
, 1, ret
, "%s", what
);
946 static struct getargs args
[] = {
947 {"debug", 'd', arg_flag
, &debug_flag
,
948 "turn on debuggin", NULL
},
949 {"version", 0, arg_flag
, &version_flag
,
950 "print version", NULL
},
951 {"help", 0, arg_flag
, &help_flag
,
958 arg_printusage (args
, sizeof(args
)/sizeof(*args
), NULL
, "hostname ...");
963 main(int argc
, char **argv
)
965 krb5_context context
;
968 krb5_ccache id1
, id2
;
970 setprogname(argv
[0]);
972 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &optidx
))
986 ret
= krb5_init_context(&context
);
988 errx (1, "krb5_init_context failed: %d", ret
);
992 test_cache_remove(context
, krb5_cc_type_file
);
993 test_cache_remove(context
, krb5_cc_type_memory
);
995 test_cache_remove(context
, krb5_cc_type_scc
);
997 #ifdef HAVE_KEYUTILS_H
998 keyctl_join_session_keyring(NULL
);
999 test_cache_remove(context
, krb5_cc_type_keyring
);
1002 test_default_name(context
);
1003 test_mcache(context
);
1005 * XXX Make sure to set default ccache names for each cc type!
1006 * Otherwise we clobber the user's ccaches.
1008 test_init_vs_destroy(context
, krb5_cc_type_memory
);
1009 test_init_vs_destroy(context
, krb5_cc_type_file
);
1011 test_init_vs_destroy(context
, krb5_cc_type_api
);
1014 * Cleanup so we can check that the permissions on the directory created by
1018 test_init_vs_destroy(context
, krb5_cc_type_scc
);
1020 #if defined(S_IRWXG) && defined(S_IRWXO)
1024 if (stat(tmpdir
, &st
) == 0) {
1025 if ((st
.st_mode
& S_IRWXG
) ||
1026 (st
.st_mode
& S_IRWXO
))
1027 krb5_errx(context
, 1,
1028 "SQLite3 ccache dir perms wrong: %d", st
.st_mode
);
1032 test_init_vs_destroy(context
, krb5_cc_type_dcc
);
1033 #ifdef HAVE_KEYUTILS_H
1034 test_init_vs_destroy(context
, krb5_cc_type_keyring
);
1037 test_def_cc_name(context
);
1039 test_cache_iter_all(context
);
1041 test_cache_iter(context
, krb5_cc_type_memory
, 0);
1044 krb5_cc_new_unique(context
, krb5_cc_type_memory
, "bar", &id1
);
1045 krb5_cc_new_unique(context
, krb5_cc_type_memory
, "baz", &id2
);
1046 krb5_parse_name(context
, "lha@SU.SE", &p
);
1047 krb5_cc_initialize(context
, id1
, p
);
1048 krb5_free_principal(context
, p
);
1051 test_cache_find(context
, "lha@SU.SE", 1);
1052 test_cache_find(context
, "hulabundulahotentot@SU.SE", 0);
1055 * XXX We should compose and krb5_cc_set_default_name() a default ccache
1056 * for each cc type that we test with test_cache_iter(), and we should do
1057 * that inside test_cache_iter().
1059 * Alternatively we should remove test_cache_iter() in favor of
1060 * test_cccol(), which is a much more complete test.
1062 test_cache_iter(context
, krb5_cc_type_memory
, 0);
1063 test_cache_iter(context
, krb5_cc_type_memory
, 1);
1064 test_cache_iter(context
, krb5_cc_type_memory
, 0);
1065 test_cache_iter(context
, krb5_cc_type_file
, 0);
1066 test_cache_iter(context
, krb5_cc_type_api
, 0);
1067 test_cache_iter(context
, krb5_cc_type_scc
, 0);
1068 test_cache_iter(context
, krb5_cc_type_scc
, 1);
1070 test_cache_iter(context
, krb5_cc_type_dcc
, 0);
1071 test_cache_iter(context
, krb5_cc_type_dcc
, 1);
1073 #ifdef HAVE_KEYUTILS_H
1074 test_cache_iter(context
, krb5_cc_type_keyring
, 0);
1075 test_cache_iter(context
, krb5_cc_type_keyring
, 1);
1078 test_copy(context
, krb5_cc_type_file
, krb5_cc_type_file
);
1079 test_copy(context
, krb5_cc_type_memory
, krb5_cc_type_memory
);
1080 test_copy(context
, krb5_cc_type_file
, krb5_cc_type_memory
);
1081 test_copy(context
, krb5_cc_type_memory
, krb5_cc_type_file
);
1082 test_copy(context
, krb5_cc_type_scc
, krb5_cc_type_file
);
1083 test_copy(context
, krb5_cc_type_file
, krb5_cc_type_scc
);
1084 test_copy(context
, krb5_cc_type_scc
, krb5_cc_type_memory
);
1085 test_copy(context
, krb5_cc_type_memory
, krb5_cc_type_scc
);
1087 test_copy(context
, krb5_cc_type_dcc
, krb5_cc_type_memory
);
1088 test_copy(context
, krb5_cc_type_dcc
, krb5_cc_type_file
);
1089 test_copy(context
, krb5_cc_type_dcc
, krb5_cc_type_scc
);
1091 #ifdef HAVE_KEYUTILS_H
1092 test_copy(context
, krb5_cc_type_keyring
, krb5_cc_type_file
);
1093 test_copy(context
, krb5_cc_type_file
, krb5_cc_type_file
);
1094 test_copy(context
, "KEYRING:", "KEYRING:bar");
1095 test_copy(context
, "KEYRING:bar", "KEYRING:baz");
1096 # ifdef HAVE_KEYCTL_GET_PERSISTENT
1097 test_copy(context
, krb5_cc_type_file
, "KEYRING:persistent");
1098 test_copy(context
, "KEYRING:persistent:", krb5_cc_type_file
);
1099 test_copy(context
, krb5_cc_type_file
, "KEYRING:persistent:foo");
1100 test_copy(context
, "KEYRING:persistent:foo", krb5_cc_type_file
);
1102 test_copy(context
, krb5_cc_type_memory
, "KEYRING:process:");
1103 test_copy(context
, "KEYRING:process:", krb5_cc_type_memory
);
1104 test_copy(context
, krb5_cc_type_memory
, "KEYRING:process:foo");
1105 test_copy(context
, "KEYRING:process:foo", krb5_cc_type_memory
);
1106 test_copy(context
, krb5_cc_type_memory
, "KEYRING:thread:");
1107 test_copy(context
, "KEYRING:thread:", krb5_cc_type_memory
);
1108 test_copy(context
, krb5_cc_type_memory
, "KEYRING:thread:foo");
1109 test_copy(context
, "KEYRING:thread:foo", krb5_cc_type_memory
);
1110 test_copy(context
, krb5_cc_type_memory
, "KEYRING:session:");
1111 test_copy(context
, "KEYRING:session:", krb5_cc_type_memory
);
1112 test_copy(context
, krb5_cc_type_memory
, "KEYRING:session:foo");
1113 test_copy(context
, "KEYRING:session:foo", krb5_cc_type_memory
);
1114 test_copy(context
, krb5_cc_type_file
, "KEYRING:user:");
1115 test_copy(context
, "KEYRING:user:", krb5_cc_type_file
);
1116 test_copy(context
, krb5_cc_type_file
, "KEYRING:user:foo");
1117 test_copy(context
, "KEYRING:user:foo", krb5_cc_type_memory
);
1118 #endif /* HAVE_KEYUTILS_H */
1120 test_move(context
, krb5_cc_type_file
);
1121 test_move(context
, krb5_cc_type_memory
);
1122 test_move(context
, krb5_cc_type_scc
);
1124 test_move(context
, krb5_cc_type_dcc
);
1126 #ifdef HAVE_KEYUTILS_H
1127 test_move(context
, krb5_cc_type_keyring
);
1128 # ifdef HAVE_KEYCTL_GET_PERSISTENT
1129 test_move(context
, "KEYRING:persistent:");
1130 test_move(context
, "KEYRING:persistent:foo");
1132 test_move(context
, "KEYRING:process:");
1133 test_move(context
, "KEYRING:process:foo");
1134 test_move(context
, "KEYRING:thread:");
1135 test_move(context
, "KEYRING:thread:foo");
1136 test_move(context
, "KEYRING:session:");
1137 test_move(context
, "KEYRING:session:foo");
1138 test_move(context
, "KEYRING:user:");
1139 test_move(context
, "KEYRING:user:foo");
1140 #endif /* HAVE_KEYUTILS_H */
1142 test_prefix_ops(context
, "FILE:/tmp/foo", &krb5_fcc_ops
);
1143 test_prefix_ops(context
, "FILE", &krb5_fcc_ops
);
1144 test_prefix_ops(context
, "MEMORY", &krb5_mcc_ops
);
1145 test_prefix_ops(context
, "MEMORY:foo", &krb5_mcc_ops
);
1146 test_prefix_ops(context
, "/tmp/kaka", &krb5_fcc_ops
);
1148 test_prefix_ops(context
, "SCC:", &krb5_scc_ops
);
1149 test_prefix_ops(context
, "SCC:foo", &krb5_scc_ops
);
1152 test_prefix_ops(context
, "DIR:", &krb5_dcc_ops
);
1153 test_prefix_ops(context
, "DIR:tkt1", &krb5_dcc_ops
);
1155 #ifdef HAVE_KEYUTILS_H
1156 test_prefix_ops(context
, "KEYRING:", &krb5_krcc_ops
);
1157 test_prefix_ops(context
, "KEYRING:foo", &krb5_krcc_ops
);
1158 #endif /* HAVE_KEYUTILS_H */
1160 krb5_cc_destroy(context
, id1
);
1161 krb5_cc_destroy(context
, id2
);
1163 test_cc_config(context
, "MEMORY", "bar", 1000); /* 1000 because fast */
1164 test_cc_config(context
, "FILE", "/tmp/foocc", 30); /* 30 because slower */
1166 test_cccol_dcache(context
);
1167 test_cccol_scache(context
);
1168 #ifdef HAVE_KEYUTILS_H
1172 ret
= test_cccol(context
, "KEYRING:legacy:fooccol", &what
);
1174 krb5_err(context
, 1, ret
, "%s", what
);
1176 ret
= test_cccol(context
, "MEMORY:fooccol", &what
);
1178 krb5_err(context
, 1, ret
, "%s", what
);
1180 #endif /* HAVE_KEYUTILS_H */
1184 char *config
= NULL
;
1188 if (asprintf(&d
, "%s/cccol", tmpdir
) == -1 || d
== NULL
)
1189 krb5_err(context
, 1, errno
, "asprintf");
1190 if (mkdir(d
, 0700) == -1)
1191 krb5_err(context
, 1, errno
, "mkdir(%s)", d
);
1192 if (asprintf(&fname
, "%s/foobar", d
) == -1 || fname
== NULL
||
1195 "\tdefault_file_cache_collections = FILE:%1$s/cccol/foobar\n"
1196 "\tenable_file_cache_iteration = true\n",
1197 tmpdir
) == -1 || config
== NULL
)
1198 krb5_err(context
, 1, errno
, "asprintf");
1199 ret
= krb5_set_config(context
, config
);
1201 krb5_err(context
, 1, ret
,
1202 "Could not configure context from string:\n%s\n", config
);
1203 ret
= test_cccol(context
, fname
, &what
);
1205 krb5_err(context
, 1, ret
, "%s", what
);
1211 krb5_free_context(context
);