7 #include <KerberosIV/krb.h>
10 /* General definitions */
18 #include "leash-int.h"
25 static char FAR *err_context;
27 char KRB_HelpFile[_MAX_PATH] = HELPFILE;
29 #define LEN 64 /* Maximum Hostname Length */
31 #define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */
44 for (p = s; *p; p++) {
47 /* Add more cases here */
71 int size = sizeof(message);
74 // XXX: ignore AFS for now.
79 n = _snprintf(p, size, "%s\n\n", error);
83 if (rc5 && !result_string)
85 n = _snprintf(p, size,
86 "Kerberos 5: %s (error %ld)\n",
88 rc5 & 255 // XXX: & 255??!!!
96 n = _snprintf(p, size,
98 err_describe(buffer, rcL)
105 n = _snprintf(p, size,
111 #ifdef USE_MESSAGE_BOX
113 MessageBox(NULL, message, "Leash", MB_OK | MB_ICONERROR | MB_TASKMODAL |
115 #endif /* USE_MESSAGE_BOX */
126 const char * postfix,
135 base_size = strlen(base) + 1;
136 ret_size = base_size + strlen(postfix) + 1;
137 copy = malloc(base_size);
138 ret = malloc(ret_size);
143 strncpy(copy, base, base_size);
144 copy[base_size - 1] = 0;
146 strncpy(ret, base, base_size);
147 strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1));
148 ret[ret_size - 1] = 0;
158 // INVARIANT: (ret ==> copy) && (copy ==> ret)
166 const char * postfix,
170 static krb5_context ctx = 0;
171 static char * old_cache = 0;
173 // INVARIANT: old_cache ==> ctx && ctx ==> old_cache
178 if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve ||
179 !pkrb5_cc_default_name || !pkrb5_cc_set_default_name)
184 if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc))
185 pkrb5_cc_destroy(ctx, cc);
186 pkrb5_cc_set_default_name(ctx, old_cache);
191 pkrb5_free_context(ctx);
197 char * tmp_cache = 0;
198 krb5_error_code rc = 0;
200 rc = pkrb5_init_context(&ctx);
201 if (rc) goto cleanup;
203 tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix,
211 rc = pkrb5_cc_set_default_name(ctx, tmp_cache);
215 pkrb5_free_context(ctx);
233 return Leash_int_checkpwd(principal, password, 0);
244 krb5_context ctx = 0; // statically allocated in make_temp_cache_v5
245 // XXX - we ignore errors in make_temp_cache_v? This is BAD!!!
246 make_temp_cache_v5("_checkpwd", &ctx);
247 rc = Leash_int_kinit_ex( ctx, 0,
248 principal, password, 0, 0, 0, 0,
249 Leash_get_default_noaddresses(),
250 Leash_get_default_publicip(),
253 make_temp_cache_v5(0, &ctx);
266 krb5_error_code rc = 0;
268 krb5_data result_code_string, result_string;
269 krb5_context context = 0;
270 krb5_principal princ = 0;
271 krb5_get_init_creds_opt opts;
273 DWORD addressless = 0;
275 result_string.data = 0;
276 result_code_string.data = 0;
278 if ( !pkrb5_init_context )
281 if (rc = pkrb5_init_context(&context)) {
283 com_err(argv[0], ret, "initializing kerberos library");
288 if (rc = pkrb5_parse_name(context, principal, &princ)) {
290 com_err(argv[0], ret, "parsing client name");
295 pkrb5_get_init_creds_opt_init(&opts);
296 pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
297 pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
298 pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
299 pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
301 addressless = Leash_get_default_noaddresses();
303 pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
306 if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password,
307 0, 0, 0, "kadmin/changepw", &opts)) {
308 if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
311 "Password incorrect while getting initial ticket");
316 com_err(argv[0], ret, "getting initial ticket");
322 if (rc = pkrb5_change_password(context, &creds, newpassword,
323 &result_code, &result_code_string,
326 com_err(argv[0], ret, "changing password");
332 int len = result_code_string.length +
333 (result_string.length ? (sizeof(": ") - 1) : 0) +
334 result_string.length;
335 if (len && error_str) {
336 *error_str = malloc(len + 1);
338 _snprintf(*error_str, len + 1,
340 result_code_string.length, result_code_string.data,
341 result_string.length?": ":"",
342 result_string.length, result_string.data);
349 if (result_string.data)
350 pkrb5_free_data_contents(context, &result_string);
352 if (result_code_string.data)
353 pkrb5_free_data_contents(context, &result_code_string);
356 pkrb5_free_principal(context, princ);
359 pkrb5_free_context(context);
367 * Try to change the password using krb5.
377 return Leash_int_changepwd(principal, password, newpassword, result_string, 0);
385 char** result_string,
389 char* v5_error_str = 0;
394 rc = rc5 = Leash_changepwd_v5(principal, password, newpassword,
400 char v5_prefix[] = "Kerberos 5: ";
403 clean_string(v5_error_str);
406 len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) +
408 error_str = malloc(len + 1);
414 n = _snprintf(p, size, "%s%s%s%s",
415 sep, v5_prefix, v5_error_str, sep);
420 *result_string = error_str;
423 return leash_error_message("Error while changing password.",
424 0, rc5, 0, error_str,
429 int (*Lcom_err)(LPSTR,long,LPSTR,...);
430 LPSTR (*Lerror_message)(long);
431 LPSTR (*Lerror_table_name)(long);
441 return Leash_int_kinit_ex( 0, 0,
445 Leash_get_default_forwardable(),
446 Leash_get_default_proxiable(),
447 Leash_get_default_renew_till(),
448 Leash_get_default_noaddresses(),
449 Leash_get_default_publicip(),
463 unsigned long publicip
466 return Leash_int_kinit_ex( 0, /* krb5 context */
467 0, /* parent window */
491 unsigned long publicip,
495 char aname[ANAME_SZ];
497 char realm[REALM_SZ];
498 char first_part[256];
499 char second_part[256];
513 if (renew_life > 0 && renew_life < 5)
518 /* This should be changed if the maximum ticket lifetime */
524 err_context = "parsing principal";
526 memset(temp, '\0', sizeof(temp));
527 memset(inst, '\0', sizeof(inst));
528 memset(realm, '\0', sizeof(realm));
529 memset(first_part, '\0', sizeof(first_part));
530 memset(second_part, '\0', sizeof(second_part));
532 sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part);
533 strcpy(temp, first_part);
534 strcpy(realm, second_part);
535 memset(first_part, '\0', sizeof(first_part));
536 memset(second_part, '\0', sizeof(second_part));
537 if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2)
539 strcpy(aname, first_part);
540 strcpy(inst, second_part);
546 for (i = 0; temp[i]; i++)
563 memset(temp, '\0', sizeof(temp));
565 if (strlen(inst) != 0)
570 if (strlen(realm) != 0)
576 rc5 = Leash_krb5_kinit(ctx, hParent,
577 temp, password, lifetime,
589 for ( r=realm, t=temp; c=*r; r++,t++ )
590 *t = isupper(c) ? tolower(c) : c;
593 rcA = Leash_afs_klog("afs", temp, "", lifetime);
594 rcB = Leash_afs_klog("afs", "", "", lifetime);
602 return leash_error_message("Ticket initialization failed.",
611 if ( hKrb5 && !LeashKRB5_renew() ) {
613 lifetime = Leash_get_default_lifetime() / 5;
616 TicketList * list = NULL, * token;
617 not_an_API_LeashAFSGetToken(NULL,&list,NULL);
618 for ( token = list ; token ; token = token->next )
619 Leash_afs_klog("afs", token->realm, "", lifetime);
620 not_an_API_LeashFreeTicketList(&list);
629 GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
633 TOKEN_STATISTICS Stats;
636 PSECURITY_LOGON_SESSION_DATA pSessionData;
640 *ppSessionData = NULL;
642 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
646 Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
647 CloseHandle( TokenHandle );
651 Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData );
652 if ( FAILED(Status) || !pSessionData )
655 *ppSessionData = pSessionData;
659 // IsKerberosLogon() does not validate whether or not there are valid tickets in the
660 // cache. It validates whether or not it is reasonable to assume that if we
661 // attempted to retrieve valid tickets we could do so. Microsoft does not
662 // automatically renew expired tickets. Therefore, the cache could contain
663 // expired or invalid tickets. Microsoft also caches the user's password
664 // and will use it to retrieve new TGTs if the cache is empty and tickets
668 IsKerberosLogon(VOID)
670 PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
671 BOOL Success = FALSE;
673 if ( GetSecurityLogonSessionData(&pSessionData) ) {
674 if ( pSessionData->AuthenticationPackage.Buffer ) {
680 usBuffer = (pSessionData->AuthenticationPackage).Buffer;
681 usLength = (pSessionData->AuthenticationPackage).Length;
684 lstrcpynW (buffer, usBuffer, usLength);
685 lstrcatW (buffer,L"");
686 if ( !lstrcmpW(L"Kerberos",buffer) )
690 pLsaFreeReturnBuffer(pSessionData);
696 IsWindowsVista (void)
698 static BOOL fChecked = FALSE;
699 static BOOL fIsVista = FALSE;
703 OSVERSIONINFO Version;
705 memset (&Version, 0x00, sizeof(Version));
706 Version.dwOSVersionInfoSize = sizeof(Version);
708 if (GetVersionEx (&Version))
710 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)
720 IsProcessUacLimited (void)
722 static BOOL fChecked = FALSE;
723 static BOOL fIsUAC = FALSE;
729 DWORD ElevationLevel;
733 if (IsWindowsVista()) {
734 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
736 Success = GetTokenInformation( TokenHandle,
737 TokenOrigin+1 /* ElevationLevel */,
738 &ElevationLevel, sizeof(DWORD), &ReqLen );
739 CloseHandle( TokenHandle );
740 if ( Success && ElevationLevel == 3 /* Limited */ )
750 // This looks really ugly because it is. The result of IsKerberosLogon()
751 // does not prove whether or not there are Kerberos tickets available to
752 // be imported. Only the call to Leash_ms2mit() which actually attempts
753 // to import tickets can do that. However, calling Leash_ms2mit() can
754 // result in a TGS_REQ being sent to the KDC and since Leash_importable()
755 // is called quite often we want to avoid this if at all possible.
756 // Unfortunately, we have be shown at least one case in which the primary
757 // authentication package was not Kerberos and yet there were Kerberos
758 // tickets available. Therefore, if IsKerberosLogon() is not TRUE we
759 // must call Leash_ms2mit() but we still do not want to call it in a
760 // tight loop so we cache the response and assume it won't change.
763 // And the nightmare goes on. On Vista the Lsa call we use to determine
764 // whether or not Kerberos was used for logon fails to return and worse
765 // corrupts the stack. Therefore, we must now test to see if the
766 // operating system is Vista and skip the call to IsKerberosLogon()
769 Leash_importable(void)
771 if (IsProcessUacLimited())
774 if ( !IsWindowsVista() && IsKerberosLogon() )
777 static int response = -1;
778 if (response == -1) {
779 response = Leash_ms2mit(0);
788 if ( Leash_ms2mit(1) ) {
790 lifetime = Leash_get_default_lifetime() / 5;
802 krb5_context ctx = 0;
803 krb5_error_code code = 0;
805 krb5_principal me = 0;
807 if ( !pkrb5_init_context )
810 code = pkrb5_init_context(&ctx);
811 if (code) goto cleanup;
813 code = pkrb5_cc_default(ctx, &cc);
814 if (code) goto cleanup;
816 if (code = pkrb5_cc_get_principal(ctx, cc, &me))
819 for ( r=realm, t=cell, i=0; i<krb5_princ_realm(ctx, me)->length; r++,t++,i++ ) {
820 c = krb5_princ_realm(ctx, me)->data[i];
822 *t = isupper(c) ? tolower(c) : c;
826 rcA = Leash_afs_klog("afs", cell, "", lifetime);
827 rcB = Leash_afs_klog("afs", "", "", lifetime);
835 pkrb5_free_principal(ctx, me);
837 pkrb5_cc_close(ctx, cc);
839 pkrb5_free_context(ctx);
854 not_an_API_LeashFreeTicketList(TicketList** ticketList)
856 TicketList* tempList = *ticketList, *killList;
858 //if (tempList == NULL)
865 tempList = (TicketList*)tempList->next;
866 free(killList->theTicket);
867 if (killList->tktEncType)
868 free(killList->tktEncType);
869 if (killList->keyEncType)
870 free(killList->keyEncType);
871 if (killList->addrCount) {
873 for ( n=0; n<killList->addrCount; n++) {
874 if (killList->addrList[n])
875 free(killList->addrList[n]);
878 if (killList->addrList)
879 free(killList->addrList);
881 free(killList->name);
883 free(killList->inst);
885 free(killList->realm);
894 not_an_API_LeashKRB4GetTickets(TICKETINFO FAR* ticketinfo,
895 TicketList** ticketList)
900 long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo)
906 // This function can be used to set the help file that will be
907 // referenced the DLL's PasswordProcDLL function and err_describe
908 // function. Returns true if the help file has been set to the
909 // argument or the environment variable KERB_HELP. Returns FALSE if
910 // the default helpfile as defined in by HELPFILE in lsh_pwd.h is
912 BOOL Leash_set_help_file( char *szHelpFile )
914 char tmpHelpFile[256];
917 if( szHelpFile == NULL ){
918 GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile));
920 strcpy( KRB_HelpFile, szHelpFile );
924 if( !ret && tmpHelpFile[0] ){
925 strcpy( KRB_HelpFile, tmpHelpFile );
930 strcpy( KRB_HelpFile, HELPFILE );
938 LPSTR Leash_get_help_file(void)
940 return( KRB_HelpFile);
956 get_profile_file(LPSTR confname, UINT szConfname)
958 char **configFile = NULL;
960 if (pkrb5_get_default_config_files(&configFile) || !configFile[0])
962 GetWindowsDirectory(confname,szConfname);
963 confname[szConfname-1] = '\0';
964 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
965 confname[szConfname-1] = '\0';
973 strncpy(confname, *configFile, szConfname);
974 confname[szConfname-1] = '\0';
975 pkrb5_free_config_files(configFile);
981 GetWindowsDirectory(confname,szConfname);
982 confname[szConfname-1] = '\0';
983 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
984 confname[szConfname-1] = '\0';
990 static const char *const conf_yes[] = {
991 "y", "yes", "true", "t", "1", "on",
995 static const char *const conf_no[] = {
996 "n", "no", "false", "nil", "0", "off",
1001 config_boolean_to_int(const char *s)
1003 const char *const *p;
1005 for(p=conf_yes; *p; p++) {
1006 if (!strcasecmp(*p,s))
1010 for(p=conf_no; *p; p++) {
1011 if (!strcasecmp(*p,s))
1015 /* Default to "no" */
1020 * Leash_get_default_lifetime:
1022 * This function is used to get the default ticket lifetime for this
1023 * process in minutes. A return value of 0 indicates no setting or
1024 * "default" setting obtained.
1026 * Here is where we look in order:
1028 * - LIFETIME environment variable
1029 * - HKCU\Software\MIT\Leash,lifetime
1030 * - HKLM\Software\MIT\Leash,lifetime
1031 * - string resource in the leash DLL
1035 get_DWORD_from_registry(
1046 rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
1050 dwCount = sizeof(DWORD);
1051 rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount);
1054 return rc?FALSE:TRUE;
1058 get_STRING_from_registry(
1070 if (!outbuf || outlen == 0)
1073 rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
1078 rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) outbuf, &dwCount);
1081 return rc?FALSE:TRUE;
1086 get_default_lifetime_from_registry(
1091 return get_DWORD_from_registry(hBaseKey,
1092 LEASH_REGISTRY_KEY_NAME,
1093 LEASH_REGISTRY_VALUE_LIFETIME,
1098 Leash_reset_default_lifetime(
1104 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1108 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME);
1115 Leash_set_default_lifetime(
1122 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1123 0, 0, KEY_WRITE, 0, &hKey, 0);
1127 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD,
1128 (LPBYTE) &minutes, sizeof(DWORD));
1135 Leash_get_default_lifetime(
1143 if (GetEnvironmentVariable("LIFETIME",env,sizeof(env)))
1149 if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) ||
1150 get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result))
1156 CHAR confname[MAX_PATH];
1158 if (!get_profile_file(confname, sizeof(confname)))
1161 const char *filenames[2];
1164 filenames[0] = confname;
1165 filenames[1] = NULL;
1166 if (!pprofile_init(filenames, &profile)) {
1167 char * value = NULL;
1169 retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value);
1170 if (retval == 0 && value) {
1173 retval = pkrb5_string_to_deltat(value, &d);
1175 if (retval == KRB5_DELTAT_BADFORMAT) {
1176 /* Historically some sites use relations of
1177 the form 'ticket_lifetime = 24000' where
1178 the unit is left out but is assumed to be
1179 seconds. Then there are other sites which
1180 use the form 'ticket_lifetime = 600' where
1181 the unit is assumed to be minutes. While
1182 these are technically wrong (a unit needs
1183 to be specified), we try to accomodate for
1184 this using the safe assumption that the
1185 unit is seconds and tack an 's' to the end
1186 and see if that works. */
1188 /* Of course, Leash is one of the platforms
1189 that historically assumed no units and minutes
1190 so this change is going to break some people
1191 but its better to be consistent. */
1196 cch = strlen(value) + 2; /* NUL and new 's' */
1197 if (cch > sizeof(buf))
1203 retval = pkrb5_string_to_deltat(buf, &d);
1209 } else if (retval == 0) {
1213 pprofile_release_string(value);
1215 pprofile_release(profile);
1216 /* value has been released but we can still use a check for
1217 * non-NULL to see if we were able to read a value.
1219 if (retval == 0 && value)
1225 hmLeash = GetModuleHandle(LEASH_DLL);
1229 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE,
1230 lifetime, sizeof(lifetime)))
1232 lifetime[sizeof(lifetime) - 1] = 0;
1233 return atoi(lifetime);
1241 get_default_renew_till_from_registry(
1246 return get_DWORD_from_registry(hBaseKey,
1247 LEASH_REGISTRY_KEY_NAME,
1248 LEASH_REGISTRY_VALUE_RENEW_TILL,
1253 Leash_reset_default_renew_till(
1259 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1263 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL);
1270 Leash_set_default_renew_till(
1277 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1278 0, 0, KEY_WRITE, 0, &hKey, 0);
1282 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD,
1283 (LPBYTE) &minutes, sizeof(DWORD));
1290 Leash_get_default_renew_till(
1297 if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env)))
1302 if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) ||
1303 get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result))
1309 CHAR confname[MAX_PATH];
1310 if (!get_profile_file(confname, sizeof(confname)))
1313 const char *filenames[2];
1316 filenames[0] = confname;
1317 filenames[1] = NULL;
1319 if (!pprofile_init(filenames, &profile)) {
1320 char * value = NULL;
1322 retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value);
1323 if (retval == 0 && value) {
1326 retval = pkrb5_string_to_deltat(value, &d);
1327 if (retval == KRB5_DELTAT_BADFORMAT) {
1328 /* Historically some sites use relations of
1329 the form 'ticket_lifetime = 24000' where
1330 the unit is left out but is assumed to be
1331 seconds. Then there are other sites which
1332 use the form 'ticket_lifetime = 600' where
1333 the unit is assumed to be minutes. While
1334 these are technically wrong (a unit needs
1335 to be specified), we try to accomodate for
1336 this using the safe assumption that the
1337 unit is seconds and tack an 's' to the end
1338 and see if that works. */
1340 /* Of course, Leash is one of the platforms
1341 that historically assumed no units and minutes
1342 so this change is going to break some people
1343 but its better to be consistent. */
1347 cch = strlen(value) + 2; /* NUL and new 's' */
1348 if (cch > sizeof(buf))
1354 retval = pkrb5_string_to_deltat(buf, &d);
1359 } else if (retval == 0) {
1362 pprofile_release_string(value);
1364 pprofile_release(profile);
1365 /* value has been released but we can still use a check for
1366 * non-NULL to see if we were able to read a value.
1368 if (retval == 0 && value)
1371 pprofile_release(profile);
1376 hmLeash = GetModuleHandle(LEASH_DLL);
1379 char renew_till[80];
1380 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL,
1381 renew_till, sizeof(renew_till)))
1383 renew_till[sizeof(renew_till) - 1] = 0;
1384 return atoi(renew_till);
1392 get_default_forwardable_from_registry(
1397 return get_DWORD_from_registry(hBaseKey,
1398 LEASH_REGISTRY_KEY_NAME,
1399 LEASH_REGISTRY_VALUE_FORWARDABLE,
1404 Leash_reset_default_forwardable(
1410 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1414 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE);
1421 Leash_set_default_forwardable(
1428 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1429 0, 0, KEY_WRITE, 0, &hKey, 0);
1433 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD,
1434 (LPBYTE) &minutes, sizeof(DWORD));
1441 Leash_get_default_forwardable(
1449 if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env)))
1454 if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) ||
1455 get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result))
1461 CHAR confname[MAX_PATH];
1462 if (!get_profile_file(confname, sizeof(confname)))
1465 const char *filenames[2];
1468 filenames[0] = confname;
1469 filenames[1] = NULL;
1470 if (!pprofile_init(filenames, &profile)) {
1471 retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value);
1473 result = config_boolean_to_int(value);
1474 pprofile_release_string(value);
1475 pprofile_release(profile);
1478 pprofile_release(profile);
1483 hmLeash = GetModuleHandle(LEASH_DLL);
1486 char forwardable[80];
1487 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD,
1488 forwardable, sizeof(forwardable)))
1490 forwardable[sizeof(forwardable) - 1] = 0;
1491 return atoi(forwardable);
1499 get_default_renewable_from_registry(
1504 return get_DWORD_from_registry(hBaseKey,
1505 LEASH_REGISTRY_KEY_NAME,
1506 LEASH_REGISTRY_VALUE_RENEWABLE,
1511 Leash_reset_default_renewable(
1517 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1521 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE);
1528 Leash_set_default_renewable(
1535 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1536 0, 0, KEY_WRITE, 0, &hKey, 0);
1540 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD,
1541 (LPBYTE) &minutes, sizeof(DWORD));
1548 Leash_get_default_renewable(
1555 if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env)))
1560 if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) ||
1561 get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result))
1567 CHAR confname[MAX_PATH];
1568 if (!get_profile_file(confname, sizeof(confname)))
1571 const char *filenames[2];
1574 filenames[0] = confname;
1575 filenames[1] = NULL;
1576 if (!pprofile_init(filenames, &profile)) {
1577 retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value);
1579 result = config_boolean_to_int(value);
1580 pprofile_release_string(value);
1581 pprofile_release(profile);
1584 pprofile_release(profile);
1589 hmLeash = GetModuleHandle(LEASH_DLL);
1593 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW,
1594 renewable, sizeof(renewable)))
1596 renewable[sizeof(renewable) - 1] = 0;
1597 return atoi(renewable);
1605 get_default_noaddresses_from_registry(
1610 return get_DWORD_from_registry(hBaseKey,
1611 LEASH_REGISTRY_KEY_NAME,
1612 LEASH_REGISTRY_VALUE_NOADDRESSES,
1617 Leash_reset_default_noaddresses(
1623 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1627 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES);
1634 Leash_set_default_noaddresses(
1641 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1642 0, 0, KEY_WRITE, 0, &hKey, 0);
1646 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD,
1647 (LPBYTE) &minutes, sizeof(DWORD));
1654 Leash_get_default_noaddresses(
1662 // if the profile file cannot be opened then the value will be true
1663 // if the noaddresses name cannot be found then the value will be true
1664 // if true in the library, we can't alter it by other means
1665 CHAR confname[MAX_PATH];
1667 if (!get_profile_file(confname, sizeof(confname)))
1670 const char *filenames[2];
1673 filenames[0] = confname;
1674 filenames[1] = NULL;
1675 if (!pprofile_init(filenames, &profile)) {
1676 retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
1678 result = config_boolean_to_int(value);
1679 pprofile_release_string(value);
1681 pprofile_release(profile);
1689 // The library default is false, check other locations
1691 if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env)))
1696 if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) ||
1697 get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result))
1702 hmLeash = GetModuleHandle(LEASH_DLL);
1705 char noaddresses[80];
1706 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS,
1707 noaddresses, sizeof(noaddresses)))
1709 noaddresses[sizeof(noaddresses) - 1] = 0;
1717 get_default_proxiable_from_registry(
1722 return get_DWORD_from_registry(hBaseKey,
1723 LEASH_REGISTRY_KEY_NAME,
1724 LEASH_REGISTRY_VALUE_PROXIABLE,
1729 Leash_reset_default_proxiable(
1735 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1739 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE);
1746 Leash_set_default_proxiable(
1753 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1754 0, 0, KEY_WRITE, 0, &hKey, 0);
1758 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD,
1759 (LPBYTE) &minutes, sizeof(DWORD));
1766 Leash_get_default_proxiable(
1773 if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env)))
1778 if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) ||
1779 get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result))
1785 CHAR confname[MAX_PATH];
1786 if (!get_profile_file(confname, sizeof(confname)))
1789 const char *filenames[2];
1792 filenames[0] = confname;
1793 filenames[1] = NULL;
1794 if (!pprofile_init(filenames, &profile)) {
1795 retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value);
1797 result = config_boolean_to_int(value);
1798 pprofile_release_string(value);
1799 pprofile_release(profile);
1802 pprofile_release(profile);
1807 hmLeash = GetModuleHandle(LEASH_DLL);
1811 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE,
1812 proxiable, sizeof(proxiable)))
1814 proxiable[sizeof(proxiable) - 1] = 0;
1815 return atoi(proxiable);
1823 get_default_publicip_from_registry(
1828 return get_DWORD_from_registry(hBaseKey,
1829 LEASH_REGISTRY_KEY_NAME,
1830 LEASH_REGISTRY_VALUE_PUBLICIP,
1835 Leash_reset_default_publicip(
1841 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1845 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP);
1852 Leash_set_default_publicip(
1859 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1860 0, 0, KEY_WRITE, 0, &hKey, 0);
1864 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD,
1865 (LPBYTE) &minutes, sizeof(DWORD));
1872 Leash_get_default_publicip(
1879 if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env)))
1884 if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) ||
1885 get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result))
1890 hmLeash = GetModuleHandle(LEASH_DLL);
1894 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP,
1895 publicip, sizeof(publicip)))
1897 publicip[sizeof(publicip) - 1] = 0;
1898 return atoi(publicip);
1906 get_default_use_krb4_from_registry(
1911 return get_DWORD_from_registry(hBaseKey,
1912 LEASH_REGISTRY_KEY_NAME,
1913 LEASH_REGISTRY_VALUE_USEKRB4,
1918 Leash_reset_default_use_krb4(
1924 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1928 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_USEKRB4);
1935 Leash_set_default_use_krb4(
1942 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1943 0, 0, KEY_WRITE, 0, &hKey, 0);
1947 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_USEKRB4, 0, REG_DWORD,
1948 (LPBYTE) &minutes, sizeof(DWORD));
1955 Leash_get_default_use_krb4(
1958 return 0; /* don't use krb4 */
1963 get_hide_kinit_options_from_registry(
1968 return get_DWORD_from_registry(hBaseKey,
1969 LEASH_REGISTRY_KEY_NAME,
1970 LEASH_REGISTRY_VALUE_KINIT_OPT,
1975 Leash_reset_hide_kinit_options(
1981 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1985 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT);
1992 Leash_set_hide_kinit_options(
1999 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2000 0, 0, KEY_WRITE, 0, &hKey, 0);
2004 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD,
2005 (LPBYTE) &minutes, sizeof(DWORD));
2012 Leash_get_hide_kinit_options(
2018 if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) ||
2019 get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result))
2024 hmLeash = GetModuleHandle(LEASH_DLL);
2028 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT,
2029 use_krb4, sizeof(use_krb4)))
2031 use_krb4[sizeof(use_krb4) - 1] = 0;
2032 return atoi(use_krb4);
2035 return 0; /* hide unless otherwise indicated */
2042 get_default_life_min_from_registry(
2047 return get_DWORD_from_registry(hBaseKey,
2048 LEASH_REGISTRY_KEY_NAME,
2049 LEASH_REGISTRY_VALUE_LIFE_MIN,
2054 Leash_reset_default_life_min(
2060 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2064 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN);
2071 Leash_set_default_life_min(
2078 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2079 0, 0, KEY_WRITE, 0, &hKey, 0);
2083 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD,
2084 (LPBYTE) &minutes, sizeof(DWORD));
2091 Leash_get_default_life_min(
2097 if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) ||
2098 get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result))
2103 hmLeash = GetModuleHandle(LEASH_DLL);
2107 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN,
2108 use_krb4, sizeof(use_krb4)))
2110 use_krb4[sizeof(use_krb4) - 1] = 0;
2111 return atoi(use_krb4);
2114 return 5; /* 5 minutes */
2119 get_default_life_max_from_registry(
2124 return get_DWORD_from_registry(hBaseKey,
2125 LEASH_REGISTRY_KEY_NAME,
2126 LEASH_REGISTRY_VALUE_LIFE_MAX,
2131 Leash_reset_default_life_max(
2137 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2141 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX);
2148 Leash_set_default_life_max(
2155 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2156 0, 0, KEY_WRITE, 0, &hKey, 0);
2160 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD,
2161 (LPBYTE) &minutes, sizeof(DWORD));
2168 Leash_get_default_life_max(
2174 if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) ||
2175 get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result))
2180 hmLeash = GetModuleHandle(LEASH_DLL);
2184 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX,
2185 use_krb4, sizeof(use_krb4)))
2187 use_krb4[sizeof(use_krb4) - 1] = 0;
2188 return atoi(use_krb4);
2196 get_default_renew_min_from_registry(
2201 return get_DWORD_from_registry(hBaseKey,
2202 LEASH_REGISTRY_KEY_NAME,
2203 LEASH_REGISTRY_VALUE_RENEW_MIN,
2208 Leash_reset_default_renew_min(
2214 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2218 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN);
2225 Leash_set_default_renew_min(
2232 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2233 0, 0, KEY_WRITE, 0, &hKey, 0);
2237 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD,
2238 (LPBYTE) &minutes, sizeof(DWORD));
2245 Leash_get_default_renew_min(
2251 if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) ||
2252 get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result))
2257 hmLeash = GetModuleHandle(LEASH_DLL);
2261 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN,
2262 use_krb4, sizeof(use_krb4)))
2264 use_krb4[sizeof(use_krb4) - 1] = 0;
2265 return atoi(use_krb4);
2268 return 600; /* 10 hours */
2273 get_default_renew_max_from_registry(
2278 return get_DWORD_from_registry(hBaseKey,
2279 LEASH_REGISTRY_KEY_NAME,
2280 LEASH_REGISTRY_VALUE_RENEW_MAX,
2285 Leash_reset_default_renew_max(
2291 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2295 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX);
2302 Leash_set_default_renew_max(
2309 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2310 0, 0, KEY_WRITE, 0, &hKey, 0);
2314 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD,
2315 (LPBYTE) &minutes, sizeof(DWORD));
2322 Leash_get_default_renew_max(
2328 if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) ||
2329 get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result))
2334 hmLeash = GetModuleHandle(LEASH_DLL);
2338 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX,
2339 use_krb4, sizeof(use_krb4)))
2341 use_krb4[sizeof(use_krb4) - 1] = 0;
2342 return atoi(use_krb4);
2345 return 60 * 24 * 30;
2350 get_lock_file_locations_from_registry(
2355 return get_DWORD_from_registry(hBaseKey,
2356 LEASH_REGISTRY_KEY_NAME,
2357 LEASH_REGISTRY_VALUE_LOCK_LOCATION,
2362 Leash_reset_lock_file_locations(
2368 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2372 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION);
2379 Leash_set_lock_file_locations(
2386 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2387 0, 0, KEY_WRITE, 0, &hKey, 0);
2391 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION, 0, REG_DWORD,
2392 (LPBYTE) &onoff, sizeof(DWORD));
2399 Leash_get_lock_file_locations(
2405 if (get_lock_file_locations_from_registry(HKEY_CURRENT_USER, &result) ||
2406 get_lock_file_locations_from_registry(HKEY_LOCAL_MACHINE, &result))
2411 hmLeash = GetModuleHandle(LEASH_DLL);
2414 char lock_file_locations[80];
2415 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LOCK_LOCATION,
2416 lock_file_locations, sizeof(lock_file_locations)))
2418 lock_file_locations[sizeof(lock_file_locations) - 1] = 0;
2419 return atoi(lock_file_locations);
2427 get_default_uppercaserealm_from_registry(
2432 return get_DWORD_from_registry(hBaseKey,
2433 LEASH_SETTINGS_REGISTRY_KEY_NAME,
2434 LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM,
2439 Leash_reset_default_uppercaserealm(
2445 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2449 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM);
2456 Leash_set_default_uppercaserealm(
2463 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
2464 0, 0, KEY_WRITE, 0, &hKey, 0);
2468 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD,
2469 (LPBYTE) &onoff, sizeof(DWORD));
2476 Leash_get_default_uppercaserealm(
2482 if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) ||
2483 get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result))
2488 hmLeash = GetModuleHandle(LEASH_DLL);
2491 char uppercaserealm[80];
2492 if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM,
2493 uppercaserealm, sizeof(uppercaserealm)))
2495 uppercaserealm[sizeof(uppercaserealm) - 1] = 0;
2496 return atoi(uppercaserealm);
2504 get_default_mslsa_import_from_registry(
2509 return get_DWORD_from_registry(hBaseKey,
2510 LEASH_SETTINGS_REGISTRY_KEY_NAME,
2511 LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT,
2516 Leash_reset_default_mslsa_import(
2522 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2526 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT);
2533 Leash_set_default_mslsa_import(
2540 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
2541 0, 0, KEY_WRITE, 0, &hKey, 0);
2545 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT, 0, REG_DWORD,
2546 (LPBYTE) &onoffmatch, sizeof(DWORD));
2553 Leash_get_default_mslsa_import(
2559 if (get_default_mslsa_import_from_registry(HKEY_CURRENT_USER, &result) ||
2560 get_default_mslsa_import_from_registry(HKEY_LOCAL_MACHINE, &result))
2565 hmLeash = GetModuleHandle(LEASH_DLL);
2568 char mslsa_import[80];
2569 if (LoadString(hmLeash, LSH_DEFAULT_MSLSA_IMPORT,
2570 mslsa_import, sizeof(mslsa_import)))
2572 mslsa_import[sizeof(mslsa_import) - 1] = 0;
2573 return atoi(mslsa_import);
2576 return 2; /* import only when mslsa realm matches default */
2582 get_default_preserve_kinit_settings_from_registry(
2587 return get_DWORD_from_registry(hBaseKey,
2588 LEASH_REGISTRY_KEY_NAME,
2589 LEASH_REGISTRY_VALUE_PRESERVE_KINIT,
2594 Leash_reset_default_preserve_kinit_settings(
2600 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2604 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT);
2611 Leash_set_default_preserve_kinit_settings(
2618 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2619 0, 0, KEY_WRITE, 0, &hKey, 0);
2623 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD,
2624 (LPBYTE) &onoff, sizeof(DWORD));
2631 Leash_get_default_preserve_kinit_settings(
2637 if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) ||
2638 get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result))
2643 hmLeash = GetModuleHandle(LEASH_DLL);
2646 char preserve_kinit_settings[80];
2647 if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT,
2648 preserve_kinit_settings, sizeof(preserve_kinit_settings)))
2650 preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0;
2651 return atoi(preserve_kinit_settings);
2658 Leash_reset_defaults(void)
2660 Leash_reset_default_lifetime();
2661 Leash_reset_default_renew_till();
2662 Leash_reset_default_renewable();
2663 Leash_reset_default_forwardable();
2664 Leash_reset_default_noaddresses();
2665 Leash_reset_default_proxiable();
2666 Leash_reset_default_publicip();
2667 Leash_reset_default_use_krb4();
2668 Leash_reset_hide_kinit_options();
2669 Leash_reset_default_life_min();
2670 Leash_reset_default_life_max();
2671 Leash_reset_default_renew_min();
2672 Leash_reset_default_renew_max();
2673 Leash_reset_default_uppercaserealm();
2674 Leash_reset_default_mslsa_import();
2675 Leash_reset_default_preserve_kinit_settings();
2678 static BOOL CALLBACK
2679 EnumChildProc(HWND hwnd, LPARAM lParam)
2681 HWND * h = (HWND *)lParam;
2688 FindFirstChildWindow(HWND parent)
2690 HWND hFirstChild = 0;
2691 EnumChildWindows(parent, EnumChildProc, (LPARAM) &hFirstChild);
2696 acquire_tkt_send_msg(krb5_context ctx, const char * title,
2697 const char * ccachename,
2698 krb5_principal desiredKrb5Principal,
2699 char * out_ccname, int out_cclen)
2701 krb5_error_code err;
2704 char *desiredName = 0;
2705 char *desiredRealm = 0;
2707 /* do we want a specific client principal? */
2708 if (desiredKrb5Principal != NULL) {
2709 err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName);
2712 for (p = desiredName; *p && *p != '@'; p++);
2720 hForeground = GetForegroundWindow();
2721 hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
2722 if (hNetIdMgr != NULL) {
2724 DWORD tid = GetCurrentThreadId();
2726 NETID_DLGINFO *dlginfo;
2728 sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
2730 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2734 } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
2739 dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
2741 if (dlginfo == NULL) {
2746 memset(dlginfo, 0, sizeof(NETID_DLGINFO));
2748 dlginfo->size = sizeof(NETID_DLGINFO);
2749 dlginfo->dlgtype = NETID_DLGTYPE_TGT;
2750 dlginfo->in.use_defaults = 1;
2753 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2755 dlginfo->in.title, NETID_TITLE_SZ);
2756 } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
2757 char mytitle[NETID_TITLE_SZ];
2758 sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
2759 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2761 dlginfo->in.title, NETID_TITLE_SZ);
2763 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2764 "Obtain Kerberos TGT", -1,
2765 dlginfo->in.title, NETID_TITLE_SZ);
2768 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2770 dlginfo->in.username, NETID_USERNAME_SZ);
2772 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2774 dlginfo->in.realm, NETID_REALM_SZ);
2776 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2778 dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
2779 SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
2781 if (out_ccname && out_cclen > 0) {
2782 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1,
2783 out_ccname, out_cclen, NULL, NULL);
2786 UnmapViewOfFile(dlginfo);
2790 HWND hLeash = FindWindow("LEASH.0WNDCLASS", NULL);
2791 hLeash = FindFirstChildWindow(hLeash);
2793 /* construct a marshalling of data
2794 * <title><principal><realm><ccache>
2795 * then send to Leash
2798 hData = GlobalAlloc( GHND, 4096 );
2799 SetForegroundWindow(hLeash);
2800 if ( hData && hLeash ) {
2801 char * strs = GlobalLock(hData);
2804 strcpy(strs, title);
2805 else if (desiredName)
2806 sprintf(strs, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
2808 strcpy(strs, "Obtain Kerberos TGT");
2809 strs += strlen(strs) + 1;
2810 if ( desiredName ) {
2811 strcpy(strs, desiredName);
2812 strs += strlen(strs) + 1;
2814 strcpy(strs, desiredRealm);
2815 strs += strlen(strs) + 1;
2824 /* Append the ccache name */
2826 strcpy(strs, ccachename);
2831 GlobalUnlock( hData );
2832 SendMessage(hLeash, 32810, 0, (LPARAM) hData);
2835 GlobalFree( hData );
2838 SetForegroundWindow(hForeground);
2839 if (desiredName != NULL)
2840 pkrb5_free_unparsed_name(ctx, desiredName);
2846 acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
2848 TicketList *list = NULL;
2849 TICKETINFO ticketinfo;
2851 DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
2853 char ccachename[272]="";
2857 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2858 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2863 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2864 gle = GetLastError();
2865 if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) {
2866 const char * ccdef = pkrb5_cc_default_name(ctx);
2867 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2868 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2871 not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
2872 not_an_API_LeashFreeTicketList(&list);
2874 if ( ticketinfo.btickets != GOOD_TICKETS &&
2875 dwMsLsaImport && Leash_importable() ) {
2876 // We have the option of importing tickets from the MSLSA
2877 // but should we? Do the tickets in the MSLSA cache belong
2878 // to the default realm used by Leash? Does the default
2879 // ccache name specify a principal name? Only import if we
2880 // aren't going to break the default identity as specified
2881 // by the user in Network Identity Manager.
2885 /* Determine if the default ccachename is principal name. If so, don't
2886 * import the MSLSA: credentials into it unless the names match.
2888 isCCPrinc = (strncmp("API:",ccachename, 4) == 0 && strchr(ccachename, '@'));
2890 if ( dwMsLsaImport == 1 && !isCCPrinc ) { /* always import */
2892 } else if ( dwMsLsaImport ) { /* import when realms match */
2893 krb5_error_code code;
2894 krb5_ccache mslsa_ccache=NULL;
2895 krb5_principal princ = NULL;
2896 char *mslsa_principal = NULL;
2897 char ms_realm[128] = "", *def_realm = NULL, *r;
2900 if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
2903 if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
2906 for ( r=ms_realm, i=0; i<krb5_princ_realm(ctx, princ)->length; r++, i++ ) {
2907 *r = krb5_princ_realm(ctx, princ)->data[i];
2911 if (code = pkrb5_get_default_realm(ctx, &def_realm))
2914 if (code = pkrb5_unparse_name(ctx, princ, &mslsa_principal))
2917 import = (!isCCPrinc && !strcmp(def_realm, ms_realm)) ||
2918 (isCCPrinc && !strcmp(&ccachename[4], mslsa_principal));
2921 if (mslsa_principal)
2922 pkrb5_free_unparsed_name(ctx, mslsa_principal);
2925 pkrb5_free_default_realm(ctx, def_realm);
2928 pkrb5_free_principal(ctx, princ);
2931 pkrb5_cc_close(ctx, mslsa_ccache);
2937 not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
2938 not_an_API_LeashFreeTicketList(&list);
2942 if ( prompt && ticketinfo.btickets != GOOD_TICKETS ) {
2943 acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen);
2945 * If the ticket manager returned an alternative credential cache
2946 * remember it as the default for this process.
2948 if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) {
2949 SetEnvironmentVariable("KRB5CCNAME",ccname);
2952 } else if (ccachename[0] && ccname) {
2953 strncpy(ccname, ccachename, cclen);
2954 ccname[cclen-1] = '\0';
2958 pkrb5_free_context(ctx);
2963 acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
2964 char * ccname, int cclen)
2966 TicketList *list = NULL;
2967 TICKETINFO ticketinfo;
2969 DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
2971 char ccachename[272]="";
2976 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2977 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2982 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2983 gle = GetLastError();
2984 if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) {
2985 const char * ccdef = pkrb5_cc_default_name(ctx);
2986 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2987 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2990 not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
2991 not_an_API_LeashFreeTicketList(&list);
2993 pkrb5_unparse_name(ctx, desiredPrincipal, &name);
2995 if ( ticketinfo.btickets != GOOD_TICKETS &&
2996 dwMsLsaImport && Leash_importable() ) {
2997 // We have the option of importing tickets from the MSLSA
2998 // but should we? Does the MSLSA principal match the requested
2999 // principal? If not, there is no benefit to importing.
3001 krb5_error_code code;
3002 krb5_ccache mslsa_ccache=NULL;
3003 krb5_principal princ = NULL;
3005 if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
3008 if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
3011 import = pkrb5_principal_compare(ctx, desiredPrincipal, princ);
3015 pkrb5_free_principal(ctx, princ);
3018 pkrb5_cc_close(ctx, mslsa_ccache);
3022 /* Construct a new default ccache name into which the MSLSA:
3023 * credentials can be imported, set the default ccache to that
3024 * ccache, and then only import if that ccache does not already
3025 * contain valid tickets */
3026 sprintf(ccachename, "API:%s", name);
3028 SetEnvironmentVariable("KRB5CCNAME", ccachename);
3030 not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
3031 not_an_API_LeashFreeTicketList(&list);
3033 if (ticketinfo.btickets != GOOD_TICKETS) {
3036 not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
3037 not_an_API_LeashFreeTicketList(&list);
3043 if (ticketinfo.btickets != GOOD_TICKETS || strcmp(name,ticketinfo.principal)) {
3044 acquire_tkt_send_msg(ctx, NULL, ccachename, desiredPrincipal, ccname, cclen);
3046 * If the ticket manager returned an alternative credential cache
3047 * remember it as the default for this process.
3049 if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) {
3050 SetEnvironmentVariable("KRB5CCNAME",ccname);
3052 } else if (ccachename[0] && ccname) {
3053 strncpy(ccname, ccachename, cclen);
3054 ccname[cclen-1] = '\0';
3059 pkrb5_free_unparsed_name(ctx, name);
3062 pkrb5_free_context(ctx);
3067 leash_int_get_princ_expiration_time(krb5_context ctx, krb5_ccache cc,
3068 krb5_principal desiredPrincipal,
3069 krb5_timestamp * pexpiration)
3071 krb5_principal principal = 0;
3072 char * princ_name = NULL;
3073 char * desired_name = NULL;
3075 krb5_error_code code, code2;
3076 krb5_error_code cc_code;
3078 krb5_timestamp now, expiration = 0;
3082 if (!ctx || !cc || !desiredPrincipal || !pexpiration)
3085 code = pkrb5_cc_get_principal(ctx, cc, &principal);
3090 code = pkrb5_unparse_name(ctx, desiredPrincipal, &desired_name);
3091 code2 = pkrb5_unparse_name(ctx, principal, &princ_name);
3093 /* compare principal to ident. */
3094 if ( code || !princ_name || code2 || !desired_name ||
3095 strcmp(princ_name, desired_name) ) {
3097 pkrb5_free_unparsed_name(ctx, princ_name);
3099 pkrb5_free_unparsed_name(ctx, desired_name);
3100 pkrb5_free_principal(ctx, principal);
3104 pkrb5_free_unparsed_name(ctx, princ_name);
3105 pkrb5_free_unparsed_name(ctx, desired_name);
3106 pkrb5_free_principal(ctx, principal);
3108 code = pkrb5_timeofday(ctx, &now);
3113 cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);
3115 while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
3116 krb5_data * c0 = krb5_princ_name(ctx, creds.server);
3117 krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1);
3118 krb5_data * r = krb5_princ_realm(ctx, creds.server);
3120 if ( c0 && c1 && r && c1->length == r->length &&
3121 !strncmp(c1->data,r->data,r->length) &&
3122 !strncmp("krbtgt",c0->data,c0->length) ) {
3124 /* we have a TGT, check for the expiration time.
3125 * if it is valid and renewable, use the renew time
3128 if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
3129 creds.times.starttime < now && creds.times.endtime > now) {
3130 expiration = creds.times.endtime;
3132 if ((creds.ticket_flags & TKT_FLG_RENEWABLE) &&
3133 (creds.times.renew_till > creds.times.endtime)) {
3134 expiration = creds.times.renew_till;
3140 if (cc_code == KRB5_CC_END) {
3141 cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
3143 *pexpiration = expiration;
3149 /* returns 0 on success */
3151 leash_int_find_ccache_for_princ(krb5_context ctx, krb5_principal princ,
3152 char * buffer, int * pcbbuf)
3154 krb5_ccache cache = 0;
3155 krb5_error_code code;
3157 struct _infoNC ** pNCi = NULL;
3159 krb5_timestamp expiration = 0;
3160 krb5_timestamp best_match_expiration = 0;
3161 char best_match_ccname[256] = "";
3162 DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
3164 if (!buffer || !pcbbuf)
3167 code = cc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
3171 code = cc_get_NC_info(cc_ctx, &pNCi);
3175 for(i=0; pNCi[i]; i++) {
3176 if (pNCi[i]->vers != CC_CRED_V5)
3179 code = pkrb5_cc_resolve(ctx, pNCi[i]->name, &cache);
3183 /* need a function to check the cache for the identity
3184 * and determine if it has valid tickets. If it has
3185 * the right identity and valid tickets, store the
3186 * expiration time and the cache name. If it has the
3187 * right identity but no valid tickets, store the ccache
3188 * name and an expiration time of zero. if it does not
3189 * have the right identity don't save the name.
3191 * Keep searching to find the best cache available.
3194 if (!leash_int_get_princ_expiration_time(ctx, cache, princ,
3196 if ( expiration > best_match_expiration ) {
3197 best_match_expiration = expiration;
3198 strncpy(best_match_ccname, "API:",
3199 sizeof(best_match_ccname));
3200 strncat(best_match_ccname, pNCi[i]->name,
3201 sizeof(best_match_ccname));
3202 best_match_ccname[sizeof(best_match_ccname)-1] = '\0';
3207 if(ctx != NULL && cache != NULL)
3208 pkrb5_cc_close(ctx, cache);
3212 if (dwMsLsaImport) {
3213 code = pkrb5_cc_resolve(ctx, "MSLSA:", &cache);
3214 if (code == 0 && cache) {
3215 if (!leash_int_get_princ_expiration_time(ctx, cache, princ,
3217 if ( expiration > best_match_expiration ) {
3218 best_match_expiration = expiration;
3219 strcpy(best_match_ccname, "MSLSA:");
3226 if (ctx != NULL && cache != NULL)
3227 pkrb5_cc_close(ctx, cache);
3233 cc_free_NC_info(cc_ctx, &pNCi);
3236 cc_shutdown(&cc_ctx);
3238 if (best_match_ccname[0]) {
3239 strncpy(buffer, best_match_ccname, *pcbbuf);
3240 buffer[*pcbbuf-1]='\0';
3242 *pcbbuf = strlen(buffer) + 1;
3250 not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,
3251 krb5_principal desiredKrb5Principal,
3252 char * ccname, int cclen)
3254 char *desiredName = 0;
3255 char *desiredRealm = 0;
3256 TicketList *list = NULL;
3257 char ccachename[272]="";
3259 if (!desiredKrb5Principal) {
3260 acquire_tkt_no_princ(context, ccname, cclen);
3262 if (leash_int_find_ccache_for_princ(context, desiredKrb5Principal, ccname, &cclen))
3263 acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen);