10 #include "leash-int.h"
15 static char FAR *err_context;
17 char KRB_HelpFile[_MAX_PATH] = HELPFILE;
19 #define LEN 64 /* Maximum Hostname Length */
21 #define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */
34 for (p = s; *p; p++) {
37 /* Add more cases here */
61 int size = sizeof(message) - 1; /* -1 to leave room for NULL terminator */
67 n = _snprintf(p, size, "%s\n\n", error);
71 if (rc5 && !result_string)
73 n = _snprintf(p, size,
74 "Kerberos 5: %s (error %ld)\n",
84 n = _snprintf(p, size,
86 err_describe(buffer, rcL)
93 n = _snprintf(p, size,
99 #ifdef USE_MESSAGE_BOX
100 *p = 0; /* ensure NULL termination of message */
102 MessageBox(NULL, message, "MIT Kerberos",
103 MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
104 #endif /* USE_MESSAGE_BOX */
115 const char * postfix,
124 base_size = strlen(base) + 1;
125 ret_size = base_size + strlen(postfix) + 1;
126 copy = malloc(base_size);
127 ret = malloc(ret_size);
132 strncpy(copy, base, base_size);
133 copy[base_size - 1] = 0;
135 strncpy(ret, base, base_size);
136 strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1));
137 ret[ret_size - 1] = 0;
147 // INVARIANT: (ret ==> copy) && (copy ==> ret)
155 const char * postfix,
159 static krb5_context ctx = 0;
160 static char * old_cache = 0;
162 // INVARIANT: old_cache ==> ctx && ctx ==> old_cache
167 if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve ||
168 !pkrb5_cc_default_name || !pkrb5_cc_set_default_name)
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);
180 pkrb5_free_context(ctx);
186 char * tmp_cache = 0;
187 krb5_error_code rc = 0;
189 rc = pkrb5_init_context(&ctx);
190 if (rc) goto cleanup;
192 tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix,
200 rc = pkrb5_cc_set_default_name(ctx, tmp_cache);
204 pkrb5_free_context(ctx);
222 return Leash_int_checkpwd(principal, password, 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(),
242 make_temp_cache_v5(0, &ctx);
255 krb5_error_code rc = 0;
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;
262 DWORD addressless = 0;
264 result_string.data = 0;
265 result_code_string.data = 0;
267 if ( !pkrb5_init_context )
270 if (rc = pkrb5_init_context(&context))
273 if (rc = pkrb5_parse_name(context, principal, &princ))
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);
282 addressless = Leash_get_default_noaddresses();
284 pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
287 if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password,
288 0, 0, 0, "kadmin/changepw", &opts))
291 if (rc = pkrb5_change_password(context, &creds, newpassword,
292 &result_code, &result_code_string,
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);
303 _snprintf(*error_str, len + 1,
305 result_code_string.length, result_code_string.data,
306 result_string.length?": ":"",
307 result_string.length, result_string.data);
314 if (result_string.data)
315 pkrb5_free_data_contents(context, &result_string);
317 if (result_code_string.data)
318 pkrb5_free_data_contents(context, &result_code_string);
321 pkrb5_free_principal(context, princ);
324 pkrb5_free_context(context);
332 * Try to change the password using krb5.
342 return Leash_int_changepwd(principal, password, newpassword, result_string, 0);
350 char** result_string,
354 char* v5_error_str = 0;
359 rc = rc5 = Leash_changepwd_v5(principal, password, newpassword,
365 char v5_prefix[] = "Kerberos 5: ";
368 clean_string(v5_error_str);
371 len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) +
373 error_str = malloc(len + 1);
379 n = _snprintf(p, size, "%s%s%s%s",
380 sep, v5_prefix, v5_error_str, sep);
385 *result_string = error_str;
388 return leash_error_message("Error while changing password.",
389 0, rc5, 0, error_str,
394 int (*Lcom_err)(LPSTR,long,LPSTR,...);
395 LPSTR (*Lerror_message)(long);
396 LPSTR (*Lerror_table_name)(long);
406 return Leash_int_kinit_ex( 0, 0,
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(),
428 unsigned long publicip
431 return Leash_int_kinit_ex( 0, /* krb5 context */
432 0, /* parent window */
456 unsigned long publicip,
460 char aname[ANAME_SZ];
462 char realm[REALM_SZ];
463 char first_part[256];
464 char second_part[256];
479 if (renew_life > 0 && renew_life < 5)
484 /* This should be changed if the maximum ticket lifetime */
490 err_context = "parsing principal";
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));
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)
505 strcpy(aname, first_part);
506 strcpy(inst, second_part);
512 for (i = 0; temp[i]; i++)
529 memset(temp, '\0', sizeof(temp));
531 if (strlen(inst) != 0)
536 if (strlen(realm) != 0)
542 rc5 = Leash_krb5_kinit(ctx, hParent,
543 temp, password, lifetime,
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,
559 if ( hKrb5 && !LeashKRB5_renew() ) {
561 lifetime = Leash_get_default_lifetime() / 5;
568 GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
572 TOKEN_STATISTICS Stats;
575 PSECURITY_LOGON_SESSION_DATA pSessionData;
579 *ppSessionData = NULL;
581 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
585 Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
586 CloseHandle( TokenHandle );
590 Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData );
591 if ( FAILED(Status) || !pSessionData )
594 *ppSessionData = pSessionData;
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
607 IsKerberosLogon(VOID)
609 PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
610 BOOL Success = FALSE;
612 if ( GetSecurityLogonSessionData(&pSessionData) ) {
613 if ( pSessionData->AuthenticationPackage.Buffer ) {
619 usBuffer = (pSessionData->AuthenticationPackage).Buffer;
620 usLength = (pSessionData->AuthenticationPackage).Length;
623 lstrcpynW (buffer, usBuffer, usLength);
624 lstrcatW (buffer,L"");
625 if ( !lstrcmpW(L"Kerberos",buffer) )
629 pLsaFreeReturnBuffer(pSessionData);
635 IsWindowsVista (void)
637 static BOOL fChecked = FALSE;
638 static BOOL fIsVista = FALSE;
642 OSVERSIONINFO Version;
644 memset (&Version, 0x00, sizeof(Version));
645 Version.dwOSVersionInfoSize = sizeof(Version);
647 if (GetVersionEx (&Version))
649 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)
659 IsProcessUacLimited (void)
661 static BOOL fChecked = FALSE;
662 static BOOL fIsUAC = FALSE;
668 DWORD ElevationLevel;
672 if (IsWindowsVista()) {
673 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
675 Success = GetTokenInformation( TokenHandle,
676 TokenOrigin+1 /* ElevationLevel */,
677 &ElevationLevel, sizeof(DWORD), &ReqLen );
678 CloseHandle( TokenHandle );
679 if ( Success && ElevationLevel == 3 /* Limited */ )
689 // This looks really ugly because it is. The result of IsKerberosLogon()
690 // does not prove whether or not there are Kerberos tickets available to
691 // be imported. Only the call to Leash_ms2mit() which actually attempts
692 // to import tickets can do that. However, calling Leash_ms2mit() can
693 // result in a TGS_REQ being sent to the KDC and since Leash_importable()
694 // is called quite often we want to avoid this if at all possible.
695 // Unfortunately, we have be shown at least one case in which the primary
696 // authentication package was not Kerberos and yet there were Kerberos
697 // tickets available. Therefore, if IsKerberosLogon() is not TRUE we
698 // must call Leash_ms2mit() but we still do not want to call it in a
699 // tight loop so we cache the response and assume it won't change.
702 // And the nightmare goes on. On Vista the Lsa call we use to determine
703 // whether or not Kerberos was used for logon fails to return and worse
704 // corrupts the stack. Therefore, we must now test to see if the
705 // operating system is Vista and skip the call to IsKerberosLogon()
708 Leash_importable(void)
710 if (IsProcessUacLimited())
713 if ( !IsWindowsVista() && IsKerberosLogon() )
716 static int response = -1;
717 if (response == -1) {
718 response = Leash_ms2mit(0);
727 if ( Leash_ms2mit(1) ) {
729 lifetime = Leash_get_default_lifetime() / 5;
738 Leash_krb5_kdestroy();
743 long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo)
749 // This function can be used to set the help file that will be
750 // referenced the DLL's PasswordProcDLL function and err_describe
751 // function. Returns true if the help file has been set to the
752 // argument or the environment variable KERB_HELP. Returns FALSE if
753 // the default helpfile as defined in by HELPFILE in lsh_pwd.h is
755 BOOL Leash_set_help_file( char *szHelpFile )
757 char tmpHelpFile[256];
760 if( szHelpFile == NULL ){
761 GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile));
763 strcpy( KRB_HelpFile, szHelpFile );
767 if( !ret && tmpHelpFile[0] ){
768 strcpy( KRB_HelpFile, tmpHelpFile );
773 strcpy( KRB_HelpFile, HELPFILE );
781 LPSTR Leash_get_help_file(void)
783 return( KRB_HelpFile);
799 get_profile_file(LPSTR confname, UINT szConfname)
801 char **configFile = NULL;
803 if (pkrb5_get_default_config_files(&configFile) || !configFile[0])
805 GetWindowsDirectory(confname,szConfname);
806 confname[szConfname-1] = '\0';
807 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
808 confname[szConfname-1] = '\0';
816 strncpy(confname, *configFile, szConfname);
817 confname[szConfname-1] = '\0';
818 pkrb5_free_config_files(configFile);
824 GetWindowsDirectory(confname,szConfname);
825 confname[szConfname-1] = '\0';
826 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
827 confname[szConfname-1] = '\0';
833 static const char *const conf_yes[] = {
834 "y", "yes", "true", "t", "1", "on",
838 static const char *const conf_no[] = {
839 "n", "no", "false", "nil", "0", "off",
844 config_boolean_to_int(const char *s)
846 const char *const *p;
848 for(p=conf_yes; *p; p++) {
849 if (!strcasecmp(*p,s))
853 for(p=conf_no; *p; p++) {
854 if (!strcasecmp(*p,s))
858 /* Default to "no" */
863 * Leash_get_default_lifetime:
865 * This function is used to get the default ticket lifetime for this
866 * process in minutes. A return value of 0 indicates no setting or
867 * "default" setting obtained.
869 * Here is where we look in order:
871 * - LIFETIME environment variable
872 * - HKCU\Software\MIT\Leash,lifetime
873 * - HKLM\Software\MIT\Leash,lifetime
874 * - string resource in the leash DLL
878 get_DWORD_from_registry(
889 rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
893 dwCount = sizeof(DWORD);
894 rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount);
897 return rc?FALSE:TRUE;
902 get_default_lifetime_from_registry(
907 return get_DWORD_from_registry(hBaseKey,
908 LEASH_REGISTRY_KEY_NAME,
909 LEASH_REGISTRY_VALUE_LIFETIME,
914 Leash_reset_default_lifetime(
920 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
924 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME);
931 Leash_set_default_lifetime(
938 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
939 0, 0, KEY_WRITE, 0, &hKey, 0);
943 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD,
944 (LPBYTE) &minutes, sizeof(DWORD));
951 Leash_get_default_lifetime(
959 if (GetEnvironmentVariable("LIFETIME",env,sizeof(env)))
965 if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) ||
966 get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result))
972 CHAR confname[MAX_PATH];
974 if (!get_profile_file(confname, sizeof(confname)))
977 const char *filenames[2];
980 filenames[0] = confname;
982 if (!pprofile_init(filenames, &profile)) {
985 retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value);
986 if (retval == 0 && value) {
989 retval = pkrb5_string_to_deltat(value, &d);
991 if (retval == KRB5_DELTAT_BADFORMAT) {
992 /* Historically some sites use relations of
993 the form 'ticket_lifetime = 24000' where
994 the unit is left out but is assumed to be
995 seconds. Then there are other sites which
996 use the form 'ticket_lifetime = 600' where
997 the unit is assumed to be minutes. While
998 these are technically wrong (a unit needs
999 to be specified), we try to accomodate for
1000 this using the safe assumption that the
1001 unit is seconds and tack an 's' to the end
1002 and see if that works. */
1004 /* Of course, Leash is one of the platforms
1005 that historically assumed no units and minutes
1006 so this change is going to break some people
1007 but its better to be consistent. */
1012 cch = strlen(value) + 2; /* NUL and new 's' */
1013 if (cch > sizeof(buf))
1019 retval = pkrb5_string_to_deltat(buf, &d);
1025 } else if (retval == 0) {
1029 pprofile_release_string(value);
1031 pprofile_release(profile);
1032 /* value has been released but we can still use a check for
1033 * non-NULL to see if we were able to read a value.
1035 if (retval == 0 && value)
1041 hmLeash = GetModuleHandle(LEASH_DLL);
1045 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE,
1046 lifetime, sizeof(lifetime)))
1048 lifetime[sizeof(lifetime) - 1] = 0;
1049 return atoi(lifetime);
1057 get_default_renew_till_from_registry(
1062 return get_DWORD_from_registry(hBaseKey,
1063 LEASH_REGISTRY_KEY_NAME,
1064 LEASH_REGISTRY_VALUE_RENEW_TILL,
1069 Leash_reset_default_renew_till(
1075 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1079 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL);
1086 Leash_set_default_renew_till(
1093 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1094 0, 0, KEY_WRITE, 0, &hKey, 0);
1098 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD,
1099 (LPBYTE) &minutes, sizeof(DWORD));
1106 Leash_get_default_renew_till(
1113 if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env)))
1118 if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) ||
1119 get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result))
1125 CHAR confname[MAX_PATH];
1126 if (!get_profile_file(confname, sizeof(confname)))
1129 const char *filenames[2];
1132 filenames[0] = confname;
1133 filenames[1] = NULL;
1135 if (!pprofile_init(filenames, &profile)) {
1136 char * value = NULL;
1138 retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value);
1139 if (retval == 0 && value) {
1142 retval = pkrb5_string_to_deltat(value, &d);
1143 if (retval == KRB5_DELTAT_BADFORMAT) {
1144 /* Historically some sites use relations of
1145 the form 'ticket_lifetime = 24000' where
1146 the unit is left out but is assumed to be
1147 seconds. Then there are other sites which
1148 use the form 'ticket_lifetime = 600' where
1149 the unit is assumed to be minutes. While
1150 these are technically wrong (a unit needs
1151 to be specified), we try to accomodate for
1152 this using the safe assumption that the
1153 unit is seconds and tack an 's' to the end
1154 and see if that works. */
1156 /* Of course, Leash is one of the platforms
1157 that historically assumed no units and minutes
1158 so this change is going to break some people
1159 but its better to be consistent. */
1163 cch = strlen(value) + 2; /* NUL and new 's' */
1164 if (cch > sizeof(buf))
1170 retval = pkrb5_string_to_deltat(buf, &d);
1175 } else if (retval == 0) {
1178 pprofile_release_string(value);
1180 pprofile_release(profile);
1181 /* value has been released but we can still use a check for
1182 * non-NULL to see if we were able to read a value.
1184 if (retval == 0 && value)
1187 pprofile_release(profile);
1192 hmLeash = GetModuleHandle(LEASH_DLL);
1195 char renew_till[80];
1196 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL,
1197 renew_till, sizeof(renew_till)))
1199 renew_till[sizeof(renew_till) - 1] = 0;
1200 return atoi(renew_till);
1208 get_default_forwardable_from_registry(
1213 return get_DWORD_from_registry(hBaseKey,
1214 LEASH_REGISTRY_KEY_NAME,
1215 LEASH_REGISTRY_VALUE_FORWARDABLE,
1220 Leash_reset_default_forwardable(
1226 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1230 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE);
1237 Leash_set_default_forwardable(
1244 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1245 0, 0, KEY_WRITE, 0, &hKey, 0);
1249 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD,
1250 (LPBYTE) &minutes, sizeof(DWORD));
1257 Leash_get_default_forwardable(
1265 if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env)))
1270 if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) ||
1271 get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result))
1277 CHAR confname[MAX_PATH];
1278 if (!get_profile_file(confname, sizeof(confname)))
1281 const char *filenames[2];
1284 filenames[0] = confname;
1285 filenames[1] = NULL;
1286 if (!pprofile_init(filenames, &profile)) {
1287 retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value);
1289 result = config_boolean_to_int(value);
1290 pprofile_release_string(value);
1291 pprofile_release(profile);
1294 pprofile_release(profile);
1299 hmLeash = GetModuleHandle(LEASH_DLL);
1302 char forwardable[80];
1303 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD,
1304 forwardable, sizeof(forwardable)))
1306 forwardable[sizeof(forwardable) - 1] = 0;
1307 return atoi(forwardable);
1315 get_default_renewable_from_registry(
1320 return get_DWORD_from_registry(hBaseKey,
1321 LEASH_REGISTRY_KEY_NAME,
1322 LEASH_REGISTRY_VALUE_RENEWABLE,
1327 Leash_reset_default_renewable(
1333 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1337 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE);
1344 Leash_set_default_renewable(
1351 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1352 0, 0, KEY_WRITE, 0, &hKey, 0);
1356 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD,
1357 (LPBYTE) &minutes, sizeof(DWORD));
1364 Leash_get_default_renewable(
1371 if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env)))
1376 if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) ||
1377 get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result))
1383 CHAR confname[MAX_PATH];
1384 if (!get_profile_file(confname, sizeof(confname)))
1387 const char *filenames[2];
1390 filenames[0] = confname;
1391 filenames[1] = NULL;
1392 if (!pprofile_init(filenames, &profile)) {
1393 retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value);
1395 result = config_boolean_to_int(value);
1396 pprofile_release_string(value);
1397 pprofile_release(profile);
1400 pprofile_release(profile);
1405 hmLeash = GetModuleHandle(LEASH_DLL);
1409 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW,
1410 renewable, sizeof(renewable)))
1412 renewable[sizeof(renewable) - 1] = 0;
1413 return atoi(renewable);
1421 get_default_noaddresses_from_registry(
1426 return get_DWORD_from_registry(hBaseKey,
1427 LEASH_REGISTRY_KEY_NAME,
1428 LEASH_REGISTRY_VALUE_NOADDRESSES,
1433 Leash_reset_default_noaddresses(
1439 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1443 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES);
1450 Leash_set_default_noaddresses(
1457 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1458 0, 0, KEY_WRITE, 0, &hKey, 0);
1462 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD,
1463 (LPBYTE) &minutes, sizeof(DWORD));
1470 Leash_get_default_noaddresses(
1478 // if the profile file cannot be opened then the value will be true
1479 // if the noaddresses name cannot be found then the value will be true
1480 // if true in the library, we can't alter it by other means
1481 CHAR confname[MAX_PATH];
1483 if (!get_profile_file(confname, sizeof(confname)))
1486 const char *filenames[2];
1489 filenames[0] = confname;
1490 filenames[1] = NULL;
1491 if (!pprofile_init(filenames, &profile)) {
1492 retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
1494 result = config_boolean_to_int(value);
1495 pprofile_release_string(value);
1497 pprofile_release(profile);
1505 // The library default is false, check other locations
1507 if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env)))
1512 if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) ||
1513 get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result))
1518 hmLeash = GetModuleHandle(LEASH_DLL);
1521 char noaddresses[80];
1522 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS,
1523 noaddresses, sizeof(noaddresses)))
1525 noaddresses[sizeof(noaddresses) - 1] = 0;
1533 get_default_proxiable_from_registry(
1538 return get_DWORD_from_registry(hBaseKey,
1539 LEASH_REGISTRY_KEY_NAME,
1540 LEASH_REGISTRY_VALUE_PROXIABLE,
1545 Leash_reset_default_proxiable(
1551 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1555 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE);
1562 Leash_set_default_proxiable(
1569 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1570 0, 0, KEY_WRITE, 0, &hKey, 0);
1574 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD,
1575 (LPBYTE) &minutes, sizeof(DWORD));
1582 Leash_get_default_proxiable(
1589 if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env)))
1594 if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) ||
1595 get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result))
1601 CHAR confname[MAX_PATH];
1602 if (!get_profile_file(confname, sizeof(confname)))
1605 const char *filenames[2];
1608 filenames[0] = confname;
1609 filenames[1] = NULL;
1610 if (!pprofile_init(filenames, &profile)) {
1611 retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value);
1613 result = config_boolean_to_int(value);
1614 pprofile_release_string(value);
1615 pprofile_release(profile);
1618 pprofile_release(profile);
1623 hmLeash = GetModuleHandle(LEASH_DLL);
1627 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE,
1628 proxiable, sizeof(proxiable)))
1630 proxiable[sizeof(proxiable) - 1] = 0;
1631 return atoi(proxiable);
1639 get_default_publicip_from_registry(
1644 return get_DWORD_from_registry(hBaseKey,
1645 LEASH_REGISTRY_KEY_NAME,
1646 LEASH_REGISTRY_VALUE_PUBLICIP,
1651 Leash_reset_default_publicip(
1657 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1661 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP);
1668 Leash_set_default_publicip(
1675 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1676 0, 0, KEY_WRITE, 0, &hKey, 0);
1680 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD,
1681 (LPBYTE) &minutes, sizeof(DWORD));
1688 Leash_get_default_publicip(
1695 if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env)))
1700 if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) ||
1701 get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result))
1706 hmLeash = GetModuleHandle(LEASH_DLL);
1710 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP,
1711 publicip, sizeof(publicip)))
1713 publicip[sizeof(publicip) - 1] = 0;
1714 return atoi(publicip);
1722 get_hide_kinit_options_from_registry(
1727 return get_DWORD_from_registry(hBaseKey,
1728 LEASH_REGISTRY_KEY_NAME,
1729 LEASH_REGISTRY_VALUE_KINIT_OPT,
1734 Leash_reset_hide_kinit_options(
1740 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1744 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT);
1751 Leash_set_hide_kinit_options(
1758 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1759 0, 0, KEY_WRITE, 0, &hKey, 0);
1763 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD,
1764 (LPBYTE) &minutes, sizeof(DWORD));
1771 Leash_get_hide_kinit_options(
1777 if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) ||
1778 get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result))
1783 hmLeash = GetModuleHandle(LEASH_DLL);
1786 char hide_kinit_options[80];
1787 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT,
1788 hide_kinit_options, sizeof(hide_kinit_options)))
1790 hide_kinit_options[sizeof(hide_kinit_options) - 1] = 0;
1791 return atoi(hide_kinit_options);
1794 return 0; /* hide unless otherwise indicated */
1801 get_default_life_min_from_registry(
1806 return get_DWORD_from_registry(hBaseKey,
1807 LEASH_REGISTRY_KEY_NAME,
1808 LEASH_REGISTRY_VALUE_LIFE_MIN,
1813 Leash_reset_default_life_min(
1819 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1823 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN);
1830 Leash_set_default_life_min(
1837 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1838 0, 0, KEY_WRITE, 0, &hKey, 0);
1842 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD,
1843 (LPBYTE) &minutes, sizeof(DWORD));
1850 Leash_get_default_life_min(
1856 if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) ||
1857 get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result))
1862 hmLeash = GetModuleHandle(LEASH_DLL);
1866 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN,
1867 life_min, sizeof(life_min)))
1869 life_min[sizeof(life_min) - 1] = 0;
1870 return atoi(life_min);
1873 return 5; /* 5 minutes */
1878 get_default_life_max_from_registry(
1883 return get_DWORD_from_registry(hBaseKey,
1884 LEASH_REGISTRY_KEY_NAME,
1885 LEASH_REGISTRY_VALUE_LIFE_MAX,
1890 Leash_reset_default_life_max(
1896 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1900 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX);
1907 Leash_set_default_life_max(
1914 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1915 0, 0, KEY_WRITE, 0, &hKey, 0);
1919 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD,
1920 (LPBYTE) &minutes, sizeof(DWORD));
1927 Leash_get_default_life_max(
1933 if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) ||
1934 get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result))
1939 hmLeash = GetModuleHandle(LEASH_DLL);
1943 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX,
1944 life_max, sizeof(life_max)))
1946 life_max[sizeof(life_max) - 1] = 0;
1947 return atoi(life_max);
1955 get_default_renew_min_from_registry(
1960 return get_DWORD_from_registry(hBaseKey,
1961 LEASH_REGISTRY_KEY_NAME,
1962 LEASH_REGISTRY_VALUE_RENEW_MIN,
1967 Leash_reset_default_renew_min(
1973 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1977 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN);
1984 Leash_set_default_renew_min(
1991 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1992 0, 0, KEY_WRITE, 0, &hKey, 0);
1996 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD,
1997 (LPBYTE) &minutes, sizeof(DWORD));
2004 Leash_get_default_renew_min(
2010 if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) ||
2011 get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result))
2016 hmLeash = GetModuleHandle(LEASH_DLL);
2020 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN,
2021 renew_min, sizeof(renew_min)))
2023 renew_min[sizeof(renew_min) - 1] = 0;
2024 return atoi(renew_min);
2027 return 600; /* 10 hours */
2032 get_default_renew_max_from_registry(
2037 return get_DWORD_from_registry(hBaseKey,
2038 LEASH_REGISTRY_KEY_NAME,
2039 LEASH_REGISTRY_VALUE_RENEW_MAX,
2044 Leash_reset_default_renew_max(
2050 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2054 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX);
2061 Leash_set_default_renew_max(
2068 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2069 0, 0, KEY_WRITE, 0, &hKey, 0);
2073 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD,
2074 (LPBYTE) &minutes, sizeof(DWORD));
2081 Leash_get_default_renew_max(
2087 if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) ||
2088 get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result))
2093 hmLeash = GetModuleHandle(LEASH_DLL);
2097 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX,
2098 renew_max, sizeof(renew_max)))
2100 renew_max[sizeof(renew_max) - 1] = 0;
2101 return atoi(renew_max);
2104 return 60 * 24 * 30;
2109 get_default_uppercaserealm_from_registry(
2114 return get_DWORD_from_registry(hBaseKey,
2115 LEASH_SETTINGS_REGISTRY_KEY_NAME,
2116 LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM,
2121 Leash_reset_default_uppercaserealm(
2127 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2131 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM);
2138 Leash_set_default_uppercaserealm(
2145 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
2146 0, 0, KEY_WRITE, 0, &hKey, 0);
2150 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD,
2151 (LPBYTE) &onoff, sizeof(DWORD));
2158 Leash_get_default_uppercaserealm(
2164 if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) ||
2165 get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result))
2170 hmLeash = GetModuleHandle(LEASH_DLL);
2173 char uppercaserealm[80];
2174 if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM,
2175 uppercaserealm, sizeof(uppercaserealm)))
2177 uppercaserealm[sizeof(uppercaserealm) - 1] = 0;
2178 return atoi(uppercaserealm);
2186 get_default_mslsa_import_from_registry(
2191 return get_DWORD_from_registry(hBaseKey,
2192 LEASH_SETTINGS_REGISTRY_KEY_NAME,
2193 LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT,
2198 Leash_reset_default_mslsa_import(
2204 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2208 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT);
2215 Leash_set_default_mslsa_import(
2222 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
2223 0, 0, KEY_WRITE, 0, &hKey, 0);
2227 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT, 0, REG_DWORD,
2228 (LPBYTE) &onoffmatch, sizeof(DWORD));
2235 Leash_get_default_mslsa_import(
2241 if (get_default_mslsa_import_from_registry(HKEY_CURRENT_USER, &result) ||
2242 get_default_mslsa_import_from_registry(HKEY_LOCAL_MACHINE, &result))
2247 hmLeash = GetModuleHandle(LEASH_DLL);
2250 char mslsa_import[80];
2251 if (LoadString(hmLeash, LSH_DEFAULT_MSLSA_IMPORT,
2252 mslsa_import, sizeof(mslsa_import)))
2254 mslsa_import[sizeof(mslsa_import) - 1] = 0;
2255 return atoi(mslsa_import);
2258 return 2; /* import only when mslsa realm matches default */
2264 get_default_preserve_kinit_settings_from_registry(
2269 return get_DWORD_from_registry(hBaseKey,
2270 LEASH_REGISTRY_KEY_NAME,
2271 LEASH_REGISTRY_VALUE_PRESERVE_KINIT,
2276 Leash_reset_default_preserve_kinit_settings(
2282 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2286 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT);
2293 Leash_set_default_preserve_kinit_settings(
2300 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2301 0, 0, KEY_WRITE, 0, &hKey, 0);
2305 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD,
2306 (LPBYTE) &onoff, sizeof(DWORD));
2313 Leash_get_default_preserve_kinit_settings(
2319 if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) ||
2320 get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result))
2325 hmLeash = GetModuleHandle(LEASH_DLL);
2328 char preserve_kinit_settings[80];
2329 if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT,
2330 preserve_kinit_settings, sizeof(preserve_kinit_settings)))
2332 preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0;
2333 return atoi(preserve_kinit_settings);
2340 Leash_reset_defaults(void)
2342 Leash_reset_default_lifetime();
2343 Leash_reset_default_renew_till();
2344 Leash_reset_default_renewable();
2345 Leash_reset_default_forwardable();
2346 Leash_reset_default_noaddresses();
2347 Leash_reset_default_proxiable();
2348 Leash_reset_default_publicip();
2349 Leash_reset_hide_kinit_options();
2350 Leash_reset_default_life_min();
2351 Leash_reset_default_life_max();
2352 Leash_reset_default_renew_min();
2353 Leash_reset_default_renew_max();
2354 Leash_reset_default_uppercaserealm();
2355 Leash_reset_default_mslsa_import();
2356 Leash_reset_default_preserve_kinit_settings();
2360 acquire_tkt_send_msg_leash(const char *title,
2361 const char *ccachename,
2365 DWORD leashProcessId = 0;
2366 DWORD bufsize = 4096;
2368 HANDLE hLeashProcess = NULL;
2369 HANDLE hMapFile = NULL;
2370 HANDLE hTarget = NULL;
2371 HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL);
2378 GetWindowThreadProcessId(hLeashWnd, &leashProcessId);
2379 hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE,
2383 // can't get process handle; use GetLastError() for more info
2386 hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
2387 NULL, // default security
2388 PAGE_READWRITE, // read/write access
2389 0, // max size (high 32)
2390 bufsize, // max size (low 32)
2393 // GetLastError() for more info
2394 CloseHandle(hLeashProcess);
2398 SetForegroundWindow(hLeashWnd);
2400 view = MapViewOfFile(hMapFile,
2401 FILE_MAP_ALL_ACCESS,
2406 /* construct a marshalling of data
2407 * <title><principal><realm><ccache>
2408 * then send to Leash
2410 strs = (char *)view;
2411 // first reserve space for three more NULLs (4 strings total)
2415 strcpy_s(strs, bufsize, title);
2416 else if (name != NULL && realm != NULL)
2417 sprintf_s(strs, bufsize,
2418 "MIT Kerberos: Get Ticket for %s@%s", name, realm);
2420 strcpy_s(strs, bufsize, "MIT Kerberos: Get Ticket");
2421 step = strlen(strs);
2426 strcpy_s(strs, bufsize, name);
2427 step = strlen(strs);
2430 if (realm != NULL) {
2431 strcpy_s(strs, bufsize, realm);
2432 step = strlen(strs);
2446 /* Append the ccache name */
2447 if (ccachename != NULL)
2448 strcpy_s(strs, bufsize, ccachename);
2452 UnmapViewOfFile(view);
2454 // Duplicate the file mapping handle to one leash can use
2455 if (DuplicateHandle(GetCurrentProcess(),
2461 DUPLICATE_SAME_ACCESS |
2462 DUPLICATE_CLOSE_SOURCE)) {
2463 /* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */
2464 SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget);
2471 acquire_tkt_send_msg(krb5_context ctx, const char * title,
2472 const char * ccachename,
2473 krb5_principal desiredKrb5Principal,
2474 char * out_ccname, int out_cclen)
2476 krb5_error_code err;
2479 char *desiredName = 0;
2480 char *desiredRealm = 0;
2482 /* do we want a specific client principal? */
2483 if (desiredKrb5Principal != NULL) {
2484 err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName);
2487 for (p = desiredName; *p && *p != '@'; p++);
2495 hForeground = GetForegroundWindow();
2496 hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
2497 if (hNetIdMgr != NULL) {
2499 DWORD tid = GetCurrentThreadId();
2501 NETID_DLGINFO *dlginfo;
2503 sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
2505 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2509 } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
2514 dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
2516 if (dlginfo == NULL) {
2521 memset(dlginfo, 0, sizeof(NETID_DLGINFO));
2523 dlginfo->size = sizeof(NETID_DLGINFO);
2524 dlginfo->dlgtype = NETID_DLGTYPE_TGT;
2525 dlginfo->in.use_defaults = 1;
2528 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2530 dlginfo->in.title, NETID_TITLE_SZ);
2531 } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
2532 char mytitle[NETID_TITLE_SZ];
2533 sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
2534 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2536 dlginfo->in.title, NETID_TITLE_SZ);
2538 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2539 "Obtain Kerberos TGT", -1,
2540 dlginfo->in.title, NETID_TITLE_SZ);
2543 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2545 dlginfo->in.username, NETID_USERNAME_SZ);
2547 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2549 dlginfo->in.realm, NETID_REALM_SZ);
2551 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2553 dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
2554 SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
2556 if (out_ccname && out_cclen > 0) {
2557 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1,
2558 out_ccname, out_cclen, NULL, NULL);
2561 UnmapViewOfFile(dlginfo);
2564 acquire_tkt_send_msg_leash(title,
2565 ccachename, desiredName, desiredRealm);
2568 SetForegroundWindow(hForeground);
2569 if (desiredName != NULL)
2570 pkrb5_free_unparsed_name(ctx, desiredName);
2575 static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache)
2577 krb5_cc_cursor cur = NULL;
2580 krb5_error_code code;
2581 BOOL have_tickets = FALSE;
2583 // Don't need the actual ticket.
2584 flags = KRB5_TC_NOTICKET;
2585 code = pkrb5_cc_set_flags(ctx, cache, flags);
2588 code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
2593 while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
2594 if ((!pkrb5_is_config_principal(ctx, creds.server)) &&
2595 ((time_t)(DWORD)creds.times.endtime - time(0) > 0))
2596 have_tickets = TRUE;
2598 pkrb5_free_cred_contents(ctx, &creds);
2600 if (code == KRB5_CC_END) {
2601 code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
2605 code = pkrb5_cc_set_flags(ctx, cache, flags);
2610 return have_tickets;
2614 cc_have_tickets_for_princ(krb5_context ctx,
2616 krb5_principal princ)
2618 krb5_error_code code;
2619 krb5_principal cc_princ = NULL;
2620 BOOL have_tickets = FALSE;
2621 code = pkrb5_cc_get_principal(ctx, cache, &cc_princ);
2625 if (pkrb5_principal_compare(ctx, princ, cc_princ))
2626 have_tickets = cc_have_tickets(ctx, cache);
2629 if (cc_princ != NULL)
2630 pkrb5_free_principal(ctx, cc_princ);
2631 return have_tickets;
2634 static BOOL cc_default_have_tickets(krb5_context ctx)
2636 krb5_ccache cache = NULL;
2637 BOOL have_tickets = FALSE;
2638 if (pkrb5_cc_default(ctx, &cache) == 0)
2639 have_tickets = cc_have_tickets(ctx, cache);
2641 pkrb5_cc_close(ctx, cache);
2642 return have_tickets;
2646 cccol_have_tickets_for_princ(krb5_context ctx,
2647 krb5_principal princ,
2651 krb5_error_code code;
2653 krb5_cccol_cursor cursor;
2654 BOOL have_tickets = FALSE;
2657 code = pkrb5_cccol_cursor_new(ctx, &cursor);
2661 while (!have_tickets &&
2662 !(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&
2664 if (cc_have_tickets_for_princ(ctx, cache, princ)) {
2665 if (pkrb5_cc_get_full_name(ctx, cache, &ccfullname)==0) {
2666 strcpy_s(ccname, cclen, ccfullname);
2667 pkrb5_free_string(ctx, ccfullname);
2668 have_tickets = TRUE;
2671 pkrb5_cc_close(ctx, cache);
2673 pkrb5_cccol_cursor_free(ctx, &cursor);
2676 return have_tickets;
2680 acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
2682 TicketList *list = NULL;
2684 DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
2686 char ccachename[272]="";
2691 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2692 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2697 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2698 gle = GetLastError();
2699 if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) {
2700 const char * ccdef = pkrb5_cc_default_name(ctx);
2701 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2702 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2705 haveTickets = cc_default_have_tickets(ctx);
2706 if ((!haveTickets) &&
2707 dwMsLsaImport && Leash_importable() ) {
2708 // We have the option of importing tickets from the MSLSA
2709 // but should we? Do the tickets in the MSLSA cache belong
2710 // to the default realm used by Leash? Does the default
2711 // ccache name specify a principal name? Only import if we
2712 // aren't going to break the default identity as specified
2713 // by the user in Network Identity Manager.
2717 /* Determine if the default ccachename is principal name. If so, don't
2718 * import the MSLSA: credentials into it unless the names match.
2720 isCCPrinc = (strncmp("API:",ccachename, 4) == 0 && strchr(ccachename, '@'));
2722 if ( dwMsLsaImport == 1 && !isCCPrinc ) { /* always import */
2724 } else if ( dwMsLsaImport ) { /* import when realms match */
2725 krb5_error_code code;
2726 krb5_ccache mslsa_ccache=NULL;
2727 krb5_principal princ = NULL;
2728 char *mslsa_principal = NULL;
2729 char ms_realm[128] = "", *def_realm = NULL, *r;
2732 if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
2735 if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
2738 for ( r=ms_realm, i=0; i<krb5_princ_realm(ctx, princ)->length; r++, i++ ) {
2739 *r = krb5_princ_realm(ctx, princ)->data[i];
2743 if (code = pkrb5_get_default_realm(ctx, &def_realm))
2746 if (code = pkrb5_unparse_name(ctx, princ, &mslsa_principal))
2749 import = (!isCCPrinc && !strcmp(def_realm, ms_realm)) ||
2750 (isCCPrinc && !strcmp(&ccachename[4], mslsa_principal));
2753 if (mslsa_principal)
2754 pkrb5_free_unparsed_name(ctx, mslsa_principal);
2757 pkrb5_free_default_realm(ctx, def_realm);
2760 pkrb5_free_principal(ctx, princ);
2763 pkrb5_cc_close(ctx, mslsa_ccache);
2768 haveTickets = cc_default_have_tickets(ctx);
2772 if ( prompt && !haveTickets ) {
2773 acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen);
2775 * If the ticket manager returned an alternative credential cache
2776 * remember it as the default for this process.
2778 if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) {
2779 SetEnvironmentVariable("KRB5CCNAME",ccname);
2782 } else if (ccachename[0] && ccname) {
2783 strncpy(ccname, ccachename, cclen);
2784 ccname[cclen-1] = '\0';
2787 pkrb5_free_context(ctx);
2792 acquire_tkt_for_princ(krb5_context ctx, krb5_principal desiredPrincipal,
2793 char * ccname, int cclen)
2796 char ccachename[272]="";
2800 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2801 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2804 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2805 gle = GetLastError();
2806 if ((gle == ERROR_ENVVAR_NOT_FOUND || !ccachename[0]) && ctx != NULL) {
2807 const char * ccdef = pkrb5_cc_default_name(ctx);
2808 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2809 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2811 if (!cccol_have_tickets_for_princ(ctx, desiredPrincipal, ccname, cclen)) {
2813 acquire_tkt_send_msg(ctx, NULL,
2814 ccachename, desiredPrincipal, ccname, cclen);
2816 * If the ticket manager returned an alternative credential cache
2817 * remember it as the default for this process.
2819 if (ccname != NULL && ccname[0] &&
2820 strcmp(ccachename, ccname)) {
2821 SetEnvironmentVariable("KRB5CCNAME",ccname);
2829 not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,
2830 krb5_principal desiredKrb5Principal,
2831 char * ccname, int cclen)
2833 if (!desiredKrb5Principal) {
2834 acquire_tkt_no_princ(context, ccname, cclen);
2836 acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen);