1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (C) 1990 by the Massachusetts Institute of Technology 36 * 37 * Export of this software from the United States of America may 38 * require a specific license from the United States Government. 39 * It is the responsibility of any person or organization contemplating 40 * export to obtain such a license before exporting. 41 * 42 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 43 * distribute this software and its documentation for any purpose and 44 * without fee is hereby granted, provided that the above copyright 45 * notice appear in all copies and that both that copyright notice and 46 * this permission notice appear in supporting documentation, and that 47 * the name of M.I.T. not be used in advertising or publicity pertaining 48 * to distribution of the software without specific, written prior 49 * permission. M.I.T. makes no representations about the suitability of 50 * this software for any purpose. It is provided "as is" without express 51 * or implied warranty. 52 */ 53 54 #include <sys/cdefs.h> 55 56 __FBSDID("$FreeBSD$"); 57 58 #ifdef KRB5 59 60 #include <arpa/telnet.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include <unistd.h> 65 #include <netdb.h> 66 #include <ctype.h> 67 #include <pwd.h> 68 #define Authenticator k5_Authenticator 69 #include <krb5.h> 70 #undef Authenticator 71 72 #include "encrypt.h" 73 #include "auth.h" 74 #include "misc.h" 75 76 int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */ 77 78 /* These values need to be the same as those defined in telnet/main.c. */ 79 /* Either define them in both places, or put in some common header file. */ 80 #define OPTS_FORWARD_CREDS 0x00000002 81 #define OPTS_FORWARDABLE_CREDS 0x00000001 82 83 void kerberos5_forward (Authenticator *); 84 85 static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, 86 AUTHTYPE_KERBEROS_V5, }; 87 88 #define KRB_AUTH 0 /* Authentication data follows */ 89 #define KRB_REJECT 1 /* Rejected (reason might follow) */ 90 #define KRB_ACCEPT 2 /* Accepted */ 91 #define KRB_RESPONSE 3 /* Response for mutual auth. */ 92 93 #define KRB_FORWARD 4 /* Forwarded credentials follow */ 94 #define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ 95 #define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ 96 97 static krb5_data auth; 98 static krb5_ticket *ticket; 99 100 static krb5_context context; 101 static krb5_auth_context auth_context; 102 103 static int 104 Data(Authenticator *ap, int type, const char *d, int c) 105 { 106 unsigned char *p = str_data + 4; 107 const unsigned char *cd = d; 108 109 if (c == -1) 110 c = strlen(cd); 111 112 if (auth_debug_mode) { 113 printf("%s:%d: [%d] (%d)", 114 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 115 str_data[3], 116 type, c); 117 printd(d, c); 118 printf("\r\n"); 119 } 120 *p++ = ap->type; 121 *p++ = ap->way; 122 *p++ = type; 123 while (c-- > 0) { 124 if ((*p++ = *cd++) == IAC) 125 *p++ = IAC; 126 } 127 *p++ = IAC; 128 *p++ = SE; 129 if (str_data[3] == TELQUAL_IS) 130 printsub('>', &str_data[2], p - &str_data[2]); 131 return(net_write(str_data, p - str_data)); 132 } 133 134 int 135 kerberos5_init(Authenticator *ap __unused, int server) 136 { 137 krb5_error_code ret; 138 139 ret = krb5_init_context(&context); 140 if (ret) 141 return 0; 142 if (server) { 143 krb5_keytab kt; 144 krb5_kt_cursor cursor; 145 146 ret = krb5_kt_default(context, &kt); 147 if (ret) 148 return 0; 149 150 ret = krb5_kt_start_seq_get (context, kt, &cursor); 151 if (ret) { 152 krb5_kt_close (context, kt); 153 return 0; 154 } 155 krb5_kt_end_seq_get (context, kt, &cursor); 156 krb5_kt_close (context, kt); 157 158 str_data[3] = TELQUAL_REPLY; 159 } else 160 str_data[3] = TELQUAL_IS; 161 return(1); 162 } 163 164 extern int net; 165 166 static int 167 kerberos5_send(const char *name, Authenticator *ap) 168 { 169 krb5_error_code ret; 170 krb5_ccache ccache; 171 int ap_opts; 172 krb5_data cksum_data; 173 char foo[2]; 174 175 if (!UserNameRequested) { 176 if (auth_debug_mode) { 177 printf("Kerberos V5: no user name supplied\r\n"); 178 } 179 return(0); 180 } 181 182 ret = krb5_cc_default(context, &ccache); 183 if (ret) { 184 if (auth_debug_mode) { 185 printf("Kerberos V5: could not get default ccache: %s\r\n", 186 krb5_get_err_text (context, ret)); 187 } 188 return 0; 189 } 190 191 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) 192 ap_opts = AP_OPTS_MUTUAL_REQUIRED; 193 else 194 ap_opts = 0; 195 196 ret = krb5_auth_con_init (context, &auth_context); 197 if (ret) { 198 if (auth_debug_mode) { 199 printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", 200 krb5_get_err_text(context, ret)); 201 } 202 return(0); 203 } 204 205 ret = krb5_auth_con_setaddrs_from_fd (context, 206 auth_context, 207 &net); 208 if (ret) { 209 if (auth_debug_mode) { 210 printf ("Kerberos V5:" 211 " krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", 212 krb5_get_err_text(context, ret)); 213 } 214 return(0); 215 } 216 217 krb5_auth_setkeytype (context, auth_context, KEYTYPE_DES); 218 219 foo[0] = ap->type; 220 foo[1] = ap->way; 221 222 cksum_data.length = sizeof(foo); 223 cksum_data.data = foo; 224 225 226 { 227 krb5_principal service; 228 char sname[128]; 229 230 231 ret = krb5_sname_to_principal (context, 232 RemoteHostName, 233 NULL, 234 KRB5_NT_SRV_HST, 235 &service); 236 if(ret) { 237 if (auth_debug_mode) { 238 printf ("Kerberos V5:" 239 " krb5_sname_to_principal(%s) failed (%s)\r\n", 240 RemoteHostName, krb5_get_err_text(context, ret)); 241 } 242 return 0; 243 } 244 ret = krb5_unparse_name_fixed(context, service, sname, sizeof(sname)); 245 if(ret) { 246 if (auth_debug_mode) { 247 printf ("Kerberos V5:" 248 " krb5_unparse_name_fixed failed (%s)\r\n", 249 krb5_get_err_text(context, ret)); 250 } 251 return 0; 252 } 253 printf("[ Trying %s (%s)... ]\r\n", name, sname); 254 ret = krb5_mk_req_exact(context, &auth_context, ap_opts, 255 service, 256 &cksum_data, ccache, &auth); 257 krb5_free_principal (context, service); 258 259 } 260 if (ret) { 261 if (1 || auth_debug_mode) { 262 printf("Kerberos V5: mk_req failed (%s)\r\n", 263 krb5_get_err_text(context, ret)); 264 } 265 return(0); 266 } 267 268 if (!auth_sendname((unsigned char *)UserNameRequested, 269 strlen(UserNameRequested))) { 270 if (auth_debug_mode) 271 printf("Not enough room for user name\r\n"); 272 return(0); 273 } 274 if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { 275 if (auth_debug_mode) 276 printf("Not enough room for authentication data\r\n"); 277 return(0); 278 } 279 if (auth_debug_mode) { 280 printf("Sent Kerberos V5 credentials to server\r\n"); 281 } 282 return(1); 283 } 284 285 int 286 kerberos5_send_mutual(Authenticator *ap) 287 { 288 return kerberos5_send("mutual KERBEROS5", ap); 289 } 290 291 int 292 kerberos5_send_oneway(Authenticator *ap) 293 { 294 return kerberos5_send("KERBEROS5", ap); 295 } 296 297 void 298 kerberos5_is(Authenticator *ap, unsigned char *data, int cnt) 299 { 300 krb5_error_code ret; 301 krb5_data outbuf; 302 krb5_keyblock *key_block; 303 char *name; 304 krb5_principal server; 305 int zero = 0; 306 307 if (cnt-- < 1) 308 return; 309 switch (*data++) { 310 case KRB_AUTH: 311 auth.data = (char *)data; 312 auth.length = cnt; 313 314 auth_context = NULL; 315 316 ret = krb5_auth_con_init (context, &auth_context); 317 if (ret) { 318 Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1); 319 auth_finished(ap, AUTH_REJECT); 320 if (auth_debug_mode) 321 printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", 322 krb5_get_err_text(context, ret)); 323 return; 324 } 325 326 ret = krb5_auth_con_setaddrs_from_fd (context, 327 auth_context, 328 &zero); 329 if (ret) { 330 Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1); 331 auth_finished(ap, AUTH_REJECT); 332 if (auth_debug_mode) 333 printf("Kerberos V5: " 334 "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", 335 krb5_get_err_text(context, ret)); 336 return; 337 } 338 339 ret = krb5_sock_to_principal (context, 340 0, 341 "host", 342 KRB5_NT_SRV_HST, 343 &server); 344 if (ret) { 345 Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1); 346 auth_finished(ap, AUTH_REJECT); 347 if (auth_debug_mode) 348 printf("Kerberos V5: " 349 "krb5_sock_to_principal failed (%s)\r\n", 350 krb5_get_err_text(context, ret)); 351 return; 352 } 353 354 ret = krb5_rd_req(context, 355 &auth_context, 356 &auth, 357 server, 358 NULL, 359 NULL, 360 &ticket); 361 362 krb5_free_principal (context, server); 363 if (ret) { 364 char *errbuf; 365 366 asprintf(&errbuf, 367 "Read req failed: %s", 368 krb5_get_err_text(context, ret)); 369 Data(ap, KRB_REJECT, errbuf, -1); 370 if (auth_debug_mode) 371 printf("%s\r\n", errbuf); 372 free (errbuf); 373 return; 374 } 375 376 { 377 char foo[2]; 378 379 foo[0] = ap->type; 380 foo[1] = ap->way; 381 382 ret = krb5_verify_authenticator_checksum(context, 383 auth_context, 384 foo, 385 sizeof(foo)); 386 387 if (ret) { 388 char *errbuf; 389 asprintf(&errbuf, "Bad checksum: %s", 390 krb5_get_err_text(context, ret)); 391 Data(ap, KRB_REJECT, errbuf, -1); 392 if (auth_debug_mode) 393 printf ("%s\r\n", errbuf); 394 free(errbuf); 395 return; 396 } 397 } 398 ret = krb5_auth_con_getremotesubkey (context, 399 auth_context, 400 &key_block); 401 402 if (ret) { 403 Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1); 404 auth_finished(ap, AUTH_REJECT); 405 if (auth_debug_mode) 406 printf("Kerberos V5: " 407 "krb5_auth_con_getremotesubkey failed (%s)\r\n", 408 krb5_get_err_text(context, ret)); 409 return; 410 } 411 412 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 413 ret = krb5_mk_rep(context, auth_context, &outbuf); 414 if (ret) { 415 Data(ap, KRB_REJECT, 416 "krb5_mk_rep failed", -1); 417 auth_finished(ap, AUTH_REJECT); 418 if (auth_debug_mode) 419 printf("Kerberos V5: " 420 "krb5_mk_rep failed (%s)\r\n", 421 krb5_get_err_text(context, ret)); 422 return; 423 } 424 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 425 } 426 if (krb5_unparse_name(context, ticket->client, &name)) 427 name = 0; 428 429 if(UserNameRequested && krb5_kuserok(context, 430 ticket->client, 431 UserNameRequested)) { 432 Data(ap, KRB_ACCEPT, name, name ? -1 : 0); 433 if (auth_debug_mode) { 434 printf("Kerberos5 identifies him as ``%s''\r\n", 435 name ? name : ""); 436 } 437 438 if(key_block->keytype == ETYPE_DES_CBC_MD5 || 439 key_block->keytype == ETYPE_DES_CBC_MD4 || 440 key_block->keytype == ETYPE_DES_CBC_CRC) { 441 Session_Key skey; 442 443 skey.type = SK_DES; 444 skey.length = 8; 445 skey.data = key_block->keyvalue.data; 446 encrypt_session_key(&skey, 0); 447 } 448 449 } else { 450 char *msg; 451 452 asprintf (&msg, "user `%s' is not authorized to " 453 "login as `%s'", 454 name ? name : "<unknown>", 455 UserNameRequested ? UserNameRequested : "<nobody>"); 456 if (msg == NULL) 457 Data(ap, KRB_REJECT, NULL, 0); 458 else { 459 Data(ap, KRB_REJECT, (void *)msg, -1); 460 free(msg); 461 } 462 auth_finished (ap, AUTH_REJECT); 463 krb5_free_keyblock_contents(context, key_block); 464 break; 465 } 466 auth_finished(ap, AUTH_USER); 467 krb5_free_keyblock_contents(context, key_block); 468 469 break; 470 case KRB_FORWARD: { 471 struct passwd *pwd; 472 char ccname[1024]; /* XXX */ 473 krb5_data inbuf; 474 krb5_ccache ccache; 475 inbuf.data = (char *)data; 476 inbuf.length = cnt; 477 478 pwd = getpwnam (UserNameRequested); 479 if (pwd == NULL) 480 break; 481 482 snprintf (ccname, sizeof(ccname), 483 "FILE:/tmp/krb5cc_%u", pwd->pw_uid); 484 485 ret = krb5_cc_resolve (context, ccname, &ccache); 486 if (ret) { 487 if (auth_debug_mode) 488 printf ("Kerberos V5: could not get ccache: %s\r\n", 489 krb5_get_err_text(context, ret)); 490 break; 491 } 492 493 ret = krb5_cc_initialize (context, 494 ccache, 495 ticket->client); 496 if (ret) { 497 if (auth_debug_mode) 498 printf ("Kerberos V5: could not init ccache: %s\r\n", 499 krb5_get_err_text(context, ret)); 500 break; 501 } 502 503 #if defined(DCE) 504 esetenv("KRB5CCNAME", ccname, 1); 505 #endif 506 ret = krb5_rd_cred2 (context, 507 auth_context, 508 ccache, 509 &inbuf); 510 if(ret) { 511 char *errbuf; 512 513 asprintf (&errbuf, 514 "Read forwarded creds failed: %s", 515 krb5_get_err_text (context, ret)); 516 if(errbuf == NULL) 517 Data(ap, KRB_FORWARD_REJECT, NULL, 0); 518 else 519 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 520 if (auth_debug_mode) 521 printf("Could not read forwarded credentials: %s\r\n", 522 errbuf); 523 free (errbuf); 524 } else { 525 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 526 #if defined(DCE) 527 dfsfwd = 1; 528 #endif 529 } 530 chown (ccname + 5, pwd->pw_uid, -1); 531 if (auth_debug_mode) 532 printf("Forwarded credentials obtained\r\n"); 533 break; 534 } 535 default: 536 if (auth_debug_mode) 537 printf("Unknown Kerberos option %d\r\n", data[-1]); 538 Data(ap, KRB_REJECT, 0, 0); 539 break; 540 } 541 } 542 543 void 544 kerberos5_reply(Authenticator *ap, unsigned char *data, int cnt) 545 { 546 static int mutual_complete = 0; 547 548 if (cnt-- < 1) 549 return; 550 switch (*data++) { 551 case KRB_REJECT: 552 if (cnt > 0) { 553 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 554 cnt, data); 555 } else 556 printf("[ Kerberos V5 refuses authentication ]\r\n"); 557 auth_send_retry(); 558 return; 559 case KRB_ACCEPT: { 560 krb5_error_code ret; 561 Session_Key skey; 562 krb5_keyblock *keyblock; 563 564 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 565 !mutual_complete) { 566 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); 567 auth_send_retry(); 568 return; 569 } 570 if (cnt) 571 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); 572 else 573 printf("[ Kerberos V5 accepts you ]\r\n"); 574 575 ret = krb5_auth_con_getlocalsubkey (context, 576 auth_context, 577 &keyblock); 578 if (ret) 579 ret = krb5_auth_con_getkey (context, 580 auth_context, 581 &keyblock); 582 if(ret) { 583 printf("[ krb5_auth_con_getkey: %s ]\r\n", 584 krb5_get_err_text(context, ret)); 585 auth_send_retry(); 586 return; 587 } 588 589 skey.type = SK_DES; 590 skey.length = 8; 591 skey.data = keyblock->keyvalue.data; 592 encrypt_session_key(&skey, 0); 593 krb5_free_keyblock_contents (context, keyblock); 594 auth_finished(ap, AUTH_USER); 595 if (forward_flags & OPTS_FORWARD_CREDS) 596 kerberos5_forward(ap); 597 break; 598 } 599 case KRB_RESPONSE: 600 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 601 /* the rest of the reply should contain a krb_ap_rep */ 602 krb5_ap_rep_enc_part *reply; 603 krb5_data inbuf; 604 krb5_error_code ret; 605 606 inbuf.length = cnt; 607 inbuf.data = (char *)data; 608 609 ret = krb5_rd_rep(context, auth_context, &inbuf, &reply); 610 if (ret) { 611 printf("[ Mutual authentication failed: %s ]\r\n", 612 krb5_get_err_text (context, ret)); 613 auth_send_retry(); 614 return; 615 } 616 krb5_free_ap_rep_enc_part(context, reply); 617 mutual_complete = 1; 618 } 619 return; 620 case KRB_FORWARD_ACCEPT: 621 printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); 622 return; 623 case KRB_FORWARD_REJECT: 624 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 625 cnt, data); 626 return; 627 default: 628 if (auth_debug_mode) 629 printf("Unknown Kerberos option %d\r\n", data[-1]); 630 return; 631 } 632 } 633 634 int 635 kerberos5_status(Authenticator *ap __unused, char *name, int level) 636 { 637 if (level < AUTH_USER) 638 return(level); 639 640 if (UserNameRequested && 641 krb5_kuserok(context, 642 ticket->client, 643 UserNameRequested)) 644 { 645 strcpy(name, UserNameRequested); 646 return(AUTH_VALID); 647 } else 648 return(AUTH_USER); 649 } 650 651 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 652 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 653 654 void 655 kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 656 { 657 int i; 658 659 buf[buflen-1] = '\0'; /* make sure its NULL terminated */ 660 buflen -= 1; 661 662 switch(data[3]) { 663 case KRB_REJECT: /* Rejected (reason might follow) */ 664 strlcpy((char *)buf, " REJECT ", buflen); 665 goto common; 666 667 case KRB_ACCEPT: /* Accepted (name might follow) */ 668 strlcpy((char *)buf, " ACCEPT ", buflen); 669 common: 670 BUMP(buf, buflen); 671 if (cnt <= 4) 672 break; 673 ADDC(buf, buflen, '"'); 674 for (i = 4; i < cnt; i++) 675 ADDC(buf, buflen, data[i]); 676 ADDC(buf, buflen, '"'); 677 ADDC(buf, buflen, '\0'); 678 break; 679 680 681 case KRB_AUTH: /* Authentication data follows */ 682 strlcpy((char *)buf, " AUTH", buflen); 683 goto common2; 684 685 case KRB_RESPONSE: 686 strlcpy((char *)buf, " RESPONSE", buflen); 687 goto common2; 688 689 case KRB_FORWARD: /* Forwarded credentials follow */ 690 strlcpy((char *)buf, " FORWARD", buflen); 691 goto common2; 692 693 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 694 strlcpy((char *)buf, " FORWARD_ACCEPT", buflen); 695 goto common2; 696 697 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 698 /* (reason might follow) */ 699 strlcpy((char *)buf, " FORWARD_REJECT", buflen); 700 goto common2; 701 702 default: 703 snprintf(buf, buflen, " %d (unknown)", data[3]); 704 common2: 705 BUMP(buf, buflen); 706 for (i = 4; i < cnt; i++) { 707 snprintf(buf, buflen, " %d", data[i]); 708 BUMP(buf, buflen); 709 } 710 break; 711 } 712 } 713 714 void 715 kerberos5_forward(Authenticator *ap) 716 { 717 krb5_error_code ret; 718 krb5_ccache ccache; 719 krb5_creds creds; 720 krb5_kdc_flags flags; 721 krb5_data out_data; 722 krb5_principal principal; 723 724 ret = krb5_cc_default (context, &ccache); 725 if (ret) { 726 if (auth_debug_mode) 727 printf ("KerberosV5: could not get default ccache: %s\r\n", 728 krb5_get_err_text (context, ret)); 729 return; 730 } 731 732 ret = krb5_cc_get_principal (context, ccache, &principal); 733 if (ret) { 734 if (auth_debug_mode) 735 printf ("KerberosV5: could not get principal: %s\r\n", 736 krb5_get_err_text (context, ret)); 737 return; 738 } 739 740 memset (&creds, 0, sizeof(creds)); 741 742 creds.client = principal; 743 744 ret = krb5_build_principal (context, 745 &creds.server, 746 strlen(principal->realm), 747 principal->realm, 748 "krbtgt", 749 principal->realm, 750 NULL); 751 752 if (ret) { 753 if (auth_debug_mode) 754 printf ("KerberosV5: could not get principal: %s\r\n", 755 krb5_get_err_text (context, ret)); 756 return; 757 } 758 759 creds.times.endtime = 0; 760 761 flags.i = 0; 762 flags.b.forwarded = 1; 763 if (forward_flags & OPTS_FORWARDABLE_CREDS) 764 flags.b.forwardable = 1; 765 766 ret = krb5_get_forwarded_creds (context, 767 auth_context, 768 ccache, 769 flags.i, 770 RemoteHostName, 771 &creds, 772 &out_data); 773 if (ret) { 774 if (auth_debug_mode) 775 printf ("Kerberos V5: error getting forwarded creds: %s\r\n", 776 krb5_get_err_text (context, ret)); 777 return; 778 } 779 780 if(!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { 781 if (auth_debug_mode) 782 printf("Not enough room for authentication data\r\n"); 783 } else { 784 if (auth_debug_mode) 785 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 786 } 787 } 788 789 #if defined(DCE) 790 /* if this was a K5 authentication try and join a PAG for the user. */ 791 void 792 kerberos5_dfspag(void) 793 { 794 if (dfsk5ok) { 795 dfspag = krb5_dfs_pag(context, dfsfwd, ticket->client, 796 UserNameRequested); 797 } 798 } 799 #endif 800 801 #endif /* KRB5 */ 802