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 int 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 i, cc_names[i].str); 347 } else { 348 if (cc_names[i].fail) 349 krb5_errx(context, 1, "test %d \"%s\" was successful", 350 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 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 test_move(context, "API"); 665 }); 666 }); 667 dispatch_group_async(inner, q, ^{ 668 dispatch_apply(number, q, ^(size_t num) { 669 test_move(context, "API"); 670 }); 671 }); 672 dispatch_group_async(inner, q, ^{ 673 dispatch_apply(number / 10, q, ^(size_t num) { 674 test_cache_iter(context, type, 0); 675 }); 676 }); 677 dispatch_group_async(inner, q, ^{ 678 dispatch_apply(number / 10, q, ^(size_t num) { 679 test_cache_iter_all(context); 680 }); 681 }); 682 683 dispatch_group_wait(inner, DISPATCH_TIME_FOREVER); 684 dispatch_release(inner); 685 dispatch_semaphore_signal(sema); 686 }); 687 } 688 689 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 690 dispatch_release(group); 691} 692 693#endif 694 695static struct getargs args[] = { 696 {"debug", 'd', arg_flag, &debug_flag, 697 "turn on debuggin", NULL }, 698 {"version", 0, arg_flag, &version_flag, 699 "print version", NULL }, 700 {"help", 0, arg_flag, &help_flag, 701 NULL, NULL } 702}; 703 704static void 705usage (int ret) 706{ 707 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "hostname ..."); 708 exit (ret); 709} 710 711int 712main(int argc, char **argv) 713{ 714 krb5_context context; 715 krb5_error_code ret; 716 int optidx = 0; 717 krb5_ccache id1, id2; 718 719 setprogname(argv[0]); 720 721 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 722 usage(1); 723 724 if (help_flag) 725 usage (0); 726 727 if(version_flag){ 728 print_version(NULL); 729 exit(0); 730 } 731 732 ret = krb5_init_context(&context); 733 if (ret) 734 errx (1, "krb5_init_context failed: %d", ret); 735 736 test_cache_remove(context, krb5_cc_type_file); 737 test_cache_remove(context, krb5_cc_type_memory); 738#ifdef HAVE_SCC 739 test_cache_remove(context, krb5_cc_type_scc); 740#endif 741 742 test_default_name(context); 743 test_mcache(context); 744 test_init_vs_destroy(context, krb5_cc_type_memory); 745 test_init_vs_destroy(context, krb5_cc_type_file); 746#if 0 747 test_init_vs_destroy(context, krb5_cc_type_api); 748#endif 749#ifdef HAVE_SCC 750 test_init_vs_destroy(context, krb5_cc_type_scc); 751#endif 752 test_mcc_default(); 753 test_def_cc_name(context); 754 755 test_cache_iter_all(context); 756 757 test_cache_iter(context, krb5_cc_type_memory, 0); 758 { 759 krb5_principal p; 760 krb5_cc_new_unique(context, krb5_cc_type_memory, "bar", &id1); 761 krb5_cc_new_unique(context, krb5_cc_type_memory, "baz", &id2); 762 krb5_parse_name(context, "lha@SU.SE", &p); 763 krb5_cc_initialize(context, id1, p); 764 krb5_cc_initialize(context, id1, p); 765 krb5_cc_initialize(context, id1, p); 766 krb5_cc_initialize(context, id1, p); 767 krb5_cc_initialize(context, id1, p); 768 krb5_cc_initialize(context, id1, p); 769 krb5_free_principal(context, p); 770 } 771 772 test_cache_find(context, "lha@SU.SE", 1); 773 test_cache_find(context, "hulabundulahotentot@SU.SE", 0); 774 775 test_cache_iter(context, krb5_cc_type_memory, 0); 776 test_cache_iter(context, krb5_cc_type_memory, 1); 777 test_cache_iter(context, krb5_cc_type_memory, 0); 778 test_cache_iter(context, krb5_cc_type_file, 0); 779 test_cache_iter(context, krb5_cc_type_api, 0); 780#ifdef HAVE_SCC 781 test_cache_iter(context, krb5_cc_type_scc, 0); 782 test_cache_iter(context, krb5_cc_type_scc, 1); 783#endif 784#ifdef HAVE_KCC 785 test_cache_iter(context, krb5_cc_type_kcc, 0); 786 test_cache_iter(context, krb5_cc_type_kcc, 1); 787#endif 788 789 test_copy(context, krb5_cc_type_file, krb5_cc_type_file); 790 test_copy(context, krb5_cc_type_memory, krb5_cc_type_memory); 791 test_copy(context, krb5_cc_type_file, krb5_cc_type_memory); 792 test_copy(context, krb5_cc_type_memory, krb5_cc_type_file); 793#ifdef HAVE_SCC 794 test_copy(context, krb5_cc_type_scc, krb5_cc_type_file); 795 test_copy(context, krb5_cc_type_file, krb5_cc_type_scc); 796 test_copy(context, krb5_cc_type_scc, krb5_cc_type_memory); 797 test_copy(context, krb5_cc_type_memory, krb5_cc_type_scc); 798#endif 799#ifdef HAVE_KCC 800 test_copy(context, krb5_cc_type_kcc, krb5_cc_type_file); 801 test_copy(context, krb5_cc_type_file, krb5_cc_type_kcc); 802 test_copy(context, krb5_cc_type_kcc, krb5_cc_type_memory); 803 test_copy(context, krb5_cc_type_memory, krb5_cc_type_kcc); 804#endif 805 test_move(context, krb5_cc_type_file); 806 test_move(context, krb5_cc_type_memory); 807#ifdef HAVE_KCM 808 test_move(context, krb5_cc_type_kcm); 809#endif 810#ifdef HAVE_SCC 811 test_move(context, krb5_cc_type_scc); 812#endif 813 814 test_prefix_ops(context, "FILE:/tmp/foo", &krb5_fcc_ops); 815 test_prefix_ops(context, "FILE", &krb5_fcc_ops); 816 test_prefix_ops(context, "MEMORY", &krb5_mcc_ops); 817 test_prefix_ops(context, "MEMORY:foo", &krb5_mcc_ops); 818 test_prefix_ops(context, "/tmp/kaka", &krb5_fcc_ops); 819#ifdef HAVE_SCC 820 test_prefix_ops(context, "SCC:", &krb5_scc_ops); 821 test_prefix_ops(context, "SCC:foo", &krb5_scc_ops); 822#endif 823#ifdef HAVE_KCC 824 test_prefix_ops(context, "KCC:", &krb5_kcc_ops); 825 test_prefix_ops(context, "KCC:foo", &krb5_kcc_ops); 826#endif 827#ifdef HAVE_XCC 828 test_prefix_ops(context, "XCACHE:", &krb5_xcc_ops); 829 test_prefix_ops(context, "XCACHE:68ADE5C1-C1FF-4088-8AA2-8AF815CDCC5A", &krb5_xcc_ops); 830#endif 831 832 krb5_cc_destroy(context, id1); 833 krb5_cc_destroy(context, id2); 834 835 test_cc_config(context); 836 837#ifdef HAVE_DISPATCH_DISPATCH_H 838 test_threaded(context); 839#endif 840 841 krb5_free_context(context); 842 843 return 0; 844} 845