1/* 2 * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 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. 16 * 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. 20 * 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. */ 32 33#include "krb5_locl.h" 34#include <getarg.h> 35#include <err.h> 36 37#ifdef __APPLE_PRIVATE__ 38#include <dispatch/dispatch.h> 39#endif 40 41static int debug_flag = 0; 42static int version_flag = 0; 43static int help_flag = 0; 44 45#ifdef KRB5_USE_PATH_TOKENS 46#define TEST_CC_NAME "%{TEMP}/krb5-cc-test-foo" 47#else 48#define TEST_CC_NAME "/tmp/krb5-cc-test-foo" 49#endif 50 51static void 52test_default_name(krb5_context context) 53{ 54 krb5_error_code ret; 55 const char *p, *test_cc_name = TEST_CC_NAME; 56 char *p1, *p2, *p3; 57 58 p = krb5_cc_default_name(context); 59 if (p == NULL) 60 krb5_errx (context, 1, "krb5_cc_default_name 1 failed"); 61 p1 = estrdup(p); 62 63 ret = krb5_cc_set_default_name(context, NULL); 64 if (ret) 65 krb5_errx (context, 1, "krb5_cc_set_default_name failed"); 66 67 p = krb5_cc_default_name(context); 68 if (p == NULL) 69 krb5_errx (context, 1, "krb5_cc_default_name 2 failed"); 70 p2 = estrdup(p); 71 72 if (strcmp(p1, p2) != 0) 73 krb5_errx (context, 1, "krb5_cc_default_name no longer same"); 74 75 ret = krb5_cc_set_default_name(context, test_cc_name); 76 if (ret) 77 krb5_errx (context, 1, "krb5_cc_set_default_name 1 failed"); 78 79 p = krb5_cc_default_name(context); 80 if (p == NULL) 81 krb5_errx (context, 1, "krb5_cc_default_name 2 failed"); 82 p3 = estrdup(p); 83 84#ifndef KRB5_USE_PATH_TOKENS 85 /* If we are using path tokens, we don't expect the p3 and 86 test_cc_name to match since p3 is going to have expanded 87 tokens. */ 88 if (strcmp(p3, test_cc_name) != 0) 89 krb5_errx (context, 1, "krb5_cc_set_default_name 1 failed"); 90#endif 91 92 free(p1); 93 free(p2); 94 free(p3); 95} 96 97/* 98 * Check that a closed cc still keeps it data and that it's no longer 99 * there when it's destroyed. 100 */ 101 102static void 103test_mcache(krb5_context context) 104{ 105 krb5_error_code ret; 106 krb5_ccache id, id2; 107 const char *nc, *tc; 108 char *c; 109 krb5_principal p, p2; 110 111 ret = krb5_parse_name(context, "lha@SU.SE", &p); 112 if (ret) 113 krb5_err(context, 1, ret, "krb5_parse_name"); 114 115 ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); 116 if (ret) 117 krb5_err(context, 1, ret, "krb5_cc_new_unique"); 118 119 ret = krb5_cc_initialize(context, id, p); 120 if (ret) 121 krb5_err(context, 1, ret, "krb5_cc_initialize"); 122 123 nc = krb5_cc_get_name(context, id); 124 if (nc == NULL) 125 krb5_errx(context, 1, "krb5_cc_get_name"); 126 127 tc = krb5_cc_get_type(context, id); 128 if (tc == NULL) 129 krb5_errx(context, 1, "krb5_cc_get_name"); 130 131 if (asprintf(&c, "%s:%s", tc, nc) < 0 || c == NULL) 132 errx(1, "malloc"); 133 134 krb5_cc_close(context, id); 135 136 ret = krb5_cc_resolve(context, c, &id2); 137 if (ret) 138 krb5_err(context, 1, ret, "krb5_cc_resolve"); 139 140 ret = krb5_cc_get_principal(context, id2, &p2); 141 if (ret) 142 krb5_err(context, 1, ret, "krb5_cc_get_principal"); 143 144 if (krb5_principal_compare(context, p, p2) == FALSE) 145 krb5_errx(context, 1, "p != p2"); 146 147 krb5_cc_destroy(context, id2); 148 krb5_free_principal(context, p); 149 krb5_free_principal(context, p2); 150 151 ret = krb5_cc_resolve(context, c, &id2); 152 if (ret) 153 krb5_err(context, 1, ret, "krb5_cc_resolve"); 154 155 ret = krb5_cc_get_principal(context, id2, &p2); 156 if (ret == 0) 157 krb5_errx(context, 1, "krb5_cc_get_principal"); 158 159 krb5_cc_destroy(context, id2); 160 free(c); 161} 162 163/* 164 * Test that init works on a destroyed cc. 165 */ 166 167static void 168test_init_vs_destroy(krb5_context context, const char *type) 169{ 170 krb5_error_code ret; 171 krb5_ccache id, id2; 172 krb5_principal p, p2; 173 char *n = NULL; 174 175 ret = krb5_parse_name(context, "lha@SU.SE", &p); 176 if (ret) 177 krb5_err(context, 1, ret, "krb5_parse_name"); 178 179 ret = krb5_cc_new_unique(context, type, NULL, &id); 180 if (ret) 181 krb5_err(context, 1, ret, "krb5_cc_new_unique: %s", type); 182 183 if (asprintf(&n, "%s:%s", 184 krb5_cc_get_type(context, id), 185 krb5_cc_get_name(context, id)) < 0 || n == NULL) 186 errx(1, "malloc"); 187 188 189 ret = krb5_cc_resolve(context, n, &id2); 190 free(n); 191 if (ret) 192 krb5_err(context, 1, ret, "krb5_cc_resolve"); 193 194 krb5_cc_destroy(context, id); 195 196 ret = krb5_cc_initialize(context, id2, p); 197 if (ret) 198 krb5_err(context, 1, ret, "krb5_cc_initialize"); 199 200 ret = krb5_cc_get_principal(context, id2, &p2); 201 if (ret) 202 krb5_err(context, 1, ret, "krb5_cc_get_principal"); 203 204 krb5_cc_destroy(context, id2); 205 krb5_free_principal(context, p); 206 krb5_free_principal(context, p2); 207} 208 209static void 210test_cache_remove(krb5_context context, const char *type) 211{ 212 krb5_error_code ret; 213 krb5_ccache id; 214 krb5_principal p; 215 krb5_creds cred; 216 217 ret = krb5_parse_name(context, "lha@SU.SE", &p); 218 if (ret) 219 krb5_err(context, 1, ret, "krb5_parse_name"); 220 221 ret = krb5_cc_new_unique(context, type, NULL, &id); 222 if (ret) 223 krb5_err(context, 1, ret, "krb5_cc_gen_new: %s", type); 224 225 ret = krb5_cc_initialize(context, id, p); 226 if (ret) 227 krb5_err(context, 1, ret, "krb5_cc_initialize"); 228 229 /* */ 230 memset(&cred, 0, sizeof(cred)); 231 ret = krb5_parse_name(context, "krbtgt/SU.SE@SU.SE", &cred.server); 232 if (ret) 233 krb5_err(context, 1, ret, "krb5_parse_name"); 234 ret = krb5_parse_name(context, "lha@SU.SE", &cred.client); 235 if (ret) 236 krb5_err(context, 1, ret, "krb5_parse_name"); 237 238 ret = krb5_cc_store_cred(context, id, &cred); 239 if (ret) 240 krb5_err(context, 1, ret, "krb5_cc_store_cred"); 241 242 ret = krb5_cc_remove_cred(context, id, 0, &cred); 243 if (ret) 244 krb5_err(context, 1, ret, "krb5_cc_remove_cred"); 245 246 ret = krb5_cc_destroy(context, id); 247 if (ret) 248 krb5_err(context, 1, ret, "krb5_cc_destroy"); 249 250 krb5_free_principal(context, p); 251 krb5_free_principal(context, cred.server); 252 krb5_free_principal(context, cred.client); 253} 254 255static void 256test_mcc_default(void) 257{ 258 krb5_context context; 259 krb5_error_code ret; 260 krb5_ccache id, id2; 261 int i; 262 263 for (i = 0; i < 10; i++) { 264 265 ret = krb5_init_context(&context); 266 if (ret) 267 krb5_err(context, 1, ret, "krb5_init_context"); 268 269 ret = krb5_cc_set_default_name(context, "MEMORY:foo"); 270 if (ret) 271 krb5_err(context, 1, ret, "krb5_cc_set_default_name"); 272 273 ret = krb5_cc_default(context, &id); 274 if (ret) 275 krb5_err(context, 1, ret, "krb5_cc_default"); 276 277 ret = krb5_cc_default(context, &id2); 278 if (ret) 279 krb5_err(context, 1, ret, "krb5_cc_default"); 280 281 ret = krb5_cc_close(context, id); 282 if (ret) 283 krb5_err(context, 1, ret, "krb5_cc_close"); 284 285 ret = krb5_cc_close(context, id2); 286 if (ret) 287 krb5_err(context, 1, ret, "krb5_cc_close"); 288 289 krb5_free_context(context); 290 } 291} 292 293struct { 294 char *str; 295 int fail; 296 char *res; 297} cc_names[] = { 298#ifdef KRB5_USE_PATH_TOKENS 299#ifdef _WIN32 300 { "%{APPDATA}", 0 }, 301 { "%{COMMON_APPDATA}", 0}, 302 { "%{LOCAL_APPDATA}", 0}, 303 { "%{SYSTEM}", 0}, 304 { "%{WINDOWS}", 0}, 305 { "%{USERCONFIG}", 0}, 306 { "%{COMMONCONFIG}", 0}, 307#else 308 { "%{LIBDIR}", 0}, 309 { "%{BINDIR}", 0}, 310 { "%{LIBEXEC}", 0}, 311 { "%{SBINDIR}", 0}, 312#endif 313#if __APPLE__ 314 { "%{ApplicationResources}", 1}, /* only for .app's */ 315#endif 316 { "%{USERID}", 0}, 317 { "%{uid}", 0}, 318 { "%{TEMP}", 0}, 319#endif 320 { "foo", 0, "foo" }, 321 { "foo%}", 0, "foo%}" }, 322 { "%{uid}", 0 }, 323 { "foo%{null}", 0, "foo" }, 324 { "foo%{null}bar", 0, "foobar" }, 325 { "%{", 1 }, 326 { "%{foo %{", 1 }, 327 { "%{{", 1 }, 328 { "%{{}", 1 }, 329 { "%{nulll}", 1 }, 330 { "%{does not exist}", 1 }, 331 { "%{}", 1 } 332}; 333 334static void 335test_def_cc_name(krb5_context context) 336{ 337 krb5_error_code ret; 338 char *str; 339 size_t i; 340 341 for (i = 0; i < sizeof(cc_names)/sizeof(cc_names[0]); i++) { 342 ret = _krb5_expand_default_cc_name(context, cc_names[i].str, &str); 343 if (ret) { 344 if (cc_names[i].fail == 0) 345 krb5_errx(context, 1, "test %d \"%s\" failed", 346 (int)i, cc_names[i].str); 347 } else { 348 if (cc_names[i].fail) 349 krb5_errx(context, 1, "test %d \"%s\" was successful", 350 (int)i, cc_names[i].str); 351 if (cc_names[i].res && strcmp(cc_names[i].res, str) != 0) 352 krb5_errx(context, 1, "test %d %s != %s", 353 (int)i, cc_names[i].res, str); 354 if (debug_flag) 355 printf("%s => %s\n", cc_names[i].str, str); 356 free(str); 357 } 358 } 359} 360 361static void 362test_cache_find(krb5_context context, const char *principal, int find) 363{ 364 krb5_principal client; 365 krb5_error_code ret; 366 krb5_ccache id = NULL; 367 368 ret = krb5_parse_name(context, principal, &client); 369 if (ret) 370 krb5_err(context, 1, ret, "parse_name for %s failed", principal); 371 372 ret = krb5_cc_cache_match(context, client, &id); 373 if (ret && find) 374 krb5_err(context, 1, ret, "cc_cache_match for %s failed", principal); 375 if (ret == 0 && !find) 376 krb5_err(context, 1, ret, "cc_cache_match for %s found", principal); 377 378 if (id) 379 krb5_cc_close(context, id); 380 krb5_free_principal(context, client); 381} 382 383 384static void 385test_cache_iter(krb5_context context, const char *type, int destroy) 386{ 387 krb5_cc_cache_cursor cursor; 388 krb5_error_code ret; 389 krb5_ccache id; 390 391 ret = krb5_cc_cache_get_first (context, type, &cursor); 392 if (ret == KRB5_CC_NOSUPP) 393 return; 394 else if (ret) 395 krb5_err(context, 1, ret, "krb5_cc_cache_get_first(%s)", type); 396 397 398 while ((ret = krb5_cc_cache_next (context, cursor, &id)) == 0) { 399 krb5_principal principal; 400 char *name; 401 402 if (debug_flag) 403 printf("name: %s\n", krb5_cc_get_name(context, id)); 404 ret = krb5_cc_get_principal(context, id, &principal); 405 if (ret == 0) { 406 ret = krb5_unparse_name(context, principal, &name); 407 if (ret == 0) { 408 if (debug_flag) 409 printf("\tprincipal: %s\n", name); 410 free(name); 411 } 412 krb5_free_principal(context, principal); 413 } 414 if (destroy) 415 krb5_cc_destroy(context, id); 416 else 417 krb5_cc_close(context, id); 418 } 419 if (ret != KRB5_CC_END) 420 krb5_err(context, 1, ret, "krb5_cc_cache_next returned not expected error"); 421 422 krb5_cc_cache_end_seq_get(context, cursor); 423} 424 425static void 426test_cache_iter_all(krb5_context context) 427{ 428 krb5_cccol_cursor cursor; 429 krb5_error_code ret; 430 krb5_ccache id; 431 432 ret = krb5_cccol_cursor_new (context, &cursor); 433 if (ret) 434 krb5_err(context, 1, ret, "krb5_cccol_cursor_new"); 435 436 437 while ((ret = krb5_cccol_cursor_next (context, cursor, &id)) == 0 && id != NULL) { 438 krb5_principal principal; 439 char *name; 440 441 if (debug_flag) 442 printf("name: %s\n", krb5_cc_get_name(context, id)); 443 ret = krb5_cc_get_principal(context, id, &principal); 444 if (ret == 0) { 445 ret = krb5_unparse_name(context, principal, &name); 446 if (ret == 0) { 447 if (debug_flag) 448 printf("\tprincipal: %s\n", name); 449 free(name); 450 } 451 krb5_free_principal(context, principal); 452 } 453 krb5_cc_close(context, id); 454 } 455 if (ret != KRB5_CC_END) 456 krb5_err(context, 1, ret, "krb5_cccol_cursor_next returned not expected error"); 457 458 krb5_cccol_cursor_free(context, &cursor); 459} 460 461 462static void 463test_copy(krb5_context context, const char *from, const char *to) 464{ 465 krb5_ccache fromid, toid; 466 krb5_error_code ret; 467 krb5_principal p, p2; 468 469 ret = krb5_parse_name(context, "lha@SU.SE", &p); 470 if (ret) 471 krb5_err(context, 1, ret, "krb5_parse_name"); 472 473 ret = krb5_cc_new_unique(context, from, NULL, &fromid); 474 if (ret) 475 krb5_err(context, 1, ret, "krb5_cc_new_unique: %s", from); 476 477 ret = krb5_cc_initialize(context, fromid, p); 478 if (ret) 479 krb5_err(context, 1, ret, "krb5_cc_initialize"); 480 481 ret = krb5_cc_new_unique(context, to, NULL, &toid); 482 if (ret) 483 krb5_err(context, 1, ret, "krb5_cc_gen_new: %s", to); 484 485 ret = krb5_cc_copy_cache(context, fromid, toid); 486 if (ret) 487 krb5_err(context, 1, ret, "krb5_cc_copy_cache"); 488 489 ret = krb5_cc_get_principal(context, toid, &p2); 490 if (ret) 491 krb5_err(context, 1, ret, "krb5_cc_get_principal"); 492 493 if (krb5_principal_compare(context, p, p2) == FALSE) 494 krb5_errx(context, 1, "p != p2"); 495 496 krb5_free_principal(context, p); 497 krb5_free_principal(context, p2); 498 499 krb5_cc_destroy(context, fromid); 500 krb5_cc_destroy(context, toid); 501} 502 503static void 504test_move(krb5_context context, const char *type) 505{ 506 const krb5_cc_ops *ops; 507 krb5_ccache fromid, toid; 508 krb5_error_code ret; 509 krb5_principal p, p2; 510 511 ops = krb5_cc_get_prefix_ops(context, type); 512 if (ops == NULL) 513 return; 514 515 ret = krb5_cc_new_unique(context, type, NULL, &fromid); 516 if (ret == KRB5_CC_NOSUPP) 517 return; 518 else if (ret) 519 krb5_err(context, 1, ret, "krb5_cc_new_unique: %s", type); 520 521 ret = krb5_parse_name(context, "lha@SU.SE", &p); 522 if (ret) 523 krb5_err(context, 1, ret, "krb5_parse_name"); 524 525 ret = krb5_cc_initialize(context, fromid, p); 526 if (ret) 527 krb5_err(context, 1, ret, "krb5_cc_initialize"); 528 529 ret = krb5_cc_new_unique(context, type, NULL, &toid); 530 if (ret) 531 krb5_err(context, 1, ret, "krb5_cc_new_unique"); 532 533 ret = krb5_cc_initialize(context, toid, p); 534 if (ret) 535 krb5_err(context, 1, ret, "krb5_cc_initialize"); 536 537 ret = krb5_cc_get_principal(context, toid, &p2); 538 if (ret) 539 krb5_err(context, 1, ret, "krb5_cc_get_principal"); 540 541 if (krb5_principal_compare(context, p, p2) == FALSE) 542 krb5_errx(context, 1, "p != p2"); 543 544 krb5_free_principal(context, p); 545 krb5_free_principal(context, p2); 546 547 krb5_cc_destroy(context, toid); 548 krb5_cc_destroy(context, fromid); 549} 550 551 552static void 553test_prefix_ops(krb5_context context, const char *name, const krb5_cc_ops *ops) 554{ 555 const krb5_cc_ops *o; 556 557 o = krb5_cc_get_prefix_ops(context, name); 558 if (o == NULL) 559 krb5_errx(context, 1, "found no match for prefix '%s'", name); 560 if (strcmp(o->prefix, ops->prefix) != 0) 561 krb5_errx(context, 1, "ops for prefix '%s' is not " 562 "the expected %s != %s", name, o->prefix, ops->prefix); 563} 564 565static void 566test_cc_config(krb5_context context) 567{ 568 krb5_error_code ret; 569 krb5_principal p; 570 krb5_ccache id; 571 unsigned int i; 572 573 ret = krb5_cc_new_unique(context, "MEMORY", "bar", &id); 574 if (ret) 575 krb5_err(context, 1, ret, "krb5_cc_new_unique"); 576 577 ret = krb5_parse_name(context, "lha@SU.SE", &p); 578 if (ret) 579 krb5_err(context, 1, ret, "krb5_parse_name"); 580 581 ret = krb5_cc_initialize(context, id, p); 582 if (ret) 583 krb5_err(context, 1, ret, "krb5_cc_initialize"); 584 585 for (i = 0; i < 1000; i++) { 586 krb5_data data, data2; 587 const char *name = "foo"; 588 krb5_principal p1 = NULL; 589 590 if (i & 1) 591 p1 = p; 592 593 data.data = rk_UNCONST(name); 594 data.length = strlen(name); 595 596 ret = krb5_cc_set_config(context, id, p1, "FriendlyName", &data); 597 if (ret) 598 krb5_errx(context, 1, "krb5_cc_set_config: add"); 599 600 ret = krb5_cc_get_config(context, id, p1, "FriendlyName", &data2); 601 if (ret) 602 krb5_errx(context, 1, "krb5_cc_get_config: first"); 603 krb5_data_free(&data2); 604 605 ret = krb5_cc_set_config(context, id, p1, "FriendlyName", &data); 606 if (ret) 607 krb5_errx(context, 1, "krb5_cc_set_config: add -second"); 608 609 ret = krb5_cc_get_config(context, id, p1, "FriendlyName", &data2); 610 if (ret) 611 krb5_errx(context, 1, "krb5_cc_get_config: second"); 612 krb5_data_free(&data2); 613 614 ret = krb5_cc_set_config(context, id, p1, "FriendlyName", NULL); 615 if (ret) 616 krb5_errx(context, 1, "krb5_cc_set_config: delete"); 617 618 ret = krb5_cc_get_config(context, id, p1, "FriendlyName", &data2); 619 if (ret == 0) 620 krb5_errx(context, 1, "krb5_cc_get_config: non-existant"); 621 } 622 623 krb5_cc_destroy(context, id); 624 krb5_free_principal(context, p); 625} 626 627#ifdef HAVE_DISPATCH_DISPATCH_H 628 629static void 630test_threaded(krb5_context context) 631{ 632 dispatch_semaphore_t sema; 633 dispatch_queue_t q; 634 dispatch_group_t group; 635 time_t old; 636 const char *type = "API"; 637 638 /* clean up old caches first */ 639 test_cache_iter(context, type, 1); 640 641 sema = dispatch_semaphore_create(10); 642 643 q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 644 645 old = time(NULL); 646 647 group = dispatch_group_create(); 648 if (group == NULL) abort(); 649 650 while (time(NULL) - old < 10) { 651 size_t number = 100; 652 653 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 654 655 if (debug_flag) 656 printf("time: %d\n", (int)(time(NULL) - old)); 657 658 dispatch_group_async(group, q, ^{ 659 dispatch_group_t inner = dispatch_group_create(); 660 if (inner == NULL) abort(); 661 662 dispatch_group_async(inner, q, ^{ 663 dispatch_apply(number, q, ^(size_t num) { 664 krb5_context c; 665 krb5_init_context(&c); 666 test_move(c, "API"); 667 krb5_free_context(c); 668 }); 669 }); 670 dispatch_group_async(inner, q, ^{ 671 dispatch_apply(number, q, ^(size_t num) { 672 krb5_context c; 673 krb5_init_context(&c); 674 test_move(c, "API"); 675 krb5_free_context(c); 676 }); 677 }); 678 dispatch_group_async(inner, q, ^{ 679 dispatch_apply(number / 10, q, ^(size_t num) { 680 krb5_context c; 681 krb5_init_context(&c); 682 test_cache_iter(c, type, 0); 683 krb5_free_context(c); 684 }); 685 }); 686 dispatch_group_async(inner, q, ^{ 687 dispatch_apply(number / 10, q, ^(size_t num) { 688 krb5_context c; 689 krb5_init_context(&c); 690 test_cache_iter_all(c); 691 krb5_free_context(c); 692 }); 693 }); 694 695 dispatch_group_wait(inner, DISPATCH_TIME_FOREVER); 696 dispatch_release(inner); 697 dispatch_semaphore_signal(sema); 698 }); 699 } 700 701 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 702 dispatch_release(group); 703} 704 705#endif 706 707static struct getargs args[] = { 708 {"debug", 'd', arg_flag, &debug_flag, 709 "turn on debuggin", NULL }, 710 {"version", 0, arg_flag, &version_flag, 711 "print version", NULL }, 712 {"help", 0, arg_flag, &help_flag, 713 NULL, NULL } 714}; 715 716static void 717usage (int ret) 718{ 719 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "hostname ..."); 720 exit (ret); 721} 722 723int 724main(int argc, char **argv) 725{ 726 krb5_context context; 727 krb5_error_code ret; 728 int optidx = 0; 729 krb5_ccache id1, id2; 730 731 setprogname(argv[0]); 732 733 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 734 usage(1); 735 736 if (help_flag) 737 usage (0); 738 739 if(version_flag){ 740 print_version(NULL); 741 exit(0); 742 } 743 744 ret = krb5_init_context(&context); 745 if (ret) 746 errx (1, "krb5_init_context failed: %d", ret); 747 748 test_cache_remove(context, krb5_cc_type_file); 749 test_cache_remove(context, krb5_cc_type_memory); 750#ifdef HAVE_SCC 751 test_cache_remove(context, krb5_cc_type_scc); 752#endif 753 754 test_default_name(context); 755 test_mcache(context); 756 test_init_vs_destroy(context, krb5_cc_type_memory); 757 test_init_vs_destroy(context, krb5_cc_type_file); 758#if 0 759 test_init_vs_destroy(context, krb5_cc_type_api); 760#endif 761#ifdef HAVE_SCC 762 test_init_vs_destroy(context, krb5_cc_type_scc); 763#endif 764 test_mcc_default(); 765 test_def_cc_name(context); 766 767 test_cache_iter_all(context); 768 769 test_cache_iter(context, krb5_cc_type_memory, 0); 770 { 771 krb5_principal p; 772 krb5_cc_new_unique(context, krb5_cc_type_memory, "bar", &id1); 773 krb5_cc_new_unique(context, krb5_cc_type_memory, "baz", &id2); 774 krb5_parse_name(context, "lha@SU.SE", &p); 775 krb5_cc_initialize(context, id1, p); 776 krb5_cc_initialize(context, id1, p); 777 krb5_cc_initialize(context, id1, p); 778 krb5_cc_initialize(context, id1, p); 779 krb5_cc_initialize(context, id1, p); 780 krb5_cc_initialize(context, id1, p); 781 krb5_free_principal(context, p); 782 } 783 784 test_cache_find(context, "lha@SU.SE", 1); 785 test_cache_find(context, "hulabundulahotentot@SU.SE", 0); 786 787 test_cache_iter(context, krb5_cc_type_memory, 0); 788 test_cache_iter(context, krb5_cc_type_memory, 1); 789 test_cache_iter(context, krb5_cc_type_memory, 0); 790 test_cache_iter(context, krb5_cc_type_file, 0); 791 test_cache_iter(context, krb5_cc_type_api, 0); 792#ifdef HAVE_SCC 793 test_cache_iter(context, krb5_cc_type_scc, 0); 794 test_cache_iter(context, krb5_cc_type_scc, 1); 795#endif 796#ifdef HAVE_KCC 797 test_cache_iter(context, krb5_cc_type_kcc, 0); 798 test_cache_iter(context, krb5_cc_type_kcc, 1); 799#endif 800 801 test_copy(context, krb5_cc_type_file, krb5_cc_type_file); 802 test_copy(context, krb5_cc_type_memory, krb5_cc_type_memory); 803 test_copy(context, krb5_cc_type_file, krb5_cc_type_memory); 804 test_copy(context, krb5_cc_type_memory, krb5_cc_type_file); 805#ifdef HAVE_SCC 806 test_copy(context, krb5_cc_type_scc, krb5_cc_type_file); 807 test_copy(context, krb5_cc_type_file, krb5_cc_type_scc); 808 test_copy(context, krb5_cc_type_scc, krb5_cc_type_memory); 809 test_copy(context, krb5_cc_type_memory, krb5_cc_type_scc); 810#endif 811#ifdef HAVE_KCC 812 test_copy(context, krb5_cc_type_kcc, krb5_cc_type_file); 813 test_copy(context, krb5_cc_type_file, krb5_cc_type_kcc); 814 test_copy(context, krb5_cc_type_kcc, krb5_cc_type_memory); 815 test_copy(context, krb5_cc_type_memory, krb5_cc_type_kcc); 816#endif 817 test_move(context, krb5_cc_type_file); 818 test_move(context, krb5_cc_type_memory); 819#ifdef HAVE_KCM 820 test_move(context, krb5_cc_type_kcm); 821#endif 822#ifdef HAVE_SCC 823 test_move(context, krb5_cc_type_scc); 824#endif 825 826 test_prefix_ops(context, "FILE:/tmp/foo", &krb5_fcc_ops); 827 test_prefix_ops(context, "FILE", &krb5_fcc_ops); 828 test_prefix_ops(context, "MEMORY", &krb5_mcc_ops); 829 test_prefix_ops(context, "MEMORY:foo", &krb5_mcc_ops); 830 test_prefix_ops(context, "/tmp/kaka", &krb5_fcc_ops); 831#ifdef HAVE_SCC 832 test_prefix_ops(context, "SCC:", &krb5_scc_ops); 833 test_prefix_ops(context, "SCC:foo", &krb5_scc_ops); 834#endif 835#ifdef HAVE_KCC 836 test_prefix_ops(context, "KCC:", &krb5_kcc_ops); 837 test_prefix_ops(context, "KCC:foo", &krb5_kcc_ops); 838#endif 839#ifdef HAVE_XCC 840 test_prefix_ops(context, "XCACHE:", &krb5_xcc_ops); 841 test_prefix_ops(context, "XCACHE:68ADE5C1-C1FF-4088-8AA2-8AF815CDCC5A", &krb5_xcc_ops); 842#endif 843 844 krb5_cc_destroy(context, id1); 845 krb5_cc_destroy(context, id2); 846 847 test_cc_config(context); 848 849#ifdef HAVE_DISPATCH_DISPATCH_H 850 test_threaded(context); 851#endif 852 853 krb5_free_context(context); 854 855 return 0; 856} 857