Path: blob/main/crypto/krb5/src/windows/leashdll/lshfunc.c
34914 views
#include <windows.h>1#include <stdio.h>2#include <sys/types.h>3#include <winsock2.h>4#include "leashdll.h"5#include <time.h>67#include <leashwin.h>8#include "leasherr.h"9#include "leash-int.h"10#include "leashids.h"1112#include "reminder.h"1314static char FAR *err_context;1516char KRB_HelpFile[_MAX_PATH] = HELPFILE;1718#define LEN 64 /* Maximum Hostname Length */1920#define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */2122static23char*24clean_string(25char* s26)27{28char* p = s;29char* b = s;3031if (!s) return s;3233for (p = s; *p; p++) {34switch (*p) {35case '\007':36/* Add more cases here */37break;38default:39*b = *p;40b++;41}42}43*b = *p;44return s;45}4647static48int49leash_error_message(50const char *error,51int rcL,52int rc5,53int rcA,54char* result_string,55int displayMB56)57{58char message[2048];59char *p = message;60int size = sizeof(message) - 1; /* -1 to leave room for NULL terminator */61int n;6263if (!rc5 && !rcL)64return 0;6566n = _snprintf(p, size, "%s\n\n", error);67p += n;68size -= n;6970if (rc5 && !result_string)71{72n = _snprintf(p, size,73"Kerberos 5: %s (error %ld)\n",74perror_message(rc5),75rc576);77p += n;78size -= n;79}80if (rcL)81{82char buffer[1024];83n = _snprintf(p, size,84"\n%s\n",85err_describe(buffer, rcL)86);87p += n;88size -= n;89}90if (result_string)91{92n = _snprintf(p, size,93"%s\n",94result_string);95p += n;96size -= n;97}98#ifdef USE_MESSAGE_BOX99*p = 0; /* ensure NULL termination of message */100if ( displayMB )101MessageBox(NULL, message, "MIT Kerberos",102MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);103#endif /* USE_MESSAGE_BOX */104if (rc5) return rc5;105if (rcL) return rcL;106return 0;107}108109110static111char *112make_postfix(113const char * base,114const char * postfix,115char ** rcopy116)117{118int base_size;119int ret_size;120char * copy = 0;121char * ret = 0;122123base_size = strlen(base) + 1;124ret_size = base_size + strlen(postfix) + 1;125copy = malloc(base_size);126ret = malloc(ret_size);127128if (!copy || !ret)129goto cleanup;130131strncpy(copy, base, base_size);132copy[base_size - 1] = 0;133134strncpy(ret, base, base_size);135strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1));136ret[ret_size - 1] = 0;137138cleanup:139if (!copy || !ret) {140if (copy)141free(copy);142if (ret)143free(ret);144copy = ret = 0;145}146// INVARIANT: (ret ==> copy) && (copy ==> ret)147*rcopy = copy;148return ret;149}150151static152long153make_temp_cache_v5(154const char * postfix,155krb5_context * pctx156)157{158static krb5_context ctx = 0;159static char * old_cache = 0;160161// INVARIANT: old_cache ==> ctx && ctx ==> old_cache162163if (pctx)164*pctx = 0;165166if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve ||167!pkrb5_cc_default_name || !pkrb5_cc_set_default_name)168return 0;169170if (old_cache) {171krb5_ccache cc = 0;172if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc))173pkrb5_cc_destroy(ctx, cc);174pkrb5_cc_set_default_name(ctx, old_cache);175free(old_cache);176old_cache = 0;177}178if (ctx) {179pkrb5_free_context(ctx);180ctx = 0;181}182183if (postfix)184{185char * tmp_cache = 0;186krb5_error_code rc = 0;187188rc = pkrb5_init_context(&ctx);189if (rc) goto cleanup;190191tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix,192&old_cache);193194if (!tmp_cache) {195rc = ENOMEM;196goto cleanup;197}198199rc = pkrb5_cc_set_default_name(ctx, tmp_cache);200201cleanup:202if (rc && ctx) {203pkrb5_free_context(ctx);204ctx = 0;205}206if (tmp_cache)207free(tmp_cache);208if (pctx)209*pctx = ctx;210return rc;211}212return 0;213}214215long216Leash_checkpwd(217char *principal,218char *password219)220{221return Leash_int_checkpwd(principal, password, 0);222}223224long225Leash_int_checkpwd(226char * principal,227char * password,228int displayErrors229)230{231long rc = 0;232krb5_context ctx = 0; // statically allocated in make_temp_cache_v5233// XXX - we ignore errors in make_temp_cache_v? This is BAD!!!234make_temp_cache_v5("_checkpwd", &ctx);235rc = Leash_int_kinit_ex( ctx, 0,236principal, password, 0, 0, 0, 0,237Leash_get_default_noaddresses(),238Leash_get_default_publicip(),239displayErrors240);241make_temp_cache_v5(0, &ctx);242return rc;243}244245static246long247Leash_changepwd_v5(248char * principal,249char * password,250char * newpassword,251char** error_str252)253{254krb5_error_code rc = 0;255int result_code;256krb5_data result_code_string, result_string;257krb5_context context = 0;258krb5_principal princ = 0;259krb5_get_init_creds_opt opts;260krb5_creds creds;261DWORD addressless = 0;262263result_string.data = 0;264result_code_string.data = 0;265266if ( !pkrb5_init_context )267goto cleanup;268269if (rc = pkrb5_init_context(&context))270goto cleanup;271272if (rc = pkrb5_parse_name(context, principal, &princ))273goto cleanup;274275pkrb5_get_init_creds_opt_init(&opts);276pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);277pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);278pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);279pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);280281addressless = Leash_get_default_noaddresses();282if (addressless)283pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);284285286if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password,2870, 0, 0, "kadmin/changepw", &opts))288goto cleanup;289290if (rc = pkrb5_change_password(context, &creds, newpassword,291&result_code, &result_code_string,292&result_string))293goto cleanup;294295if (result_code) {296int len = result_code_string.length +297(result_string.length ? (sizeof(": ") - 1) : 0) +298result_string.length;299if (len && error_str) {300*error_str = malloc(len + 1);301if (*error_str)302_snprintf(*error_str, len + 1,303"%.*s%s%.*s",304result_code_string.length, result_code_string.data,305result_string.length?": ":"",306result_string.length, result_string.data);307}308rc = result_code;309goto cleanup;310}311312cleanup:313if (result_string.data)314pkrb5_free_data_contents(context, &result_string);315316if (result_code_string.data)317pkrb5_free_data_contents(context, &result_code_string);318319if (princ)320pkrb5_free_principal(context, princ);321322if (context)323pkrb5_free_context(context);324325return rc;326}327328/*329* Leash_changepwd330*331* Try to change the password using krb5.332*/333long334Leash_changepwd(335char * principal,336char * password,337char * newpassword,338char** result_string339)340{341return Leash_int_changepwd(principal, password, newpassword, result_string, 0);342}343344long345Leash_int_changepwd(346char * principal,347char * password,348char * newpassword,349char** result_string,350int displayErrors351)352{353char* v5_error_str = 0;354char* error_str = 0;355int rc5 = 0;356int rc = 0;357if (hKrb5)358rc = rc5 = Leash_changepwd_v5(principal, password, newpassword,359&v5_error_str);360if (!rc)361return 0;362if (v5_error_str) {363int len = 0;364char v5_prefix[] = "Kerberos 5: ";365char sep[] = "\n";366367clean_string(v5_error_str);368369if (v5_error_str)370len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) +371sizeof(sep);372error_str = malloc(len + 1);373if (error_str) {374char* p = error_str;375int size = len + 1;376int n;377if (v5_error_str) {378n = _snprintf(p, size, "%s%s%s%s",379sep, v5_prefix, v5_error_str, sep);380p += n;381size -= n;382}383if (result_string)384*result_string = error_str;385}386}387return leash_error_message("Error while changing password.",3880, rc5, 0, error_str,389displayErrors390);391}392393int (*Lcom_err)(LPSTR,long,LPSTR,...);394LPSTR (*Lerror_message)(long);395LPSTR (*Lerror_table_name)(long);396397398long399Leash_kinit(400char * principal,401char * password,402int lifetime403)404{405return Leash_int_kinit_ex( 0, 0,406principal,407password,408lifetime,409Leash_get_default_forwardable(),410Leash_get_default_proxiable(),411Leash_get_default_renew_till(),412Leash_get_default_noaddresses(),413Leash_get_default_publicip(),4140415);416}417418long419Leash_kinit_ex(420char * principal,421char * password,422int lifetime,423int forwardable,424int proxiable,425int renew_life,426int addressless,427unsigned long publicip428)429{430return Leash_int_kinit_ex( 0, /* krb5 context */4310, /* parent window */432principal,433password,434lifetime,435forwardable,436proxiable,437renew_life,438addressless,439publicip,4400441);442}443444long445Leash_int_kinit_ex(446krb5_context ctx,447HWND hParent,448char * principal,449char * password,450int lifetime,451int forwardable,452int proxiable,453int renew_life,454int addressless,455unsigned long publicip,456int displayErrors457)458{459char aname[ANAME_SZ];460char inst[INST_SZ];461char realm[REALM_SZ];462char first_part[256];463char second_part[256];464char temp[1024];465char* custom_msg;466int count;467int i;468int rc5 = 0;469int rcA = 0;470int rcB = 0;471int rcL = 0;472473if (lifetime < 5)474lifetime = 1;475else476lifetime /= 5;477478if (renew_life > 0 && renew_life < 5)479renew_life = 1;480else481renew_life /= 5;482483/* This should be changed if the maximum ticket lifetime */484/* changes */485486if (lifetime > 255)487lifetime = 255;488489err_context = "parsing principal";490491memset(temp, '\0', sizeof(temp));492memset(inst, '\0', sizeof(inst));493memset(realm, '\0', sizeof(realm));494memset(first_part, '\0', sizeof(first_part));495memset(second_part, '\0', sizeof(second_part));496497sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part);498strcpy(temp, first_part);499strcpy(realm, second_part);500memset(first_part, '\0', sizeof(first_part));501memset(second_part, '\0', sizeof(second_part));502if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2)503{504strcpy(aname, first_part);505strcpy(inst, second_part);506}507else508{509count = 0;510i = 0;511for (i = 0; temp[i]; i++)512{513if (temp[i] == '.')514++count;515}516if (count > 1)517{518strcpy(aname, temp);519}520else521{522{523strcpy(aname, temp);524}525}526}527528memset(temp, '\0', sizeof(temp));529strcpy(temp, aname);530if (strlen(inst) != 0)531{532strcat(temp, "/");533strcat(temp, inst);534}535if (strlen(realm) != 0)536{537strcat(temp, "@");538strcat(temp, realm);539}540541rc5 = Leash_krb5_kinit(ctx, hParent,542temp, password, lifetime,543forwardable,544proxiable,545renew_life,546addressless,547publicip548);549custom_msg = (rc5 == KRB5KRB_AP_ERR_BAD_INTEGRITY) ? "Password incorrect" : NULL;550return leash_error_message("Ticket initialization failed.",551rcL, rc5, rcA, custom_msg,552displayErrors);553}554555long FAR556Leash_renew(void)557{558if ( hKrb5 && !LeashKRB5_renew() ) {559int lifetime;560lifetime = Leash_get_default_lifetime() / 5;561return 1;562}563return 0;564}565566BOOL567GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)568{569NTSTATUS Status = 0;570HANDLE TokenHandle;571TOKEN_STATISTICS Stats;572DWORD ReqLen;573BOOL Success;574PSECURITY_LOGON_SESSION_DATA pSessionData;575576if (!ppSessionData)577return FALSE;578*ppSessionData = NULL;579580Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );581if ( !Success )582return FALSE;583584Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );585CloseHandle( TokenHandle );586if ( !Success )587return FALSE;588589Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData );590if ( FAILED(Status) || !pSessionData )591return FALSE;592593*ppSessionData = pSessionData;594return TRUE;595}596597// IsKerberosLogon() does not validate whether or not there are valid tickets in the598// cache. It validates whether or not it is reasonable to assume that if we599// attempted to retrieve valid tickets we could do so. Microsoft does not600// automatically renew expired tickets. Therefore, the cache could contain601// expired or invalid tickets. Microsoft also caches the user's password602// and will use it to retrieve new TGTs if the cache is empty and tickets603// are requested.604605BOOL606IsKerberosLogon(VOID)607{608PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;609BOOL Success = FALSE;610611if ( GetSecurityLogonSessionData(&pSessionData) ) {612if ( pSessionData->AuthenticationPackage.Buffer ) {613WCHAR buffer[256];614WCHAR *usBuffer;615int usLength;616617Success = FALSE;618usBuffer = (pSessionData->AuthenticationPackage).Buffer;619usLength = (pSessionData->AuthenticationPackage).Length;620if (usLength < 256)621{622lstrcpynW (buffer, usBuffer, usLength);623lstrcatW (buffer,L"");624if ( !lstrcmpW(L"Kerberos",buffer) )625Success = TRUE;626}627}628pLsaFreeReturnBuffer(pSessionData);629}630return Success;631}632633static BOOL634IsWindowsVista (void)635{636static BOOL fChecked = FALSE;637static BOOL fIsVista = FALSE;638639if (!fChecked)640{641OSVERSIONINFO Version;642643memset (&Version, 0x00, sizeof(Version));644Version.dwOSVersionInfoSize = sizeof(Version);645646if (GetVersionEx (&Version))647{648if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)649fIsVista = TRUE;650}651fChecked = TRUE;652}653654return fIsVista;655}656657static BOOL658IsProcessUacLimited (void)659{660static BOOL fChecked = FALSE;661static BOOL fIsUAC = FALSE;662663if (!fChecked)664{665NTSTATUS Status = 0;666HANDLE TokenHandle;667DWORD ElevationLevel;668DWORD ReqLen;669BOOL Success;670671if (IsWindowsVista()) {672Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );673if ( Success ) {674Success = GetTokenInformation( TokenHandle,675TokenOrigin+1 /* ElevationLevel */,676&ElevationLevel, sizeof(DWORD), &ReqLen );677CloseHandle( TokenHandle );678if ( Success && ElevationLevel == 3 /* Limited */ )679fIsUAC = TRUE;680}681}682fChecked = TRUE;683}684return fIsUAC;685686}687688long FAR689Leash_importable(void)690{691/* Import functionality has been removed. */692return FALSE;693}694695long FAR696Leash_import(void)697{698/* Import functionality has been removed. */699return 0;700}701702long703Leash_kdestroy(void)704{705Leash_krb5_kdestroy();706707return 0;708}709710long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo)711{712return(255);713}714715716// This function can be used to set the help file that will be717// referenced the DLL's PasswordProcDLL function and err_describe718// function. Returns true if the help file has been set to the719// argument or the environment variable KERB_HELP. Returns FALSE if720// the default helpfile as defined in by HELPFILE in lsh_pwd.h is721// used.722BOOL Leash_set_help_file( char *szHelpFile )723{724char tmpHelpFile[256];725BOOL ret = 0;726727if( szHelpFile == NULL ){728GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile));729} else {730strcpy( KRB_HelpFile, szHelpFile );731ret++;732}733734if( !ret && tmpHelpFile[0] ){735strcpy( KRB_HelpFile, tmpHelpFile );736ret++;737}738739if( !ret){740strcpy( KRB_HelpFile, HELPFILE );741}742743return(ret);744}745746747748LPSTR Leash_get_help_file(void)749{750return( KRB_HelpFile);751}752753int754Leash_debug(755int class,756int priority,757char* fmt, ...758)759{760761return 0;762}763764765static int766get_profile_file(LPSTR confname, UINT szConfname)767{768char **configFile = NULL;769if (hKrb5) {770if (pkrb5_get_default_config_files(&configFile) || !configFile[0])771{772GetWindowsDirectory(confname,szConfname);773confname[szConfname-1] = '\0';774strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));775confname[szConfname-1] = '\0';776return FALSE;777}778779*confname = 0;780781if (configFile)782{783strncpy(confname, *configFile, szConfname);784confname[szConfname-1] = '\0';785pkrb5_free_config_files(configFile);786}787}788789if (!*confname)790{791GetWindowsDirectory(confname,szConfname);792confname[szConfname-1] = '\0';793strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));794confname[szConfname-1] = '\0';795}796797return FALSE;798}799800static const char *const conf_yes[] = {801"y", "yes", "true", "t", "1", "on",8020,803};804805static const char *const conf_no[] = {806"n", "no", "false", "nil", "0", "off",8070,808};809810int811config_boolean_to_int(const char *s)812{813const char *const *p;814815for(p=conf_yes; *p; p++) {816if (!strcasecmp(*p,s))817return 1;818}819820for(p=conf_no; *p; p++) {821if (!strcasecmp(*p,s))822return 0;823}824825/* Default to "no" */826return 0;827}828829/*830* Leash_get_default_lifetime:831*832* This function is used to get the default ticket lifetime for this833* process in minutes. A return value of 0 indicates no setting or834* "default" setting obtained.835*836* Here is where we look in order:837*838* - LIFETIME environment variable839* - HKCU\Software\MIT\Leash,lifetime840* - HKLM\Software\MIT\Leash,lifetime841* - string resource in the leash DLL842*/843844static BOOL845get_DWORD_from_registry(846HKEY hBaseKey,847char * key,848char * value,849DWORD * result850)851{852HKEY hKey;853DWORD dwCount;854LONG rc;855856rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);857if (rc)858return FALSE;859860dwCount = sizeof(DWORD);861rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount);862RegCloseKey(hKey);863864return rc?FALSE:TRUE;865}866867static868BOOL869get_default_lifetime_from_registry(870HKEY hBaseKey,871DWORD * result872)873{874return get_DWORD_from_registry(hBaseKey,875LEASH_REGISTRY_KEY_NAME,876LEASH_REGISTRY_VALUE_LIFETIME,877result);878}879880DWORD881Leash_reset_default_lifetime(882)883{884HKEY hKey;885LONG rc;886887rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);888if (rc)889return rc;890891rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME);892RegCloseKey(hKey);893894return rc;895}896897DWORD898Leash_set_default_lifetime(899DWORD minutes900)901{902HKEY hKey;903LONG rc;904905rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,9060, 0, KEY_WRITE, 0, &hKey, 0);907if (rc)908return rc;909910rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD,911(LPBYTE) &minutes, sizeof(DWORD));912RegCloseKey(hKey);913914return rc;915}916917DWORD918Leash_get_default_lifetime(919)920{921HMODULE hmLeash;922char env[32];923DWORD result;924925926if (GetEnvironmentVariable("LIFETIME",env,sizeof(env)))927{928return atoi(env);929}930931932if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) ||933get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result))934{935return result;936}937938if ( hKrb5 ) {939CHAR confname[MAX_PATH];940941if (!get_profile_file(confname, sizeof(confname)))942{943profile_t profile;944const char *filenames[2];945long retval;946947filenames[0] = confname;948filenames[1] = NULL;949if (!pprofile_init(filenames, &profile)) {950char * value = NULL;951952retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value);953if (retval == 0 && value) {954krb5_deltat d;955956retval = pkrb5_string_to_deltat(value, &d);957958if (retval == KRB5_DELTAT_BADFORMAT) {959/* Historically some sites use relations of960the form 'ticket_lifetime = 24000' where961the unit is left out but is assumed to be962seconds. Then there are other sites which963use the form 'ticket_lifetime = 600' where964the unit is assumed to be minutes. While965these are technically wrong (a unit needs966to be specified), we try to accommodate for967this using the safe assumption that the968unit is seconds and tack an 's' to the end969and see if that works. */970971/* Of course, Leash is one of the platforms972that historically assumed no units and minutes973so this change is going to break some people974but its better to be consistent. */975size_t cch;976char buf[256];977978do {979cch = strlen(value) + 2; /* NUL and new 's' */980if (cch > sizeof(buf))981break;982983strcpy(buf, value);984strcat(buf, "s");985986retval = pkrb5_string_to_deltat(buf, &d);987988if (retval == 0) {989result = d / 60;990}991} while(0);992} else if (retval == 0) {993result = d / 60;994}995996pprofile_release_string(value);997}998pprofile_release(profile);999/* value has been released but we can still use a check for1000* non-NULL to see if we were able to read a value.1001*/1002if (retval == 0 && value)1003return result;1004}1005}1006}10071008hmLeash = GetModuleHandle(LEASH_DLL);1009if (hmLeash)1010{1011char lifetime[80];1012if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE,1013lifetime, sizeof(lifetime)))1014{1015lifetime[sizeof(lifetime) - 1] = 0;1016return atoi(lifetime);1017}1018}1019return 0;1020}10211022static1023BOOL1024get_default_renew_till_from_registry(1025HKEY hBaseKey,1026DWORD * result1027)1028{1029return get_DWORD_from_registry(hBaseKey,1030LEASH_REGISTRY_KEY_NAME,1031LEASH_REGISTRY_VALUE_RENEW_TILL,1032result);1033}10341035DWORD1036Leash_reset_default_renew_till(1037)1038{1039HKEY hKey;1040LONG rc;10411042rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1043if (rc)1044return rc;10451046rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL);1047RegCloseKey(hKey);10481049return rc;1050}10511052DWORD1053Leash_set_default_renew_till(1054DWORD minutes1055)1056{1057HKEY hKey;1058LONG rc;10591060rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,10610, 0, KEY_WRITE, 0, &hKey, 0);1062if (rc)1063return rc;10641065rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD,1066(LPBYTE) &minutes, sizeof(DWORD));1067RegCloseKey(hKey);10681069return rc;1070}10711072DWORD1073Leash_get_default_renew_till(1074)1075{1076HMODULE hmLeash;1077char env[32];1078DWORD result;10791080if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env)))1081{1082return atoi(env);1083}10841085if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) ||1086get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result))1087{1088return result;1089}10901091if ( hKrb5 ) {1092CHAR confname[MAX_PATH];1093if (!get_profile_file(confname, sizeof(confname)))1094{1095profile_t profile;1096const char *filenames[2];1097int value=0;1098long retval;1099filenames[0] = confname;1100filenames[1] = NULL;11011102if (!pprofile_init(filenames, &profile)) {1103char * value = NULL;11041105retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value);1106if (retval == 0 && value) {1107krb5_deltat d;11081109retval = pkrb5_string_to_deltat(value, &d);1110if (retval == KRB5_DELTAT_BADFORMAT) {1111/* Historically some sites use relations of1112the form 'ticket_lifetime = 24000' where1113the unit is left out but is assumed to be1114seconds. Then there are other sites which1115use the form 'ticket_lifetime = 600' where1116the unit is assumed to be minutes. While1117these are technically wrong (a unit needs1118to be specified), we try to accommodate for1119this using the safe assumption that the1120unit is seconds and tack an 's' to the end1121and see if that works. */11221123/* Of course, Leash is one of the platforms1124that historically assumed no units and minutes1125so this change is going to break some people1126but its better to be consistent. */1127size_t cch;1128char buf[256];1129do {1130cch = strlen(value) + 2; /* NUL and new 's' */1131if (cch > sizeof(buf))1132break;11331134strcpy(buf, value);1135strcat(buf, "s");11361137retval = pkrb5_string_to_deltat(buf, &d);1138if (retval == 0) {1139result = d / 60;1140}1141} while(0);1142} else if (retval == 0) {1143result = d / 60;1144}1145pprofile_release_string(value);1146}1147pprofile_release(profile);1148/* value has been released but we can still use a check for1149* non-NULL to see if we were able to read a value.1150*/1151if (retval == 0 && value)1152return result;11531154pprofile_release(profile);1155}1156}1157}11581159hmLeash = GetModuleHandle(LEASH_DLL);1160if (hmLeash)1161{1162char renew_till[80];1163if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL,1164renew_till, sizeof(renew_till)))1165{1166renew_till[sizeof(renew_till) - 1] = 0;1167return atoi(renew_till);1168}1169}1170return 0;1171}11721173static1174BOOL1175get_default_forwardable_from_registry(1176HKEY hBaseKey,1177DWORD * result1178)1179{1180return get_DWORD_from_registry(hBaseKey,1181LEASH_REGISTRY_KEY_NAME,1182LEASH_REGISTRY_VALUE_FORWARDABLE,1183result);1184}11851186DWORD1187Leash_reset_default_forwardable(1188)1189{1190HKEY hKey;1191LONG rc;11921193rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1194if (rc)1195return rc;11961197rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE);1198RegCloseKey(hKey);11991200return rc;1201}12021203DWORD1204Leash_set_default_forwardable(1205DWORD minutes1206)1207{1208HKEY hKey;1209LONG rc;12101211rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,12120, 0, KEY_WRITE, 0, &hKey, 0);1213if (rc)1214return rc;12151216rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD,1217(LPBYTE) &minutes, sizeof(DWORD));1218RegCloseKey(hKey);12191220return rc;1221}12221223DWORD1224Leash_get_default_forwardable(1225)1226{1227HMODULE hmLeash;12281229char env[32];1230DWORD result;12311232if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env)))1233{1234return atoi(env);1235}12361237if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) ||1238get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result))1239{1240return result;1241}12421243if ( hKrb5 ) {1244CHAR confname[MAX_PATH];1245if (!get_profile_file(confname, sizeof(confname)))1246{1247profile_t profile;1248const char *filenames[2];1249char *value=0;1250long retval;1251filenames[0] = confname;1252filenames[1] = NULL;1253if (!pprofile_init(filenames, &profile)) {1254retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value);1255if ( value ) {1256result = config_boolean_to_int(value);1257pprofile_release_string(value);1258pprofile_release(profile);1259return result;1260}1261pprofile_release(profile);1262}1263}1264}12651266hmLeash = GetModuleHandle(LEASH_DLL);1267if (hmLeash)1268{1269char forwardable[80];1270if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD,1271forwardable, sizeof(forwardable)))1272{1273forwardable[sizeof(forwardable) - 1] = 0;1274return atoi(forwardable);1275}1276}1277return 0;1278}12791280static1281BOOL1282get_default_renewable_from_registry(1283HKEY hBaseKey,1284DWORD * result1285)1286{1287return get_DWORD_from_registry(hBaseKey,1288LEASH_REGISTRY_KEY_NAME,1289LEASH_REGISTRY_VALUE_RENEWABLE,1290result);1291}12921293DWORD1294Leash_reset_default_renewable(1295)1296{1297HKEY hKey;1298LONG rc;12991300rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1301if (rc)1302return rc;13031304rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE);1305RegCloseKey(hKey);13061307return rc;1308}13091310DWORD1311Leash_set_default_renewable(1312DWORD minutes1313)1314{1315HKEY hKey;1316LONG rc;13171318rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,13190, 0, KEY_WRITE, 0, &hKey, 0);1320if (rc)1321return rc;13221323rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD,1324(LPBYTE) &minutes, sizeof(DWORD));1325RegCloseKey(hKey);13261327return rc;1328}13291330DWORD1331Leash_get_default_renewable(1332)1333{1334HMODULE hmLeash;1335char env[32];1336DWORD result;13371338if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env)))1339{1340return atoi(env);1341}13421343if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) ||1344get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result))1345{1346return result;1347}13481349if ( hKrb5 ) {1350CHAR confname[MAX_PATH];1351if (!get_profile_file(confname, sizeof(confname)))1352{1353profile_t profile;1354const char *filenames[2];1355char *value=0;1356long retval;1357filenames[0] = confname;1358filenames[1] = NULL;1359if (!pprofile_init(filenames, &profile)) {1360retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value);1361if ( value ) {1362result = config_boolean_to_int(value);1363pprofile_release_string(value);1364pprofile_release(profile);1365return result;1366}1367pprofile_release(profile);1368}1369}1370}13711372hmLeash = GetModuleHandle(LEASH_DLL);1373if (hmLeash)1374{1375char renewable[80];1376if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW,1377renewable, sizeof(renewable)))1378{1379renewable[sizeof(renewable) - 1] = 0;1380return atoi(renewable);1381}1382}1383return 0;1384}13851386static1387BOOL1388get_default_noaddresses_from_registry(1389HKEY hBaseKey,1390DWORD * result1391)1392{1393return get_DWORD_from_registry(hBaseKey,1394LEASH_REGISTRY_KEY_NAME,1395LEASH_REGISTRY_VALUE_NOADDRESSES,1396result);1397}13981399DWORD1400Leash_reset_default_noaddresses(1401)1402{1403HKEY hKey;1404LONG rc;14051406rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1407if (rc)1408return rc;14091410rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES);1411RegCloseKey(hKey);14121413return rc;1414}14151416DWORD1417Leash_set_default_noaddresses(1418DWORD minutes1419)1420{1421HKEY hKey;1422LONG rc;14231424rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,14250, 0, KEY_WRITE, 0, &hKey, 0);1426if (rc)1427return rc;14281429rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD,1430(LPBYTE) &minutes, sizeof(DWORD));1431RegCloseKey(hKey);14321433return rc;1434}14351436DWORD1437Leash_get_default_noaddresses(1438)1439{1440HMODULE hmLeash;1441char env[32];1442DWORD result;14431444if ( hKrb5 ) {1445// if the profile file cannot be opened then the value will be true1446// if the noaddresses name cannot be found then the value will be true1447// if true in the library, we can't alter it by other means1448CHAR confname[MAX_PATH];1449result = 1;1450if (!get_profile_file(confname, sizeof(confname)))1451{1452profile_t profile;1453const char *filenames[2];1454char *value=0;1455long retval;1456filenames[0] = confname;1457filenames[1] = NULL;1458if (!pprofile_init(filenames, &profile)) {1459retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);1460if ( value ) {1461result = config_boolean_to_int(value);1462pprofile_release_string(value);1463}1464pprofile_release(profile);1465}1466}14671468if ( result )1469return 1;1470}14711472// The library default is false, check other locations14731474if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env)))1475{1476return atoi(env);1477}14781479if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) ||1480get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result))1481{1482return result;1483}14841485hmLeash = GetModuleHandle(LEASH_DLL);1486if (hmLeash)1487{1488char noaddresses[80];1489if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS,1490noaddresses, sizeof(noaddresses)))1491{1492noaddresses[sizeof(noaddresses) - 1] = 0;1493}1494}1495return 1;1496}14971498static1499BOOL1500get_default_proxiable_from_registry(1501HKEY hBaseKey,1502DWORD * result1503)1504{1505return get_DWORD_from_registry(hBaseKey,1506LEASH_REGISTRY_KEY_NAME,1507LEASH_REGISTRY_VALUE_PROXIABLE,1508result);1509}15101511DWORD1512Leash_reset_default_proxiable(1513)1514{1515HKEY hKey;1516LONG rc;15171518rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1519if (rc)1520return rc;15211522rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE);1523RegCloseKey(hKey);15241525return rc;1526}15271528DWORD1529Leash_set_default_proxiable(1530DWORD minutes1531)1532{1533HKEY hKey;1534LONG rc;15351536rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,15370, 0, KEY_WRITE, 0, &hKey, 0);1538if (rc)1539return rc;15401541rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD,1542(LPBYTE) &minutes, sizeof(DWORD));1543RegCloseKey(hKey);15441545return rc;1546}15471548DWORD1549Leash_get_default_proxiable(1550)1551{1552HMODULE hmLeash;1553char env[32];1554DWORD result;15551556if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env)))1557{1558return atoi(env);1559}15601561if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) ||1562get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result))1563{1564return result;1565}15661567if ( hKrb5 ) {1568CHAR confname[MAX_PATH];1569if (!get_profile_file(confname, sizeof(confname)))1570{1571profile_t profile;1572const char *filenames[2];1573char *value=0;1574long retval;1575filenames[0] = confname;1576filenames[1] = NULL;1577if (!pprofile_init(filenames, &profile)) {1578retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value);1579if ( value ) {1580result = config_boolean_to_int(value);1581pprofile_release_string(value);1582pprofile_release(profile);1583return result;1584}1585pprofile_release(profile);1586}1587}1588}15891590hmLeash = GetModuleHandle(LEASH_DLL);1591if (hmLeash)1592{1593char proxiable[80];1594if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE,1595proxiable, sizeof(proxiable)))1596{1597proxiable[sizeof(proxiable) - 1] = 0;1598return atoi(proxiable);1599}1600}1601return 0;1602}16031604static1605BOOL1606get_default_publicip_from_registry(1607HKEY hBaseKey,1608DWORD * result1609)1610{1611return get_DWORD_from_registry(hBaseKey,1612LEASH_REGISTRY_KEY_NAME,1613LEASH_REGISTRY_VALUE_PUBLICIP,1614result);1615}16161617DWORD1618Leash_reset_default_publicip(1619)1620{1621HKEY hKey;1622LONG rc;16231624rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1625if (rc)1626return rc;16271628rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP);1629RegCloseKey(hKey);16301631return rc;1632}16331634DWORD1635Leash_set_default_publicip(1636DWORD minutes1637)1638{1639HKEY hKey;1640LONG rc;16411642rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,16430, 0, KEY_WRITE, 0, &hKey, 0);1644if (rc)1645return rc;16461647rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD,1648(LPBYTE) &minutes, sizeof(DWORD));1649RegCloseKey(hKey);16501651return rc;1652}16531654DWORD1655Leash_get_default_publicip(1656)1657{1658HMODULE hmLeash;1659char env[32];1660DWORD result;16611662if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env)))1663{1664return atoi(env);1665}16661667if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) ||1668get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result))1669{1670return result;1671}16721673hmLeash = GetModuleHandle(LEASH_DLL);1674if (hmLeash)1675{1676char publicip[80];1677if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP,1678publicip, sizeof(publicip)))1679{1680publicip[sizeof(publicip) - 1] = 0;1681return atoi(publicip);1682}1683}1684return 0;1685}16861687static1688BOOL1689get_hide_kinit_options_from_registry(1690HKEY hBaseKey,1691DWORD * result1692)1693{1694return get_DWORD_from_registry(hBaseKey,1695LEASH_REGISTRY_KEY_NAME,1696LEASH_REGISTRY_VALUE_KINIT_OPT,1697result);1698}16991700DWORD1701Leash_reset_hide_kinit_options(1702)1703{1704HKEY hKey;1705LONG rc;17061707rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1708if (rc)1709return rc;17101711rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT);1712RegCloseKey(hKey);17131714return rc;1715}17161717DWORD1718Leash_set_hide_kinit_options(1719DWORD minutes1720)1721{1722HKEY hKey;1723LONG rc;17241725rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,17260, 0, KEY_WRITE, 0, &hKey, 0);1727if (rc)1728return rc;17291730rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD,1731(LPBYTE) &minutes, sizeof(DWORD));1732RegCloseKey(hKey);17331734return rc;1735}17361737DWORD1738Leash_get_hide_kinit_options(1739)1740{1741HMODULE hmLeash;1742DWORD result;17431744if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) ||1745get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result))1746{1747return result;1748}17491750hmLeash = GetModuleHandle(LEASH_DLL);1751if (hmLeash)1752{1753char hide_kinit_options[80];1754if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT,1755hide_kinit_options, sizeof(hide_kinit_options)))1756{1757hide_kinit_options[sizeof(hide_kinit_options) - 1] = 0;1758return atoi(hide_kinit_options);1759}1760}1761return 0; /* hide unless otherwise indicated */1762}1763176417651766static1767BOOL1768get_default_life_min_from_registry(1769HKEY hBaseKey,1770DWORD * result1771)1772{1773return get_DWORD_from_registry(hBaseKey,1774LEASH_REGISTRY_KEY_NAME,1775LEASH_REGISTRY_VALUE_LIFE_MIN,1776result);1777}17781779DWORD1780Leash_reset_default_life_min(1781)1782{1783HKEY hKey;1784LONG rc;17851786rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1787if (rc)1788return rc;17891790rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN);1791RegCloseKey(hKey);17921793return rc;1794}17951796DWORD1797Leash_set_default_life_min(1798DWORD minutes1799)1800{1801HKEY hKey;1802LONG rc;18031804rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,18050, 0, KEY_WRITE, 0, &hKey, 0);1806if (rc)1807return rc;18081809rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD,1810(LPBYTE) &minutes, sizeof(DWORD));1811RegCloseKey(hKey);18121813return rc;1814}18151816DWORD1817Leash_get_default_life_min(1818)1819{1820HMODULE hmLeash;1821DWORD result;18221823if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) ||1824get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result))1825{1826return result;1827}18281829hmLeash = GetModuleHandle(LEASH_DLL);1830if (hmLeash)1831{1832char life_min[80];1833if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN,1834life_min, sizeof(life_min)))1835{1836life_min[sizeof(life_min) - 1] = 0;1837return atoi(life_min);1838}1839}1840return 5; /* 5 minutes */1841}18421843static1844BOOL1845get_default_life_max_from_registry(1846HKEY hBaseKey,1847DWORD * result1848)1849{1850return get_DWORD_from_registry(hBaseKey,1851LEASH_REGISTRY_KEY_NAME,1852LEASH_REGISTRY_VALUE_LIFE_MAX,1853result);1854}18551856DWORD1857Leash_reset_default_life_max(1858)1859{1860HKEY hKey;1861LONG rc;18621863rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1864if (rc)1865return rc;18661867rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX);1868RegCloseKey(hKey);18691870return rc;1871}18721873DWORD1874Leash_set_default_life_max(1875DWORD minutes1876)1877{1878HKEY hKey;1879LONG rc;18801881rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,18820, 0, KEY_WRITE, 0, &hKey, 0);1883if (rc)1884return rc;18851886rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD,1887(LPBYTE) &minutes, sizeof(DWORD));1888RegCloseKey(hKey);18891890return rc;1891}18921893DWORD1894Leash_get_default_life_max(1895)1896{1897HMODULE hmLeash;1898DWORD result;18991900if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) ||1901get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result))1902{1903return result;1904}19051906hmLeash = GetModuleHandle(LEASH_DLL);1907if (hmLeash)1908{1909char life_max[80];1910if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX,1911life_max, sizeof(life_max)))1912{1913life_max[sizeof(life_max) - 1] = 0;1914return atoi(life_max);1915}1916}1917return 1440;1918}19191920static1921BOOL1922get_default_renew_min_from_registry(1923HKEY hBaseKey,1924DWORD * result1925)1926{1927return get_DWORD_from_registry(hBaseKey,1928LEASH_REGISTRY_KEY_NAME,1929LEASH_REGISTRY_VALUE_RENEW_MIN,1930result);1931}19321933DWORD1934Leash_reset_default_renew_min(1935)1936{1937HKEY hKey;1938LONG rc;19391940rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);1941if (rc)1942return rc;19431944rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN);1945RegCloseKey(hKey);19461947return rc;1948}19491950DWORD1951Leash_set_default_renew_min(1952DWORD minutes1953)1954{1955HKEY hKey;1956LONG rc;19571958rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,19590, 0, KEY_WRITE, 0, &hKey, 0);1960if (rc)1961return rc;19621963rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD,1964(LPBYTE) &minutes, sizeof(DWORD));1965RegCloseKey(hKey);19661967return rc;1968}19691970DWORD1971Leash_get_default_renew_min(1972)1973{1974HMODULE hmLeash;1975DWORD result;19761977if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) ||1978get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result))1979{1980return result;1981}19821983hmLeash = GetModuleHandle(LEASH_DLL);1984if (hmLeash)1985{1986char renew_min[80];1987if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN,1988renew_min, sizeof(renew_min)))1989{1990renew_min[sizeof(renew_min) - 1] = 0;1991return atoi(renew_min);1992}1993}1994return 600; /* 10 hours */1995}19961997static1998BOOL1999get_default_renew_max_from_registry(2000HKEY hBaseKey,2001DWORD * result2002)2003{2004return get_DWORD_from_registry(hBaseKey,2005LEASH_REGISTRY_KEY_NAME,2006LEASH_REGISTRY_VALUE_RENEW_MAX,2007result);2008}20092010DWORD2011Leash_reset_default_renew_max(2012)2013{2014HKEY hKey;2015LONG rc;20162017rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);2018if (rc)2019return rc;20202021rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX);2022RegCloseKey(hKey);20232024return rc;2025}20262027DWORD2028Leash_set_default_renew_max(2029DWORD minutes2030)2031{2032HKEY hKey;2033LONG rc;20342035rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,20360, 0, KEY_WRITE, 0, &hKey, 0);2037if (rc)2038return rc;20392040rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD,2041(LPBYTE) &minutes, sizeof(DWORD));2042RegCloseKey(hKey);20432044return rc;2045}20462047DWORD2048Leash_get_default_renew_max(2049)2050{2051HMODULE hmLeash;2052DWORD result;20532054if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) ||2055get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result))2056{2057return result;2058}20592060hmLeash = GetModuleHandle(LEASH_DLL);2061if (hmLeash)2062{2063char renew_max[80];2064if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX,2065renew_max, sizeof(renew_max)))2066{2067renew_max[sizeof(renew_max) - 1] = 0;2068return atoi(renew_max);2069}2070}2071return 60 * 24 * 30;2072}20732074static2075BOOL2076get_default_uppercaserealm_from_registry(2077HKEY hBaseKey,2078DWORD * result2079)2080{2081return get_DWORD_from_registry(hBaseKey,2082LEASH_SETTINGS_REGISTRY_KEY_NAME,2083LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM,2084result);2085}20862087DWORD2088Leash_reset_default_uppercaserealm(2089)2090{2091HKEY hKey;2092LONG rc;20932094rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);2095if (rc)2096return rc;20972098rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM);2099RegCloseKey(hKey);21002101return rc;2102}21032104DWORD2105Leash_set_default_uppercaserealm(2106DWORD onoff2107)2108{2109HKEY hKey;2110LONG rc;21112112rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,21130, 0, KEY_WRITE, 0, &hKey, 0);2114if (rc)2115return rc;21162117rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD,2118(LPBYTE) &onoff, sizeof(DWORD));2119RegCloseKey(hKey);21202121return rc;2122}21232124DWORD2125Leash_get_default_uppercaserealm(2126)2127{2128HMODULE hmLeash;2129DWORD result;21302131if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) ||2132get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result))2133{2134return result;2135}21362137hmLeash = GetModuleHandle(LEASH_DLL);2138if (hmLeash)2139{2140char uppercaserealm[80];2141if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM,2142uppercaserealm, sizeof(uppercaserealm)))2143{2144uppercaserealm[sizeof(uppercaserealm) - 1] = 0;2145return atoi(uppercaserealm);2146}2147}2148return 1;2149}21502151DWORD2152Leash_reset_default_mslsa_import(2153)2154{2155return ERROR_INVALID_FUNCTION;2156}21572158DWORD2159Leash_set_default_mslsa_import(2160DWORD onoffmatch2161)2162{2163return ERROR_INVALID_FUNCTION;2164}21652166DWORD2167Leash_get_default_mslsa_import(2168)2169{2170return 0;2171}217221732174static2175BOOL2176get_default_preserve_kinit_settings_from_registry(2177HKEY hBaseKey,2178DWORD * result2179)2180{2181return get_DWORD_from_registry(hBaseKey,2182LEASH_REGISTRY_KEY_NAME,2183LEASH_REGISTRY_VALUE_PRESERVE_KINIT,2184result);2185}21862187DWORD2188Leash_reset_default_preserve_kinit_settings(2189)2190{2191HKEY hKey;2192LONG rc;21932194rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);2195if (rc)2196return rc;21972198rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT);2199RegCloseKey(hKey);22002201return rc;2202}22032204DWORD2205Leash_set_default_preserve_kinit_settings(2206DWORD onoff2207)2208{2209HKEY hKey;2210LONG rc;22112212rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,22130, 0, KEY_WRITE, 0, &hKey, 0);2214if (rc)2215return rc;22162217rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD,2218(LPBYTE) &onoff, sizeof(DWORD));2219RegCloseKey(hKey);22202221return rc;2222}22232224DWORD2225Leash_get_default_preserve_kinit_settings(2226)2227{2228HMODULE hmLeash;2229DWORD result;22302231if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) ||2232get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result))2233{2234return result;2235}22362237hmLeash = GetModuleHandle(LEASH_DLL);2238if (hmLeash)2239{2240char preserve_kinit_settings[80];2241if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT,2242preserve_kinit_settings, sizeof(preserve_kinit_settings)))2243{2244preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0;2245return atoi(preserve_kinit_settings);2246}2247}2248return 1;2249}22502251void2252Leash_reset_defaults(void)2253{2254Leash_reset_default_lifetime();2255Leash_reset_default_renew_till();2256Leash_reset_default_renewable();2257Leash_reset_default_forwardable();2258Leash_reset_default_noaddresses();2259Leash_reset_default_proxiable();2260Leash_reset_default_publicip();2261Leash_reset_hide_kinit_options();2262Leash_reset_default_life_min();2263Leash_reset_default_life_max();2264Leash_reset_default_renew_min();2265Leash_reset_default_renew_max();2266Leash_reset_default_uppercaserealm();2267Leash_reset_default_preserve_kinit_settings();2268}22692270static void2271acquire_tkt_send_msg_leash(const char *title,2272const char *ccachename,2273const char *name,2274const char *realm)2275{2276DWORD leashProcessId = 0;2277DWORD bufsize = 4096;2278DWORD step;2279HANDLE hLeashProcess = NULL;2280HANDLE hMapFile = NULL;2281HANDLE hTarget = NULL;2282HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL);2283char *strs;2284void *view;2285if (!hLeashWnd)2286// no leash window2287return;22882289GetWindowThreadProcessId(hLeashWnd, &leashProcessId);2290hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE,2291FALSE,2292leashProcessId);2293if (!hLeashProcess)2294// can't get process handle; use GetLastError() for more info2295return;22962297hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file2298NULL, // default security2299PAGE_READWRITE, // read/write access23000, // max size (high 32)2301bufsize, // max size (low 32)2302NULL); // name2303if (!hMapFile) {2304// GetLastError() for more info2305CloseHandle(hLeashProcess);2306return;2307}23082309SetForegroundWindow(hLeashWnd);23102311view = MapViewOfFile(hMapFile,2312FILE_MAP_ALL_ACCESS,23130,23140,2315bufsize);2316if (view != NULL) {2317/* construct a marshalling of data2318* <title><principal><realm><ccache>2319* then send to Leash2320*/2321strs = (char *)view;2322// first reserve space for three more NULLs (4 strings total)2323bufsize -= 3;2324// Dialog title2325if (title != NULL)2326strcpy_s(strs, bufsize, title);2327else if (name != NULL && realm != NULL)2328sprintf_s(strs, bufsize,2329"MIT Kerberos: Get Ticket for %s@%s", name, realm);2330else2331strcpy_s(strs, bufsize, "MIT Kerberos: Get Ticket");2332step = strlen(strs);2333strs += step + 1;2334bufsize -= step;2335// name and realm2336if (name != NULL) {2337strcpy_s(strs, bufsize, name);2338step = strlen(strs);2339strs += step + 1;2340bufsize -= step;2341if (realm != NULL) {2342strcpy_s(strs, bufsize, realm);2343step = strlen(strs);2344strs += step + 1;2345bufsize -= step;2346} else {2347*strs = 0;2348strs++;2349}2350} else {2351*strs = 0;2352strs++;2353*strs = 0;2354strs++;2355}23562357/* Append the ccache name */2358if (ccachename != NULL)2359strcpy_s(strs, bufsize, ccachename);2360else2361*strs = 0;23622363UnmapViewOfFile(view);2364}2365// Duplicate the file mapping handle to one leash can use2366if (DuplicateHandle(GetCurrentProcess(),2367hMapFile,2368hLeashProcess,2369&hTarget,2370PAGE_READWRITE,2371FALSE,2372DUPLICATE_SAME_ACCESS |2373DUPLICATE_CLOSE_SOURCE)) {2374/* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */2375SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget);2376} else {2377// GetLastError()2378}2379}23802381static int2382acquire_tkt_send_msg(krb5_context ctx, const char * title,2383const char * ccachename,2384krb5_principal desiredKrb5Principal,2385char * out_ccname, int out_cclen)2386{2387krb5_error_code err;2388HWND hNetIdMgr;2389HWND hForeground;2390char *desiredName = 0;2391char *desiredRealm = 0;23922393/* do we want a specific client principal? */2394if (desiredKrb5Principal != NULL) {2395err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName);2396if (!err) {2397char * p;2398for (p = desiredName; *p && *p != '@'; p++);2399if ( *p == '@' ) {2400*p = '\0';2401desiredRealm = ++p;2402}2403}2404}24052406hForeground = GetForegroundWindow();2407hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");2408if (hNetIdMgr != NULL) {2409HANDLE hMap;2410DWORD tid = GetCurrentThreadId();2411char mapname[256];2412NETID_DLGINFO *dlginfo;24132414sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);24152416hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,24170, 4096, mapname);2418if (hMap == NULL) {2419return -1;2420} else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {2421CloseHandle(hMap);2422return -1;2423}24242425dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,24260, 0, 4096, NULL);2427if (dlginfo == NULL) {2428CloseHandle(hMap);2429return -1;2430}24312432memset(dlginfo, 0, sizeof(NETID_DLGINFO));24332434dlginfo->size = sizeof(NETID_DLGINFO);2435dlginfo->dlgtype = NETID_DLGTYPE_TGT;2436dlginfo->in.use_defaults = 1;24372438if (title) {2439MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2440title, -1,2441dlginfo->in.title, NETID_TITLE_SZ);2442} else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {2443char mytitle[NETID_TITLE_SZ];2444sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);2445MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2446mytitle, -1,2447dlginfo->in.title, NETID_TITLE_SZ);2448} else {2449MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2450"Obtain Kerberos TGT", -1,2451dlginfo->in.title, NETID_TITLE_SZ);2452}2453if (desiredName)2454MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2455desiredName, -1,2456dlginfo->in.username, NETID_USERNAME_SZ);2457if (desiredRealm)2458MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2459desiredRealm, -1,2460dlginfo->in.realm, NETID_REALM_SZ);2461if (ccachename)2462MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,2463ccachename, -1,2464dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);2465SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);24662467if (out_ccname && out_cclen > 0) {2468WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1,2469out_ccname, out_cclen, NULL, NULL);2470}24712472UnmapViewOfFile(dlginfo);2473CloseHandle(hMap);2474} else {2475acquire_tkt_send_msg_leash(title,2476ccachename, desiredName, desiredRealm);2477}24782479SetForegroundWindow(hForeground);2480if (desiredName != NULL)2481pkrb5_free_unparsed_name(ctx, desiredName);24822483return 0;2484}24852486static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache)2487{2488krb5_cc_cursor cur = NULL;2489krb5_creds creds;2490krb5_flags flags;2491krb5_error_code code;2492BOOL have_tickets = FALSE;24932494// Don't need the actual ticket.2495flags = KRB5_TC_NOTICKET;2496code = pkrb5_cc_set_flags(ctx, cache, flags);2497if (code)2498goto cleanup;2499code = pkrb5_cc_start_seq_get(ctx, cache, &cur);2500if (code)2501goto cleanup;25022503_tzset();2504while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {2505if ((!pkrb5_is_config_principal(ctx, creds.server)) &&2506((time_t)(DWORD)creds.times.endtime - time(0) > 0))2507have_tickets = TRUE;25082509pkrb5_free_cred_contents(ctx, &creds);2510}2511if (code == KRB5_CC_END) {2512code = pkrb5_cc_end_seq_get(ctx, cache, &cur);2513if (code)2514goto cleanup;2515flags = 0;2516code = pkrb5_cc_set_flags(ctx, cache, flags);2517if (code)2518goto cleanup;2519}2520cleanup:2521return have_tickets;2522}25232524static BOOL2525cc_have_tickets_for_princ(krb5_context ctx,2526krb5_ccache cache,2527krb5_principal princ)2528{2529krb5_error_code code;2530krb5_principal cc_princ = NULL;2531BOOL have_tickets = FALSE;2532code = pkrb5_cc_get_principal(ctx, cache, &cc_princ);2533if (code)2534goto cleanup;25352536if (pkrb5_principal_compare(ctx, princ, cc_princ))2537have_tickets = cc_have_tickets(ctx, cache);25382539cleanup:2540if (cc_princ != NULL)2541pkrb5_free_principal(ctx, cc_princ);2542return have_tickets;2543}25442545static BOOL cc_default_have_tickets(krb5_context ctx)2546{2547krb5_ccache cache = NULL;2548BOOL have_tickets = FALSE;2549if (pkrb5_cc_default(ctx, &cache) == 0)2550have_tickets = cc_have_tickets(ctx, cache);2551if (cache != NULL)2552pkrb5_cc_close(ctx, cache);2553return have_tickets;2554}25552556static BOOL2557cccol_have_tickets_for_princ(krb5_context ctx,2558krb5_principal princ,2559char *ccname,2560int cclen)2561{2562krb5_error_code code;2563krb5_ccache cache;2564krb5_cccol_cursor cursor;2565BOOL have_tickets = FALSE;2566char *ccfullname;25672568code = pkrb5_cccol_cursor_new(ctx, &cursor);2569if (code)2570goto cleanup;25712572while (!have_tickets &&2573!(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&2574cache != NULL) {2575if (cc_have_tickets_for_princ(ctx, cache, princ)) {2576if (pkrb5_cc_get_full_name(ctx, cache, &ccfullname)==0) {2577strcpy_s(ccname, cclen, ccfullname);2578pkrb5_free_string(ctx, ccfullname);2579have_tickets = TRUE;2580}2581}2582pkrb5_cc_close(ctx, cache);2583}2584pkrb5_cccol_cursor_free(ctx, &cursor);2585cleanup:25862587return have_tickets;2588}25892590static void2591acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)2592{2593krb5_context ctx;2594DWORD gle;2595char ccachename[272]="";2596char loginenv[16];2597BOOL prompt;2598BOOL haveTickets;25992600GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));2601prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);26022603ctx = context;26042605SetLastError(0);2606GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));2607gle = GetLastError();2608if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) {2609const char * ccdef = pkrb5_cc_default_name(ctx);2610SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);2611GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));2612}26132614haveTickets = cc_default_have_tickets(ctx);26152616if ( prompt && !haveTickets ) {2617acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen);2618/*2619* If the ticket manager returned an alternative credential cache2620* remember it as the default for this process.2621*/2622if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) {2623SetEnvironmentVariable("KRB5CCNAME",ccname);2624}26252626} else if (ccachename[0] && ccname) {2627strncpy(ccname, ccachename, cclen);2628ccname[cclen-1] = '\0';2629}2630if ( !context )2631pkrb5_free_context(ctx);2632}263326342635static void2636acquire_tkt_for_princ(krb5_context ctx, krb5_principal desiredPrincipal,2637char * ccname, int cclen)2638{2639DWORD gle;2640char ccachename[272]="";2641char loginenv[16];2642BOOL prompt;26432644GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));2645prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);26462647SetLastError(0);2648GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));2649gle = GetLastError();2650if ((gle == ERROR_ENVVAR_NOT_FOUND || !ccachename[0]) && ctx != NULL) {2651const char * ccdef = pkrb5_cc_default_name(ctx);2652SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);2653GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));2654}2655if (!cccol_have_tickets_for_princ(ctx, desiredPrincipal, ccname, cclen)) {2656if (prompt) {2657acquire_tkt_send_msg(ctx, NULL,2658ccachename, desiredPrincipal, ccname, cclen);2659/*2660* If the ticket manager returned an alternative credential cache2661* remember it as the default for this process.2662*/2663if (ccname != NULL && ccname[0] &&2664strcmp(ccachename, ccname)) {2665SetEnvironmentVariable("KRB5CCNAME",ccname);2666}2667}2668}2669}267026712672void FAR2673not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,2674krb5_principal desiredKrb5Principal,2675char * ccname, int cclen)2676{2677if (!desiredKrb5Principal) {2678acquire_tkt_no_princ(context, ccname, cclen);2679} else {2680acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen);2681}2682return;2683}268426852686