1 #include <windows.h> 2 #include <stdio.h> 3 #include <sys/types.h> 4 #include <winsock2.h> 5 #include "leashdll.h" 6 #include <time.h> 7 8 #include <leashwin.h> 9 #include "leasherr.h" 10 #include "leash-int.h" 11 #include "leashids.h" 12 13 #include "reminder.h" 14 15 static char FAR *err_context; 16 17 char KRB_HelpFile[_MAX_PATH] = HELPFILE; 18 19 #define LEN 64 /* Maximum Hostname Length */ 20 21 #define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */ 22 23 static 24 char* 25 clean_string( 26 char* s 27 ) 28 { 29 char* p = s; 30 char* b = s; 31 32 if (!s) return s; 33 34 for (p = s; *p; p++) { 35 switch (*p) { 36 case '\007': 37 /* Add more cases here */ 38 break; 39 default: 40 *b = *p; 41 b++; 42 } 43 } 44 *b = *p; 45 return s; 46 } 47 48 static 49 int 50 leash_error_message( 51 const char *error, 52 int rcL, 53 int rc5, 54 int rcA, 55 char* result_string, 56 int displayMB 57 ) 58 { 59 char message[2048]; 60 char *p = message; 61 int size = sizeof(message) - 1; /* -1 to leave room for NULL terminator */ 62 int n; 63 64 if (!rc5 && !rcL) 65 return 0; 66 67 n = _snprintf(p, size, "%s\n\n", error); 68 p += n; 69 size -= n; 70 71 if (rc5 && !result_string) 72 { 73 n = _snprintf(p, size, 74 "Kerberos 5: %s (error %ld)\n", 75 perror_message(rc5), 76 rc5 77 ); 78 p += n; 79 size -= n; 80 } 81 if (rcL) 82 { 83 char buffer[1024]; 84 n = _snprintf(p, size, 85 "\n%s\n", 86 err_describe(buffer, rcL) 87 ); 88 p += n; 89 size -= n; 90 } 91 if (result_string) 92 { 93 n = _snprintf(p, size, 94 "%s\n", 95 result_string); 96 p += n; 97 size -= n; 98 } 99 #ifdef USE_MESSAGE_BOX 100 *p = 0; /* ensure NULL termination of message */ 101 if ( displayMB ) 102 MessageBox(NULL, message, "MIT Kerberos", 103 MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); 104 #endif /* USE_MESSAGE_BOX */ 105 if (rc5) return rc5; 106 if (rcL) return rcL; 107 return 0; 108 } 109 110 111 static 112 char * 113 make_postfix( 114 const char * base, 115 const char * postfix, 116 char ** rcopy 117 ) 118 { 119 int base_size; 120 int ret_size; 121 char * copy = 0; 122 char * ret = 0; 123 124 base_size = strlen(base) + 1; 125 ret_size = base_size + strlen(postfix) + 1; 126 copy = malloc(base_size); 127 ret = malloc(ret_size); 128 129 if (!copy || !ret) 130 goto cleanup; 131 132 strncpy(copy, base, base_size); 133 copy[base_size - 1] = 0; 134 135 strncpy(ret, base, base_size); 136 strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1)); 137 ret[ret_size - 1] = 0; 138 139 cleanup: 140 if (!copy || !ret) { 141 if (copy) 142 free(copy); 143 if (ret) 144 free(ret); 145 copy = ret = 0; 146 } 147 // INVARIANT: (ret ==> copy) && (copy ==> ret) 148 *rcopy = copy; 149 return ret; 150 } 151 152 static 153 long 154 make_temp_cache_v5( 155 const char * postfix, 156 krb5_context * pctx 157 ) 158 { 159 static krb5_context ctx = 0; 160 static char * old_cache = 0; 161 162 // INVARIANT: old_cache ==> ctx && ctx ==> old_cache 163 164 if (pctx) 165 *pctx = 0; 166 167 if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve || 168 !pkrb5_cc_default_name || !pkrb5_cc_set_default_name) 169 return 0; 170 171 if (old_cache) { 172 krb5_ccache cc = 0; 173 if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc)) 174 pkrb5_cc_destroy(ctx, cc); 175 pkrb5_cc_set_default_name(ctx, old_cache); 176 free(old_cache); 177 old_cache = 0; 178 } 179 if (ctx) { 180 pkrb5_free_context(ctx); 181 ctx = 0; 182 } 183 184 if (postfix) 185 { 186 char * tmp_cache = 0; 187 krb5_error_code rc = 0; 188 189 rc = pkrb5_init_context(&ctx); 190 if (rc) goto cleanup; 191 192 tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix, 193 &old_cache); 194 195 if (!tmp_cache) { 196 rc = ENOMEM; 197 goto cleanup; 198 } 199 200 rc = pkrb5_cc_set_default_name(ctx, tmp_cache); 201 202 cleanup: 203 if (rc && ctx) { 204 pkrb5_free_context(ctx); 205 ctx = 0; 206 } 207 if (tmp_cache) 208 free(tmp_cache); 209 if (pctx) 210 *pctx = ctx; 211 return rc; 212 } 213 return 0; 214 } 215 216 long 217 Leash_checkpwd( 218 char *principal, 219 char *password 220 ) 221 { 222 return Leash_int_checkpwd(principal, password, 0); 223 } 224 225 long 226 Leash_int_checkpwd( 227 char * principal, 228 char * password, 229 int displayErrors 230 ) 231 { 232 long rc = 0; 233 krb5_context ctx = 0; // statically allocated in make_temp_cache_v5 234 // XXX - we ignore errors in make_temp_cache_v? This is BAD!!! 235 make_temp_cache_v5("_checkpwd", &ctx); 236 rc = Leash_int_kinit_ex( ctx, 0, 237 principal, password, 0, 0, 0, 0, 238 Leash_get_default_noaddresses(), 239 Leash_get_default_publicip(), 240 displayErrors 241 ); 242 make_temp_cache_v5(0, &ctx); 243 return rc; 244 } 245 246 static 247 long 248 Leash_changepwd_v5( 249 char * principal, 250 char * password, 251 char * newpassword, 252 char** error_str 253 ) 254 { 255 krb5_error_code rc = 0; 256 int result_code; 257 krb5_data result_code_string, result_string; 258 krb5_context context = 0; 259 krb5_principal princ = 0; 260 krb5_get_init_creds_opt opts; 261 krb5_creds creds; 262 DWORD addressless = 0; 263 264 result_string.data = 0; 265 result_code_string.data = 0; 266 267 if ( !pkrb5_init_context ) 268 goto cleanup; 269 270 if (rc = pkrb5_init_context(&context)) 271 goto cleanup; 272 273 if (rc = pkrb5_parse_name(context, principal, &princ)) 274 goto cleanup; 275 276 pkrb5_get_init_creds_opt_init(&opts); 277 pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); 278 pkrb5_get_init_creds_opt_set_renew_life(&opts, 0); 279 pkrb5_get_init_creds_opt_set_forwardable(&opts, 0); 280 pkrb5_get_init_creds_opt_set_proxiable(&opts, 0); 281 282 addressless = Leash_get_default_noaddresses(); 283 if (addressless) 284 pkrb5_get_init_creds_opt_set_address_list(&opts,NULL); 285 286 287 if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password, 288 0, 0, 0, "kadmin/changepw", &opts)) 289 goto cleanup; 290 291 if (rc = pkrb5_change_password(context, &creds, newpassword, 292 &result_code, &result_code_string, 293 &result_string)) 294 goto cleanup; 295 296 if (result_code) { 297 int len = result_code_string.length + 298 (result_string.length ? (sizeof(": ") - 1) : 0) + 299 result_string.length; 300 if (len && error_str) { 301 *error_str = malloc(len + 1); 302 if (*error_str) 303 _snprintf(*error_str, len + 1, 304 "%.*s%s%.*s", 305 result_code_string.length, result_code_string.data, 306 result_string.length?": ":"", 307 result_string.length, result_string.data); 308 } 309 rc = result_code; 310 goto cleanup; 311 } 312 313 cleanup: 314 if (result_string.data) 315 pkrb5_free_data_contents(context, &result_string); 316 317 if (result_code_string.data) 318 pkrb5_free_data_contents(context, &result_code_string); 319 320 if (princ) 321 pkrb5_free_principal(context, princ); 322 323 if (context) 324 pkrb5_free_context(context); 325 326 return rc; 327 } 328 329 /* 330 * Leash_changepwd 331 * 332 * Try to change the password using krb5. 333 */ 334 long 335 Leash_changepwd( 336 char * principal, 337 char * password, 338 char * newpassword, 339 char** result_string 340 ) 341 { 342 return Leash_int_changepwd(principal, password, newpassword, result_string, 0); 343 } 344 345 long 346 Leash_int_changepwd( 347 char * principal, 348 char * password, 349 char * newpassword, 350 char** result_string, 351 int displayErrors 352 ) 353 { 354 char* v5_error_str = 0; 355 char* error_str = 0; 356 int rc5 = 0; 357 int rc = 0; 358 if (hKrb5) 359 rc = rc5 = Leash_changepwd_v5(principal, password, newpassword, 360 &v5_error_str); 361 if (!rc) 362 return 0; 363 if (v5_error_str) { 364 int len = 0; 365 char v5_prefix[] = "Kerberos 5: "; 366 char sep[] = "\n"; 367 368 clean_string(v5_error_str); 369 370 if (v5_error_str) 371 len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) + 372 sizeof(sep); 373 error_str = malloc(len + 1); 374 if (error_str) { 375 char* p = error_str; 376 int size = len + 1; 377 int n; 378 if (v5_error_str) { 379 n = _snprintf(p, size, "%s%s%s%s", 380 sep, v5_prefix, v5_error_str, sep); 381 p += n; 382 size -= n; 383 } 384 if (result_string) 385 *result_string = error_str; 386 } 387 } 388 return leash_error_message("Error while changing password.", 389 0, rc5, 0, error_str, 390 displayErrors 391 ); 392 } 393 394 int (*Lcom_err)(LPSTR,long,LPSTR,...); 395 LPSTR (*Lerror_message)(long); 396 LPSTR (*Lerror_table_name)(long); 397 398 399 long 400 Leash_kinit( 401 char * principal, 402 char * password, 403 int lifetime 404 ) 405 { 406 return Leash_int_kinit_ex( 0, 0, 407 principal, 408 password, 409 lifetime, 410 Leash_get_default_forwardable(), 411 Leash_get_default_proxiable(), 412 Leash_get_default_renew_till(), 413 Leash_get_default_noaddresses(), 414 Leash_get_default_publicip(), 415 0 416 ); 417 } 418 419 long 420 Leash_kinit_ex( 421 char * principal, 422 char * password, 423 int lifetime, 424 int forwardable, 425 int proxiable, 426 int renew_life, 427 int addressless, 428 unsigned long publicip 429 ) 430 { 431 return Leash_int_kinit_ex( 0, /* krb5 context */ 432 0, /* parent window */ 433 principal, 434 password, 435 lifetime, 436 forwardable, 437 proxiable, 438 renew_life, 439 addressless, 440 publicip, 441 0 442 ); 443 } 444 445 long 446 Leash_int_kinit_ex( 447 krb5_context ctx, 448 HWND hParent, 449 char * principal, 450 char * password, 451 int lifetime, 452 int forwardable, 453 int proxiable, 454 int renew_life, 455 int addressless, 456 unsigned long publicip, 457 int displayErrors 458 ) 459 { 460 char aname[ANAME_SZ]; 461 char inst[INST_SZ]; 462 char realm[REALM_SZ]; 463 char first_part[256]; 464 char second_part[256]; 465 char temp[1024]; 466 char* custom_msg; 467 int count; 468 int i; 469 int rc5 = 0; 470 int rcA = 0; 471 int rcB = 0; 472 int rcL = 0; 473 474 if (lifetime < 5) 475 lifetime = 1; 476 else 477 lifetime /= 5; 478 479 if (renew_life > 0 && renew_life < 5) 480 renew_life = 1; 481 else 482 renew_life /= 5; 483 484 /* This should be changed if the maximum ticket lifetime */ 485 /* changes */ 486 487 if (lifetime > 255) 488 lifetime = 255; 489 490 err_context = "parsing principal"; 491 492 memset(temp, '\0', sizeof(temp)); 493 memset(inst, '\0', sizeof(inst)); 494 memset(realm, '\0', sizeof(realm)); 495 memset(first_part, '\0', sizeof(first_part)); 496 memset(second_part, '\0', sizeof(second_part)); 497 498 sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part); 499 strcpy(temp, first_part); 500 strcpy(realm, second_part); 501 memset(first_part, '\0', sizeof(first_part)); 502 memset(second_part, '\0', sizeof(second_part)); 503 if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2) 504 { 505 strcpy(aname, first_part); 506 strcpy(inst, second_part); 507 } 508 else 509 { 510 count = 0; 511 i = 0; 512 for (i = 0; temp[i]; i++) 513 { 514 if (temp[i] == '.') 515 ++count; 516 } 517 if (count > 1) 518 { 519 strcpy(aname, temp); 520 } 521 else 522 { 523 { 524 strcpy(aname, temp); 525 } 526 } 527 } 528 529 memset(temp, '\0', sizeof(temp)); 530 strcpy(temp, aname); 531 if (strlen(inst) != 0) 532 { 533 strcat(temp, "/"); 534 strcat(temp, inst); 535 } 536 if (strlen(realm) != 0) 537 { 538 strcat(temp, "@"); 539 strcat(temp, realm); 540 } 541 542 rc5 = Leash_krb5_kinit(ctx, hParent, 543 temp, password, lifetime, 544 forwardable, 545 proxiable, 546 renew_life, 547 addressless, 548 publicip 549 ); 550 custom_msg = (rc5 == KRB5KRB_AP_ERR_BAD_INTEGRITY) ? "Password incorrect" : NULL; 551 return leash_error_message("Ticket initialization failed.", 552 rcL, rc5, rcA, custom_msg, 553 displayErrors); 554 } 555 556 long FAR 557 Leash_renew(void) 558 { 559 if ( hKrb5 && !LeashKRB5_renew() ) { 560 int lifetime; 561 lifetime = Leash_get_default_lifetime() / 5; 562 return 1; 563 } 564 return 0; 565 } 566 567 BOOL 568 GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData) 569 { 570 NTSTATUS Status = 0; 571 HANDLE TokenHandle; 572 TOKEN_STATISTICS Stats; 573 DWORD ReqLen; 574 BOOL Success; 575 PSECURITY_LOGON_SESSION_DATA pSessionData; 576 577 if (!ppSessionData) 578 return FALSE; 579 *ppSessionData = NULL; 580 581 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); 582 if ( !Success ) 583 return FALSE; 584 585 Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen ); 586 CloseHandle( TokenHandle ); 587 if ( !Success ) 588 return FALSE; 589 590 Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData ); 591 if ( FAILED(Status) || !pSessionData ) 592 return FALSE; 593 594 *ppSessionData = pSessionData; 595 return TRUE; 596 } 597 598 // IsKerberosLogon() does not validate whether or not there are valid tickets in the 599 // cache. It validates whether or not it is reasonable to assume that if we 600 // attempted to retrieve valid tickets we could do so. Microsoft does not 601 // automatically renew expired tickets. Therefore, the cache could contain 602 // expired or invalid tickets. Microsoft also caches the user's password 603 // and will use it to retrieve new TGTs if the cache is empty and tickets 604 // are requested. 605 606 BOOL 607 IsKerberosLogon(VOID) 608 { 609 PSECURITY_LOGON_SESSION_DATA pSessionData = NULL; 610 BOOL Success = FALSE; 611 612 if ( GetSecurityLogonSessionData(&pSessionData) ) { 613 if ( pSessionData->AuthenticationPackage.Buffer ) { 614 WCHAR buffer[256]; 615 WCHAR *usBuffer; 616 int usLength; 617 618 Success = FALSE; 619 usBuffer = (pSessionData->AuthenticationPackage).Buffer; 620 usLength = (pSessionData->AuthenticationPackage).Length; 621 if (usLength < 256) 622 { 623 lstrcpynW (buffer, usBuffer, usLength); 624 lstrcatW (buffer,L""); 625 if ( !lstrcmpW(L"Kerberos",buffer) ) 626 Success = TRUE; 627 } 628 } 629 pLsaFreeReturnBuffer(pSessionData); 630 } 631 return Success; 632 } 633 634 static BOOL 635 IsWindowsVista (void) 636 { 637 static BOOL fChecked = FALSE; 638 static BOOL fIsVista = FALSE; 639 640 if (!fChecked) 641 { 642 OSVERSIONINFO Version; 643 644 memset (&Version, 0x00, sizeof(Version)); 645 Version.dwOSVersionInfoSize = sizeof(Version); 646 647 if (GetVersionEx (&Version)) 648 { 649 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6) 650 fIsVista = TRUE; 651 } 652 fChecked = TRUE; 653 } 654 655 return fIsVista; 656 } 657 658 static BOOL 659 IsProcessUacLimited (void) 660 { 661 static BOOL fChecked = FALSE; 662 static BOOL fIsUAC = FALSE; 663 664 if (!fChecked) 665 { 666 NTSTATUS Status = 0; 667 HANDLE TokenHandle; 668 DWORD ElevationLevel; 669 DWORD ReqLen; 670 BOOL Success; 671 672 if (IsWindowsVista()) { 673 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); 674 if ( Success ) { 675 Success = GetTokenInformation( TokenHandle, 676 TokenOrigin+1 /* ElevationLevel */, 677 &ElevationLevel, sizeof(DWORD), &ReqLen ); 678 CloseHandle( TokenHandle ); 679 if ( Success && ElevationLevel == 3 /* Limited */ ) 680 fIsUAC = TRUE; 681 } 682 } 683 fChecked = TRUE; 684 } 685 return fIsUAC; 686 687 } 688 689 long FAR 690 Leash_importable(void) 691 { 692 /* Import functionality has been removed. */ 693 return FALSE; 694 } 695 696 long FAR 697 Leash_import(void) 698 { 699 /* Import functionality has been removed. */ 700 return 0; 701 } 702 703 long 704 Leash_kdestroy(void) 705 { 706 Leash_krb5_kdestroy(); 707 708 return 0; 709 } 710 711 long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo) 712 { 713 return(255); 714 } 715 716 717 // This function can be used to set the help file that will be 718 // referenced the DLL's PasswordProcDLL function and err_describe 719 // function. Returns true if the help file has been set to the 720 // argument or the environment variable KERB_HELP. Returns FALSE if 721 // the default helpfile as defined in by HELPFILE in lsh_pwd.h is 722 // used. 723 BOOL Leash_set_help_file( char *szHelpFile ) 724 { 725 char tmpHelpFile[256]; 726 BOOL ret = 0; 727 728 if( szHelpFile == NULL ){ 729 GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile)); 730 } else { 731 strcpy( KRB_HelpFile, szHelpFile ); 732 ret++; 733 } 734 735 if( !ret && tmpHelpFile[0] ){ 736 strcpy( KRB_HelpFile, tmpHelpFile ); 737 ret++; 738 } 739 740 if( !ret){ 741 strcpy( KRB_HelpFile, HELPFILE ); 742 } 743 744 return(ret); 745 } 746 747 748 749 LPSTR Leash_get_help_file(void) 750 { 751 return( KRB_HelpFile); 752 } 753 754 int 755 Leash_debug( 756 int class, 757 int priority, 758 char* fmt, ... 759 ) 760 { 761 762 return 0; 763 } 764 765 766 static int 767 get_profile_file(LPSTR confname, UINT szConfname) 768 { 769 char **configFile = NULL; 770 if (hKrb5) { 771 if (pkrb5_get_default_config_files(&configFile) || !configFile[0]) 772 { 773 GetWindowsDirectory(confname,szConfname); 774 confname[szConfname-1] = '\0'; 775 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname)); 776 confname[szConfname-1] = '\0'; 777 return FALSE; 778 } 779 780 *confname = 0; 781 782 if (configFile) 783 { 784 strncpy(confname, *configFile, szConfname); 785 confname[szConfname-1] = '\0'; 786 pkrb5_free_config_files(configFile); 787 } 788 } 789 790 if (!*confname) 791 { 792 GetWindowsDirectory(confname,szConfname); 793 confname[szConfname-1] = '\0'; 794 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname)); 795 confname[szConfname-1] = '\0'; 796 } 797 798 return FALSE; 799 } 800 801 static const char *const conf_yes[] = { 802 "y", "yes", "true", "t", "1", "on", 803 0, 804 }; 805 806 static const char *const conf_no[] = { 807 "n", "no", "false", "nil", "0", "off", 808 0, 809 }; 810 811 int 812 config_boolean_to_int(const char *s) 813 { 814 const char *const *p; 815 816 for(p=conf_yes; *p; p++) { 817 if (!strcasecmp(*p,s)) 818 return 1; 819 } 820 821 for(p=conf_no; *p; p++) { 822 if (!strcasecmp(*p,s)) 823 return 0; 824 } 825 826 /* Default to "no" */ 827 return 0; 828 } 829 830 /* 831 * Leash_get_default_lifetime: 832 * 833 * This function is used to get the default ticket lifetime for this 834 * process in minutes. A return value of 0 indicates no setting or 835 * "default" setting obtained. 836 * 837 * Here is where we look in order: 838 * 839 * - LIFETIME environment variable 840 * - HKCU\Software\MIT\Leash,lifetime 841 * - HKLM\Software\MIT\Leash,lifetime 842 * - string resource in the leash DLL 843 */ 844 845 static BOOL 846 get_DWORD_from_registry( 847 HKEY hBaseKey, 848 char * key, 849 char * value, 850 DWORD * result 851 ) 852 { 853 HKEY hKey; 854 DWORD dwCount; 855 LONG rc; 856 857 rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey); 858 if (rc) 859 return FALSE; 860 861 dwCount = sizeof(DWORD); 862 rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount); 863 RegCloseKey(hKey); 864 865 return rc?FALSE:TRUE; 866 } 867 868 static 869 BOOL 870 get_default_lifetime_from_registry( 871 HKEY hBaseKey, 872 DWORD * result 873 ) 874 { 875 return get_DWORD_from_registry(hBaseKey, 876 LEASH_REGISTRY_KEY_NAME, 877 LEASH_REGISTRY_VALUE_LIFETIME, 878 result); 879 } 880 881 DWORD 882 Leash_reset_default_lifetime( 883 ) 884 { 885 HKEY hKey; 886 LONG rc; 887 888 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 889 if (rc) 890 return rc; 891 892 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME); 893 RegCloseKey(hKey); 894 895 return rc; 896 } 897 898 DWORD 899 Leash_set_default_lifetime( 900 DWORD minutes 901 ) 902 { 903 HKEY hKey; 904 LONG rc; 905 906 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 907 0, 0, KEY_WRITE, 0, &hKey, 0); 908 if (rc) 909 return rc; 910 911 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD, 912 (LPBYTE) &minutes, sizeof(DWORD)); 913 RegCloseKey(hKey); 914 915 return rc; 916 } 917 918 DWORD 919 Leash_get_default_lifetime( 920 ) 921 { 922 HMODULE hmLeash; 923 char env[32]; 924 DWORD result; 925 926 927 if (GetEnvironmentVariable("LIFETIME",env,sizeof(env))) 928 { 929 return atoi(env); 930 } 931 932 933 if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) || 934 get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result)) 935 { 936 return result; 937 } 938 939 if ( hKrb5 ) { 940 CHAR confname[MAX_PATH]; 941 942 if (!get_profile_file(confname, sizeof(confname))) 943 { 944 profile_t profile; 945 const char *filenames[2]; 946 long retval; 947 948 filenames[0] = confname; 949 filenames[1] = NULL; 950 if (!pprofile_init(filenames, &profile)) { 951 char * value = NULL; 952 953 retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value); 954 if (retval == 0 && value) { 955 krb5_deltat d; 956 957 retval = pkrb5_string_to_deltat(value, &d); 958 959 if (retval == KRB5_DELTAT_BADFORMAT) { 960 /* Historically some sites use relations of 961 the form 'ticket_lifetime = 24000' where 962 the unit is left out but is assumed to be 963 seconds. Then there are other sites which 964 use the form 'ticket_lifetime = 600' where 965 the unit is assumed to be minutes. While 966 these are technically wrong (a unit needs 967 to be specified), we try to accommodate for 968 this using the safe assumption that the 969 unit is seconds and tack an 's' to the end 970 and see if that works. */ 971 972 /* Of course, Leash is one of the platforms 973 that historically assumed no units and minutes 974 so this change is going to break some people 975 but its better to be consistent. */ 976 size_t cch; 977 char buf[256]; 978 979 do { 980 cch = strlen(value) + 2; /* NUL and new 's' */ 981 if (cch > sizeof(buf)) 982 break; 983 984 strcpy(buf, value); 985 strcat(buf, "s"); 986 987 retval = pkrb5_string_to_deltat(buf, &d); 988 989 if (retval == 0) { 990 result = d / 60; 991 } 992 } while(0); 993 } else if (retval == 0) { 994 result = d / 60; 995 } 996 997 pprofile_release_string(value); 998 } 999 pprofile_release(profile); 1000 /* value has been released but we can still use a check for 1001 * non-NULL to see if we were able to read a value. 1002 */ 1003 if (retval == 0 && value) 1004 return result; 1005 } 1006 } 1007 } 1008 1009 hmLeash = GetModuleHandle(LEASH_DLL); 1010 if (hmLeash) 1011 { 1012 char lifetime[80]; 1013 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE, 1014 lifetime, sizeof(lifetime))) 1015 { 1016 lifetime[sizeof(lifetime) - 1] = 0; 1017 return atoi(lifetime); 1018 } 1019 } 1020 return 0; 1021 } 1022 1023 static 1024 BOOL 1025 get_default_renew_till_from_registry( 1026 HKEY hBaseKey, 1027 DWORD * result 1028 ) 1029 { 1030 return get_DWORD_from_registry(hBaseKey, 1031 LEASH_REGISTRY_KEY_NAME, 1032 LEASH_REGISTRY_VALUE_RENEW_TILL, 1033 result); 1034 } 1035 1036 DWORD 1037 Leash_reset_default_renew_till( 1038 ) 1039 { 1040 HKEY hKey; 1041 LONG rc; 1042 1043 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1044 if (rc) 1045 return rc; 1046 1047 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL); 1048 RegCloseKey(hKey); 1049 1050 return rc; 1051 } 1052 1053 DWORD 1054 Leash_set_default_renew_till( 1055 DWORD minutes 1056 ) 1057 { 1058 HKEY hKey; 1059 LONG rc; 1060 1061 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1062 0, 0, KEY_WRITE, 0, &hKey, 0); 1063 if (rc) 1064 return rc; 1065 1066 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD, 1067 (LPBYTE) &minutes, sizeof(DWORD)); 1068 RegCloseKey(hKey); 1069 1070 return rc; 1071 } 1072 1073 DWORD 1074 Leash_get_default_renew_till( 1075 ) 1076 { 1077 HMODULE hmLeash; 1078 char env[32]; 1079 DWORD result; 1080 1081 if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env))) 1082 { 1083 return atoi(env); 1084 } 1085 1086 if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) || 1087 get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result)) 1088 { 1089 return result; 1090 } 1091 1092 if ( hKrb5 ) { 1093 CHAR confname[MAX_PATH]; 1094 if (!get_profile_file(confname, sizeof(confname))) 1095 { 1096 profile_t profile; 1097 const char *filenames[2]; 1098 int value=0; 1099 long retval; 1100 filenames[0] = confname; 1101 filenames[1] = NULL; 1102 1103 if (!pprofile_init(filenames, &profile)) { 1104 char * value = NULL; 1105 1106 retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value); 1107 if (retval == 0 && value) { 1108 krb5_deltat d; 1109 1110 retval = pkrb5_string_to_deltat(value, &d); 1111 if (retval == KRB5_DELTAT_BADFORMAT) { 1112 /* Historically some sites use relations of 1113 the form 'ticket_lifetime = 24000' where 1114 the unit is left out but is assumed to be 1115 seconds. Then there are other sites which 1116 use the form 'ticket_lifetime = 600' where 1117 the unit is assumed to be minutes. While 1118 these are technically wrong (a unit needs 1119 to be specified), we try to accommodate for 1120 this using the safe assumption that the 1121 unit is seconds and tack an 's' to the end 1122 and see if that works. */ 1123 1124 /* Of course, Leash is one of the platforms 1125 that historically assumed no units and minutes 1126 so this change is going to break some people 1127 but its better to be consistent. */ 1128 size_t cch; 1129 char buf[256]; 1130 do { 1131 cch = strlen(value) + 2; /* NUL and new 's' */ 1132 if (cch > sizeof(buf)) 1133 break; 1134 1135 strcpy(buf, value); 1136 strcat(buf, "s"); 1137 1138 retval = pkrb5_string_to_deltat(buf, &d); 1139 if (retval == 0) { 1140 result = d / 60; 1141 } 1142 } while(0); 1143 } else if (retval == 0) { 1144 result = d / 60; 1145 } 1146 pprofile_release_string(value); 1147 } 1148 pprofile_release(profile); 1149 /* value has been released but we can still use a check for 1150 * non-NULL to see if we were able to read a value. 1151 */ 1152 if (retval == 0 && value) 1153 return result; 1154 1155 pprofile_release(profile); 1156 } 1157 } 1158 } 1159 1160 hmLeash = GetModuleHandle(LEASH_DLL); 1161 if (hmLeash) 1162 { 1163 char renew_till[80]; 1164 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL, 1165 renew_till, sizeof(renew_till))) 1166 { 1167 renew_till[sizeof(renew_till) - 1] = 0; 1168 return atoi(renew_till); 1169 } 1170 } 1171 return 0; 1172 } 1173 1174 static 1175 BOOL 1176 get_default_forwardable_from_registry( 1177 HKEY hBaseKey, 1178 DWORD * result 1179 ) 1180 { 1181 return get_DWORD_from_registry(hBaseKey, 1182 LEASH_REGISTRY_KEY_NAME, 1183 LEASH_REGISTRY_VALUE_FORWARDABLE, 1184 result); 1185 } 1186 1187 DWORD 1188 Leash_reset_default_forwardable( 1189 ) 1190 { 1191 HKEY hKey; 1192 LONG rc; 1193 1194 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1195 if (rc) 1196 return rc; 1197 1198 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE); 1199 RegCloseKey(hKey); 1200 1201 return rc; 1202 } 1203 1204 DWORD 1205 Leash_set_default_forwardable( 1206 DWORD minutes 1207 ) 1208 { 1209 HKEY hKey; 1210 LONG rc; 1211 1212 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1213 0, 0, KEY_WRITE, 0, &hKey, 0); 1214 if (rc) 1215 return rc; 1216 1217 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD, 1218 (LPBYTE) &minutes, sizeof(DWORD)); 1219 RegCloseKey(hKey); 1220 1221 return rc; 1222 } 1223 1224 DWORD 1225 Leash_get_default_forwardable( 1226 ) 1227 { 1228 HMODULE hmLeash; 1229 1230 char env[32]; 1231 DWORD result; 1232 1233 if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env))) 1234 { 1235 return atoi(env); 1236 } 1237 1238 if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) || 1239 get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result)) 1240 { 1241 return result; 1242 } 1243 1244 if ( hKrb5 ) { 1245 CHAR confname[MAX_PATH]; 1246 if (!get_profile_file(confname, sizeof(confname))) 1247 { 1248 profile_t profile; 1249 const char *filenames[2]; 1250 char *value=0; 1251 long retval; 1252 filenames[0] = confname; 1253 filenames[1] = NULL; 1254 if (!pprofile_init(filenames, &profile)) { 1255 retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value); 1256 if ( value ) { 1257 result = config_boolean_to_int(value); 1258 pprofile_release_string(value); 1259 pprofile_release(profile); 1260 return result; 1261 } 1262 pprofile_release(profile); 1263 } 1264 } 1265 } 1266 1267 hmLeash = GetModuleHandle(LEASH_DLL); 1268 if (hmLeash) 1269 { 1270 char forwardable[80]; 1271 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD, 1272 forwardable, sizeof(forwardable))) 1273 { 1274 forwardable[sizeof(forwardable) - 1] = 0; 1275 return atoi(forwardable); 1276 } 1277 } 1278 return 0; 1279 } 1280 1281 static 1282 BOOL 1283 get_default_renewable_from_registry( 1284 HKEY hBaseKey, 1285 DWORD * result 1286 ) 1287 { 1288 return get_DWORD_from_registry(hBaseKey, 1289 LEASH_REGISTRY_KEY_NAME, 1290 LEASH_REGISTRY_VALUE_RENEWABLE, 1291 result); 1292 } 1293 1294 DWORD 1295 Leash_reset_default_renewable( 1296 ) 1297 { 1298 HKEY hKey; 1299 LONG rc; 1300 1301 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1302 if (rc) 1303 return rc; 1304 1305 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE); 1306 RegCloseKey(hKey); 1307 1308 return rc; 1309 } 1310 1311 DWORD 1312 Leash_set_default_renewable( 1313 DWORD minutes 1314 ) 1315 { 1316 HKEY hKey; 1317 LONG rc; 1318 1319 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1320 0, 0, KEY_WRITE, 0, &hKey, 0); 1321 if (rc) 1322 return rc; 1323 1324 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD, 1325 (LPBYTE) &minutes, sizeof(DWORD)); 1326 RegCloseKey(hKey); 1327 1328 return rc; 1329 } 1330 1331 DWORD 1332 Leash_get_default_renewable( 1333 ) 1334 { 1335 HMODULE hmLeash; 1336 char env[32]; 1337 DWORD result; 1338 1339 if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env))) 1340 { 1341 return atoi(env); 1342 } 1343 1344 if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) || 1345 get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result)) 1346 { 1347 return result; 1348 } 1349 1350 if ( hKrb5 ) { 1351 CHAR confname[MAX_PATH]; 1352 if (!get_profile_file(confname, sizeof(confname))) 1353 { 1354 profile_t profile; 1355 const char *filenames[2]; 1356 char *value=0; 1357 long retval; 1358 filenames[0] = confname; 1359 filenames[1] = NULL; 1360 if (!pprofile_init(filenames, &profile)) { 1361 retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value); 1362 if ( value ) { 1363 result = config_boolean_to_int(value); 1364 pprofile_release_string(value); 1365 pprofile_release(profile); 1366 return result; 1367 } 1368 pprofile_release(profile); 1369 } 1370 } 1371 } 1372 1373 hmLeash = GetModuleHandle(LEASH_DLL); 1374 if (hmLeash) 1375 { 1376 char renewable[80]; 1377 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW, 1378 renewable, sizeof(renewable))) 1379 { 1380 renewable[sizeof(renewable) - 1] = 0; 1381 return atoi(renewable); 1382 } 1383 } 1384 return 0; 1385 } 1386 1387 static 1388 BOOL 1389 get_default_noaddresses_from_registry( 1390 HKEY hBaseKey, 1391 DWORD * result 1392 ) 1393 { 1394 return get_DWORD_from_registry(hBaseKey, 1395 LEASH_REGISTRY_KEY_NAME, 1396 LEASH_REGISTRY_VALUE_NOADDRESSES, 1397 result); 1398 } 1399 1400 DWORD 1401 Leash_reset_default_noaddresses( 1402 ) 1403 { 1404 HKEY hKey; 1405 LONG rc; 1406 1407 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1408 if (rc) 1409 return rc; 1410 1411 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES); 1412 RegCloseKey(hKey); 1413 1414 return rc; 1415 } 1416 1417 DWORD 1418 Leash_set_default_noaddresses( 1419 DWORD minutes 1420 ) 1421 { 1422 HKEY hKey; 1423 LONG rc; 1424 1425 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1426 0, 0, KEY_WRITE, 0, &hKey, 0); 1427 if (rc) 1428 return rc; 1429 1430 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD, 1431 (LPBYTE) &minutes, sizeof(DWORD)); 1432 RegCloseKey(hKey); 1433 1434 return rc; 1435 } 1436 1437 DWORD 1438 Leash_get_default_noaddresses( 1439 ) 1440 { 1441 HMODULE hmLeash; 1442 char env[32]; 1443 DWORD result; 1444 1445 if ( hKrb5 ) { 1446 // if the profile file cannot be opened then the value will be true 1447 // if the noaddresses name cannot be found then the value will be true 1448 // if true in the library, we can't alter it by other means 1449 CHAR confname[MAX_PATH]; 1450 result = 1; 1451 if (!get_profile_file(confname, sizeof(confname))) 1452 { 1453 profile_t profile; 1454 const char *filenames[2]; 1455 char *value=0; 1456 long retval; 1457 filenames[0] = confname; 1458 filenames[1] = NULL; 1459 if (!pprofile_init(filenames, &profile)) { 1460 retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value); 1461 if ( value ) { 1462 result = config_boolean_to_int(value); 1463 pprofile_release_string(value); 1464 } 1465 pprofile_release(profile); 1466 } 1467 } 1468 1469 if ( result ) 1470 return 1; 1471 } 1472 1473 // The library default is false, check other locations 1474 1475 if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env))) 1476 { 1477 return atoi(env); 1478 } 1479 1480 if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) || 1481 get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result)) 1482 { 1483 return result; 1484 } 1485 1486 hmLeash = GetModuleHandle(LEASH_DLL); 1487 if (hmLeash) 1488 { 1489 char noaddresses[80]; 1490 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS, 1491 noaddresses, sizeof(noaddresses))) 1492 { 1493 noaddresses[sizeof(noaddresses) - 1] = 0; 1494 } 1495 } 1496 return 1; 1497 } 1498 1499 static 1500 BOOL 1501 get_default_proxiable_from_registry( 1502 HKEY hBaseKey, 1503 DWORD * result 1504 ) 1505 { 1506 return get_DWORD_from_registry(hBaseKey, 1507 LEASH_REGISTRY_KEY_NAME, 1508 LEASH_REGISTRY_VALUE_PROXIABLE, 1509 result); 1510 } 1511 1512 DWORD 1513 Leash_reset_default_proxiable( 1514 ) 1515 { 1516 HKEY hKey; 1517 LONG rc; 1518 1519 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1520 if (rc) 1521 return rc; 1522 1523 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE); 1524 RegCloseKey(hKey); 1525 1526 return rc; 1527 } 1528 1529 DWORD 1530 Leash_set_default_proxiable( 1531 DWORD minutes 1532 ) 1533 { 1534 HKEY hKey; 1535 LONG rc; 1536 1537 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1538 0, 0, KEY_WRITE, 0, &hKey, 0); 1539 if (rc) 1540 return rc; 1541 1542 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD, 1543 (LPBYTE) &minutes, sizeof(DWORD)); 1544 RegCloseKey(hKey); 1545 1546 return rc; 1547 } 1548 1549 DWORD 1550 Leash_get_default_proxiable( 1551 ) 1552 { 1553 HMODULE hmLeash; 1554 char env[32]; 1555 DWORD result; 1556 1557 if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env))) 1558 { 1559 return atoi(env); 1560 } 1561 1562 if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) || 1563 get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result)) 1564 { 1565 return result; 1566 } 1567 1568 if ( hKrb5 ) { 1569 CHAR confname[MAX_PATH]; 1570 if (!get_profile_file(confname, sizeof(confname))) 1571 { 1572 profile_t profile; 1573 const char *filenames[2]; 1574 char *value=0; 1575 long retval; 1576 filenames[0] = confname; 1577 filenames[1] = NULL; 1578 if (!pprofile_init(filenames, &profile)) { 1579 retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value); 1580 if ( value ) { 1581 result = config_boolean_to_int(value); 1582 pprofile_release_string(value); 1583 pprofile_release(profile); 1584 return result; 1585 } 1586 pprofile_release(profile); 1587 } 1588 } 1589 } 1590 1591 hmLeash = GetModuleHandle(LEASH_DLL); 1592 if (hmLeash) 1593 { 1594 char proxiable[80]; 1595 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE, 1596 proxiable, sizeof(proxiable))) 1597 { 1598 proxiable[sizeof(proxiable) - 1] = 0; 1599 return atoi(proxiable); 1600 } 1601 } 1602 return 0; 1603 } 1604 1605 static 1606 BOOL 1607 get_default_publicip_from_registry( 1608 HKEY hBaseKey, 1609 DWORD * result 1610 ) 1611 { 1612 return get_DWORD_from_registry(hBaseKey, 1613 LEASH_REGISTRY_KEY_NAME, 1614 LEASH_REGISTRY_VALUE_PUBLICIP, 1615 result); 1616 } 1617 1618 DWORD 1619 Leash_reset_default_publicip( 1620 ) 1621 { 1622 HKEY hKey; 1623 LONG rc; 1624 1625 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1626 if (rc) 1627 return rc; 1628 1629 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP); 1630 RegCloseKey(hKey); 1631 1632 return rc; 1633 } 1634 1635 DWORD 1636 Leash_set_default_publicip( 1637 DWORD minutes 1638 ) 1639 { 1640 HKEY hKey; 1641 LONG rc; 1642 1643 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1644 0, 0, KEY_WRITE, 0, &hKey, 0); 1645 if (rc) 1646 return rc; 1647 1648 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD, 1649 (LPBYTE) &minutes, sizeof(DWORD)); 1650 RegCloseKey(hKey); 1651 1652 return rc; 1653 } 1654 1655 DWORD 1656 Leash_get_default_publicip( 1657 ) 1658 { 1659 HMODULE hmLeash; 1660 char env[32]; 1661 DWORD result; 1662 1663 if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env))) 1664 { 1665 return atoi(env); 1666 } 1667 1668 if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) || 1669 get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result)) 1670 { 1671 return result; 1672 } 1673 1674 hmLeash = GetModuleHandle(LEASH_DLL); 1675 if (hmLeash) 1676 { 1677 char publicip[80]; 1678 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP, 1679 publicip, sizeof(publicip))) 1680 { 1681 publicip[sizeof(publicip) - 1] = 0; 1682 return atoi(publicip); 1683 } 1684 } 1685 return 0; 1686 } 1687 1688 static 1689 BOOL 1690 get_hide_kinit_options_from_registry( 1691 HKEY hBaseKey, 1692 DWORD * result 1693 ) 1694 { 1695 return get_DWORD_from_registry(hBaseKey, 1696 LEASH_REGISTRY_KEY_NAME, 1697 LEASH_REGISTRY_VALUE_KINIT_OPT, 1698 result); 1699 } 1700 1701 DWORD 1702 Leash_reset_hide_kinit_options( 1703 ) 1704 { 1705 HKEY hKey; 1706 LONG rc; 1707 1708 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1709 if (rc) 1710 return rc; 1711 1712 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT); 1713 RegCloseKey(hKey); 1714 1715 return rc; 1716 } 1717 1718 DWORD 1719 Leash_set_hide_kinit_options( 1720 DWORD minutes 1721 ) 1722 { 1723 HKEY hKey; 1724 LONG rc; 1725 1726 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1727 0, 0, KEY_WRITE, 0, &hKey, 0); 1728 if (rc) 1729 return rc; 1730 1731 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD, 1732 (LPBYTE) &minutes, sizeof(DWORD)); 1733 RegCloseKey(hKey); 1734 1735 return rc; 1736 } 1737 1738 DWORD 1739 Leash_get_hide_kinit_options( 1740 ) 1741 { 1742 HMODULE hmLeash; 1743 DWORD result; 1744 1745 if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) || 1746 get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result)) 1747 { 1748 return result; 1749 } 1750 1751 hmLeash = GetModuleHandle(LEASH_DLL); 1752 if (hmLeash) 1753 { 1754 char hide_kinit_options[80]; 1755 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT, 1756 hide_kinit_options, sizeof(hide_kinit_options))) 1757 { 1758 hide_kinit_options[sizeof(hide_kinit_options) - 1] = 0; 1759 return atoi(hide_kinit_options); 1760 } 1761 } 1762 return 0; /* hide unless otherwise indicated */ 1763 } 1764 1765 1766 1767 static 1768 BOOL 1769 get_default_life_min_from_registry( 1770 HKEY hBaseKey, 1771 DWORD * result 1772 ) 1773 { 1774 return get_DWORD_from_registry(hBaseKey, 1775 LEASH_REGISTRY_KEY_NAME, 1776 LEASH_REGISTRY_VALUE_LIFE_MIN, 1777 result); 1778 } 1779 1780 DWORD 1781 Leash_reset_default_life_min( 1782 ) 1783 { 1784 HKEY hKey; 1785 LONG rc; 1786 1787 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1788 if (rc) 1789 return rc; 1790 1791 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN); 1792 RegCloseKey(hKey); 1793 1794 return rc; 1795 } 1796 1797 DWORD 1798 Leash_set_default_life_min( 1799 DWORD minutes 1800 ) 1801 { 1802 HKEY hKey; 1803 LONG rc; 1804 1805 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1806 0, 0, KEY_WRITE, 0, &hKey, 0); 1807 if (rc) 1808 return rc; 1809 1810 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD, 1811 (LPBYTE) &minutes, sizeof(DWORD)); 1812 RegCloseKey(hKey); 1813 1814 return rc; 1815 } 1816 1817 DWORD 1818 Leash_get_default_life_min( 1819 ) 1820 { 1821 HMODULE hmLeash; 1822 DWORD result; 1823 1824 if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) || 1825 get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result)) 1826 { 1827 return result; 1828 } 1829 1830 hmLeash = GetModuleHandle(LEASH_DLL); 1831 if (hmLeash) 1832 { 1833 char life_min[80]; 1834 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN, 1835 life_min, sizeof(life_min))) 1836 { 1837 life_min[sizeof(life_min) - 1] = 0; 1838 return atoi(life_min); 1839 } 1840 } 1841 return 5; /* 5 minutes */ 1842 } 1843 1844 static 1845 BOOL 1846 get_default_life_max_from_registry( 1847 HKEY hBaseKey, 1848 DWORD * result 1849 ) 1850 { 1851 return get_DWORD_from_registry(hBaseKey, 1852 LEASH_REGISTRY_KEY_NAME, 1853 LEASH_REGISTRY_VALUE_LIFE_MAX, 1854 result); 1855 } 1856 1857 DWORD 1858 Leash_reset_default_life_max( 1859 ) 1860 { 1861 HKEY hKey; 1862 LONG rc; 1863 1864 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1865 if (rc) 1866 return rc; 1867 1868 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX); 1869 RegCloseKey(hKey); 1870 1871 return rc; 1872 } 1873 1874 DWORD 1875 Leash_set_default_life_max( 1876 DWORD minutes 1877 ) 1878 { 1879 HKEY hKey; 1880 LONG rc; 1881 1882 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1883 0, 0, KEY_WRITE, 0, &hKey, 0); 1884 if (rc) 1885 return rc; 1886 1887 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD, 1888 (LPBYTE) &minutes, sizeof(DWORD)); 1889 RegCloseKey(hKey); 1890 1891 return rc; 1892 } 1893 1894 DWORD 1895 Leash_get_default_life_max( 1896 ) 1897 { 1898 HMODULE hmLeash; 1899 DWORD result; 1900 1901 if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) || 1902 get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result)) 1903 { 1904 return result; 1905 } 1906 1907 hmLeash = GetModuleHandle(LEASH_DLL); 1908 if (hmLeash) 1909 { 1910 char life_max[80]; 1911 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX, 1912 life_max, sizeof(life_max))) 1913 { 1914 life_max[sizeof(life_max) - 1] = 0; 1915 return atoi(life_max); 1916 } 1917 } 1918 return 1440; 1919 } 1920 1921 static 1922 BOOL 1923 get_default_renew_min_from_registry( 1924 HKEY hBaseKey, 1925 DWORD * result 1926 ) 1927 { 1928 return get_DWORD_from_registry(hBaseKey, 1929 LEASH_REGISTRY_KEY_NAME, 1930 LEASH_REGISTRY_VALUE_RENEW_MIN, 1931 result); 1932 } 1933 1934 DWORD 1935 Leash_reset_default_renew_min( 1936 ) 1937 { 1938 HKEY hKey; 1939 LONG rc; 1940 1941 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 1942 if (rc) 1943 return rc; 1944 1945 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN); 1946 RegCloseKey(hKey); 1947 1948 return rc; 1949 } 1950 1951 DWORD 1952 Leash_set_default_renew_min( 1953 DWORD minutes 1954 ) 1955 { 1956 HKEY hKey; 1957 LONG rc; 1958 1959 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 1960 0, 0, KEY_WRITE, 0, &hKey, 0); 1961 if (rc) 1962 return rc; 1963 1964 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD, 1965 (LPBYTE) &minutes, sizeof(DWORD)); 1966 RegCloseKey(hKey); 1967 1968 return rc; 1969 } 1970 1971 DWORD 1972 Leash_get_default_renew_min( 1973 ) 1974 { 1975 HMODULE hmLeash; 1976 DWORD result; 1977 1978 if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) || 1979 get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result)) 1980 { 1981 return result; 1982 } 1983 1984 hmLeash = GetModuleHandle(LEASH_DLL); 1985 if (hmLeash) 1986 { 1987 char renew_min[80]; 1988 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN, 1989 renew_min, sizeof(renew_min))) 1990 { 1991 renew_min[sizeof(renew_min) - 1] = 0; 1992 return atoi(renew_min); 1993 } 1994 } 1995 return 600; /* 10 hours */ 1996 } 1997 1998 static 1999 BOOL 2000 get_default_renew_max_from_registry( 2001 HKEY hBaseKey, 2002 DWORD * result 2003 ) 2004 { 2005 return get_DWORD_from_registry(hBaseKey, 2006 LEASH_REGISTRY_KEY_NAME, 2007 LEASH_REGISTRY_VALUE_RENEW_MAX, 2008 result); 2009 } 2010 2011 DWORD 2012 Leash_reset_default_renew_max( 2013 ) 2014 { 2015 HKEY hKey; 2016 LONG rc; 2017 2018 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 2019 if (rc) 2020 return rc; 2021 2022 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX); 2023 RegCloseKey(hKey); 2024 2025 return rc; 2026 } 2027 2028 DWORD 2029 Leash_set_default_renew_max( 2030 DWORD minutes 2031 ) 2032 { 2033 HKEY hKey; 2034 LONG rc; 2035 2036 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 2037 0, 0, KEY_WRITE, 0, &hKey, 0); 2038 if (rc) 2039 return rc; 2040 2041 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD, 2042 (LPBYTE) &minutes, sizeof(DWORD)); 2043 RegCloseKey(hKey); 2044 2045 return rc; 2046 } 2047 2048 DWORD 2049 Leash_get_default_renew_max( 2050 ) 2051 { 2052 HMODULE hmLeash; 2053 DWORD result; 2054 2055 if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) || 2056 get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result)) 2057 { 2058 return result; 2059 } 2060 2061 hmLeash = GetModuleHandle(LEASH_DLL); 2062 if (hmLeash) 2063 { 2064 char renew_max[80]; 2065 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX, 2066 renew_max, sizeof(renew_max))) 2067 { 2068 renew_max[sizeof(renew_max) - 1] = 0; 2069 return atoi(renew_max); 2070 } 2071 } 2072 return 60 * 24 * 30; 2073 } 2074 2075 static 2076 BOOL 2077 get_default_uppercaserealm_from_registry( 2078 HKEY hBaseKey, 2079 DWORD * result 2080 ) 2081 { 2082 return get_DWORD_from_registry(hBaseKey, 2083 LEASH_SETTINGS_REGISTRY_KEY_NAME, 2084 LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 2085 result); 2086 } 2087 2088 DWORD 2089 Leash_reset_default_uppercaserealm( 2090 ) 2091 { 2092 HKEY hKey; 2093 LONG rc; 2094 2095 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 2096 if (rc) 2097 return rc; 2098 2099 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM); 2100 RegCloseKey(hKey); 2101 2102 return rc; 2103 } 2104 2105 DWORD 2106 Leash_set_default_uppercaserealm( 2107 DWORD onoff 2108 ) 2109 { 2110 HKEY hKey; 2111 LONG rc; 2112 2113 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, 2114 0, 0, KEY_WRITE, 0, &hKey, 0); 2115 if (rc) 2116 return rc; 2117 2118 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD, 2119 (LPBYTE) &onoff, sizeof(DWORD)); 2120 RegCloseKey(hKey); 2121 2122 return rc; 2123 } 2124 2125 DWORD 2126 Leash_get_default_uppercaserealm( 2127 ) 2128 { 2129 HMODULE hmLeash; 2130 DWORD result; 2131 2132 if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) || 2133 get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result)) 2134 { 2135 return result; 2136 } 2137 2138 hmLeash = GetModuleHandle(LEASH_DLL); 2139 if (hmLeash) 2140 { 2141 char uppercaserealm[80]; 2142 if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM, 2143 uppercaserealm, sizeof(uppercaserealm))) 2144 { 2145 uppercaserealm[sizeof(uppercaserealm) - 1] = 0; 2146 return atoi(uppercaserealm); 2147 } 2148 } 2149 return 1; 2150 } 2151 2152 DWORD 2153 Leash_reset_default_mslsa_import( 2154 ) 2155 { 2156 return ERROR_INVALID_FUNCTION; 2157 } 2158 2159 DWORD 2160 Leash_set_default_mslsa_import( 2161 DWORD onoffmatch 2162 ) 2163 { 2164 return ERROR_INVALID_FUNCTION; 2165 } 2166 2167 DWORD 2168 Leash_get_default_mslsa_import( 2169 ) 2170 { 2171 return 0; 2172 } 2173 2174 2175 static 2176 BOOL 2177 get_default_preserve_kinit_settings_from_registry( 2178 HKEY hBaseKey, 2179 DWORD * result 2180 ) 2181 { 2182 return get_DWORD_from_registry(hBaseKey, 2183 LEASH_REGISTRY_KEY_NAME, 2184 LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 2185 result); 2186 } 2187 2188 DWORD 2189 Leash_reset_default_preserve_kinit_settings( 2190 ) 2191 { 2192 HKEY hKey; 2193 LONG rc; 2194 2195 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); 2196 if (rc) 2197 return rc; 2198 2199 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT); 2200 RegCloseKey(hKey); 2201 2202 return rc; 2203 } 2204 2205 DWORD 2206 Leash_set_default_preserve_kinit_settings( 2207 DWORD onoff 2208 ) 2209 { 2210 HKEY hKey; 2211 LONG rc; 2212 2213 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 2214 0, 0, KEY_WRITE, 0, &hKey, 0); 2215 if (rc) 2216 return rc; 2217 2218 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD, 2219 (LPBYTE) &onoff, sizeof(DWORD)); 2220 RegCloseKey(hKey); 2221 2222 return rc; 2223 } 2224 2225 DWORD 2226 Leash_get_default_preserve_kinit_settings( 2227 ) 2228 { 2229 HMODULE hmLeash; 2230 DWORD result; 2231 2232 if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) || 2233 get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result)) 2234 { 2235 return result; 2236 } 2237 2238 hmLeash = GetModuleHandle(LEASH_DLL); 2239 if (hmLeash) 2240 { 2241 char preserve_kinit_settings[80]; 2242 if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT, 2243 preserve_kinit_settings, sizeof(preserve_kinit_settings))) 2244 { 2245 preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0; 2246 return atoi(preserve_kinit_settings); 2247 } 2248 } 2249 return 1; 2250 } 2251 2252 void 2253 Leash_reset_defaults(void) 2254 { 2255 Leash_reset_default_lifetime(); 2256 Leash_reset_default_renew_till(); 2257 Leash_reset_default_renewable(); 2258 Leash_reset_default_forwardable(); 2259 Leash_reset_default_noaddresses(); 2260 Leash_reset_default_proxiable(); 2261 Leash_reset_default_publicip(); 2262 Leash_reset_hide_kinit_options(); 2263 Leash_reset_default_life_min(); 2264 Leash_reset_default_life_max(); 2265 Leash_reset_default_renew_min(); 2266 Leash_reset_default_renew_max(); 2267 Leash_reset_default_uppercaserealm(); 2268 Leash_reset_default_preserve_kinit_settings(); 2269 } 2270 2271 static void 2272 acquire_tkt_send_msg_leash(const char *title, 2273 const char *ccachename, 2274 const char *name, 2275 const char *realm) 2276 { 2277 DWORD leashProcessId = 0; 2278 DWORD bufsize = 4096; 2279 DWORD step; 2280 HANDLE hLeashProcess = NULL; 2281 HANDLE hMapFile = NULL; 2282 HANDLE hTarget = NULL; 2283 HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL); 2284 char *strs; 2285 void *view; 2286 if (!hLeashWnd) 2287 // no leash window 2288 return; 2289 2290 GetWindowThreadProcessId(hLeashWnd, &leashProcessId); 2291 hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE, 2292 FALSE, 2293 leashProcessId); 2294 if (!hLeashProcess) 2295 // can't get process handle; use GetLastError() for more info 2296 return; 2297 2298 hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file 2299 NULL, // default security 2300 PAGE_READWRITE, // read/write access 2301 0, // max size (high 32) 2302 bufsize, // max size (low 32) 2303 NULL); // name 2304 if (!hMapFile) { 2305 // GetLastError() for more info 2306 CloseHandle(hLeashProcess); 2307 return; 2308 } 2309 2310 SetForegroundWindow(hLeashWnd); 2311 2312 view = MapViewOfFile(hMapFile, 2313 FILE_MAP_ALL_ACCESS, 2314 0, 2315 0, 2316 bufsize); 2317 if (view != NULL) { 2318 /* construct a marshalling of data 2319 * <title><principal><realm><ccache> 2320 * then send to Leash 2321 */ 2322 strs = (char *)view; 2323 // first reserve space for three more NULLs (4 strings total) 2324 bufsize -= 3; 2325 // Dialog title 2326 if (title != NULL) 2327 strcpy_s(strs, bufsize, title); 2328 else if (name != NULL && realm != NULL) 2329 sprintf_s(strs, bufsize, 2330 "MIT Kerberos: Get Ticket for %s@%s", name, realm); 2331 else 2332 strcpy_s(strs, bufsize, "MIT Kerberos: Get Ticket"); 2333 step = strlen(strs); 2334 strs += step + 1; 2335 bufsize -= step; 2336 // name and realm 2337 if (name != NULL) { 2338 strcpy_s(strs, bufsize, name); 2339 step = strlen(strs); 2340 strs += step + 1; 2341 bufsize -= step; 2342 if (realm != NULL) { 2343 strcpy_s(strs, bufsize, realm); 2344 step = strlen(strs); 2345 strs += step + 1; 2346 bufsize -= step; 2347 } else { 2348 *strs = 0; 2349 strs++; 2350 } 2351 } else { 2352 *strs = 0; 2353 strs++; 2354 *strs = 0; 2355 strs++; 2356 } 2357 2358 /* Append the ccache name */ 2359 if (ccachename != NULL) 2360 strcpy_s(strs, bufsize, ccachename); 2361 else 2362 *strs = 0; 2363 2364 UnmapViewOfFile(view); 2365 } 2366 // Duplicate the file mapping handle to one leash can use 2367 if (DuplicateHandle(GetCurrentProcess(), 2368 hMapFile, 2369 hLeashProcess, 2370 &hTarget, 2371 PAGE_READWRITE, 2372 FALSE, 2373 DUPLICATE_SAME_ACCESS | 2374 DUPLICATE_CLOSE_SOURCE)) { 2375 /* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */ 2376 SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget); 2377 } else { 2378 // GetLastError() 2379 } 2380 } 2381 2382 static int 2383 acquire_tkt_send_msg(krb5_context ctx, const char * title, 2384 const char * ccachename, 2385 krb5_principal desiredKrb5Principal, 2386 char * out_ccname, int out_cclen) 2387 { 2388 krb5_error_code err; 2389 HWND hNetIdMgr; 2390 HWND hForeground; 2391 char *desiredName = 0; 2392 char *desiredRealm = 0; 2393 2394 /* do we want a specific client principal? */ 2395 if (desiredKrb5Principal != NULL) { 2396 err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName); 2397 if (!err) { 2398 char * p; 2399 for (p = desiredName; *p && *p != '@'; p++); 2400 if ( *p == '@' ) { 2401 *p = '\0'; 2402 desiredRealm = ++p; 2403 } 2404 } 2405 } 2406 2407 hForeground = GetForegroundWindow(); 2408 hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); 2409 if (hNetIdMgr != NULL) { 2410 HANDLE hMap; 2411 DWORD tid = GetCurrentThreadId(); 2412 char mapname[256]; 2413 NETID_DLGINFO *dlginfo; 2414 2415 sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); 2416 2417 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 2418 0, 4096, mapname); 2419 if (hMap == NULL) { 2420 return -1; 2421 } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { 2422 CloseHandle(hMap); 2423 return -1; 2424 } 2425 2426 dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 2427 0, 0, 4096, NULL); 2428 if (dlginfo == NULL) { 2429 CloseHandle(hMap); 2430 return -1; 2431 } 2432 2433 memset(dlginfo, 0, sizeof(NETID_DLGINFO)); 2434 2435 dlginfo->size = sizeof(NETID_DLGINFO); 2436 dlginfo->dlgtype = NETID_DLGTYPE_TGT; 2437 dlginfo->in.use_defaults = 1; 2438 2439 if (title) { 2440 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2441 title, -1, 2442 dlginfo->in.title, NETID_TITLE_SZ); 2443 } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { 2444 char mytitle[NETID_TITLE_SZ]; 2445 sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); 2446 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2447 mytitle, -1, 2448 dlginfo->in.title, NETID_TITLE_SZ); 2449 } else { 2450 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2451 "Obtain Kerberos TGT", -1, 2452 dlginfo->in.title, NETID_TITLE_SZ); 2453 } 2454 if (desiredName) 2455 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2456 desiredName, -1, 2457 dlginfo->in.username, NETID_USERNAME_SZ); 2458 if (desiredRealm) 2459 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2460 desiredRealm, -1, 2461 dlginfo->in.realm, NETID_REALM_SZ); 2462 if (ccachename) 2463 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, 2464 ccachename, -1, 2465 dlginfo->in.ccache, NETID_CCACHE_NAME_SZ); 2466 SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); 2467 2468 if (out_ccname && out_cclen > 0) { 2469 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1, 2470 out_ccname, out_cclen, NULL, NULL); 2471 } 2472 2473 UnmapViewOfFile(dlginfo); 2474 CloseHandle(hMap); 2475 } else { 2476 acquire_tkt_send_msg_leash(title, 2477 ccachename, desiredName, desiredRealm); 2478 } 2479 2480 SetForegroundWindow(hForeground); 2481 if (desiredName != NULL) 2482 pkrb5_free_unparsed_name(ctx, desiredName); 2483 2484 return 0; 2485 } 2486 2487 static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache) 2488 { 2489 krb5_cc_cursor cur = NULL; 2490 krb5_creds creds; 2491 krb5_flags flags; 2492 krb5_error_code code; 2493 BOOL have_tickets = FALSE; 2494 2495 // Don't need the actual ticket. 2496 flags = KRB5_TC_NOTICKET; 2497 code = pkrb5_cc_set_flags(ctx, cache, flags); 2498 if (code) 2499 goto cleanup; 2500 code = pkrb5_cc_start_seq_get(ctx, cache, &cur); 2501 if (code) 2502 goto cleanup; 2503 2504 _tzset(); 2505 while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) { 2506 if ((!pkrb5_is_config_principal(ctx, creds.server)) && 2507 ((time_t)(DWORD)creds.times.endtime - time(0) > 0)) 2508 have_tickets = TRUE; 2509 2510 pkrb5_free_cred_contents(ctx, &creds); 2511 } 2512 if (code == KRB5_CC_END) { 2513 code = pkrb5_cc_end_seq_get(ctx, cache, &cur); 2514 if (code) 2515 goto cleanup; 2516 flags = 0; 2517 code = pkrb5_cc_set_flags(ctx, cache, flags); 2518 if (code) 2519 goto cleanup; 2520 } 2521 cleanup: 2522 return have_tickets; 2523 } 2524 2525 static BOOL 2526 cc_have_tickets_for_princ(krb5_context ctx, 2527 krb5_ccache cache, 2528 krb5_principal princ) 2529 { 2530 krb5_error_code code; 2531 krb5_principal cc_princ = NULL; 2532 BOOL have_tickets = FALSE; 2533 code = pkrb5_cc_get_principal(ctx, cache, &cc_princ); 2534 if (code) 2535 goto cleanup; 2536 2537 if (pkrb5_principal_compare(ctx, princ, cc_princ)) 2538 have_tickets = cc_have_tickets(ctx, cache); 2539 2540 cleanup: 2541 if (cc_princ != NULL) 2542 pkrb5_free_principal(ctx, cc_princ); 2543 return have_tickets; 2544 } 2545 2546 static BOOL cc_default_have_tickets(krb5_context ctx) 2547 { 2548 krb5_ccache cache = NULL; 2549 BOOL have_tickets = FALSE; 2550 if (pkrb5_cc_default(ctx, &cache) == 0) 2551 have_tickets = cc_have_tickets(ctx, cache); 2552 if (cache != NULL) 2553 pkrb5_cc_close(ctx, cache); 2554 return have_tickets; 2555 } 2556 2557 static BOOL 2558 cccol_have_tickets_for_princ(krb5_context ctx, 2559 krb5_principal princ, 2560 char *ccname, 2561 int cclen) 2562 { 2563 krb5_error_code code; 2564 krb5_ccache cache; 2565 krb5_cccol_cursor cursor; 2566 BOOL have_tickets = FALSE; 2567 char *ccfullname; 2568 2569 code = pkrb5_cccol_cursor_new(ctx, &cursor); 2570 if (code) 2571 goto cleanup; 2572 2573 while (!have_tickets && 2574 !(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) && 2575 cache != NULL) { 2576 if (cc_have_tickets_for_princ(ctx, cache, princ)) { 2577 if (pkrb5_cc_get_full_name(ctx, cache, &ccfullname)==0) { 2578 strcpy_s(ccname, cclen, ccfullname); 2579 pkrb5_free_string(ctx, ccfullname); 2580 have_tickets = TRUE; 2581 } 2582 } 2583 pkrb5_cc_close(ctx, cache); 2584 } 2585 pkrb5_cccol_cursor_free(ctx, &cursor); 2586 cleanup: 2587 2588 return have_tickets; 2589 } 2590 2591 static void 2592 acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen) 2593 { 2594 krb5_context ctx; 2595 DWORD gle; 2596 char ccachename[272]=""; 2597 char loginenv[16]; 2598 BOOL prompt; 2599 BOOL haveTickets; 2600 2601 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv)); 2602 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); 2603 2604 ctx = context; 2605 2606 SetLastError(0); 2607 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); 2608 gle = GetLastError(); 2609 if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) { 2610 const char * ccdef = pkrb5_cc_default_name(ctx); 2611 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL); 2612 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); 2613 } 2614 2615 haveTickets = cc_default_have_tickets(ctx); 2616 2617 if ( prompt && !haveTickets ) { 2618 acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen); 2619 /* 2620 * If the ticket manager returned an alternative credential cache 2621 * remember it as the default for this process. 2622 */ 2623 if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) { 2624 SetEnvironmentVariable("KRB5CCNAME",ccname); 2625 } 2626 2627 } else if (ccachename[0] && ccname) { 2628 strncpy(ccname, ccachename, cclen); 2629 ccname[cclen-1] = '\0'; 2630 } 2631 if ( !context ) 2632 pkrb5_free_context(ctx); 2633 } 2634 2635 2636 static void 2637 acquire_tkt_for_princ(krb5_context ctx, krb5_principal desiredPrincipal, 2638 char * ccname, int cclen) 2639 { 2640 DWORD gle; 2641 char ccachename[272]=""; 2642 char loginenv[16]; 2643 BOOL prompt; 2644 2645 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv)); 2646 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); 2647 2648 SetLastError(0); 2649 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); 2650 gle = GetLastError(); 2651 if ((gle == ERROR_ENVVAR_NOT_FOUND || !ccachename[0]) && ctx != NULL) { 2652 const char * ccdef = pkrb5_cc_default_name(ctx); 2653 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL); 2654 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); 2655 } 2656 if (!cccol_have_tickets_for_princ(ctx, desiredPrincipal, ccname, cclen)) { 2657 if (prompt) { 2658 acquire_tkt_send_msg(ctx, NULL, 2659 ccachename, desiredPrincipal, ccname, cclen); 2660 /* 2661 * If the ticket manager returned an alternative credential cache 2662 * remember it as the default for this process. 2663 */ 2664 if (ccname != NULL && ccname[0] && 2665 strcmp(ccachename, ccname)) { 2666 SetEnvironmentVariable("KRB5CCNAME",ccname); 2667 } 2668 } 2669 } 2670 } 2671 2672 2673 void FAR 2674 not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context, 2675 krb5_principal desiredKrb5Principal, 2676 char * ccname, int cclen) 2677 { 2678 if (!desiredKrb5Principal) { 2679 acquire_tkt_no_princ(context, ccname, cclen); 2680 } else { 2681 acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen); 2682 } 2683 return; 2684 } 2685