summaryrefslogtreecommitdiffstats
path: root/src/windows/leashdll
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2011-09-28 20:54:16 +0000
committerSam Hartman <hartmans@mit.edu>2011-09-28 20:54:16 +0000
commit6a45252bb3a6a808bb6f3dc32a7f1d85a7c04df1 (patch)
tree301620431d615b612ef8adbc741e304719759a01 /src/windows/leashdll
parent52ea04b2b732f73396dc945f23bae64e4f851299 (diff)
downloadkrb5-6a45252bb3a6a808bb6f3dc32a7f1d85a7c04df1.tar.gz
krb5-6a45252bb3a6a808bb6f3dc32a7f1d85a7c04df1.tar.xz
krb5-6a45252bb3a6a808bb6f3dc32a7f1d85a7c04df1.zip
Added leashdll/wshelper related files from KFW
From: Alexey Melnikov <alexey.melnikov@isode.com> git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25243 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/windows/leashdll')
-rw-r--r--src/windows/leashdll/AFSroutines.c852
-rw-r--r--src/windows/leashdll/include/krb4/conf-pc.h108
-rw-r--r--src/windows/leashdll/include/krb4/conf.h74
-rw-r--r--src/windows/leashdll/include/krb4/osconf.h59
-rw-r--r--src/windows/leashdll/include/leasherr.h32
-rw-r--r--src/windows/leashdll/include/leashinfo.h2
-rw-r--r--src/windows/leashdll/include/leashwin.h188
-rw-r--r--src/windows/leashdll/include/loadfuncs-com_err.h44
-rw-r--r--src/windows/leashdll/include/loadfuncs-krb5.h1757
-rw-r--r--src/windows/leashdll/include/loadfuncs-lsa.h45
-rw-r--r--src/windows/leashdll/include/loadfuncs-profile.h151
-rw-r--r--src/windows/leashdll/include/loadfuncs.h41
-rw-r--r--src/windows/leashdll/krb5routines.c1530
-rw-r--r--src/windows/leashdll/leash-int.h357
-rw-r--r--src/windows/leashdll/leashdll.c444
-rw-r--r--src/windows/leashdll/leashdll.h259
-rw-r--r--src/windows/leashdll/leasherr.c119
-rw-r--r--src/windows/leashdll/leasherr.et22
-rw-r--r--src/windows/leashdll/leashids.h115
-rw-r--r--src/windows/leashdll/leashw32.def108
-rw-r--r--src/windows/leashdll/loadfuncs.c88
-rw-r--r--src/windows/leashdll/lsh_pwd.c2430
-rw-r--r--src/windows/leashdll/lsh_pwd.rc261
-rw-r--r--src/windows/leashdll/lshcallb.c15
-rw-r--r--src/windows/leashdll/lshfunc.c3867
-rw-r--r--src/windows/leashdll/registry.c105
-rw-r--r--src/windows/leashdll/reminder.h12
-rw-r--r--src/windows/leashdll/res/islogo.bmpbin0 -> 20118 bytes
-rw-r--r--src/windows/leashdll/res/leash.icobin0 -> 25214 bytes
-rw-r--r--src/windows/leashdll/resource.h19
-rw-r--r--src/windows/leashdll/timesync.c297
-rw-r--r--src/windows/leashdll/ver.rc4
-rw-r--r--src/windows/leashdll/winerr.c240
-rw-r--r--src/windows/leashdll/winutil.c138
34 files changed, 13783 insertions, 0 deletions
diff --git a/src/windows/leashdll/AFSroutines.c b/src/windows/leashdll/AFSroutines.c
new file mode 100644
index 0000000000..a67b164e3b
--- /dev/null
+++ b/src/windows/leashdll/AFSroutines.c
@@ -0,0 +1,852 @@
+//* Module name: AFSroutines.c
+
+#include <windows.h>
+#include <stdio.h>
+#include <time.h>
+
+/* Private Include files */
+#include <conf.h>
+#include <leasherr.h>
+#include <krb.h>
+#include "leashdll.h"
+#include <leashwin.h>
+
+#ifndef NO_AFS
+#include "afscompat.h"
+#endif
+#include "leash-int.h"
+
+#define MAXCELLCHARS 64
+#define MAXHOSTCHARS 64
+#define MAXHOSTSPERCELL 8
+#define TRANSARCAFSDAEMON "TransarcAFSDaemon"
+typedef struct {
+ char name[MAXCELLCHARS];
+ short numServers;
+ short flags;
+ struct sockaddr_in hostAddr[MAXHOSTSPERCELL];
+ char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS];
+ char *linkedCell;
+} afsconf_cell;
+
+DWORD AfsOnLine = 1;
+extern DWORD AfsAvailable;
+
+int not_an_API_LeashAFSGetToken(TICKETINFO * ticketinfo, TicketList** ticketList, char * kprinc);
+DWORD GetServiceStatus(LPSTR lpszMachineName, LPSTR lpszServiceName, DWORD *lpdwCurrentState);
+BOOL SetAfsStatus(DWORD AfsStatus);
+BOOL GetAfsStatus(DWORD *AfsStatus);
+void Leash_afs_error(LONG rc, LPCSTR FailedFunctionName);
+
+static char *afs_realm_of_cell(afsconf_cell *);
+static long get_cellconfig_callback(void *, struct sockaddr_in *, char *);
+static int get_cellconfig(char *, afsconf_cell *, char *);
+
+/**************************************/
+/* LeashAFSdestroyToken(): */
+/**************************************/
+int
+Leash_afs_unlog(
+ void
+ )
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ long rc;
+ char HostName[64];
+ DWORD CurrentState;
+
+ if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
+ return(0);
+
+ CurrentState = 0;
+ memset(HostName, '\0', sizeof(HostName));
+ gethostname(HostName, sizeof(HostName));
+ if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
+ return(0);
+ if (CurrentState != SERVICE_RUNNING)
+ return(0);
+
+ rc = ktc_ForgetAllTokens();
+
+ return(0);
+#endif
+}
+
+
+int
+not_an_API_LeashAFSGetToken(
+ TICKETINFO * ticketinfo,
+ TicketList** ticketList,
+ char * kerberosPrincipal
+ )
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ struct ktc_principal aserver;
+ struct ktc_principal aclient;
+ struct ktc_token atoken;
+ int EndMonth;
+ int EndDay;
+ int cellNum;
+ int BreakAtEnd;
+ char UserName[64];
+ char CellName[64];
+ char ServiceName[64];
+ char InstanceName[64];
+ char EndTime[16];
+ char Buffer[256];
+ char Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
+ char TokenStatus[16];
+ time_t CurrentTime;
+ struct tm *newtime;
+ DWORD CurrentState;
+ DWORD rc;
+ char HostName[64];
+
+
+ TicketList* list = NULL;
+ if ( ticketinfo ) {
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal[0] = '\0';
+ }
+ if ( !kerberosPrincipal )
+ kerberosPrincipal = "";
+
+ if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
+ return(0);
+
+ CurrentState = 0;
+ memset(HostName, '\0', sizeof(HostName));
+ gethostname(HostName, sizeof(HostName));
+ if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
+ return(0);
+ if (CurrentState != SERVICE_RUNNING)
+ return(0);
+
+ BreakAtEnd = 0;
+ cellNum = 0;
+ while (1)
+ {
+ if (rc = ktc_ListTokens(cellNum, &cellNum, &aserver))
+ {
+ if (rc != KTC_NOENT)
+ return(0);
+
+ if (BreakAtEnd == 1)
+ break;
+ }
+ BreakAtEnd = 1;
+ memset(&atoken, '\0', sizeof(atoken));
+ if (rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient))
+ {
+ if (rc == KTC_ERROR)
+ return(0);
+
+ continue;
+ }
+
+ if (!list)
+ {
+ list = (TicketList*) calloc(1, sizeof(TicketList));
+ (*ticketList) = list;
+ }
+ else
+ {
+ list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
+ list = (TicketList*) list->next;
+ }
+
+ CurrentTime = time(NULL);
+
+ newtime = localtime(&atoken.endTime);
+
+ memset(UserName, '\0', sizeof(UserName));
+ strcpy(UserName, aclient.name);
+
+ memset(CellName, '\0', sizeof(CellName));
+ strcpy(CellName, aclient.cell);
+
+ memset(InstanceName, '\0', sizeof(InstanceName));
+ strcpy(InstanceName, aclient.instance);
+
+ memset(ServiceName, '\0', sizeof(ServiceName));
+ strcpy(ServiceName, aserver.name);
+
+ memset(TokenStatus, '\0', sizeof(TokenStatus));
+
+ EndDay = newtime->tm_mday;
+
+ EndMonth = newtime->tm_mon + 1;;
+
+ sprintf(EndTime, "%02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
+
+ sprintf(Buffer," %s %02d %s %s%s%s@%s %s",
+ Months[EndMonth - 1], EndDay, EndTime,
+ UserName,
+ InstanceName[0] ? "." : "",
+ InstanceName,
+ CellName,
+ TokenStatus);
+
+ list->theTicket = (char*) calloc(1, sizeof(Buffer));
+ if (!list->theTicket)
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+
+ strcpy(list->theTicket, Buffer);
+ list->name = strdup(aclient.name);
+ list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL;
+ list->realm = strdup(aclient.cell);
+ list->tktEncType = NULL;
+ list->keyEncType = NULL;
+ list->addrCount = 0;
+ list->addrList = NULL;
+
+ if ( ticketinfo ) {
+ sprintf(Buffer,"%s@%s",UserName,CellName);
+ if (!ticketinfo->principal[0] || !stricmp(Buffer,kerberosPrincipal)) {
+ strcpy(ticketinfo->principal, Buffer);
+ ticketinfo->issue_date = 0;
+ ticketinfo->lifetime = atoken.endTime;
+ ticketinfo->renew_till = 0;
+
+ _tzset();
+ if ( ticketinfo->lifetime - time(0) <= 0L )
+ ticketinfo->btickets = EXPD_TICKETS;
+ else
+ ticketinfo->btickets = GOOD_TICKETS;
+ }
+ }
+ }
+ return(0);
+#endif
+}
+
+static char OpenAFSConfigKeyName[] = "SOFTWARE\\OpenAFS\\Client";
+
+static int
+use_krb524(void)
+{
+ HKEY parmKey;
+ DWORD code, len;
+ DWORD use524 = 0;
+
+ code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(use524);
+ code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
+ (BYTE *) &use524, &len);
+ RegCloseKey(parmKey);
+ }
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(use524);
+ code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
+ (BYTE *) &use524, &len);
+ RegCloseKey (parmKey);
+ }
+ }
+ return use524;
+}
+
+
+
+int
+Leash_afs_klog(
+ char *service,
+ char *cell,
+ char *realm,
+ int LifeTime
+ )
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ long rc;
+ CREDENTIALS creds;
+ KTEXT_ST ticket;
+ struct ktc_principal aserver;
+ struct ktc_principal aclient;
+ char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
+ char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
+ char local_cell[MAXCELLCHARS+1];
+ char Dmycell[MAXCELLCHARS+1];
+ struct ktc_token atoken;
+ struct ktc_token btoken;
+ afsconf_cell ak_cellconfig; /* General information about the cell */
+ char RealmName[128];
+ char CellName[128];
+ char ServiceName[128];
+ DWORD CurrentState;
+ char HostName[64];
+ BOOL try_krb5 = 0;
+ int retry = 0;
+ int len;
+#ifndef NO_KRB5
+ krb5_context context = 0;
+ krb5_ccache _krb425_ccache = 0;
+ krb5_creds increds;
+ krb5_creds * k5creds = 0;
+ krb5_error_code r;
+ krb5_principal client_principal = 0;
+ krb5_flags flags = 0;
+#endif /* NO_KRB5 */
+
+ if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
+ return(0);
+
+ if ( !realm ) realm = "";
+ if ( !cell ) cell = "";
+ if ( !service ) service = "";
+
+ CurrentState = 0;
+ memset(HostName, '\0', sizeof(HostName));
+ gethostname(HostName, sizeof(HostName));
+ if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
+ return(0);
+ if (CurrentState != SERVICE_RUNNING)
+ return(0);
+
+ memset(RealmName, '\0', sizeof(RealmName));
+ memset(CellName, '\0', sizeof(CellName));
+ memset(ServiceName, '\0', sizeof(ServiceName));
+ memset(realm_of_user, '\0', sizeof(realm_of_user));
+ memset(realm_of_cell, '\0', sizeof(realm_of_cell));
+ memset(Dmycell, '\0', sizeof(Dmycell));
+
+ // NULL or empty cell returns information on local cell
+ if (cell && cell[0])
+ strcpy(Dmycell, cell);
+ rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
+ if (rc && cell && cell[0]) {
+ memset(Dmycell, '\0', sizeof(Dmycell));
+ rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
+ }
+ if (rc)
+ return(rc);
+
+#ifndef NO_KRB5
+ if (!(r = Leash_krb5_initialize(&context, &_krb425_ccache))) {
+ int i;
+
+ memset((char *)&increds, 0, sizeof(increds));
+
+ (*pkrb5_cc_get_principal)(context, _krb425_ccache, &client_principal);
+ i = krb5_princ_realm(context, client_principal)->length;
+ if (i > REALM_SZ-1)
+ i = REALM_SZ-1;
+ strncpy(realm_of_user,krb5_princ_realm(context, client_principal)->data,i);
+ realm_of_user[i] = 0;
+ try_krb5 = 1;
+ }
+#endif /* NO_KRB5 */
+ if ( !try_krb5 || !realm_of_user[0] ) {
+ if ((rc = (*pkrb_get_tf_realm)((*ptkt_string)(), realm_of_user)) != KSUCCESS)
+ {
+ return(rc);
+ }
+ }
+ strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));
+
+ if (strlen(service) == 0)
+ strcpy(ServiceName, "afs");
+ else
+ strcpy(ServiceName, service);
+
+ if (strlen(cell) == 0)
+ strcpy(CellName, local_cell);
+ else
+ strcpy(CellName, cell);
+
+ if (strlen(realm) == 0)
+ strcpy(RealmName, realm_of_cell);
+ else
+ strcpy(RealmName, realm);
+
+ memset(&creds, '\0', sizeof(creds));
+
+#ifndef NO_KRB5
+ if ( try_krb5 ) {
+ /* First try Service/Cell@REALM */
+ if (r = (*pkrb5_build_principal)(context, &increds.server,
+ strlen(RealmName),
+ RealmName,
+ ServiceName,
+ CellName,
+ 0))
+ {
+ try_krb5 = 0;
+ goto use_krb4;
+ }
+
+ increds.client = client_principal;
+ increds.times.endtime = 0;
+ /* Ask for DES since that is what V4 understands */
+ increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+
+#ifdef KRB5_TC_NOTICKET
+ flags = 0;
+ r = pkrb5_cc_set_flags(context, _krb425_ccache, flags);
+#endif
+ if (r == 0)
+ r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
+ if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+ r == KRB5KRB_ERR_GENERIC /* Heimdal */) {
+ /* Next try Service@REALM */
+ pkrb5_free_principal(context, increds.server);
+ r = pkrb5_build_principal(context, &increds.server,
+ strlen(RealmName),
+ RealmName,
+ ServiceName,
+ 0);
+ if (r == 0)
+ r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
+ }
+
+ pkrb5_free_principal(context, increds.server);
+ pkrb5_free_principal(context, client_principal);
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+ pkrb5_cc_set_flags(context, _krb425_ccache, flags);
+#endif
+ (void) pkrb5_cc_close(context, _krb425_ccache);
+ _krb425_ccache = 0;
+
+ if (r || k5creds == 0) {
+ pkrb5_free_context(context);
+ try_krb5 = 0;
+ goto use_krb4;
+ }
+
+ /* This code inserts the entire K5 ticket into the token
+ * No need to perform a krb524 translation which is
+ * commented out in the code below
+ */
+ if ( use_krb524() || k5creds->ticket.length > MAXKTCTICKETLEN )
+ goto try_krb524d;
+
+ memset(&aserver, '\0', sizeof(aserver));
+ strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
+ strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1);
+
+ memset(&atoken, '\0', sizeof(atoken));
+ atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
+ atoken.startTime = k5creds->times.starttime;
+ atoken.endTime = k5creds->times.endtime;
+ memcpy(&atoken.sessionKey, k5creds->keyblock.contents, k5creds->keyblock.length);
+ atoken.ticketLen = k5creds->ticket.length;
+ memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen);
+
+ retry_gettoken5:
+ rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient);
+ if (rc != 0 && rc != KTC_NOENT && rc != KTC_NOCELL) {
+ if ( rc == KTC_NOCM && retry < 20 ) {
+ Sleep(500);
+ retry++;
+ goto retry_gettoken5;
+ }
+ goto try_krb524d;
+ }
+
+ if (atoken.kvno == btoken.kvno &&
+ atoken.ticketLen == btoken.ticketLen &&
+ !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
+ !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
+ {
+ /* Success */
+ pkrb5_free_creds(context, k5creds);
+ pkrb5_free_context(context);
+ return(0);
+ }
+
+ // * Reset the "aclient" structure before we call ktc_SetToken.
+ // * This structure was first set by the ktc_GetToken call when
+ // * we were comparing whether identical tokens already existed.
+
+ len = min(k5creds->client->data[0].length,MAXKTCNAMELEN - 1);
+ strncpy(aclient.name, k5creds->client->data[0].data, len);
+ aclient.name[len] = '\0';
+
+ if ( k5creds->client->length > 1 ) {
+ char * p;
+ strcat(aclient.name, ".");
+ p = aclient.name + strlen(aclient.name);
+ len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
+ strncpy(p, k5creds->client->data[1].data, len);
+ p[len] = '\0';
+ }
+ aclient.instance[0] = '\0';
+
+ strcpy(aclient.cell, realm_of_cell);
+
+ len = min(k5creds->client->realm.length,strlen(realm_of_cell));
+ if ( strncmp(realm_of_cell, k5creds->client->realm.data, len) ) {
+ char * p;
+ strcat(aclient.name, "@");
+ p = aclient.name + strlen(aclient.name);
+ len = min(k5creds->client->realm.length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
+ strncpy(p, k5creds->client->realm.data, len);
+ p[len] = '\0';
+ }
+
+ rc = ktc_SetToken(&aserver, &atoken, &aclient, 0);
+ if (!rc) {
+ /* Success */
+ pkrb5_free_creds(context, k5creds);
+ pkrb5_free_context(context);
+ return(0);
+ }
+
+ try_krb524d:
+ /* This requires krb524d to be running with the KDC */
+ r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
+ pkrb5_free_creds(context, k5creds);
+ pkrb5_free_context(context);
+ if (r) {
+ try_krb5 = 0;
+ goto use_krb4;
+ }
+ rc = KSUCCESS;
+ } else
+#endif /* NO_KRB5 */
+ {
+ use_krb4:
+ rc = (*pkrb_get_cred)(ServiceName, CellName, RealmName, &creds);
+ if (rc == NO_TKT_FIL) {
+ // if the problem is that we have no krb4 tickets
+ // do not attempt to continue
+ return(rc);
+ }
+ if (rc != KSUCCESS)
+ rc = (*pkrb_get_cred)(ServiceName, "", RealmName, &creds);
+ }
+ if (rc != KSUCCESS)
+ {
+ if ((rc = (*pkrb_mk_req)(&ticket, ServiceName, CellName, RealmName, 0)) == KSUCCESS)
+ {
+ if ((rc = (*pkrb_get_cred)(ServiceName, CellName, RealmName, &creds)) != KSUCCESS)
+ {
+ return(rc);
+ }
+ }
+ else if ((rc = (*pkrb_mk_req)(&ticket, ServiceName, "", RealmName, 0)) == KSUCCESS)
+ {
+ if ((rc = (*pkrb_get_cred)(ServiceName, "", RealmName, &creds)) != KSUCCESS)
+ {
+ return(rc);
+ }
+ }
+ else
+ {
+ return(rc);
+ }
+ }
+
+ memset(&aserver, '\0', sizeof(aserver));
+ strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
+ strncpy(aserver.cell, CellName, MAXKTCNAMELEN - 1);
+
+ memset(&atoken, '\0', sizeof(atoken));
+ atoken.kvno = creds.kvno;
+ atoken.startTime = creds.issue_date;
+ atoken.endTime = (*pkrb_life_to_time)(creds.issue_date,creds.lifetime);
+ memcpy(&atoken.sessionKey, creds.session, 8);
+ atoken.ticketLen = creds.ticket_st.length;
+ memcpy(atoken.ticket, creds.ticket_st.dat, atoken.ticketLen);
+
+ if (!(rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient)) &&
+ atoken.kvno == btoken.kvno &&
+ atoken.ticketLen == btoken.ticketLen &&
+ !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
+ !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
+ {
+ return(0);
+ }
+
+ // * Reset the "aclient" structure before we call ktc_SetToken.
+ // * This structure was first set by the ktc_GetToken call when
+ // * we were comparing whether identical tokens already existed.
+
+ strncpy(aclient.name, creds.pname, MAXKTCNAMELEN - 1);
+ aclient.name[MAXKTCNAMELEN - 1] = '\0';
+ if (creds.pinst[0])
+ {
+ strncat(aclient.name, ".", MAXKTCNAMELEN - 1 - strlen(aclient.name));
+ aclient.name[MAXKTCNAMELEN - 1] = '\0';
+ strncat(aclient.name, creds.pinst, MAXKTCNAMELEN - 1 - strlen(aclient.name));
+ aclient.name[MAXKTCNAMELEN - 1] = '\0';
+ }
+ strcpy(aclient.instance, "");
+
+ if ( strcmp(realm_of_cell, creds.realm) )
+ {
+ strncat(aclient.name, "@", MAXKTCNAMELEN - 1 - strlen(aclient.name));
+ aclient.name[MAXKTCNAMELEN - 1] = '\0';
+ strncat(aclient.name, creds.realm, MAXKTCNAMELEN - 1 - strlen(aclient.name));
+ aclient.name[MAXKTCNAMELEN - 1] = '\0';
+ }
+ aclient.name[MAXKTCNAMELEN-1] = '\0';
+
+ strcpy(aclient.cell, CellName);
+
+ // * NOTE: On WIN32, the order of SetToken params changed...
+ // * to ktc_SetToken(&aserver, &aclient, &atoken, 0)
+ // * from ktc_SetToken(&aserver, &atoken, &aclient, 0) on Unix...
+ // * The afscompat ktc_SetToken provides the Unix order
+
+ if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0))
+ {
+ Leash_afs_error(rc, "ktc_SetToken()");
+ return(rc);
+ }
+
+ return(0);
+#endif
+}
+
+/**************************************/
+/* afs_realm_of_cell(): */
+/**************************************/
+static char *afs_realm_of_cell(afsconf_cell *cellconfig)
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ char krbhst[MAX_HSTNM]="";
+ static char krbrlm[REALM_SZ+1]="";
+#ifndef NO_KRB5
+ krb5_context ctx = 0;
+ char ** realmlist=NULL;
+ krb5_error_code r;
+#endif /* NO_KRB5 */
+
+ if (!cellconfig)
+ return 0;
+
+#ifndef NO_KRB5
+ if ( pkrb5_init_context ) {
+ r = pkrb5_init_context(&ctx);
+ if ( !r )
+ r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist);
+ if ( !r && realmlist && realmlist[0] ) {
+ strcpy(krbrlm, realmlist[0]);
+ pkrb5_free_host_realm(ctx, realmlist);
+ }
+ if (ctx)
+ pkrb5_free_context(ctx);
+ }
+#endif /* NO_KRB5 */
+
+ if ( !krbrlm[0] ) {
+ strcpy(krbrlm, (char *)(*pkrb_realmofhost)(cellconfig->hostName[0]));
+ if ((*pkrb_get_krbhst)(krbhst, krbrlm, 1) != KSUCCESS)
+ krbrlm[0] = '\0';
+ }
+
+ if ( !krbrlm[0] )
+ {
+ char *s = krbrlm;
+ char *t = cellconfig->name;
+ int c;
+
+ while (c = *t++)
+ {
+ if (islower(c)) c=toupper(c);
+ *s++ = c;
+ }
+ *s++ = 0;
+ }
+ return(krbrlm);
+#endif
+}
+
+/**************************************/
+/* get_cellconfig(): */
+/**************************************/
+static int get_cellconfig(char *cell, afsconf_cell *cellconfig, char *local_cell)
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ int rc;
+
+ local_cell[0] = (char)0;
+ memset(cellconfig, 0, sizeof(*cellconfig));
+
+ /* WIN32: cm_GetRootCellName(local_cell) - NOTE: no way to get max chars */
+ if (rc = cm_GetRootCellName(local_cell))
+ {
+ return(rc);
+ }
+
+ if (strlen(cell) == 0)
+ strcpy(cell, local_cell);
+
+ /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
+ strcpy(cellconfig->name, cell);
+
+ return cm_SearchCell(cell, get_cellconfig_callback, NULL, (void*)cellconfig);
+#endif
+}
+
+/**************************************/
+/* get_cellconfig_callback(): */
+/**************************************/
+static long get_cellconfig_callback(void *cellconfig, struct sockaddr_in *addrp, char *namep)
+{
+#ifdef NO_AFS
+ return(0);
+#else
+ afsconf_cell *cc = (afsconf_cell *)cellconfig;
+
+ cc->hostAddr[cc->numServers] = *addrp;
+ strcpy(cc->hostName[cc->numServers], namep);
+ cc->numServers++;
+ return(0);
+#endif
+}
+
+
+/**************************************/
+/* Leash_afs_error(): */
+/**************************************/
+void
+Leash_afs_error(LONG rc, LPCSTR FailedFunctionName)
+{
+#ifdef NO_AFS
+ return;
+#else
+ char message[256];
+ const char *errText;
+
+ // Using AFS defines as error messages for now, until Transarc
+ // gets back to me with "string" translations of each of these
+ // const. defines.
+ if (rc == KTC_ERROR)
+ errText = "KTC_ERROR";
+ else if (rc == KTC_TOOBIG)
+ errText = "KTC_TOOBIG";
+ else if (rc == KTC_INVAL)
+ errText = "KTC_INVAL";
+ else if (rc == KTC_NOENT)
+ errText = "KTC_NOENT";
+ else if (rc == KTC_PIOCTLFAIL)
+ errText = "KTC_PIOCTLFAIL";
+ else if (rc == KTC_NOPIOCTL)
+ errText = "KTC_NOPIOCTL";
+ else if (rc == KTC_NOCELL)
+ errText = "KTC_NOCELL";
+ else if (rc == KTC_NOCM)
+ errText = "KTC_NOCM: The service, Transarc AFS Daemon, most likely is not started!";
+ else
+ errText = "Unknown error!";
+
+ sprintf(message, "%s\n(%s failed)", errText, FailedFunctionName);
+ MessageBox(NULL, message, "AFS", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
+ return;
+
+#endif
+}
+
+DWORD GetServiceStatus(
+ LPSTR lpszMachineName,
+ LPSTR lpszServiceName,
+ DWORD *lpdwCurrentState)
+{
+#ifdef NO_AFS
+ return(NOERROR);
+#else
+ DWORD hr = NOERROR;
+ SC_HANDLE schSCManager = NULL;
+ SC_HANDLE schService = NULL;
+ DWORD fdwDesiredAccess = 0;
+ SERVICE_STATUS ssServiceStatus = {0};
+ BOOL fRet = FALSE;
+
+ if ((pOpenSCManagerA == NULL) ||
+ (pOpenServiceA == NULL) ||
+ (pQueryServiceStatus == NULL) ||
+ (pCloseServiceHandle == NULL))
+ {
+ *lpdwCurrentState = SERVICE_RUNNING;
+ return(NOERROR);
+ }
+
+ *lpdwCurrentState = 0;
+
+ fdwDesiredAccess = GENERIC_READ;
+
+ schSCManager = (*pOpenSCManagerA)(lpszMachineName,
+ NULL,
+ fdwDesiredAccess);
+
+ if(schSCManager == NULL)
+ {
+ hr = GetLastError();
+ goto cleanup;
+ }
+
+ schService = (*pOpenServiceA)(schSCManager,
+ lpszServiceName,
+ fdwDesiredAccess);
+
+ if(schService == NULL)
+ {
+ hr = GetLastError();
+ goto cleanup;
+ }
+
+ fRet = (*pQueryServiceStatus)(schService,
+ &ssServiceStatus);
+
+ if(fRet == FALSE)
+ {
+ hr = GetLastError();
+ goto cleanup;
+ }
+
+ *lpdwCurrentState = ssServiceStatus.dwCurrentState;
+
+cleanup:
+
+ (*pCloseServiceHandle)(schService);
+ (*pCloseServiceHandle)(schSCManager);
+
+ return(hr);
+#endif
+}
+
+BOOL
+SetAfsStatus(
+ DWORD AfsStatus
+ )
+{
+#ifdef NO_AFS
+ return(TRUE);
+#else
+ return write_registry_setting(LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS,
+ REG_DWORD, &AfsStatus,
+ sizeof(AfsStatus)) ? FALSE : TRUE;
+#endif
+}
+
+BOOL
+GetAfsStatus(
+ DWORD *AfsStatus
+ )
+{
+#ifdef NO_AFS
+ return(TRUE);
+#else
+ return read_registry_setting(LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS,
+ AfsStatus, sizeof(DWORD)) ? FALSE : TRUE;
+#endif
+}
diff --git a/src/windows/leashdll/include/krb4/conf-pc.h b/src/windows/leashdll/include/krb4/conf-pc.h
new file mode 100644
index 0000000000..65a8779caf
--- /dev/null
+++ b/src/windows/leashdll/include/krb4/conf-pc.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: IBM PC 8086
+ */
+
+#if defined(_WIN32) && !defined(WIN32)
+#define WIN32
+#endif
+
+#if ( defined(WIN16) || defined(WIN32) || defined(_WINDOWS)) && !defined(WINDOWS)
+#define WINDOWS
+#endif
+
+#if defined(__OS2__) && !defined(OS2)
+#define OS2
+#endif
+
+#ifdef WIN16
+#define BITS16
+#else
+#ifdef MSDOS
+#define BITS16
+#else
+#define BITS32
+#endif
+#endif
+#define LSBFIRST
+
+#define index(s,c) strchr(s,c) /* PC version of index */
+#define rindex(s,c) strrchr(s,c)
+#if !defined(OS2) && !defined(LWP) /* utils.h under OS/2 */
+#define bcmp(s1,s2,n) memcmp((s1),(s2),(n))
+#define bcopy(a,b,c) memcpy( (b), (a), (c) )
+#define bzero(a,b) memset( (a), 0, (b) )
+#endif
+
+typedef unsigned char u_char;
+typedef unsigned long u_long;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+#define NO_UIDGID_T
+
+#if !defined(WINDOWS) && !defined(DWORD)
+typedef long DWORD;
+#endif
+
+#if defined(PC)&&!defined(WINDOWS)
+#ifndef LPSTR
+typedef char *LPSTR;
+typedef char *LPBYTE;
+typedef char *CHARPTR;
+typedef char *LPINT;
+typedef unsigned int WORD;
+#endif
+#define LONG long
+#define FAR
+#define PASCAL
+#define EXPORT
+#endif
+
+#ifdef OS2
+#include <utils.h>
+#define lstrcpy strcpy
+#define lstrlen strlen
+#define lstrcmp strcmp
+#define lstrcpyn strncpy
+#endif
+
+#ifdef WIN32
+#define _export
+#endif
+
+#if defined(BITS32)
+#define far
+#define near
+#endif
+
+#ifdef WINDOWS
+#include <windows.h>
+#endif
+
+#ifdef WIN32
+#include <windowsx.h>
+#endif
+
+#ifdef WIN16
+#pragma message ( "WIN16 in " __FILE__ )
+#include <time.h>
+#include <process.h>
+#ifndef KRB_INT32
+#define KRB_INT32 long
+#endif
+#ifndef KRB_UINT32
+#define KRB_UINT32 unsigned KRB_INT32
+#endif
+#endif
+
+
+#define RANDOM_KRB_INT32_1 ((KRB_INT32) time(NULL))
+#define RANDOM_KRB_INT32_2 ((KRB_INT32) getpid())
+#define TIME_GMT_UNIXSEC unix_time_gmt_unixsec((unsigned KRB_INT32 *)0);
+#ifndef MAXPATHLEN
+#define MAXPATHLEN _MAX_PATH
+#endif
diff --git a/src/windows/leashdll/include/krb4/conf.h b/src/windows/leashdll/include/krb4/conf.h
new file mode 100644
index 0000000000..2e2a84cd6e
--- /dev/null
+++ b/src/windows/leashdll/include/krb4/conf.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Configuration info for operating system, hardware description,
+ * language implementation, C library, etc.
+ *
+ * This file should be included in (almost) every file in the Kerberos
+ * sources, and probably should *not* be needed outside of those
+ * sources. (How do we deal with /usr/include/des.h and
+ * /usr/include/krb.h?)
+ */
+
+#ifndef _CONF_H_
+#define _CONF_H_
+
+#include "osconf.h"
+
+#ifdef SHORTNAMES
+#include "names.h"
+#endif
+
+/*
+ * Language implementation-specific definitions
+ */
+
+/* special cases */
+#ifdef __HIGHC__
+/* broken implementation of ANSI C */
+#undef __STDC__
+#endif
+
+#if !defined(__STDC__) && !defined(PC)
+#define const
+#define volatile
+#define signed
+typedef char *pointer; /* pointer to generic data */
+#ifndef PROTOTYPE
+#define PROTOTYPE(p) ()
+#endif
+#else
+typedef void *pointer;
+#ifndef PROTOTYPE
+#define PROTOTYPE(p) p
+#endif
+#endif
+
+/* Does your compiler understand "void"? */
+#ifdef notdef
+#define void int
+#endif
+
+/*
+ * A few checks to see that necessary definitions are included.
+ */
+
+#ifndef MSBFIRST
+#ifndef LSBFIRST
+#error byte order not defined
+#endif
+#endif
+
+/* machine size */
+#ifndef BITS16
+#ifndef BITS32
+#error number of bits?
+#endif
+#endif
+
+/* end of checks */
+
+#endif /* _CONF_H_ */
diff --git a/src/windows/leashdll/include/krb4/osconf.h b/src/windows/leashdll/include/krb4/osconf.h
new file mode 100644
index 0000000000..340421e868
--- /dev/null
+++ b/src/windows/leashdll/include/krb4/osconf.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Athena configuration.
+ */
+
+#ifndef _OSCONF_H_
+#define _OSCONF_H_
+
+#ifndef PC
+#if defined(IBMPC) || defined(__MSDOS__) || defined(OS2) || defined(_MSDOS) || defined(_WIN32)
+#define PC
+#endif
+#endif
+
+#ifdef tahoe
+#include "conf-bsdtahoe.h"
+#else /* !tahoe */
+#ifdef vax
+#include "conf-bsdvax.h"
+#else /* !vax */
+#if defined(mips) && defined(ultrix)
+#include "conf-ultmips2.h"
+#else /* !Ultrix MIPS-2 */
+#ifdef ibm032
+#include "conf-bsdibm032.h"
+#else /* !ibm032 */
+#ifdef apollo
+#include "conf-bsdapollo.h"
+#else /* !apollo */
+#ifdef sun
+#ifdef sparc
+#include "conf-bsdsparc.h"
+#else /* sun but not sparc */
+#ifdef i386
+#include "conf-bsd386i.h"
+#else /* sun but not (sparc or 386i) */
+#include "conf-bsdm68k.h"
+#endif /* i386 */
+#endif /* sparc */
+#else /* !sun */
+#ifdef pyr
+#include "conf-pyr.h"
+#else
+#if defined(PC) || defined(__MSDOS__) || defined(OS2) || defined(_MSDOS) || defined(_WIN32)
+#include "conf-pc.h"
+#endif /* PC */
+#endif /* pyr */
+#endif /* sun */
+#endif /* apollo */
+#endif /* ibm032 */
+#endif /* mips */
+#endif /* vax */
+#endif /* tahoe */
+
+#endif /* _OSCONF_H_ */
diff --git a/src/windows/leashdll/include/leasherr.h b/src/windows/leashdll/include/leasherr.h
new file mode 100644
index 0000000000..834765fbb8
--- /dev/null
+++ b/src/windows/leashdll/include/leasherr.h
@@ -0,0 +1,32 @@
+/*
+ * leasherr.h
+ * This file is the #include file for leasherr.et.
+ * Please do not edit it as it is automatically generated.
+ */
+
+#define LSH_ONLYONEME (40591872L)
+#define LSH_INVPRINCIPAL (40591873L)
+#define LSH_FAILEDREALM (40591874L)
+#define LSH_INVINSTANCE (40591875L)
+#define LSH_INVREALM (40591876L)
+#define LSH_EOF (40591877L)
+#define LSH_EXPIRESOON (40591878L)
+#define LSH_NOMATCH (40591879L)
+#define LSH_BADCHARS (40591880L)
+#define LSH_FATAL_ERROR (40591881L)
+#define LSH_BADWINSOCK (40591882L)
+#define LSH_BADTIMESERV (40591883L)
+#define LSH_NOSOCKET (40591884L)
+#define LSH_NOCONNECT (40591885L)
+#define LSH_TIMEFAILED (40591886L)
+#define LSH_GETTIMEOFDAY (40591887L)
+#define LSH_SETTIMEOFDAY (40591888L)
+#define LSH_RECVTIME (40591889L)
+#define LSH_RECVBYTES (40591890L)
+#define LSH_ALREADY_SETTIME (40591891L)
+extern void initialize_lsh_error_table(struct et_list **);
+#define ERROR_TABLE_BASE_lsh (40591872L)
+
+/* for compatibility with older versions... */
+#define init_lsh_err_tbl() initialize_lsh_error_table(&_et_list)
+#define lsh_err_base ERROR_TABLE_BASE_lsh
diff --git a/src/windows/leashdll/include/leashinfo.h b/src/windows/leashdll/include/leashinfo.h
new file mode 100644
index 0000000000..7365aa1b54
--- /dev/null
+++ b/src/windows/leashdll/include/leashinfo.h
@@ -0,0 +1,2 @@
+#define LSH_TIME_HOST 1970
+#define LSH_DEFAULT_TICKET_LIFE 1971
diff --git a/src/windows/leashdll/include/leashwin.h b/src/windows/leashdll/include/leashwin.h
new file mode 100644
index 0000000000..477c6c30cd
--- /dev/null
+++ b/src/windows/leashdll/include/leashwin.h
@@ -0,0 +1,188 @@
+#ifndef __LEASHWIN__
+#define __LEASHWIN__
+
+#include <krb.h>
+
+#define DLGTYPE_PASSWD 0
+#define DLGTYPE_CHPASSWD 1
+typedef struct {
+ int dlgtype;
+ // Tells whether dialog box is in change pwd more or init ticket mode???
+ // (verify this):
+ int dlgstatemax; // What is this???
+ // The title on the Dialog box - for Renewing or Initializing:
+ LPSTR title;
+ LPSTR principal;
+} LSH_DLGINFO, FAR *LPLSH_DLGINFO;
+
+#define LEASH_USERNAME_SZ 64
+#define LEASH_REALM_SZ 192
+#define LEASH_TITLE_SZ 128
+#define LEASH_CCACHE_NAME_SZ 264
+
+typedef struct {
+ DWORD size;
+ int dlgtype;
+ // Tells whether dialog box is in change pwd mode or init ticket mode
+ LPSTR title; // in v3, set to in.title
+ LPSTR username; // in v3, set to in.username
+ LPSTR realm; // in v3, set to in.realm
+ int use_defaults;
+ int forwardable;
+ int noaddresses;
+ int lifetime;
+ int renew_till;
+ int proxiable;
+ int publicip;
+ // Version 1 of this structure ends here
+ struct {
+ char username[LEASH_USERNAME_SZ];
+ char realm[LEASH_REALM_SZ];
+ // Version 2 of this structure ends here
+ char ccache[LEASH_CCACHE_NAME_SZ];
+ } out;
+ struct {
+ char title[LEASH_TITLE_SZ];
+ char username[LEASH_USERNAME_SZ];
+ char realm[LEASH_REALM_SZ];
+ char ccache[LEASH_CCACHE_NAME_SZ];
+ } in;
+} LSH_DLGINFO_EX, *LPLSH_DLGINFO_EX;
+
+#define LSH_DLGINFO_EX_V1_SZ (sizeof(DWORD) + 3 * sizeof(LPSTR) + 8 * sizeof(int))
+#define LSH_DLGINFO_EX_V2_SZ (LSH_DLGINFO_EX_V1_SZ + LEASH_USERNAME_SZ + LEASH_REALM_SZ)
+#define LSH_DLGINFO_EX_V3_SZ (LSH_DLGINFO_EX_V2_SZ + LEASH_TITLE_SZ + LEASH_USERNAME_SZ + LEASH_REALM_SZ + 2 * LEASH_CCACHE_NAME_SZ)
+
+#ifndef NETIDMGR
+#define NETID_USERNAME_SZ 128
+#define NETID_REALM_SZ 192
+#define NETID_TITLE_SZ 256
+#define NETID_CCACHE_NAME_SZ 264
+
+#define NETID_DLGTYPE_TGT 0
+#define NETID_DLGTYPE_CHPASSWD 1
+typedef struct {
+ DWORD size;
+ DWORD dlgtype;
+ // Tells whether dialog box is in change pwd mode or init ticket mode
+ struct {
+ WCHAR title[NETID_TITLE_SZ];
+ WCHAR username[NETID_USERNAME_SZ];
+ WCHAR realm[NETID_REALM_SZ];
+ WCHAR ccache[NETID_CCACHE_NAME_SZ];
+ DWORD use_defaults;
+ DWORD forwardable;
+ DWORD noaddresses;
+ DWORD lifetime;
+ DWORD renew_till;
+ DWORD proxiable;
+ DWORD publicip;
+ DWORD must_use_specified_principal;
+ } in;
+ struct {
+ WCHAR username[NETID_USERNAME_SZ];
+ WCHAR realm[NETID_REALM_SZ];
+ WCHAR ccache[NETID_CCACHE_NAME_SZ];
+ } out;
+ // Version 1 of this structure ends here
+} NETID_DLGINFO, *LPNETID_DLGINFO;
+
+#define NETID_DLGINFO_V1_SZ (10 * sizeof(DWORD) \
+ + sizeof(WCHAR) * (NETID_TITLE_SZ + \
+ 2 * NETID_USERNAME_SZ + 2 * NETID_REALM_SZ + \
+ 2 * NETID_CCACHE_NAME_SZ))
+#endif /* NETIDMGR */
+
+typedef struct {
+ char principal[MAX_K_NAME_SZ]; /* Principal name/instance/realm */
+ int btickets; /* Do we have tickets? */
+ long lifetime; /* Lifetime -- needs to have
+ room for 255 5-minute
+ periods * 5 * 60 */
+ long issue_date; /* The issue time */
+ long renew_till; /* The Renew time (k5 only) */
+} TICKETINFO;
+
+int FAR Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo);
+int FAR Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfoex);
+int FAR Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo);
+int FAR Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo);
+
+long FAR Leash_checkpwd(char *principal, char *password);
+long FAR Leash_changepwd(char *principal, char *password, char *newpassword, char** result_string);
+long FAR Leash_kinit(char *principal, char *password, int lifetime);
+long FAR Leash_kinit_ex(char * principal, char * password, int lifetime,
+ int forwardable, int proxiable, int renew_life,
+ int addressless, unsigned long publicIP);
+
+long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo);
+long FAR Leash_kdestroy(void);
+long FAR Leash_get_lsh_errno( LONG FAR *err_val);
+
+long FAR Leash_renew(void);
+long FAR Leash_importable(void);
+long FAR Leash_import(void);
+
+BOOL Leash_set_help_file( char FAR *szHelpFile );
+LPSTR Leash_get_help_file(void);
+
+void Leash_reset_defaults(void);
+
+#define NO_TICKETS 0
+#define EXPD_TICKETS 2
+#define GOOD_TICKETS 1
+
+/* Leash Configuration functions - alters Current User Registry */
+DWORD Leash_get_default_lifetime();
+DWORD Leash_set_default_lifetime(DWORD minutes);
+DWORD Leash_reset_default_lifetime();
+DWORD Leash_get_default_renew_till();
+DWORD Leash_set_default_renew_till(DWORD minutes);
+DWORD Leash_reset_default_renew_till();
+DWORD Leash_get_default_renewable();
+DWORD Leash_set_default_renewable(DWORD onoff);
+DWORD Leash_reset_default_renewable();
+DWORD Leash_get_default_forwardable();
+DWORD Leash_set_default_forwardable(DWORD onoff);
+DWORD Leash_reset_default_forwardable();
+DWORD Leash_get_default_noaddresses();
+DWORD Leash_set_default_noaddresses(DWORD onoff);
+DWORD Leash_reset_default_noaddresses();
+DWORD Leash_get_default_proxiable();
+DWORD Leash_set_default_proxiable(DWORD onoff);
+DWORD Leash_reset_default_proxiable();
+DWORD Leash_get_default_publicip();
+DWORD Leash_set_default_publicip(DWORD ipv4addr);
+DWORD Leash_reset_default_publicip();
+DWORD Leash_get_default_use_krb4();
+DWORD Leash_set_default_use_krb4(DWORD onoff);
+DWORD Leash_reset_default_use_krb4();
+DWORD Leash_get_hide_kinit_options();
+DWORD Leash_set_hide_kinit_options(DWORD onoff);
+DWORD Leash_reset_hide_kinit_options();
+DWORD Leash_get_default_life_min();
+DWORD Leash_set_default_life_min(DWORD minutes);
+DWORD Leash_reset_default_life_min();
+DWORD Leash_get_default_life_max();
+DWORD Leash_set_default_life_max(DWORD minutes);
+DWORD Leash_reset_default_life_max();
+DWORD Leash_get_default_renew_min();
+DWORD Leash_set_default_renew_min(DWORD minutes);
+DWORD Leash_reset_default_renew_min();
+DWORD Leash_get_default_renew_max();
+DWORD Leash_set_default_renew_max(DWORD minutes);
+DWORD Leash_reset_default_renew_max();
+DWORD Leash_get_lock_file_locations();
+DWORD Leash_set_lock_file_locations(DWORD onoff);
+DWORD Leash_reset_lock_file_locations();
+DWORD Leash_get_default_uppercaserealm();
+DWORD Leash_set_default_uppercaserealm(DWORD onoff);
+DWORD Leash_reset_default_uppercaserealm();
+DWORD Leash_get_default_mslsa_import();
+DWORD Leash_set_default_mslsa_import(DWORD onoffmatch);
+DWORD Leash_reset_default_mslsa_import();
+DWORD Leash_get_default_preserve_kinit_settings();
+DWORD Leash_set_default_preserve_kinit_settings(DWORD onoff);
+DWORD Leash_reset_default_preserve_kinit_settings();
+
+#endif /* LEASHWIN */
diff --git a/src/windows/leashdll/include/loadfuncs-com_err.h b/src/windows/leashdll/include/loadfuncs-com_err.h
new file mode 100644
index 0000000000..a579749c17
--- /dev/null
+++ b/src/windows/leashdll/include/loadfuncs-com_err.h
@@ -0,0 +1,44 @@
+#ifndef __LOADFUNCS_COM_ERR_H__
+#define __LOADFUNCS_COM_ERR_H__
+
+#include "loadfuncs.h"
+#include <com_err.h>
+
+#if defined(_WIN64)
+#define COMERR_DLL "comerr64.dll"
+#else
+#define COMERR_DLL "comerr32.dll"
+#endif
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV_C,
+ com_err,
+ (const char FAR *, errcode_t, const char FAR *, ...)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ com_err_va,
+ (const char FAR *whoami, errcode_t code, const char FAR *fmt, va_list ap)
+ );
+TYPEDEF_FUNC(
+ const char FAR *,
+ KRB5_CALLCONV,
+ error_message,
+ (errcode_t)
+ );
+TYPEDEF_FUNC(
+ errcode_t,
+ KRB5_CALLCONV,
+ add_error_table,
+ (const struct error_table FAR *)
+ );
+TYPEDEF_FUNC(
+ errcode_t,
+ KRB5_CALLCONV,
+ remove_error_table,
+ (const struct error_table FAR *)
+ );
+
+#endif /* __LOADFUNCS_COM_ERR_H__ */
diff --git a/src/windows/leashdll/include/loadfuncs-krb5.h b/src/windows/leashdll/include/loadfuncs-krb5.h
new file mode 100644
index 0000000000..1fab675391
--- /dev/null
+++ b/src/windows/leashdll/include/loadfuncs-krb5.h
@@ -0,0 +1,1757 @@
+#ifndef __LOADFUNCS_KRB5_H__
+#define __LOADFUNCS_KRB5_H__
+
+#include "loadfuncs.h"
+#include <krb5.h>
+
+#if defined(_WIN64)
+#define KRB5_DLL "krb5_64.dll"
+#else
+#define KRB5_DLL "krb5_32.dll"
+#endif
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_principal,
+ (krb5_context, krb5_principal)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_authenticator,
+ (krb5_context, krb5_authenticator * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_authenticator_contents,
+ (krb5_context, krb5_authenticator * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_addresses,
+ (krb5_context, krb5_address * * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_address,
+ (krb5_context, krb5_address * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_authdata,
+ (krb5_context, krb5_authdata * * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_enc_tkt_part,
+ (krb5_context, krb5_enc_tkt_part * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_ticket,
+ (krb5_context, krb5_ticket * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_tickets,
+ (krb5_context, krb5_ticket * * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_kdc_req,
+ (krb5_context, krb5_kdc_req * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_kdc_rep,
+ (krb5_context, krb5_kdc_rep * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_last_req,
+ (krb5_context, krb5_last_req_entry * * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_enc_kdc_rep_part,
+ (krb5_context, krb5_enc_kdc_rep_part * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_error,
+ (krb5_context, krb5_error * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_ap_req,
+ (krb5_context, krb5_ap_req * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_ap_rep,
+ (krb5_context, krb5_ap_rep * )
+ );
+
+/* Removed around the time of krb5_rc_* change... */
+#if 0
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_safe,
+ (krb5_context, krb5_safe * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_priv,
+ (krb5_context, krb5_priv * )
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_priv_enc_part,
+ (krb5_context, krb5_priv_enc_part * )
+ );
+#endif
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_cred,
+ (krb5_context, krb5_cred *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_creds,
+ (krb5_context, krb5_creds *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_cred_contents,
+ (krb5_context, krb5_creds *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_cred_enc_part,
+ (krb5_context, krb5_cred_enc_part *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_checksum,
+ (krb5_context, krb5_checksum *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_checksum_contents,
+ (krb5_context, krb5_checksum *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_keyblock,
+ (krb5_context, krb5_keyblock *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_keyblock_contents,
+ (krb5_context, krb5_keyblock *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_pa_data,
+ (krb5_context, krb5_pa_data * *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_ap_rep_enc_part,
+ (krb5_context, krb5_ap_rep_enc_part *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_tkt_authent,
+ (krb5_context, krb5_tkt_authent *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_pwd_data,
+ (krb5_context, krb5_pwd_data *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_pwd_sequences,
+ (krb5_context, passwd_phrase_element * *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_data,
+ (krb5_context, krb5_data *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_data_contents,
+ (krb5_context, krb5_data *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_unparsed_name,
+ (krb5_context, char *)
+ );
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_cksumtypes,
+ (krb5_context, krb5_cksumtype *)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_encrypt,
+ (krb5_context context, const krb5_keyblock *key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ const krb5_data *input, krb5_enc_data *output)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_decrypt,
+ (krb5_context context, const krb5_keyblock *key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ const krb5_enc_data *input, krb5_data *output)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_encrypt_length,
+ (krb5_context context, krb5_enctype enctype,
+ size_t inputlen, size_t *length)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_block_size,
+ (krb5_context context, krb5_enctype enctype,
+ size_t *blocksize)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_make_random_key,
+ (krb5_context context, krb5_enctype enctype,
+ krb5_keyblock *random_key)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_random_make_octets,
+ (krb5_context context, krb5_data *data)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_random_seed,
+ (krb5_context context, krb5_data *data)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_string_to_key,
+ (krb5_context context, krb5_enctype enctype,
+ const krb5_data *string, const krb5_data *salt,
+ krb5_keyblock *key)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_enctype_compare,
+ (krb5_context context, krb5_enctype e1, krb5_enctype e2,
+ krb5_boolean *similar)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_make_checksum,
+ (krb5_context context, krb5_cksumtype cksumtype,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *input, krb5_checksum *cksum)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_verify_checksum,
+ (krb5_context context,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *data,
+ const krb5_checksum *cksum,
+ krb5_boolean *valid)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_checksum_length,
+ (krb5_context context, krb5_cksumtype cksumtype,
+ size_t *length)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_c_keyed_checksum_types,
+ (krb5_context context, krb5_enctype enctype,
+ unsigned int *count, krb5_cksumtype **cksumtypes)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_boolean,
+ KRB5_CALLCONV,
+ valid_enctype,
+ (const krb5_enctype ktype)
+ );
+
+TYPEDEF_FUNC(
+ krb5_boolean,
+ KRB5_CALLCONV,
+ valid_cksumtype,
+ (const krb5_cksumtype ctype)
+ );
+
+TYPEDEF_FUNC(
+ krb5_boolean,
+ KRB5_CALLCONV,
+ is_coll_proof_cksum,
+ (const krb5_cksumtype ctype)
+ );
+
+TYPEDEF_FUNC(
+ krb5_boolean,
+ KRB5_CALLCONV,
+ is_keyed_cksum,
+ (const krb5_cksumtype ctype)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_init_context,
+ (krb5_context *)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_context,
+ (krb5_context)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_decrypt_tkt_part,
+ (krb5_context,
+ const krb5_keyblock *,
+ krb5_ticket * )
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_tgt_creds,
+ (krb5_context,
+ krb5_creds ** )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_credentials,
+ (krb5_context,
+ const krb5_flags,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_creds * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_credentials_validate,
+ (krb5_context,
+ const krb5_flags,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_creds * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_credentials_renew,
+ (krb5_context,
+ const krb5_flags,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_creds * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_req,
+ (krb5_context,
+ krb5_auth_context *,
+ const krb5_flags,
+ char *,
+ char *,
+ krb5_data *,
+ krb5_ccache,
+ krb5_data * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_req_extended,
+ (krb5_context,
+ krb5_auth_context *,
+ const krb5_flags,
+ krb5_data *,
+ krb5_creds *,
+ krb5_data * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_rep,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_rep,
+ (krb5_context,
+ krb5_auth_context,
+ const krb5_data *,
+ krb5_ap_rep_enc_part * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_error,
+ (krb5_context,
+ const krb5_error *,
+ krb5_data * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_error,
+ (krb5_context,
+ const krb5_data *,
+ krb5_error * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_safe,
+ (krb5_context,
+ krb5_auth_context,
+ const krb5_data *,
+ krb5_data *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_priv,
+ (krb5_context,
+ krb5_auth_context,
+ const krb5_data *,
+ krb5_data *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_parse_name,
+ (krb5_context,
+ const char *,
+ krb5_principal * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_unparse_name,
+ (krb5_context,
+ krb5_const_principal,
+ char * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_unparse_name_ext,
+ (krb5_context,
+ krb5_const_principal,
+ char * *,
+ int *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_set_principal_realm,
+ (krb5_context, krb5_principal, const char *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_boolean,
+ KRB5_CALLCONV,
+ krb5_principal_compare,
+ (krb5_context,
+ krb5_const_principal,
+ krb5_const_principal)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_keyblock,
+ (krb5_context,
+ const krb5_keyblock *,
+ krb5_keyblock * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_keyblock_contents,
+ (krb5_context,
+ const krb5_keyblock *,
+ krb5_keyblock *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_creds,
+ (krb5_context,
+ const krb5_creds *,
+ krb5_creds * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_data,
+ (krb5_context,
+ const krb5_data *,
+ krb5_data * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_principal,
+ (krb5_context,
+ krb5_const_principal,
+ krb5_principal *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_addr,
+ (krb5_context,
+ const krb5_address *,
+ krb5_address * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_addresses,
+ (krb5_context,
+ krb5_address * const *,
+ krb5_address * * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_ticket,
+ (krb5_context,
+ const krb5_ticket *,
+ krb5_ticket * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_authdata,
+ (krb5_context,
+ krb5_authdata * const *,
+ krb5_authdata * * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_authenticator,
+ (krb5_context,
+ const krb5_authenticator *,
+ krb5_authenticator * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_copy_checksum,
+ (krb5_context,
+ const krb5_checksum *,
+ krb5_checksum * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_server_rcache,
+ (krb5_context,
+ const krb5_data *, krb5_rcache *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV_C,
+ krb5_build_principal_ext,
+ (krb5_context, krb5_principal *, int, const char *, ...)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV_C,
+ krb5_build_principal,
+ (krb5_context, krb5_principal *, int, const char *, ...)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_425_conv_principal,
+ (krb5_context,
+ const char *name,
+ const char *instance, const char *realm,
+ krb5_principal *princ)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_524_conv_principal,
+ (krb5_context context, const krb5_principal princ,
+ char *name, char *inst, char *realm)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_chpw_req,
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *ap_req, char *passwd, krb5_data *packet)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_chpw_rep,
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *packet, int *result_code,
+ krb5_data *result_data)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_chpw_result_code_string,
+ (krb5_context context, int result_code,
+ char **result_codestr)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_register,
+ (krb5_context,
+ struct _krb5_kt_ops * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_resolve,
+ (krb5_context,
+ const char *,
+ krb5_keytab * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_default_name,
+ (krb5_context,
+ char *,
+ int )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_default,
+ (krb5_context,
+ krb5_keytab * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_free_entry,
+ (krb5_context,
+ krb5_keytab_entry * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_remove_entry,
+ (krb5_context,
+ krb5_keytab,
+ krb5_keytab_entry * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_add_entry,
+ (krb5_context,
+ krb5_keytab,
+ krb5_keytab_entry * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_resolve,
+ (krb5_context,
+ const char *,
+ krb5_ccache * )
+ );
+
+TYPEDEF_FUNC(
+ const char*,
+ KRB5_CALLCONV,
+ krb5_cc_default_name,
+ (krb5_context)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_set_default_name,
+ (krb5_context, const char *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_default,
+ (krb5_context,
+ krb5_ccache *)
+ );
+
+TYPEDEF_FUNC(
+ unsigned int,
+ KRB5_CALLCONV,
+ krb5_get_notification_message,
+ (void)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_copy_creds,
+ (krb5_context context,
+ krb5_ccache incc,
+ krb5_ccache outcc)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_us_timeofday,
+ (krb5_context,
+ krb5_int32 *,
+ krb5_int32 * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_timeofday,
+ (krb5_context,
+ krb5_int32 * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_os_localaddr,
+ (krb5_context,
+ krb5_address * * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_default_realm,
+ (krb5_context,
+ char * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_set_default_realm,
+ (krb5_context,
+ const char * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_free_default_realm,
+ (krb5_context,
+ const char * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_sname_to_principal,
+ (krb5_context,
+ const char *,
+ const char *,
+ krb5_int32,
+ krb5_principal *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_change_password,
+ (krb5_context context, krb5_creds *creds, char *newpw,
+ int *result_code, krb5_data *result_code_string,
+ krb5_data *result_string)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_default_config_files,
+ (char ***filenames)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_config_files,
+ (char **filenames)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_in_tkt,
+ (krb5_context,
+ const krb5_flags,
+ krb5_address * const *,
+ krb5_enctype *,
+ krb5_preauthtype *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock * *),
+ krb5_const_pointer,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_keyblock *,
+ krb5_const_pointer,
+ krb5_kdc_rep * ),
+ krb5_const_pointer,
+ krb5_creds *,
+ krb5_ccache,
+ krb5_kdc_rep * * )
+ );
+
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_in_tkt_with_password,
+ (krb5_context,
+ const krb5_flags,
+ krb5_address * const *,
+ krb5_enctype *,
+ krb5_preauthtype *,
+ const char *,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_kdc_rep * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_in_tkt_with_skey,
+ (krb5_context,
+ const krb5_flags,
+ krb5_address * const *,
+ krb5_enctype *,
+ krb5_preauthtype *,
+ const krb5_keyblock *,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_kdc_rep * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_in_tkt_with_keytab,
+ (krb5_context,
+ const krb5_flags,
+ krb5_address * const *,
+ krb5_enctype *,
+ krb5_preauthtype *,
+ const krb5_keytab,
+ krb5_ccache,
+ krb5_creds *,
+ krb5_kdc_rep * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_req,
+ (krb5_context,
+ krb5_auth_context *,
+ const krb5_data *,
+ krb5_const_principal,
+ krb5_keytab,
+ krb5_flags *,
+ krb5_ticket * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_read_service_key,
+ (krb5_context,
+ krb5_pointer,
+ krb5_principal,
+ krb5_kvno,
+ krb5_enctype,
+ krb5_keyblock * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_safe,
+ (krb5_context,
+ krb5_auth_context,
+ const krb5_data *,
+ krb5_data *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_priv,
+ (krb5_context,
+ krb5_auth_context,
+ const krb5_data *,
+ krb5_data *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_register,
+ (krb5_context,
+ krb5_cc_ops *,
+ krb5_boolean )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_sendauth,
+ (krb5_context,
+ krb5_auth_context *,
+ krb5_pointer,
+ char *,
+ krb5_principal,
+ krb5_principal,
+ krb5_flags,
+ krb5_data *,
+ krb5_creds *,
+ krb5_ccache,
+ krb5_error * *,
+ krb5_ap_rep_enc_part * *,
+ krb5_creds * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_recvauth,
+ (krb5_context,
+ krb5_auth_context *,
+ krb5_pointer,
+ char *,
+ krb5_principal,
+ krb5_int32,
+ krb5_keytab,
+ krb5_ticket * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_ncred,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_creds * *,
+ krb5_data * *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_mk_1cred,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_creds *,
+ krb5_data * *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_rd_cred,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_data *,
+ krb5_creds * * *,
+ krb5_replay_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_fwd_tgt_creds,
+ (krb5_context,
+ krb5_auth_context,
+ char *,
+ krb5_principal,
+ krb5_principal,
+ krb5_ccache,
+ int forwardable,
+ krb5_data *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_init,
+ (krb5_context,
+ krb5_auth_context *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_free,
+ (krb5_context,
+ krb5_auth_context)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_setflags,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_int32)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getflags,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_int32 *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_setuseruserkey,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_keyblock *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getkey,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_keyblock **)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getlocalsubkey,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_keyblock * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_set_req_cksumtype,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_cksumtype)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getlocalseqnumber,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_int32 *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getremoteseqnumber,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_int32 *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_setrcache,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_rcache)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getauthenticator,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_authenticator * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_getremotesubkey,
+ (krb5_context,
+ krb5_auth_context,
+ krb5_keyblock * *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_read_password,
+ (krb5_context,
+ const char *,
+ const char *,
+ char *,
+ int * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_host_realm,
+ (krb5_context,
+ const char *,
+ char * * * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_free_host_realm,
+ (krb5_context,
+ char * const * )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_realm_domain,
+ (krb5_context,
+ const char *,
+ char ** )
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_auth_con_genaddrs,
+ (krb5_context,
+ krb5_auth_context,
+ int, int)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_string_to_enctype,
+ (char *, krb5_enctype *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_string_to_salttype,
+ (char *, krb5_int32 *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_string_to_cksumtype,
+ (char *, krb5_cksumtype *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_string_to_timestamp,
+ (char *, krb5_timestamp *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_string_to_deltat,
+ (char *, krb5_deltat *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_enctype_to_string,
+ (krb5_enctype, char *, size_t)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_salttype_to_string,
+ (krb5_int32, char *, size_t)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cksumtype_to_string,
+ (krb5_cksumtype, char *, size_t)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_timestamp_to_string,
+ (krb5_timestamp, char *, size_t)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_timestamp_to_sfstring,
+ (krb5_timestamp, char *, size_t, char *)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_deltat_to_string,
+ (krb5_deltat, char *, size_t)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_prompter_posix,
+ (krb5_context context,
+ void *data,
+ const char *name,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[])
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_init,
+ (krb5_get_init_creds_opt *opt)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_tkt_life,
+ (krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_renew_life,
+ (krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_forwardable,
+ (krb5_get_init_creds_opt *opt,
+ int forwardable)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_proxiable,
+ (krb5_get_init_creds_opt *opt,
+ int proxiable)
+ );
+
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_etype_list,
+ (krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_address_list,
+ (krb5_get_init_creds_opt *opt,
+ krb5_address **addresses)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_preauth_list,
+ (krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_salt,
+ (krb5_get_init_creds_opt *opt,
+ krb5_data *salt)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_opt_set_change_password_prompt,
+ (krb5_get_init_creds_opt *opt,
+ int prompt)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_password,
+ (krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_init_creds_keytab,
+ (krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab arg_keytab,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_verify_init_creds_opt_init,
+ (krb5_verify_init_creds_opt *options)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_verify_init_creds_opt_set_ap_req_nofail,
+ (krb5_verify_init_creds_opt *options,
+ int ap_req_nofail)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_verify_init_creds,
+ (krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_validated_creds,
+ (krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_ccache ccache,
+ char *in_tkt_service)
+ );
+
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_get_renewed_creds,
+ (krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_ccache ccache,
+ char *in_tkt_service)
+ );
+
+/* ------------------------------------------------------------------------- */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_realm_iterator_create,
+ (krb5_context context, void **iter_p)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_realm_iterator,
+ (krb5_context context, void **iter_p, char **ret_realm)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_realm_iterator_free,
+ (krb5_context context, void **iter_p)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ krb5_free_realm_string,
+ (krb5_context context, char *str)
+ );
+
+TYPEDEF_FUNC(
+ krb5_prompt_type*,
+ KRB5_CALLCONV,
+ krb5_get_prompt_types,
+ (krb5_context context)
+ );
+
+/* NOT IN krb5.h HEADER: */
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_decode_ticket,
+ (const krb5_data *code, krb5_ticket **rep)
+ );
+
+/* --- more --- */
+
+TYPEDEF_FUNC(
+ char *,
+ KRB5_CALLCONV,
+ krb5_cc_get_name,
+ (krb5_context context, krb5_ccache cache)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_gen_new,
+ (krb5_context context, krb5_ccache *cache)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_initialize,
+ (krb5_context context, krb5_ccache cache, krb5_principal principal)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_destroy,
+ (krb5_context context, krb5_ccache cache)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_close,
+ (krb5_context context, krb5_ccache cache)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_store_cred,
+ (krb5_context context, krb5_ccache cache, krb5_creds *creds)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_retrieve_cred,
+ (krb5_context context, krb5_ccache cache,
+ krb5_flags flags, krb5_creds *mcreds,
+ krb5_creds *creds)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_get_principal,
+ (krb5_context context, krb5_ccache cache, krb5_principal *principal)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_start_seq_get,
+ (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_next_cred,
+ (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
+ krb5_creds *creds)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_end_seq_get,
+ (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_remove_cred,
+ (krb5_context context, krb5_ccache cache, krb5_flags flags,
+ krb5_creds *creds)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_cc_set_flags,
+ (krb5_context context, krb5_ccache cache, krb5_flags flags)
+ );
+
+TYPEDEF_FUNC(
+ const char *,
+ KRB5_CALLCONV,
+ krb5_cc_get_type,
+ (krb5_context context, krb5_ccache cache)
+ );
+
+TYPEDEF_FUNC(
+ char *,
+ KRB5_CALLCONV,
+ krb5_kt_get_type,
+ (krb5_context, krb5_keytab keytab)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_get_name,
+ (krb5_context context, krb5_keytab keytab, char *name,
+ unsigned int namelen)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_close,
+ (krb5_context context, krb5_keytab keytab)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_get_entry,
+ (krb5_context context, krb5_keytab keytab,
+ krb5_const_principal principal, krb5_kvno vno,
+ krb5_enctype enctype, krb5_keytab_entry *entry)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_start_seq_get,
+ (krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_next_entry,
+ (krb5_context context, krb5_keytab keytab,
+ krb5_keytab_entry *entry, krb5_kt_cursor *cursor)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_kt_end_seq_get,
+ (krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor)
+ );
+
+TYPEDEF_FUNC(
+ krb5_error_code,
+ KRB5_CALLCONV,
+ krb5_locate_kdc,
+ (krb5_context context, const krb5_data *realm,
+ struct addrlist *addrlist,
+ int get_masters, int socktype, int family)
+ );
+#endif /* __LOADFUNCS_KRB5_H__ */
diff --git a/src/windows/leashdll/include/loadfuncs-lsa.h b/src/windows/leashdll/include/loadfuncs-lsa.h
new file mode 100644
index 0000000000..40138f5de8
--- /dev/null
+++ b/src/windows/leashdll/include/loadfuncs-lsa.h
@@ -0,0 +1,45 @@
+#ifndef __LOADFUNCS_LSA_H__
+#define __LOADFUNCS_LSA_H__
+
+#include "loadfuncs.h"
+
+#define SECUR32_DLL "secur32.dll"
+#define ADVAPI32_DLL "advapi32.dll"
+
+TYPEDEF_FUNC(
+ NTSTATUS,
+ NTAPI,
+ LsaConnectUntrusted,
+ (PHANDLE)
+ );
+TYPEDEF_FUNC(
+ NTSTATUS,
+ NTAPI,
+ LsaLookupAuthenticationPackage,
+ (HANDLE, PLSA_STRING, PULONG)
+ );
+TYPEDEF_FUNC(
+ NTSTATUS,
+ NTAPI,
+ LsaCallAuthenticationPackage,
+ (HANDLE, ULONG, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS)
+ );
+TYPEDEF_FUNC(
+ NTSTATUS,
+ NTAPI,
+ LsaFreeReturnBuffer,
+ (PVOID)
+ );
+TYPEDEF_FUNC(
+ ULONG,
+ NTAPI,
+ LsaNtStatusToWinError,
+ (NTSTATUS)
+ );
+TYPEDEF_FUNC(
+ NTSTATUS,
+ NTAPI,
+ LsaGetLogonSessionData,
+ (PLUID, PSECURITY_LOGON_SESSION_DATA*)
+ );
+#endif /* __LOADFUNCS_LSA_H__ */
diff --git a/src/windows/leashdll/include/loadfuncs-profile.h b/src/windows/leashdll/include/loadfuncs-profile.h
new file mode 100644
index 0000000000..ef7f6b7c85
--- /dev/null
+++ b/src/windows/leashdll/include/loadfuncs-profile.h
@@ -0,0 +1,151 @@
+#ifndef __LOADFUNCS_PROFILE_H__
+#define __LOADFUNCS_PROFILE_H__
+
+#include "loadfuncs.h"
+#include <profile.h>
+
+#if defined(_WIN64)
+#define PROFILE_DLL "xpprof64.dll"
+#else
+#define PROFILE_DLL "xpprof32.dll"
+#endif
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_init,
+ (const_profile_filespec_t *files, profile_t *ret_profile)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_init_path,
+ (const_profile_filespec_list_t filelist, profile_t *ret_profile)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_flush,
+ (profile_t profile)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ profile_abandon,
+ (profile_t profile)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ profile_release,
+ (profile_t profile)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_get_values,
+ (profile_t profile, const char **names, char ***ret_values)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ profile_free_list,
+ (char **list)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_get_string,
+ (profile_t profile, const char *name, const char *subname,
+ const char *subsubname, const char *def_val,
+ char **ret_string)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_get_integer,
+ (profile_t profile, const char *name, const char *subname,
+ const char *subsubname, int def_val,
+ int *ret_default)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_get_relation_names,
+ (profile_t profile, const char **names, char ***ret_names)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_get_subsection_names,
+ (profile_t profile, const char **names, char ***ret_names)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_iterator_create,
+ (profile_t profile, const char **names, int flags, void **ret_iter)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ profile_iterator_free,
+ (void **iter_p)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_iterator,
+ (void **iter_p, char **ret_name, char **ret_value)
+ );
+
+TYPEDEF_FUNC(
+ void,
+ KRB5_CALLCONV,
+ profile_release_string,
+ (char *str)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_update_relation,
+ (profile_t profile, const char **names, const char *old_value, const char *new_value)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_clear_relation,
+ (profile_t profile, const char **names)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_rename_section,
+ (profile_t profile, const char **names, const char *new_name)
+ );
+
+TYPEDEF_FUNC(
+ long,
+ KRB5_CALLCONV,
+ profile_add_relation,
+ (profile_t profile, const char **names, const char *new_value)
+ );
+
+
+#endif /* __LOADFUNCS_PROFILE_H__ */
diff --git a/src/windows/leashdll/include/loadfuncs.h b/src/windows/leashdll/include/loadfuncs.h
new file mode 100644
index 0000000000..7aef62d21c
--- /dev/null
+++ b/src/windows/leashdll/include/loadfuncs.h
@@ -0,0 +1,41 @@
+#ifndef __LOADFUNCS_H__
+#define __LOADFUNCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+
+typedef struct _FUNC_INFO {
+ void** func_ptr_var;
+ char* func_name;
+} FUNC_INFO;
+
+#define DECL_FUNC_PTR(x) FP_##x p##x
+#define MAKE_FUNC_INFO(x) { (void**) &p##x, #x }
+#define END_FUNC_INFO { 0, 0 }
+#define TYPEDEF_FUNC(ret, call, name, args) typedef ret (call *FP_##name) args
+
+void
+UnloadFuncs(
+ FUNC_INFO fi[],
+ HINSTANCE h
+ );
+
+int
+LoadFuncs(
+ const char* dll_name,
+ FUNC_INFO fi[],
+ HINSTANCE* ph, // [out, optional] - DLL handle
+ int* pindex, // [out, optional] - index of last func loaded (-1 if none)
+ int cleanup, // cleanup function pointers and unload on error
+ int go_on, // continue loading even if some functions cannot be loaded
+ int silent // do not pop-up a system dialog if DLL cannot be loaded
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LOADFUNCS_H__ */
diff --git a/src/windows/leashdll/krb5routines.c b/src/windows/leashdll/krb5routines.c
new file mode 100644
index 0000000000..7f2d28306e
--- /dev/null
+++ b/src/windows/leashdll/krb5routines.c
@@ -0,0 +1,1530 @@
+// Module name: krb5routines.c
+
+#include <windows.h>
+#define SECURITY_WIN32
+#include <security.h>
+
+/* _WIN32_WINNT must be 0x0501 or greater to pull in definition of
+ * all required LSA data types when the Vista SDK NtSecAPI.h is used.
+ */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#else
+#if _WIN32_WINNT < 0x0501
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#endif
+#include <ntsecapi.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+
+/* Private Include files */
+#include "leashdll.h"
+#include <leashwin.h>
+#include "leash-int.h"
+
+#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
+
+char *GetTicketFlag(krb5_creds *cred)
+{
+ static char buf[32];
+ int i = 0;
+
+ buf[i++] = ' ';
+ buf[i++] = '(';
+
+ if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
+ buf[i++] = 'F';
+
+ if (cred->ticket_flags & TKT_FLG_FORWARDED)
+ buf[i++] = 'f';
+
+ if (cred->ticket_flags & TKT_FLG_PROXIABLE)
+ buf[i++] = 'P';
+
+ if (cred->ticket_flags & TKT_FLG_PROXY)
+ buf[i++] = 'p';
+
+ if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
+ buf[i++] = 'D';
+
+ if (cred->ticket_flags & TKT_FLG_POSTDATED)
+ buf[i++] = 'd';
+
+ if (cred->ticket_flags & TKT_FLG_INVALID)
+ buf[i++] = 'i';
+
+ if (cred->ticket_flags & TKT_FLG_RENEWABLE)
+ buf[i++] = 'R';
+
+ if (cred->ticket_flags & TKT_FLG_INITIAL)
+ buf[i++] = 'I';
+
+ if (cred->ticket_flags & TKT_FLG_HW_AUTH)
+ buf[i++] = 'H';
+
+ if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
+ buf[i++] = 'A';
+
+ buf[i++] = ')';
+ buf[i] = '\0';
+
+ if (i <= 3)
+ buf[0] = '\0';
+
+ return buf;
+}
+
+long
+Leash_convert524(
+ krb5_context alt_ctx
+ )
+{
+#if defined(NO_KRB5) || defined(NO_KRB4)
+ return(0);
+#else
+ krb5_context ctx = 0;
+ krb5_error_code code = 0;
+ int icode = 0;
+ krb5_principal me = 0;
+ krb5_principal server = 0;
+ krb5_creds *v5creds = 0;
+ krb5_creds increds;
+ krb5_ccache cc = 0;
+ CREDENTIALS * v4creds = NULL;
+ static int init_ets = 1;
+
+ if (!pkrb5_init_context ||
+ !pkrb_in_tkt ||
+ !pkrb524_init_ets ||
+ !pkrb524_convert_creds_kdc)
+ return 0;
+
+ v4creds = (CREDENTIALS *) malloc(sizeof(CREDENTIALS));
+ memset((char *) v4creds, 0, sizeof(CREDENTIALS));
+
+ memset((char *) &increds, 0, sizeof(increds));
+ /*
+ From this point on, we can goto cleanup because increds is
+ initialized.
+ */
+
+ if (alt_ctx)
+ {
+ ctx = alt_ctx;
+ }
+ else
+ {
+ code = pkrb5_init_context(&ctx);
+ if (code) goto cleanup;
+ }
+
+ code = pkrb5_cc_default(ctx, &cc);
+ if (code) goto cleanup;
+
+ if ( init_ets ) {
+ pkrb524_init_ets(ctx);
+ init_ets = 0;
+ }
+
+ if (code = pkrb5_cc_get_principal(ctx, cc, &me))
+ goto cleanup;
+
+ if ((code = pkrb5_build_principal(ctx,
+ &server,
+ krb5_princ_realm(ctx, me)->length,
+ krb5_princ_realm(ctx, me)->data,
+ "krbtgt",
+ krb5_princ_realm(ctx, me)->data,
+ NULL))) {
+ goto cleanup;
+ }
+
+ increds.client = me;
+ increds.server = server;
+ increds.times.endtime = 0;
+ increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+ if ((code = pkrb5_get_credentials(ctx, 0,
+ cc,
+ &increds,
+ &v5creds))) {
+ goto cleanup;
+ }
+
+ if ((icode = pkrb524_convert_creds_kdc(ctx,
+ v5creds,
+ v4creds))) {
+ goto cleanup;
+ }
+
+ /* initialize ticket cache */
+ if ((icode = pkrb_in_tkt(v4creds->pname, v4creds->pinst, v4creds->realm)
+ != KSUCCESS)) {
+ goto cleanup;
+ }
+ /* stash ticket, session key, etc. for future use */
+ if ((icode = pkrb_save_credentials(v4creds->service,
+ v4creds->instance,
+ v4creds->realm,
+ v4creds->session,
+ v4creds->lifetime,
+ v4creds->kvno,
+ &(v4creds->ticket_st),
+ v4creds->issue_date))) {
+ goto cleanup;
+ }
+
+ cleanup:
+ memset(v4creds, 0, sizeof(v4creds));
+ free(v4creds);
+
+ if (v5creds) {
+ pkrb5_free_creds(ctx, v5creds);
+ }
+ if (increds.client == me)
+ me = 0;
+ if (increds.server == server)
+ server = 0;
+ pkrb5_free_cred_contents(ctx, &increds);
+ if (server) {
+ pkrb5_free_principal(ctx, server);
+ }
+ if (me) {
+ pkrb5_free_principal(ctx, me);
+ }
+ pkrb5_cc_close(ctx, cc);
+
+ if (ctx && (ctx != alt_ctx)) {
+ pkrb5_free_context(ctx);
+ }
+ return !(code || icode);
+#endif /* NO_KRB5 */
+}
+
+#ifndef ENCTYPE_LOCAL_RC4_MD4
+#define ENCTYPE_LOCAL_RC4_MD4 0xFFFFFF80
+#endif
+
+static char *
+etype_string(krb5_enctype enctype)
+{
+ static char buf[12];
+
+ switch (enctype) {
+ case ENCTYPE_NULL:
+ return "NULL";
+ case ENCTYPE_DES_CBC_CRC:
+ return "DES-CBC-CRC";
+ case ENCTYPE_DES_CBC_MD4:
+ return "DES-CBC-MD4";
+ case ENCTYPE_DES_CBC_MD5:
+ return "DES-CBC-MD5";
+ case ENCTYPE_DES_CBC_RAW:
+ return "DES-CBC-RAW";
+ case ENCTYPE_DES3_CBC_SHA:
+ return "DES3-CBC-SHA";
+ case ENCTYPE_DES3_CBC_RAW:
+ return "DES3-CBC-RAW";
+ case ENCTYPE_DES_HMAC_SHA1:
+ return "DES-HMAC-SHA1";
+ case ENCTYPE_DES3_CBC_SHA1:
+ return "DES3-CBC-SHA1";
+ case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+ return "AES128_CTS-HMAC-SHA1_96";
+ case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+ return "AES256_CTS-HMAC-SHA1_96";
+ case ENCTYPE_ARCFOUR_HMAC:
+ return "RC4-HMAC-NT";
+ case ENCTYPE_ARCFOUR_HMAC_EXP:
+ return "RC4-HMAC-NT-EXP";
+ case ENCTYPE_UNKNOWN:
+ return "UNKNOWN";
+#ifdef ENCTYPE_LOCAL_DES3_HMAC_SHA1
+ case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
+ return "LOCAL-DES3-HMAC-SHA1";
+#endif
+#ifdef ENCTYPE_LOCAL_RC4_MD4
+ case ENCTYPE_LOCAL_RC4_MD4:
+ return "LOCAL-RC4-MD4";
+#endif
+ default:
+ wsprintf(buf, "#%d", enctype);
+ return buf;
+ }
+}
+
+char *
+one_addr(krb5_address *a)
+{
+ static char retstr[256];
+ struct hostent *h;
+ int no_resolve = 1;
+
+ retstr[0] = '\0';
+
+ if ((a->addrtype == ADDRTYPE_INET && a->length == 4)
+#ifdef AF_INET6
+ || (a->addrtype == ADDRTYPE_INET6 && a->length == 16)
+#endif
+ ) {
+ int af = AF_INET;
+#ifdef AF_INET6
+ if (a->addrtype == ADDRTYPE_INET6)
+ af = AF_INET6;
+#endif
+ if (!no_resolve) {
+#ifdef HAVE_GETIPNODEBYADDR
+ int err;
+ h = getipnodebyaddr(a->contents, a->length, af, &err);
+ if (h) {
+ wsprintf(retstr, "%s", h->h_name);
+ freehostent(h);
+ }
+#else
+ h = gethostbyaddr(a->contents, a->length, af);
+ if (h) {
+ wsprintf(retstr,"%s", h->h_name);
+ }
+#endif
+ if (h)
+ return(retstr);
+ }
+ if (no_resolve || !h) {
+#ifdef HAVE_INET_NTOP
+ char buf[46];
+ const char *name = inet_ntop(a->addrtype, a->contents, buf, sizeof(buf));
+ if (name) {
+ wsprintf(retstr,"%s", name);
+ return;
+ }
+#else
+ if (a->addrtype == ADDRTYPE_INET) {
+ wsprintf(retstr,"%d.%d.%d.%d", a->contents[0], a->contents[1],
+ a->contents[2], a->contents[3]);
+ return(retstr);
+ }
+#endif
+ }
+ }
+ wsprintf(retstr,"unknown addr type %d", a->addrtype);
+ return(retstr);
+}
+
+long
+not_an_API_LeashKRB5GetTickets(
+ TICKETINFO * ticketinfo,
+ TicketList** ticketList,
+ krb5_context *krbv5Context
+ )
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+ krb5_context ctx;
+ krb5_ccache cache;
+ krb5_error_code code;
+ krb5_principal KRBv5Principal;
+ krb5_flags flags = 0;
+ krb5_cc_cursor KRBv5Cursor;
+ krb5_creds KRBv5Credentials;
+ krb5_ticket *tkt=NULL;
+ int StartMonth;
+ int EndMonth;
+ int RenewMonth;
+ int StartDay;
+ int EndDay;
+ int RenewDay;
+ int freeContextFlag;
+ char StartTimeString[256];
+ char EndTimeString[256];
+ char RenewTimeString[256];
+ char fill;
+ char *ClientName;
+ char *PrincipalName;
+ char *sServerName;
+ char Buffer[256];
+ char Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
+ char StartTime[16];
+ char EndTime[16];
+ char RenewTime[16];
+ char temp[128];
+ char *sPtr;
+ char *ticketFlag;
+ LPCSTR functionName;
+
+ TicketList* list = NULL;
+
+ ctx = NULL;
+ cache = NULL;
+ if ( ticketinfo ) {
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal[0] = '\0';
+ }
+
+ if ((code = Leash_krb5_initialize(&(*krbv5Context), &cache)))
+ return(code);
+
+ ctx = (*krbv5Context);
+
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#endif
+ if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
+ {
+ if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
+ Leash_krb5_error(code, "krb5_cc_set_flags()", 0, &ctx,
+ &cache);
+ else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND) && ctx != NULL)
+ {
+ if (cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ }
+ return code;
+ }
+
+ if ((code = pkrb5_cc_get_principal(ctx, cache, &KRBv5Principal)))
+ {
+ if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
+ Leash_krb5_error(code, "krb5_cc_get_principal()", 0, &ctx, &cache);
+ else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND) && ctx != NULL)
+ {
+ if (cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ }
+ return code;
+ }
+
+ PrincipalName = NULL;
+ ClientName = NULL;
+ sServerName = NULL;
+ if ((code = (*pkrb5_unparse_name)(ctx, KRBv5Principal,
+ (char **)&PrincipalName)))
+ {
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+ if (ctx != NULL)
+ {
+ if (cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ }
+
+ return(code);
+ }
+
+ if (!strcspn(PrincipalName, "@" ))
+ {
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+ if (ctx != NULL)
+ {
+ if (cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ }
+
+ return(code);
+ }
+
+ if ( strcmp(ticketinfo->principal, PrincipalName) )
+ wsprintf(ticketinfo->principal, "%s", PrincipalName);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+ if ((code = pkrb5_cc_start_seq_get(ctx, cache, &KRBv5Cursor)))
+ {
+ functionName = "krb5_cc_start_seq_get()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+
+ memset(&KRBv5Credentials, '\0', sizeof(KRBv5Credentials));
+
+ while (!(code = pkrb5_cc_next_cred(ctx, cache, &KRBv5Cursor, &KRBv5Credentials)))
+ {
+ if (!list)
+ {
+ list = (TicketList*) calloc(1, sizeof(TicketList));
+ (*ticketList) = list;
+ }
+ else
+ {
+ list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
+ list = (TicketList*) list->next;
+ }
+
+ if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.client, &ClientName))
+ {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+
+ if (ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+
+ ClientName = NULL;
+ sServerName = NULL;
+ continue;
+ }
+
+ if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName))
+ {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+
+ if (ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+
+ ClientName = NULL;
+ sServerName = NULL;
+ continue;
+ }
+
+ if (!KRBv5Credentials.times.starttime)
+ KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
+
+ fill = ' ';
+ memset(StartTimeString, '\0', sizeof(StartTimeString));
+ memset(EndTimeString, '\0', sizeof(EndTimeString));
+ memset(RenewTimeString, '\0', sizeof(RenewTimeString));
+ (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.starttime, StartTimeString, 17, &fill);
+ (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.endtime, EndTimeString, 17, &fill);
+ if (KRBv5Credentials.times.renew_till >= 0)
+ (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.renew_till, RenewTimeString, 17, &fill);
+ memset(temp, '\0', sizeof(temp));
+ memcpy(temp, StartTimeString, 2);
+ StartDay = atoi(temp);
+ memset(temp, (int)'\0', (size_t)sizeof(temp));
+ memcpy(temp, EndTimeString, 2);
+ EndDay = atoi(temp);
+ memset(temp, (int)'\0', (size_t)sizeof(temp));
+ memcpy(temp, RenewTimeString, 2);
+ RenewDay = atoi(temp);
+
+ memset(temp, '\0', sizeof(temp));
+ memcpy(temp, &StartTimeString[3], 2);
+ StartMonth = atoi(temp);
+ memset(temp, '\0', sizeof(temp));
+ memcpy(temp, &EndTimeString[3], 2);
+ EndMonth = atoi(temp);
+ memset(temp, '\0', sizeof(temp));
+ memcpy(temp, &RenewTimeString[3], 2);
+ RenewMonth = atoi(temp);
+
+ while (1)
+ {
+ if ((sPtr = strrchr(StartTimeString, ' ')) == NULL)
+ break;
+
+ if (strlen(sPtr) != 1)
+ break;
+
+ (*sPtr) = 0;
+ }
+
+ while (1)
+ {
+ if ((sPtr = strrchr(EndTimeString, ' ')) == NULL)
+ break;
+
+ if (strlen(sPtr) != 1)
+ break;
+
+ (*sPtr) = 0;
+ }
+
+ while (1)
+ {
+ if ((sPtr = strrchr(RenewTimeString, ' ')) == NULL)
+ break;
+
+ if (strlen(sPtr) != 1)
+ break;
+
+ (*sPtr) = 0;
+ }
+
+ memset(StartTime, '\0', sizeof(StartTime));
+ memcpy(StartTime, &StartTimeString[strlen(StartTimeString) - 5], 5);
+ memset(EndTime, '\0', sizeof(EndTime));
+ memcpy(EndTime, &EndTimeString[strlen(EndTimeString) - 5], 5);
+ memset(RenewTime, '\0', sizeof(RenewTime));
+ memcpy(RenewTime, &RenewTimeString[strlen(RenewTimeString) - 5], 5);
+
+ memset(temp, '\0', sizeof(temp));
+ strcpy(temp, ClientName);
+
+ if (!strcmp(ClientName, PrincipalName))
+ memset(temp, '\0', sizeof(temp));
+
+ memset(Buffer, '\0', sizeof(Buffer));
+
+ ticketFlag = GetTicketFlag(&KRBv5Credentials);
+
+ if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) {
+ wsprintf(Buffer,"%s %02d %s %s %02d %s [%s %02d %s] %s %s %s",
+ Months[StartMonth - 1], StartDay, StartTime,
+ Months[EndMonth - 1], EndDay, EndTime,
+ Months[RenewMonth - 1], RenewDay, RenewTime,
+ sServerName,
+ temp, ticketFlag);
+ } else {
+ wsprintf(Buffer,"%s %02d %s %s %02d %s %s %s %s",
+ Months[StartMonth - 1], StartDay, StartTime,
+ Months[EndMonth - 1], EndDay, EndTime,
+ sServerName,
+ temp, ticketFlag);
+ }
+ list->theTicket = (char*) calloc(1, strlen(Buffer)+1);
+ if (!list->theTicket)
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+ strcpy(list->theTicket, Buffer);
+ list->name = NULL;
+ list->inst = NULL;
+ list->realm = NULL;
+
+ if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
+ wsprintf(Buffer, "Ticket Encryption Type: %s", etype_string(tkt->enc_part.enctype));
+ list->tktEncType = (char*) calloc(1, strlen(Buffer)+1);
+ if (!list->tktEncType)
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+ strcpy(list->tktEncType, Buffer);
+
+ pkrb5_free_ticket(ctx, tkt);
+ tkt = NULL;
+ } else {
+ list->tktEncType = NULL;
+ }
+
+ wsprintf(Buffer, "Session Key Type: %s", etype_string(KRBv5Credentials.keyblock.enctype));
+ list->keyEncType = (char*) calloc(1, strlen(Buffer)+1);
+ if (!list->keyEncType)
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+ strcpy(list->keyEncType, Buffer);
+
+ if ( KRBv5Credentials.addresses && KRBv5Credentials.addresses[0] ) {
+ int n = 0;
+ while ( KRBv5Credentials.addresses[n] )
+ n++;
+ list->addrList = calloc(1, n * sizeof(char *));
+ if (!list->addrList) {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+ list->addrCount = n;
+ for ( n=0; n<list->addrCount; n++ ) {
+ wsprintf(Buffer, "Address: %s", one_addr(KRBv5Credentials.addresses[n]));
+ list->addrList[n] = (char*) calloc(1, strlen(Buffer)+1);
+ if (!list->addrList[n])
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+ strcpy(list->addrList[n], Buffer);
+ }
+ }
+
+ ticketinfo->issue_date = KRBv5Credentials.times.starttime;
+ ticketinfo->lifetime = KRBv5Credentials.times.endtime - KRBv5Credentials.times.starttime;
+ ticketinfo->renew_till = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
+ KRBv5Credentials.times.renew_till : 0;
+ _tzset();
+ if ( ticketinfo->issue_date + ticketinfo->lifetime - time(0) <= 0L )
+ ticketinfo->btickets = EXPD_TICKETS;
+ else
+ ticketinfo->btickets = GOOD_TICKETS;
+
+ if (ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
+
+ ClientName = NULL;
+ sServerName = NULL;
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ }
+
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ if (ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
+
+ if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
+ {
+ if ((code = pkrb5_cc_end_seq_get(ctx, cache, &KRBv5Cursor)))
+ {
+ functionName = "krb5_cc_end_seq_get()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+
+ flags = KRB5_TC_OPENCLOSE;
+#ifdef KRB5_TC_NOTICKET
+ flags |= KRB5_TC_NOTICKET;
+#endif
+ if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
+ {
+ functionName = "krb5_cc_set_flags()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+ }
+ else
+ {
+ functionName = "krb5_cc_next_cred()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+
+ if (ctx != NULL)
+ {
+ if (cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ }
+
+ return(code);
+
+ on_error:
+
+ Leash_krb5_error(code, functionName, freeContextFlag, &(*krbv5Context), &cache);
+ return(code);
+#endif //!NO_KER5
+}
+
+
+int
+LeashKRB5_renew(void)
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+ krb5_error_code code = 0;
+ krb5_context ctx = 0;
+ krb5_ccache cc = 0;
+ krb5_principal me = 0;
+ krb5_principal server = 0;
+ krb5_creds my_creds;
+ krb5_data *realm = 0;
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ memset(&my_creds, 0, sizeof(krb5_creds));
+
+ code = pkrb5_init_context(&ctx);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_default(ctx, &cc);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &me);
+ if (code) goto cleanup;
+
+ realm = krb5_princ_realm(ctx, me);
+
+ code = pkrb5_build_principal_ext(ctx, &server,
+ realm->length,realm->data,
+ KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
+ realm->length,realm->data,
+ 0);
+ if ( code ) goto cleanup;
+
+ my_creds.client = me;
+ my_creds.server = server;
+
+#ifdef KRB5_TC_NOTICKET
+ pkrb5_cc_set_flags(ctx, cc, 0);
+#endif
+ code = pkrb5_get_renewed_creds(ctx, &my_creds, me, cc, NULL);
+#ifdef KRB5_TC_NOTICKET
+ pkrb5_cc_set_flags(ctx, cc, KRB5_TC_NOTICKET);
+#endif
+ if (code) {
+ if ( code != KRB5KDC_ERR_ETYPE_NOSUPP ||
+ code != KRB5_KDC_UNREACH)
+ Leash_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc);
+ goto cleanup;
+ }
+
+ code = pkrb5_cc_initialize(ctx, cc, me);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
+ if (code) goto cleanup;
+
+ cleanup:
+ if (my_creds.client == me)
+ my_creds.client = 0;
+ if (my_creds.server == server)
+ my_creds.server = 0;
+ pkrb5_free_cred_contents(ctx, &my_creds);
+ if (me)
+ pkrb5_free_principal(ctx, me);
+ if (server)
+ pkrb5_free_principal(ctx, server);
+ if (cc)
+ pkrb5_cc_close(ctx, cc);
+ if (ctx)
+ pkrb5_free_context(ctx);
+ return(code);
+#endif /* NO_KRB5 */
+}
+
+#ifndef NO_KRB5
+static krb5_error_code KRB5_CALLCONV
+leash_krb5_prompter( krb5_context context,
+ void *data,
+ const char *name,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]);
+#endif /* NO_KRB5 */
+
+int
+Leash_krb5_kinit(
+krb5_context alt_ctx,
+HWND hParent,
+char *principal_name,
+char *password,
+krb5_deltat lifetime,
+DWORD forwardable,
+DWORD proxiable,
+krb5_deltat renew_life,
+DWORD addressless,
+DWORD publicIP
+)
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+ krb5_error_code code = 0;
+ krb5_context ctx = 0;
+ krb5_ccache cc = 0;
+ krb5_principal me = 0;
+ char* name = 0;
+ krb5_creds my_creds;
+ krb5_get_init_creds_opt options;
+ krb5_address ** addrs = NULL;
+ int i = 0, addr_count = 0;
+
+ if (!pkrb5_init_context)
+ return 0;
+
+ pkrb5_get_init_creds_opt_init(&options);
+ memset(&my_creds, 0, sizeof(my_creds));
+
+ if (alt_ctx)
+ {
+ ctx = alt_ctx;
+ }
+ else
+ {
+ code = pkrb5_init_context(&ctx);
+ if (code) goto cleanup;
+ }
+
+ code = pkrb5_cc_default(ctx, &cc);
+ if (code) goto cleanup;
+
+ code = pkrb5_parse_name(ctx, principal_name, &me);
+ if (code) goto cleanup;
+
+ code = pkrb5_unparse_name(ctx, me, &name);
+ if (code) goto cleanup;
+
+ if (lifetime == 0)
+ lifetime = Leash_get_default_lifetime();
+ else
+ lifetime *= 5*60;
+
+ if (renew_life > 0)
+ renew_life *= 5*60;
+
+ if (lifetime)
+ pkrb5_get_init_creds_opt_set_tkt_life(&options, lifetime);
+ pkrb5_get_init_creds_opt_set_forwardable(&options,
+ forwardable ? 1 : 0);
+ pkrb5_get_init_creds_opt_set_proxiable(&options,
+ proxiable ? 1 : 0);
+ pkrb5_get_init_creds_opt_set_renew_life(&options,
+ renew_life);
+ if (addressless)
+ pkrb5_get_init_creds_opt_set_address_list(&options,NULL);
+ else {
+ if (publicIP)
+ {
+ // we are going to add the public IP address specified by the user
+ // to the list provided by the operating system
+ krb5_address ** local_addrs=NULL;
+ DWORD netIPAddr;
+
+ pkrb5_os_localaddr(ctx, &local_addrs);
+ while ( local_addrs[i++] );
+ addr_count = i + 1;
+
+ addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *));
+ if ( !addrs ) {
+ pkrb5_free_addresses(ctx, local_addrs);
+ assert(0);
+ }
+ memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
+ i = 0;
+ while ( local_addrs[i] ) {
+ addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
+ if (addrs[i] == NULL) {
+ pkrb5_free_addresses(ctx, local_addrs);
+ assert(0);
+ }
+
+ addrs[i]->magic = local_addrs[i]->magic;
+ addrs[i]->addrtype = local_addrs[i]->addrtype;
+ addrs[i]->length = local_addrs[i]->length;
+ addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
+ if (!addrs[i]->contents) {
+ pkrb5_free_addresses(ctx, local_addrs);
+ assert(0);
+ }
+
+ memcpy(addrs[i]->contents,local_addrs[i]->contents,
+ local_addrs[i]->length); /* safe */
+ i++;
+ }
+ pkrb5_free_addresses(ctx, local_addrs);
+
+ addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
+ if (addrs[i] == NULL)
+ assert(0);
+
+ addrs[i]->magic = KV5M_ADDRESS;
+ addrs[i]->addrtype = AF_INET;
+ addrs[i]->length = 4;
+ addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
+ if (!addrs[i]->contents)
+ assert(0);
+
+ netIPAddr = htonl(publicIP);
+ memcpy(addrs[i]->contents,&netIPAddr,4);
+
+ pkrb5_get_init_creds_opt_set_address_list(&options,addrs);
+
+ }
+ }
+
+ code = pkrb5_get_init_creds_password(ctx,
+ &my_creds,
+ me,
+ password, // password
+ leash_krb5_prompter, // prompter
+ hParent, // prompter data
+ 0, // start time
+ 0, // service name
+ &options);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_initialize(ctx, cc, me);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
+ if (code) goto cleanup;
+
+ cleanup:
+ if ( addrs ) {
+ for ( i=0;i<addr_count;i++ ) {
+ if ( addrs[i] ) {
+ if ( addrs[i]->contents )
+ free(addrs[i]->contents);
+ free(addrs[i]);
+ }
+ }
+ }
+ if (my_creds.client == me)
+ my_creds.client = 0;
+ pkrb5_free_cred_contents(ctx, &my_creds);
+ if (name)
+ pkrb5_free_unparsed_name(ctx, name);
+ if (me)
+ pkrb5_free_principal(ctx, me);
+ if (cc)
+ pkrb5_cc_close(ctx, cc);
+ if (ctx && (ctx != alt_ctx))
+ pkrb5_free_context(ctx);
+ return(code);
+#endif //!NO_KRB5
+}
+
+
+/**************************************/
+/* LeashKRB5destroyTicket(): */
+/**************************************/
+int
+Leash_krb5_kdestroy(
+ void
+ )
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+ krb5_context ctx;
+ krb5_ccache cache;
+ krb5_error_code rc;
+
+ ctx = NULL;
+ cache = NULL;
+ if (rc = Leash_krb5_initialize(&ctx, &cache))
+ return(rc);
+
+ rc = pkrb5_cc_destroy(ctx, cache);
+
+ if (ctx != NULL)
+ pkrb5_free_context(ctx);
+
+ return(rc);
+
+#endif //!NO_KRB5
+}
+
+/**************************************/
+/* Leash_krb5_initialize(): */
+/**************************************/
+int Leash_krb5_initialize(krb5_context *ctx, krb5_ccache *cache)
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+
+ LPCSTR functionName;
+ int freeContextFlag;
+ krb5_error_code rc;
+ krb5_flags flags;
+
+ if (pkrb5_init_context == NULL)
+ return 1;
+
+ if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx)))
+ {
+ functionName = "krb5_init_context()";
+ freeContextFlag = 0;
+ goto on_error;
+ }
+
+ if (*cache == 0 && (rc = pkrb5_cc_default(*ctx, cache)))
+ {
+ functionName = "krb5_cc_default()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#endif
+ if ((rc = pkrb5_cc_set_flags(*ctx, *cache, flags)))
+ {
+ if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
+ Leash_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
+ cache);
+ else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL)
+ {
+ if (*cache != NULL)
+ pkrb5_cc_close(*ctx, *cache);
+ }
+ return rc;
+ }
+ return 0;
+
+ on_error:
+ return Leash_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
+#endif //!NO_KRB5
+}
+
+
+/**************************************/
+/* Leash_krb5_error(): */
+/**************************************/
+int
+Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
+ int FreeContextFlag, krb5_context * ctx,
+ krb5_ccache * cache)
+{
+#ifdef NO_KRB5
+ return 0;
+#else
+ char message[256];
+ const char *errText;
+ int krb5Error = ((int)(rc & 255));
+
+ /*
+ switch (krb5Error)
+ {
+ // Wrong password
+ case 31:
+ case 8:
+ return;
+ }
+ */
+
+ errText = perror_message(rc);
+ _snprintf(message, sizeof(message),
+ "%s\n(Kerberos error %ld)\n\n%s failed",
+ errText,
+ krb5Error,
+ FailedFunctionName);
+
+ MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
+ MB_TASKMODAL |
+ MB_SETFOREGROUND);
+ if (FreeContextFlag == 1)
+ {
+ if (*ctx != NULL)
+ {
+ if (*cache != NULL) {
+ pkrb5_cc_close(*ctx, *cache);
+ *cache = NULL;
+ }
+
+ pkrb5_free_context(*ctx);
+ *ctx = NULL;
+ }
+ }
+
+ return rc;
+
+#endif //!NO_KRB5
+}
+
+
+BOOL
+Leash_ms2mit(BOOL save_creds)
+{
+#ifdef NO_KRB5
+ return(FALSE);
+#else /* NO_KRB5 */
+ krb5_context kcontext = 0;
+ krb5_error_code code;
+ krb5_ccache ccache=0;
+ krb5_ccache mslsa_ccache=0;
+ krb5_creds creds;
+ krb5_cc_cursor cursor=0;
+ krb5_principal princ = 0;
+ char *cache_name=NULL;
+ BOOL rc = FALSE;
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ if (code = pkrb5_init_context(&kcontext))
+ goto cleanup;
+
+ if (code = pkrb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache))
+ goto cleanup;
+
+ if ( save_creds ) {
+ if (code = pkrb5_cc_get_principal(kcontext, mslsa_ccache, &princ))
+ goto cleanup;
+
+ if (code = pkrb5_cc_default(kcontext, &ccache))
+ goto cleanup;
+
+ if (code = pkrb5_cc_initialize(kcontext, ccache, princ))
+ goto cleanup;
+
+ if (code = pkrb5_cc_copy_creds(kcontext, mslsa_ccache, ccache))
+ goto cleanup;
+
+ rc = TRUE;
+ } else {
+ /* Enumerate tickets from cache looking for an initial ticket */
+ if ((code = pkrb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor)))
+ goto cleanup;
+
+ while (!(code = pkrb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds)))
+ {
+ if ( creds.ticket_flags & TKT_FLG_INITIAL ) {
+ rc = TRUE;
+ pkrb5_free_cred_contents(kcontext, &creds);
+ break;
+ }
+ pkrb5_free_cred_contents(kcontext, &creds);
+ }
+ pkrb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor);
+ }
+
+ cleanup:
+ if (princ)
+ pkrb5_free_principal(kcontext, princ);
+ if (ccache)
+ pkrb5_cc_close(kcontext, ccache);
+ if (mslsa_ccache)
+ pkrb5_cc_close(kcontext, mslsa_ccache);
+ if (kcontext)
+ pkrb5_free_context(kcontext);
+ return(rc);
+#endif /* NO_KRB5 */
+}
+
+
+#ifndef NO_KRB5
+/* User Query data structures and functions */
+
+struct textField {
+ char * buf; /* Destination buffer address */
+ int len; /* Destination buffer length */
+ char * label; /* Label for this field */
+ char * def; /* Default response for this field */
+ int echo; /* 0 = no, 1 = yes, 2 = asterisks */
+};
+
+static int mid_cnt = 0;
+static struct textField * mid_tb = NULL;
+
+#define ID_TEXT 150
+#define ID_MID_TEXT 300
+
+static BOOL CALLBACK
+MultiInputDialogProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ switch ( message ) {
+ case WM_INITDIALOG:
+ if ( GetDlgCtrlID((HWND) wParam) != ID_MID_TEXT )
+ {
+ SetFocus(GetDlgItem( hDialog, ID_MID_TEXT));
+ return FALSE;
+ }
+ for ( i=0; i < mid_cnt ; i++ ) {
+ if (mid_tb[i].echo == 0)
+ SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, 32, 0);
+ else if (mid_tb[i].echo == 2)
+ SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, '*', 0);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch ( LOWORD(wParam) ) {
+ case IDOK:
+ for ( i=0; i < mid_cnt ; i++ ) {
+ if ( !GetDlgItemText(hDialog, ID_MID_TEXT+i, mid_tb[i].buf, mid_tb[i].len) )
+ *mid_tb[i].buf = '\0';
+ }
+ /* fallthrough */
+ case IDCANCEL:
+ EndDialog(hDialog, LOWORD(wParam));
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static LPWORD
+lpwAlign( LPWORD lpIn )
+{
+ ULONG ul;
+
+ ul = (ULONG) lpIn;
+ ul += 3;
+ ul >>=2;
+ ul <<=2;
+ return (LPWORD) ul;;
+}
+
+/*
+ * dialog widths are measured in 1/4 character widths
+ * dialog height are measured in 1/8 character heights
+ */
+
+static LRESULT
+MultiInputDialog( HINSTANCE hinst, HWND hwndOwner,
+ char * ptext[], int numlines, int width,
+ int tb_cnt, struct textField * tb)
+{
+ HGLOBAL hgbl;
+ LPDLGTEMPLATE lpdt;
+ LPDLGITEMTEMPLATE lpdit;
+ LPWORD lpw;
+ LPWSTR lpwsz;
+ LRESULT ret;
+ int nchar, i, pwid;
+
+ hgbl = GlobalAlloc(GMEM_ZEROINIT, 4096);
+ if (!hgbl)
+ return -1;
+
+ mid_cnt = tb_cnt;
+ mid_tb = tb;
+
+ lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
+
+ // Define a dialog box.
+
+ lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
+ | DS_MODALFRAME | WS_CAPTION | DS_CENTER
+ | DS_SETFOREGROUND | DS_3DLOOK
+ | DS_SHELLFONT | DS_NOFAILCREATE;
+ lpdt->cdit = numlines + (2 * tb_cnt) + 2; // number of controls
+ lpdt->x = 10;
+ lpdt->y = 10;
+ lpdt->cx = 20 + width * 4;
+ lpdt->cy = 20 + (numlines + tb_cnt + 4) * 14;
+
+ lpw = (LPWORD) (lpdt + 1);
+ *lpw++ = 0; // no menu
+ *lpw++ = 0; // predefined dialog box class (by default)
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, "", -1, lpwsz, 128);
+ lpw += nchar;
+ *lpw++ = 8; // font size (points)
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, "MS Shell Dlg",
+ -1, lpwsz, 128);
+ lpw += nchar;
+
+ //-----------------------
+ // Define an OK button.
+ //-----------------------
+ lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
+ lpdit = (LPDLGITEMTEMPLATE) lpw;
+ lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_BORDER;
+ lpdit->dwExtendedStyle = 0;
+ lpdit->x = (lpdt->cx - 14)/4 - 20;
+ lpdit->y = 10 + (numlines + tb_cnt + 2) * 14;
+ lpdit->cx = 40;
+ lpdit->cy = 14;
+ lpdit->id = IDOK; // OK button identifier
+
+ lpw = (LPWORD) (lpdit + 1);
+ *lpw++ = 0xFFFF;
+ *lpw++ = 0x0080; // button class
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50);
+ lpw += nchar;
+ *lpw++ = 0; // no creation data
+
+ //-----------------------
+ // Define an Cancel button.
+ //-----------------------
+ lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
+ lpdit = (LPDLGITEMTEMPLATE) lpw;
+ lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP | WS_BORDER;
+ lpdit->dwExtendedStyle = 0;
+ lpdit->x = (lpdt->cx - 14)*3/4 - 20;
+ lpdit->y = 10 + (numlines + tb_cnt + 2) * 14;
+ lpdit->cx = 40;
+ lpdit->cy = 14;
+ lpdit->id = IDCANCEL; // CANCEL button identifier
+
+ lpw = (LPWORD) (lpdit + 1);
+ *lpw++ = 0xFFFF;
+ *lpw++ = 0x0080; // button class
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, "Cancel", -1, lpwsz, 50);
+ lpw += nchar;
+ *lpw++ = 0; // no creation data
+
+ /* Add controls for preface data */
+ for ( i=0; i<numlines; i++) {
+ /*-----------------------
+ * Define a static text control.
+ *-----------------------*/
+ lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
+ lpdit = (LPDLGITEMTEMPLATE) lpw;
+ lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
+ lpdit->dwExtendedStyle = 0;
+ lpdit->x = 10;
+ lpdit->y = 10 + i * 14;
+ lpdit->cx = strlen(ptext[i]) * 4 + 10;
+ lpdit->cy = 14;
+ lpdit->id = ID_TEXT + i; // text identifier
+
+ lpw = (LPWORD) (lpdit + 1);
+ *lpw++ = 0xFFFF;
+ *lpw++ = 0x0082; // static class
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, ptext[i],
+ -1, lpwsz, 2*width);
+ lpw += nchar;
+ *lpw++ = 0; // no creation data
+ }
+
+ for ( i=0, pwid = 0; i<tb_cnt; i++) {
+ if ( pwid < strlen(tb[i].label) )
+ pwid = strlen(tb[i].label);
+ }
+
+ for ( i=0; i<tb_cnt; i++) {
+ /* Prompt */
+ /*-----------------------
+ * Define a static text control.
+ *-----------------------*/
+ lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
+ lpdit = (LPDLGITEMTEMPLATE) lpw;
+ lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
+ lpdit->dwExtendedStyle = 0;
+ lpdit->x = 10;
+ lpdit->y = 10 + (numlines + i + 1) * 14;
+ lpdit->cx = pwid * 4;
+ lpdit->cy = 14;
+ lpdit->id = ID_TEXT + numlines + i; // text identifier
+
+ lpw = (LPWORD) (lpdit + 1);
+ *lpw++ = 0xFFFF;
+ *lpw++ = 0x0082; // static class
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].label ? tb[i].label : "",
+ -1, lpwsz, 128);
+ lpw += nchar;
+ *lpw++ = 0; // no creation data
+
+ /*-----------------------
+ * Define an edit control.
+ *-----------------------*/
+ lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
+ lpdit = (LPDLGITEMTEMPLATE) lpw;
+ lpdit->style = WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | WS_BORDER | (tb[i].echo == 1 ? 0L : ES_PASSWORD);
+ lpdit->dwExtendedStyle = 0;
+ lpdit->x = 10 + (pwid + 1) * 4;
+ lpdit->y = 10 + (numlines + i + 1) * 14;
+ lpdit->cx = (width - (pwid + 1)) * 4;
+ lpdit->cy = 14;
+ lpdit->id = ID_MID_TEXT + i; // identifier
+
+ lpw = (LPWORD) (lpdit + 1);
+ *lpw++ = 0xFFFF;
+ *lpw++ = 0x0081; // edit class
+
+ lpwsz = (LPWSTR) lpw;
+ nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].def ? tb[i].def : "",
+ -1, lpwsz, 128);
+ lpw += nchar;
+ *lpw++ = 0; // no creation data
+ }
+
+ GlobalUnlock(hgbl);
+ ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl,
+ hwndOwner, (DLGPROC) MultiInputDialogProc);
+ GlobalFree(hgbl);
+
+ switch ( ret ) {
+ case 0: /* Timeout */
+ return -1;
+ case IDOK:
+ return 1;
+ case IDCANCEL:
+ return 0;
+ default: {
+ char buf[256];
+ sprintf(buf,"DialogBoxIndirect() failed: %d",GetLastError());
+ MessageBox(hwndOwner,
+ buf,
+ "GetLastError()",
+ MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
+ return -1;
+ }
+ }
+}
+
+static int
+multi_field_dialog(HWND hParent, char * preface, int n, struct textField tb[])
+{
+ extern HINSTANCE hLeashInst;
+ int maxwidth = 0;
+ int numlines = 0;
+ int len;
+ char * plines[16], *p = preface ? preface : "";
+ int i;
+
+ for ( i=0; i<16; i++ )
+ plines[i] = NULL;
+
+ while (*p && numlines < 16) {
+ plines[numlines++] = p;
+ for ( ;*p && *p != '\r' && *p != '\n'; p++ );
+ if ( *p == '\r' && *(p+1) == '\n' ) {
+ *p++ = '\0';
+ p++;
+ } else if ( *p == '\n' ) {
+ *p++ = '\0';
+ }
+ if ( strlen(plines[numlines-1]) > maxwidth )
+ maxwidth = strlen(plines[numlines-1]);
+ }
+
+ for ( i=0;i<n;i++ ) {
+ len = strlen(tb[i].label) + 1 + (tb[i].len > 40 ? 40 : tb[i].len);
+ if ( maxwidth < len )
+ maxwidth = len;
+ }
+
+ return(MultiInputDialog(hLeashInst, hParent, plines, numlines, maxwidth, n, tb));
+}
+
+static krb5_error_code KRB5_CALLCONV
+leash_krb5_prompter( krb5_context context,
+ void *data,
+ const char *name,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[])
+{
+ krb5_error_code errcode = 0;
+ int i;
+ struct textField * tb = NULL;
+ int len = 0, blen=0, nlen=0;
+ HWND hParent = (HWND)data;
+
+ if (name)
+ nlen = strlen(name)+2;
+
+ if (banner)
+ blen = strlen(banner)+2;
+
+ tb = (struct textField *) malloc(sizeof(struct textField) * num_prompts);
+ if ( tb != NULL ) {
+ int ok;
+ memset(tb,0,sizeof(struct textField) * num_prompts);
+ for ( i=0; i < num_prompts; i++ ) {
+ tb[i].buf = prompts[i].reply->data;
+ tb[i].len = prompts[i].reply->length;
+ tb[i].label = prompts[i].prompt;
+ tb[i].def = NULL;
+ tb[i].echo = (prompts[i].hidden ? 2 : 1);
+ }
+
+ ok = multi_field_dialog(hParent,(char *)banner,num_prompts,tb);
+ if ( ok ) {
+ for ( i=0; i < num_prompts; i++ )
+ prompts[i].reply->length = strlen(prompts[i].reply->data);
+ } else
+ errcode = -2;
+ }
+
+ if ( tb )
+ free(tb);
+ if (errcode) {
+ for (i = 0; i < num_prompts; i++) {
+ memset(prompts[i].reply->data, 0, prompts[i].reply->length);
+ }
+ }
+ return errcode;
+}
+#endif /* NO_KRB5 */ \ No newline at end of file
diff --git a/src/windows/leashdll/leash-int.h b/src/windows/leashdll/leash-int.h
new file mode 100644
index 0000000000..fb7617ed34
--- /dev/null
+++ b/src/windows/leashdll/leash-int.h
@@ -0,0 +1,357 @@
+#ifndef __LEASH_INT_H__
+#define __LEASH_INT_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "leashdll.h"
+#include <leashwin.h>
+
+#include "tlhelp32.h"
+
+#define MIT_PWD_DLL_CLASS "MITPasswordWndDLL"
+
+BOOL
+Register_MITPasswordEditControl(
+ HINSTANCE hInst
+ );
+
+BOOL
+Unregister_MITPasswordEditControl(
+ HINSTANCE hInst
+ );
+
+// Some defines swiped from leash.h
+// These are necessary but they must be kept sync'ed with leash.h
+#define HELPFILE "leash32.hlp"
+extern char KRB_HelpFile[_MAX_PATH];
+
+// Function Prototypes.
+int lsh_com_err_proc (LPSTR whoami, long code, LPSTR fmt, va_list args);
+int DoNiftyErrorReport(long errnum, LPSTR what);
+LONG Leash_timesync(int);
+BOOL Leash_ms2mit(BOOL);
+
+#ifndef NO_AFS
+int not_an_API_LeashAFSGetToken(TICKETINFO * ticketinfo, TicketList** ticketList, char * kprinc);
+long FAR not_an_API_LeashFreeTicketList(TicketList** ticketList) ;
+#endif
+
+// Crap...
+#include <krb5.h>
+
+long
+Leash_int_kinit_ex(
+ krb5_context ctx,
+ HWND hParent,
+ char * principal,
+ char * password,
+ int lifetime,
+ int forwardable,
+ int proxiable,
+ int renew_life,
+ int addressless,
+ unsigned long publicIP,
+ int displayErrors
+ );
+
+long
+Leash_int_checkpwd(
+ char * principal,
+ char * password,
+ int displayErrors
+ );
+
+long
+Leash_int_changepwd(
+ char * principal,
+ char * password,
+ char * newpassword,
+ char** result_string,
+ int displayErrors
+ );
+
+int
+Leash_krb5_kdestroy(
+ void
+ );
+
+int
+Leash_krb5_kinit(
+ krb5_context,
+ HWND hParent,
+ char * principal_name,
+ char * password,
+ krb5_deltat lifetime,
+ DWORD forwardable,
+ DWORD proxiable,
+ krb5_deltat renew_life,
+ DWORD addressless,
+ DWORD publicIP
+ );
+
+long
+Leash_convert524(
+ krb5_context ctx
+ );
+
+int
+Leash_afs_unlog(
+ void
+ );
+
+int
+Leash_afs_klog(
+ char *,
+ char *,
+ char *,
+ int
+ );
+
+int
+LeashKRB5_renew(void);
+
+LONG
+write_registry_setting(
+ char* setting,
+ DWORD type,
+ void* buffer,
+ size_t size
+ );
+
+LONG
+read_registry_setting_user(
+ char* setting,
+ void* buffer,
+ size_t size
+ );
+
+LONG
+read_registry_setting(
+ char* setting,
+ void* buffer,
+ size_t size
+ );
+
+BOOL
+get_STRING_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ char * outbuf,
+ DWORD outlen
+ );
+
+BOOL
+get_DWORD_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ DWORD * result
+ );
+
+int
+config_boolean_to_int(
+ const char *s
+ );
+
+BOOL GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData);
+BOOL IsKerberosLogon(VOID);
+
+#ifndef NO_KRB5
+int Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
+ int FreeContextFlag, krb5_context *ctx,
+ krb5_ccache *cache);
+int Leash_krb5_initialize(krb5_context *, krb5_ccache *);
+#endif /* NO_KRB5 */
+
+LPSTR err_describe(LPSTR buf, long code);
+
+// toolhelp functions
+TYPEDEF_FUNC(
+ HANDLE,
+ WINAPI,
+ CreateToolhelp32Snapshot,
+ (DWORD, DWORD)
+ );
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ Module32First,
+ (HANDLE, LPMODULEENTRY32)
+ );
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ Module32Next,
+ (HANDLE, LPMODULEENTRY32)
+ );
+
+// psapi functions
+TYPEDEF_FUNC(
+ DWORD,
+ WINAPI,
+ GetModuleFileNameExA,
+ (HANDLE, HMODULE, LPSTR, DWORD)
+ );
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ EnumProcessModules,
+ (HANDLE, HMODULE*, DWORD, LPDWORD)
+ );
+
+#define pGetModuleFileNameEx pGetModuleFileNameExA
+#define TOOLHELPDLL "kernel32.dll"
+#define PSAPIDLL "psapi.dll"
+
+// psapi functions
+extern DECL_FUNC_PTR(GetModuleFileNameExA);
+extern DECL_FUNC_PTR(EnumProcessModules);
+
+// toolhelp functions
+extern DECL_FUNC_PTR(CreateToolhelp32Snapshot);
+extern DECL_FUNC_PTR(Module32First);
+extern DECL_FUNC_PTR(Module32Next);
+
+/* In order to avoid including the private CCAPI headers */
+typedef int cc_int32;
+
+#define CC_API_VER_1 1
+#define CC_API_VER_2 2
+
+#define CCACHE_API cc_int32
+
+/*
+** The Official Error Codes
+*/
+#define CC_NOERROR 0
+#define CC_BADNAME 1
+#define CC_NOTFOUND 2
+#define CC_END 3
+#define CC_IO 4
+#define CC_WRITE 5
+#define CC_NOMEM 6
+#define CC_FORMAT 7
+#define CC_LOCKED 8
+#define CC_BAD_API_VERSION 9
+#define CC_NO_EXIST 10
+#define CC_NOT_SUPP 11
+#define CC_BAD_PARM 12
+#define CC_ERR_CACHE_ATTACH 13
+#define CC_ERR_CACHE_RELEASE 14
+#define CC_ERR_CACHE_FULL 15
+#define CC_ERR_CRED_VERSION 16
+
+enum {
+ CC_CRED_VUNKNOWN = 0, // For validation
+ CC_CRED_V4 = 1,
+ CC_CRED_V5 = 2,
+ CC_CRED_VMAX = 3 // For validation
+};
+
+typedef struct opaque_dll_control_block_type* apiCB;
+typedef struct _infoNC {
+ char* name;
+ char* principal;
+ cc_int32 vers;
+} infoNC;
+
+TYPEDEF_FUNC(
+CCACHE_API,
+__cdecl,
+cc_initialize,
+ (
+ apiCB** cc_ctx, // < DLL's primary control structure.
+ // returned here, passed everywhere else
+ cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1)
+ cc_int32* api_supported, // < if ~NULL, max ver supported by DLL
+ const char** vendor // < if ~NULL, vendor name in read only C string
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+__cdecl,
+cc_shutdown,
+ (
+ apiCB** cc_ctx // <> DLL's primary control structure. NULL after
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+__cdecl,
+cc_get_NC_info,
+ (
+ apiCB* cc_ctx, // > DLL's primary control structure
+ struct _infoNC*** ppNCi // < (NULL before call) null terminated,
+ // list of a structs (free via cc_free_infoNC())
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+__cdecl,
+cc_free_NC_info,
+ (
+ apiCB* cc_ctx,
+ struct _infoNC*** ppNCi // < free list of structs returned by
+ // cc_get_cache_names(). set to NULL on return
+ )
+);
+#define CCAPI_DLL "krbcc32.dll"
+
+/* The following definitions are summarized from KRB4, KRB5, Leash32, and
+ * Leashw32 modules. They are current as of KfW 2.6.2. There is no
+ * guarrantee that changes to other modules will be updated in this list.
+ */
+
+/* Must match the values used in Leash32.exe */
+#define LEASH_SETTINGS_REGISTRY_KEY_NAME "Software\\MIT\\Leash32\\Settings"
+#define LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS "AfsStatus"
+#define LEASH_SETTINGS_REGISTRY_VALUE_DEBUG_WINDOW "DebugWindow"
+#define LEASH_SETTINGS_REGISTRY_VALUE_LARGE_ICONS "LargeIcons"
+#define LEASH_SETTINGS_REGISTRY_VALUE_DESTROY_TKTS "DestroyTickets"
+#define LEASH_SETTINGS_REGISTRY_VALUE_LOW_TKT_ALARM "LowTicketAlarm"
+#define LEASH_SETTINGS_REGISTRY_VALUE_AUTO_RENEW_TKTS "AutoRenewTickets"
+#define LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM "UpperCaseRealm"
+#define LEASH_SETTINGS_REGISTRY_VALUE_TIMEHOST "TIMEHOST"
+#define LEASH_SETTINGS_REGISTRY_VALUE_CREATE_MISSING_CFG "CreateMissingConfig"
+#define LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT "MsLsaImport"
+
+/* These values are defined and used within Leashw32.dll */
+#define LEASH_REGISTRY_KEY_NAME "Software\\MIT\\Leash"
+#define LEASH_REGISTRY_VALUE_LIFETIME "lifetime"
+#define LEASH_REGISTRY_VALUE_RENEW_TILL "renew_till"
+#define LEASH_REGISTRY_VALUE_RENEWABLE "renewable"
+#define LEASH_REGISTRY_VALUE_FORWARDABLE "forwardable"
+#define LEASH_REGISTRY_VALUE_NOADDRESSES "noaddresses"
+#define LEASH_REGISTRY_VALUE_PROXIABLE "proxiable"
+#define LEASH_REGISTRY_VALUE_PUBLICIP "publicip"
+#define LEASH_REGISTRY_VALUE_USEKRB4 "usekrb4"
+#define LEASH_REGISTRY_VALUE_KINIT_OPT "hide_kinit_options"
+#define LEASH_REGISTRY_VALUE_LIFE_MIN "life_min"
+#define LEASH_REGISTRY_VALUE_LIFE_MAX "life_max"
+#define LEASH_REGISTRY_VALUE_RENEW_MIN "renew_min"
+#define LEASH_REGISTRY_VALUE_RENEW_MAX "renew_max"
+#define LEASH_REGISTRY_VALUE_LOCK_LOCATION "lock_file_locations"
+#define LEASH_REGISTRY_VALUE_PRESERVE_KINIT "preserve_kinit_options"
+
+/* must match values used within krbv4w32.dll */
+#define KRB4_REGISTRY_KEY_NAME "Software\\MIT\\Kerberos4"
+#define KRB4_REGISTRY_VALUE_CONFIGFILE "config"
+#define KRB4_REGISTRY_VALUE_KRB_CONF "krb.conf"
+#define KRB4_REGISTRY_VALUE_KRB_REALMS "krb.realms"
+#define KRB4_REGISTRY_VALUE_TICKETFILE "ticketfile"
+
+/* must match values used within krb5_32.dll */
+#define KRB5_REGISTRY_KEY_NAME "Software\\MIT\\Kerberos5"
+#define KRB5_REGISTRY_VALUE_CCNAME "ccname"
+#define KRB5_REGISTRY_VALUE_CONFIGFILE "config"
+
+/* must match values used within wshelper.dll */
+#define WSHELP_REGISTRY_KEY_NAME "Software\\MIT\\WsHelper"
+#define WSHELP_REGISTRY_VALUE_DEBUG "DebugOn"
+
+#endif /* __LEASH_INT_H__ */
diff --git a/src/windows/leashdll/leashdll.c b/src/windows/leashdll/leashdll.c
new file mode 100644
index 0000000000..f5e2653423
--- /dev/null
+++ b/src/windows/leashdll/leashdll.c
@@ -0,0 +1,444 @@
+#include <windows.h>
+#include "leashdll.h"
+#include <krb.h>
+#include <leashwin.h>
+#include "leash-int.h"
+
+HINSTANCE hLeashInst;
+
+#ifndef NO_KRB4
+HINSTANCE hKrb4 = 0;
+#endif
+HINSTANCE hKrb5 = 0;
+HINSTANCE hKrb524 = 0;
+HINSTANCE hSecur32 = 0;
+HINSTANCE hComErr = 0;
+HINSTANCE hService = 0;
+HINSTANCE hProfile = 0;
+HINSTANCE hPsapi = 0;
+HINSTANCE hToolHelp32 = 0;
+HINSTANCE hCcapi = 0;
+
+DWORD AfsAvailable = 0;
+
+#ifndef NO_KRB4
+// krb4 functions
+DECL_FUNC_PTR(get_krb_err_txt_entry);
+DECL_FUNC_PTR(k_isinst);
+DECL_FUNC_PTR(k_isname);
+DECL_FUNC_PTR(k_isrealm);
+DECL_FUNC_PTR(kadm_change_your_password);
+DECL_FUNC_PTR(kname_parse);
+DECL_FUNC_PTR(krb_get_cred);
+DECL_FUNC_PTR(krb_get_krbhst);
+DECL_FUNC_PTR(krb_get_lrealm);
+DECL_FUNC_PTR(krb_get_pw_in_tkt);
+DECL_FUNC_PTR(krb_get_tf_realm);
+DECL_FUNC_PTR(krb_mk_req);
+DECL_FUNC_PTR(krb_realmofhost);
+DECL_FUNC_PTR(tf_init);
+DECL_FUNC_PTR(tf_close);
+DECL_FUNC_PTR(tf_get_cred);
+DECL_FUNC_PTR(tf_get_pname);
+DECL_FUNC_PTR(tf_get_pinst);
+DECL_FUNC_PTR(LocalHostAddr);
+DECL_FUNC_PTR(tkt_string);
+DECL_FUNC_PTR(krb_set_tkt_string);
+DECL_FUNC_PTR(initialize_krb_error_func);
+DECL_FUNC_PTR(initialize_kadm_error_table);
+DECL_FUNC_PTR(dest_tkt);
+DECL_FUNC_PTR(lsh_LoadKrb4LeashErrorTables); // XXX
+DECL_FUNC_PTR(krb_in_tkt);
+DECL_FUNC_PTR(krb_save_credentials);
+DECL_FUNC_PTR(krb_get_krbconf2);
+DECL_FUNC_PTR(krb_get_krbrealm2);
+DECL_FUNC_PTR(krb_life_to_time);
+#endif
+
+// krb5 functions
+DECL_FUNC_PTR(krb5_change_password);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
+DECL_FUNC_PTR(krb5_get_init_creds_password);
+DECL_FUNC_PTR(krb5_build_principal_ext);
+DECL_FUNC_PTR(krb5_cc_resolve);
+DECL_FUNC_PTR(krb5_cc_default);
+DECL_FUNC_PTR(krb5_cc_default_name);
+DECL_FUNC_PTR(krb5_cc_set_default_name);
+DECL_FUNC_PTR(krb5_cc_initialize);
+DECL_FUNC_PTR(krb5_cc_destroy);
+DECL_FUNC_PTR(krb5_cc_close);
+DECL_FUNC_PTR(krb5_cc_store_cred);
+DECL_FUNC_PTR(krb5_cc_copy_creds);
+// DECL_FUNC_PTR(krb5_cc_retrieve_cred);
+DECL_FUNC_PTR(krb5_cc_get_principal);
+DECL_FUNC_PTR(krb5_cc_start_seq_get);
+DECL_FUNC_PTR(krb5_cc_next_cred);
+DECL_FUNC_PTR(krb5_cc_end_seq_get);
+// DECL_FUNC_PTR(krb5_cc_remove_cred);
+DECL_FUNC_PTR(krb5_cc_set_flags);
+// DECL_FUNC_PTR(krb5_cc_get_type);
+DECL_FUNC_PTR(krb5_free_context);
+DECL_FUNC_PTR(krb5_free_cred_contents);
+DECL_FUNC_PTR(krb5_free_principal);
+DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
+DECL_FUNC_PTR(krb5_init_context);
+DECL_FUNC_PTR(krb5_parse_name);
+DECL_FUNC_PTR(krb5_timeofday);
+DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
+DECL_FUNC_PTR(krb5_unparse_name);
+DECL_FUNC_PTR(krb5_get_credentials);
+DECL_FUNC_PTR(krb5_mk_req);
+DECL_FUNC_PTR(krb5_sname_to_principal);
+DECL_FUNC_PTR(krb5_get_credentials_renew);
+DECL_FUNC_PTR(krb5_free_data);
+DECL_FUNC_PTR(krb5_free_data_contents);
+// DECL_FUNC_PTR(krb5_get_realm_domain);
+DECL_FUNC_PTR(krb5_free_unparsed_name);
+DECL_FUNC_PTR(krb5_os_localaddr);
+DECL_FUNC_PTR(krb5_copy_keyblock_contents);
+DECL_FUNC_PTR(krb5_copy_data);
+DECL_FUNC_PTR(krb5_free_creds);
+DECL_FUNC_PTR(krb5_build_principal);
+DECL_FUNC_PTR(krb5_get_renewed_creds);
+DECL_FUNC_PTR(krb5_get_default_config_files);
+DECL_FUNC_PTR(krb5_free_config_files);
+DECL_FUNC_PTR(krb5_get_default_realm);
+DECL_FUNC_PTR(krb5_free_ticket);
+DECL_FUNC_PTR(krb5_decode_ticket);
+DECL_FUNC_PTR(krb5_get_host_realm);
+DECL_FUNC_PTR(krb5_free_host_realm);
+DECL_FUNC_PTR(krb5_c_random_make_octets);
+DECL_FUNC_PTR(krb5_free_addresses);
+DECL_FUNC_PTR(krb5_free_default_realm);
+DECL_FUNC_PTR(krb5_principal_compare);
+DECL_FUNC_PTR(krb5_string_to_deltat);
+
+#ifndef NO_KRB4
+// Krb524 functions
+DECL_FUNC_PTR(krb524_init_ets);
+DECL_FUNC_PTR(krb524_convert_creds_kdc);
+#endif
+
+// ComErr functions
+DECL_FUNC_PTR(com_err);
+DECL_FUNC_PTR(error_message);
+
+// Profile functions
+DECL_FUNC_PTR(profile_init);
+DECL_FUNC_PTR(profile_release);
+DECL_FUNC_PTR(profile_get_subsection_names);
+DECL_FUNC_PTR(profile_free_list);
+DECL_FUNC_PTR(profile_get_string);
+DECL_FUNC_PTR(profile_release_string);
+DECL_FUNC_PTR(profile_get_integer);
+
+// Service functions
+DECL_FUNC_PTR(OpenSCManagerA);
+DECL_FUNC_PTR(OpenServiceA);
+DECL_FUNC_PTR(QueryServiceStatus);
+DECL_FUNC_PTR(CloseServiceHandle);
+DECL_FUNC_PTR(LsaNtStatusToWinError);
+
+// LSA Functions
+DECL_FUNC_PTR(LsaConnectUntrusted);
+DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
+DECL_FUNC_PTR(LsaCallAuthenticationPackage);
+DECL_FUNC_PTR(LsaFreeReturnBuffer);
+DECL_FUNC_PTR(LsaGetLogonSessionData);
+
+// CCAPI Functions
+DECL_FUNC_PTR(cc_initialize);
+DECL_FUNC_PTR(cc_shutdown);
+DECL_FUNC_PTR(cc_get_NC_info);
+DECL_FUNC_PTR(cc_free_NC_info);
+
+#ifndef NO_KRB4
+FUNC_INFO k4_fi[] = {
+ MAKE_FUNC_INFO(get_krb_err_txt_entry),
+ MAKE_FUNC_INFO(k_isinst),
+ MAKE_FUNC_INFO(k_isname),
+ MAKE_FUNC_INFO(k_isrealm),
+ MAKE_FUNC_INFO(kadm_change_your_password),
+ MAKE_FUNC_INFO(kname_parse),
+ MAKE_FUNC_INFO(krb_get_cred),
+ MAKE_FUNC_INFO(krb_get_krbhst),
+ MAKE_FUNC_INFO(krb_get_lrealm),
+ MAKE_FUNC_INFO(krb_get_pw_in_tkt),
+ MAKE_FUNC_INFO(krb_get_tf_realm),
+ MAKE_FUNC_INFO(krb_mk_req),
+ MAKE_FUNC_INFO(krb_realmofhost),
+ MAKE_FUNC_INFO(tf_init),
+ MAKE_FUNC_INFO(tf_close),
+ MAKE_FUNC_INFO(tf_get_cred),
+ MAKE_FUNC_INFO(tf_get_pname),
+ MAKE_FUNC_INFO(tf_get_pinst),
+ MAKE_FUNC_INFO(LocalHostAddr),
+ MAKE_FUNC_INFO(tkt_string),
+ MAKE_FUNC_INFO(krb_set_tkt_string),
+ MAKE_FUNC_INFO(initialize_krb_error_func),
+ MAKE_FUNC_INFO(initialize_kadm_error_table),
+ MAKE_FUNC_INFO(dest_tkt),
+ MAKE_FUNC_INFO(lsh_LoadKrb4LeashErrorTables), // XXX
+ MAKE_FUNC_INFO(krb_in_tkt),
+ MAKE_FUNC_INFO(krb_save_credentials),
+ MAKE_FUNC_INFO(krb_get_krbconf2),
+ MAKE_FUNC_INFO(krb_get_krbrealm2),
+ MAKE_FUNC_INFO(krb_life_to_time),
+ END_FUNC_INFO
+};
+#endif
+
+FUNC_INFO k5_fi[] = {
+ MAKE_FUNC_INFO(krb5_change_password),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_init),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list),
+ MAKE_FUNC_INFO(krb5_get_init_creds_password),
+ MAKE_FUNC_INFO(krb5_build_principal_ext),
+ MAKE_FUNC_INFO(krb5_cc_resolve),
+ MAKE_FUNC_INFO(krb5_cc_default),
+ MAKE_FUNC_INFO(krb5_cc_default_name),
+ MAKE_FUNC_INFO(krb5_cc_set_default_name),
+ MAKE_FUNC_INFO(krb5_cc_initialize),
+ MAKE_FUNC_INFO(krb5_cc_destroy),
+ MAKE_FUNC_INFO(krb5_cc_close),
+ MAKE_FUNC_INFO(krb5_cc_copy_creds),
+ MAKE_FUNC_INFO(krb5_cc_store_cred),
+// MAKE_FUNC_INFO(krb5_cc_retrieve_cred),
+ MAKE_FUNC_INFO(krb5_cc_get_principal),
+ MAKE_FUNC_INFO(krb5_cc_start_seq_get),
+ MAKE_FUNC_INFO(krb5_cc_next_cred),
+ MAKE_FUNC_INFO(krb5_cc_end_seq_get),
+// MAKE_FUNC_INFO(krb5_cc_remove_cred),
+ MAKE_FUNC_INFO(krb5_cc_set_flags),
+// MAKE_FUNC_INFO(krb5_cc_get_type),
+ MAKE_FUNC_INFO(krb5_free_context),
+ MAKE_FUNC_INFO(krb5_free_cred_contents),
+ MAKE_FUNC_INFO(krb5_free_principal),
+ MAKE_FUNC_INFO(krb5_get_in_tkt_with_password),
+ MAKE_FUNC_INFO(krb5_init_context),
+ MAKE_FUNC_INFO(krb5_parse_name),
+ MAKE_FUNC_INFO(krb5_timeofday),
+ MAKE_FUNC_INFO(krb5_timestamp_to_sfstring),
+ MAKE_FUNC_INFO(krb5_unparse_name),
+ MAKE_FUNC_INFO(krb5_get_credentials),
+ MAKE_FUNC_INFO(krb5_mk_req),
+ MAKE_FUNC_INFO(krb5_sname_to_principal),
+ MAKE_FUNC_INFO(krb5_get_credentials_renew),
+ MAKE_FUNC_INFO(krb5_free_data),
+ MAKE_FUNC_INFO(krb5_free_data_contents),
+// MAKE_FUNC_INFO(krb5_get_realm_domain),
+ MAKE_FUNC_INFO(krb5_free_unparsed_name),
+ MAKE_FUNC_INFO(krb5_os_localaddr),
+ MAKE_FUNC_INFO(krb5_copy_keyblock_contents),
+ MAKE_FUNC_INFO(krb5_copy_data),
+ MAKE_FUNC_INFO(krb5_free_creds),
+ MAKE_FUNC_INFO(krb5_build_principal),
+ MAKE_FUNC_INFO(krb5_get_renewed_creds),
+ MAKE_FUNC_INFO(krb5_free_addresses),
+ MAKE_FUNC_INFO(krb5_get_default_config_files),
+ MAKE_FUNC_INFO(krb5_free_config_files),
+ MAKE_FUNC_INFO(krb5_get_default_realm),
+ MAKE_FUNC_INFO(krb5_free_ticket),
+ MAKE_FUNC_INFO(krb5_decode_ticket),
+ MAKE_FUNC_INFO(krb5_get_host_realm),
+ MAKE_FUNC_INFO(krb5_free_host_realm),
+ MAKE_FUNC_INFO(krb5_c_random_make_octets),
+ MAKE_FUNC_INFO(krb5_free_default_realm),
+ MAKE_FUNC_INFO(krb5_principal_compare),
+ MAKE_FUNC_INFO(krb5_string_to_deltat),
+ END_FUNC_INFO
+};
+
+#ifndef NO_KRB4
+FUNC_INFO k524_fi[] = {
+ MAKE_FUNC_INFO(krb524_init_ets),
+ MAKE_FUNC_INFO(krb524_convert_creds_kdc),
+ END_FUNC_INFO
+};
+#endif
+
+FUNC_INFO profile_fi[] = {
+ MAKE_FUNC_INFO(profile_init),
+ MAKE_FUNC_INFO(profile_release),
+ MAKE_FUNC_INFO(profile_get_subsection_names),
+ MAKE_FUNC_INFO(profile_free_list),
+ MAKE_FUNC_INFO(profile_get_string),
+ MAKE_FUNC_INFO(profile_release_string),
+ MAKE_FUNC_INFO(profile_get_integer),
+ END_FUNC_INFO
+};
+
+FUNC_INFO ce_fi[] = {
+ MAKE_FUNC_INFO(com_err),
+ MAKE_FUNC_INFO(error_message),
+ END_FUNC_INFO
+};
+
+FUNC_INFO service_fi[] = {
+ MAKE_FUNC_INFO(OpenSCManagerA),
+ MAKE_FUNC_INFO(OpenServiceA),
+ MAKE_FUNC_INFO(QueryServiceStatus),
+ MAKE_FUNC_INFO(CloseServiceHandle),
+ MAKE_FUNC_INFO(LsaNtStatusToWinError),
+ END_FUNC_INFO
+};
+
+FUNC_INFO lsa_fi[] = {
+ MAKE_FUNC_INFO(LsaConnectUntrusted),
+ MAKE_FUNC_INFO(LsaLookupAuthenticationPackage),
+ MAKE_FUNC_INFO(LsaCallAuthenticationPackage),
+ MAKE_FUNC_INFO(LsaFreeReturnBuffer),
+ MAKE_FUNC_INFO(LsaGetLogonSessionData),
+ END_FUNC_INFO
+};
+
+// CCAPI v2
+FUNC_INFO ccapi_fi[] = {
+ MAKE_FUNC_INFO(cc_initialize),
+ MAKE_FUNC_INFO(cc_shutdown),
+ MAKE_FUNC_INFO(cc_get_NC_info),
+ MAKE_FUNC_INFO(cc_free_NC_info),
+ END_FUNC_INFO
+};
+
+// psapi functions
+DECL_FUNC_PTR(GetModuleFileNameExA);
+DECL_FUNC_PTR(EnumProcessModules);
+
+FUNC_INFO psapi_fi[] = {
+ MAKE_FUNC_INFO(GetModuleFileNameExA),
+ MAKE_FUNC_INFO(EnumProcessModules),
+ END_FUNC_INFO
+};
+
+// toolhelp functions
+DECL_FUNC_PTR(CreateToolhelp32Snapshot);
+DECL_FUNC_PTR(Module32First);
+DECL_FUNC_PTR(Module32Next);
+
+FUNC_INFO toolhelp_fi[] = {
+ MAKE_FUNC_INFO(CreateToolhelp32Snapshot),
+ MAKE_FUNC_INFO(Module32First),
+ MAKE_FUNC_INFO(Module32Next),
+ END_FUNC_INFO
+};
+
+BOOL WINAPI
+DllMain(
+ HANDLE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpReserved
+ )
+{
+ hLeashInst = hinstDLL;
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ OSVERSIONINFO osvi;
+#ifndef NO_KRB4
+ LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
+#endif
+ LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+ LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
+ LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
+ LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
+#ifndef NO_KRB4
+ LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
+#endif
+ LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
+ LoadFuncs(CCAPI_DLL, ccapi_fi, &hCcapi, 0, 1, 0, 0);
+
+ memset(&osvi, 0, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ // XXX: We should really use feature testing, first
+ // checking for CreateToolhelp32Snapshot. If that's
+ // not around, we try the psapi stuff.
+ //
+ // Only load LSA functions if on NT/2000/XP
+ if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ {
+ // Windows 9x
+ LoadFuncs(TOOLHELPDLL, toolhelp_fi, &hToolHelp32, 0, 1, 0, 0);
+ hPsapi = 0;
+ }
+ else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ // Windows NT
+ LoadFuncs(PSAPIDLL, psapi_fi, &hPsapi, 0, 1, 0, 0);
+ hToolHelp32 = 0;
+ }
+
+
+ /*
+ * Register window class for the MITPasswordControl that
+ * replaces normal edit controls for password input.
+ * zero any fields we don't explicitly set
+ */
+ hLeashInst = hinstDLL;
+#ifndef NO_KRB4
+ if (plsh_LoadKrb4LeashErrorTables)
+ plsh_LoadKrb4LeashErrorTables(hLeashInst, 0);
+#endif
+
+ Register_MITPasswordEditControl(hLeashInst);
+
+#ifndef NO_AFS
+ {
+ DWORD AfsStatus = 0;
+ GetAfsStatus(&AfsStatus);
+
+ AfsAvailable = afscompat_init();
+
+ if ( AfsStatus && !AfsAvailable )
+ SetAfsStatus(0);
+ }
+#endif
+ return TRUE;
+ }
+ case DLL_PROCESS_DETACH:
+#ifndef NO_AFS
+ afscompat_close();
+#endif
+#ifndef NO_KRB4
+ if (hKrb4)
+ FreeLibrary(hKrb4);
+#endif
+ if (hKrb5)
+ FreeLibrary(hKrb5);
+ if (hCcapi)
+ FreeLibrary(hCcapi);
+ if (hProfile)
+ FreeLibrary(hProfile);
+ if (hComErr)
+ FreeLibrary(hComErr);
+ if (hService)
+ FreeLibrary(hService);
+ if (hSecur32)
+ FreeLibrary(hSecur32);
+#ifndef NO_KRB4
+ if (hKrb524)
+ FreeLibrary(hKrb524);
+#endif
+ if (hPsapi)
+ FreeLibrary(hPsapi);
+ if (hToolHelp32)
+ FreeLibrary(hToolHelp32);
+
+ return TRUE;
+ default:
+ return TRUE;
+ }
+}
diff --git a/src/windows/leashdll/leashdll.h b/src/windows/leashdll/leashdll.h
new file mode 100644
index 0000000000..162fb4f21a
--- /dev/null
+++ b/src/windows/leashdll/leashdll.h
@@ -0,0 +1,259 @@
+#ifndef _LEASHDLL_H_
+#define _LEASHDLL_H_
+
+#include <com_err.h>
+#ifndef NO_KRB4
+/*
+ * This is a hack needed because the real com_err.h does
+ * not define err_func. We need it in the case where
+ * we pull in the real com_err instead of the krb4
+ * impostor.
+ */
+#ifndef _DCNS_MIT_COM_ERR_H
+typedef LPSTR (*err_func)(int, long);
+#endif
+
+#include <krberr.h>
+extern void Leash_initialize_krb_error_func(err_func func,struct et_list **);
+#undef init_krb_err_func
+#define init_krb_err_func(erf) Leash_initialize_krb_error_func(erf,&_et_list)
+
+#include <kadm_err.h>
+
+extern void Leash_initialize_kadm_error_table(struct et_list **);
+#undef init_kadm_err_tbl
+#define init_kadm_err_tbl() Leash_initialize_kadm_error_table(&_et_list)
+#define kadm_err_base ERROR_TABLE_BASE_kadm
+#endif
+
+#define krb_err_func Leash_krb_err_func
+
+#include <stdarg.h>
+int lsh_com_err_proc (LPSTR whoami, long code,
+ LPSTR fmt, va_list args);
+void FAR Leash_load_com_err_callback(FARPROC,FARPROC,FARPROC);
+
+
+#ifndef KRBERR
+#define KRBERR(code) (code + krb_err_base)
+#endif
+
+
+/* Internal Stuff */
+
+#include <windows.h>
+#define SECURITY_WIN32
+#include <security.h>
+
+/* _WIN32_WINNT must be 0x0501 or greater to pull in definition of
+ * all required LSA data types when the Vista SDK NtSecAPI.h is used.
+ */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#else
+#if _WIN32_WINNT < 0x0501
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#endif
+#include <ntsecapi.h>
+
+#ifndef NO_KRB4
+extern HINSTANCE hKrb4;
+#endif
+extern HINSTANCE hKrb5;
+extern HINSTANCE hProfile;
+
+#define TIMEHOST "TIMEHOST"
+
+#define LEASH_DEBUG_CLASS_GENERIC 0
+#define LEASH_DEBUG_CLASS_KRB4 1
+#define LEASH_DEBUG_CLASS_KRB4_APP 2
+
+#define LEASH_PRIORITY_LOW 0
+#define LEASH_PRIORITY_HIGH 1
+
+typedef struct TicketList
+{
+ char* theTicket;
+ struct TicketList* next;
+ char* tktEncType;
+ char* keyEncType;
+ int addrCount;
+ char ** addrList;
+ char * name;
+ char * inst;
+ char * realm;
+} TicketList;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN64
+#define LEASH_DLL "leashw64.dll"
+#define KRBCC32_DLL "krbcc64.dll"
+#else
+#define LEASH_DLL "leashw32.dll"
+#define KRBCC32_DLL "krbcc32.dll"
+#endif
+#define SERVICE_DLL "advapi32.dll"
+#define SECUR32_DLL "secur32.dll"
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include <loadfuncs-com_err.h>
+#include <loadfuncs-krb5.h>
+#include <loadfuncs-profile.h>
+#ifndef NO_KRB4
+#include <loadfuncs-krb.h>
+#include <loadfuncs-krb524.h>
+#endif
+#include <loadfuncs-lsa.h>
+
+#include <errno.h>
+
+#ifndef NO_AFS
+#include "afscompat.h"
+#endif
+
+// service definitions
+typedef SC_HANDLE (WINAPI *FP_OpenSCManagerA)(char *, char *, DWORD);
+typedef SC_HANDLE (WINAPI *FP_OpenServiceA)(SC_HANDLE, char *, DWORD);
+typedef BOOL (WINAPI *FP_QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS);
+typedef BOOL (WINAPI *FP_CloseServiceHandle)(SC_HANDLE);
+
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef NO_KRB4
+// krb4 functions
+extern DECL_FUNC_PTR(get_krb_err_txt_entry);
+extern DECL_FUNC_PTR(k_isinst);
+extern DECL_FUNC_PTR(k_isname);
+extern DECL_FUNC_PTR(k_isrealm);
+extern DECL_FUNC_PTR(kadm_change_your_password);
+extern DECL_FUNC_PTR(kname_parse);
+extern DECL_FUNC_PTR(krb_get_cred);
+extern DECL_FUNC_PTR(krb_get_krbhst);
+extern DECL_FUNC_PTR(krb_get_lrealm);
+extern DECL_FUNC_PTR(krb_get_pw_in_tkt);
+extern DECL_FUNC_PTR(krb_get_tf_realm);
+extern DECL_FUNC_PTR(krb_mk_req);
+extern DECL_FUNC_PTR(krb_realmofhost);
+extern DECL_FUNC_PTR(tf_init);
+extern DECL_FUNC_PTR(tf_close);
+extern DECL_FUNC_PTR(tf_get_cred);
+extern DECL_FUNC_PTR(tf_get_pname);
+extern DECL_FUNC_PTR(tf_get_pinst);
+extern DECL_FUNC_PTR(LocalHostAddr);
+extern DECL_FUNC_PTR(tkt_string);
+extern DECL_FUNC_PTR(krb_set_tkt_string);
+extern DECL_FUNC_PTR(initialize_krb_error_func);
+extern DECL_FUNC_PTR(initialize_kadm_error_table);
+extern DECL_FUNC_PTR(dest_tkt);
+extern DECL_FUNC_PTR(lsh_LoadKrb4LeashErrorTables); // XXX
+extern DECL_FUNC_PTR(krb_in_tkt);
+extern DECL_FUNC_PTR(krb_save_credentials);
+extern DECL_FUNC_PTR(krb_get_krbconf2);
+extern DECL_FUNC_PTR(krb_get_krbrealm2);
+extern DECL_FUNC_PTR(krb_life_to_time);
+#endif
+
+// krb5 functions
+extern DECL_FUNC_PTR(krb5_change_password);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
+extern DECL_FUNC_PTR(krb5_get_init_creds_password);
+extern DECL_FUNC_PTR(krb5_build_principal_ext);
+extern DECL_FUNC_PTR(krb5_cc_resolve);
+extern DECL_FUNC_PTR(krb5_cc_default);
+extern DECL_FUNC_PTR(krb5_cc_default_name);
+extern DECL_FUNC_PTR(krb5_cc_set_default_name);
+extern DECL_FUNC_PTR(krb5_cc_initialize);
+extern DECL_FUNC_PTR(krb5_cc_destroy);
+extern DECL_FUNC_PTR(krb5_cc_close);
+extern DECL_FUNC_PTR(krb5_cc_copy_creds);
+extern DECL_FUNC_PTR(krb5_cc_store_cred);
+// extern DECL_FUNC_PTR(krb5_cc_retrieve_cred);
+extern DECL_FUNC_PTR(krb5_cc_get_principal);
+extern DECL_FUNC_PTR(krb5_cc_start_seq_get);
+extern DECL_FUNC_PTR(krb5_cc_next_cred);
+extern DECL_FUNC_PTR(krb5_cc_end_seq_get);
+// extern DECL_FUNC_PTR(krb5_cc_remove_cred);
+extern DECL_FUNC_PTR(krb5_cc_set_flags);
+// extern DECL_FUNC_PTR(krb5_cc_get_type);
+extern DECL_FUNC_PTR(krb5_free_context);
+extern DECL_FUNC_PTR(krb5_free_cred_contents);
+extern DECL_FUNC_PTR(krb5_free_principal);
+extern DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
+extern DECL_FUNC_PTR(krb5_init_context);
+extern DECL_FUNC_PTR(krb5_parse_name);
+extern DECL_FUNC_PTR(krb5_timeofday);
+extern DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
+extern DECL_FUNC_PTR(krb5_unparse_name);
+extern DECL_FUNC_PTR(krb5_get_credentials);
+extern DECL_FUNC_PTR(krb5_mk_req);
+extern DECL_FUNC_PTR(krb5_sname_to_principal);
+extern DECL_FUNC_PTR(krb5_get_credentials_renew);
+extern DECL_FUNC_PTR(krb5_free_data);
+extern DECL_FUNC_PTR(krb5_free_data_contents);
+// extern DECL_FUNC_PTR(krb5_get_realm_domain);
+extern DECL_FUNC_PTR(krb5_free_unparsed_name);
+extern DECL_FUNC_PTR(krb5_os_localaddr);
+extern DECL_FUNC_PTR(krb5_copy_keyblock_contents);
+extern DECL_FUNC_PTR(krb5_copy_data);
+extern DECL_FUNC_PTR(krb5_free_creds);
+extern DECL_FUNC_PTR(krb5_build_principal);
+extern DECL_FUNC_PTR(krb5_get_renewed_creds);
+extern DECL_FUNC_PTR(krb5_free_addresses);
+extern DECL_FUNC_PTR(krb5_get_default_config_files);
+extern DECL_FUNC_PTR(krb5_free_config_files);
+extern DECL_FUNC_PTR(krb5_get_default_realm);
+extern DECL_FUNC_PTR(krb5_free_ticket);
+extern DECL_FUNC_PTR(krb5_decode_ticket);
+extern DECL_FUNC_PTR(krb5_get_host_realm);
+extern DECL_FUNC_PTR(krb5_free_host_realm);
+extern DECL_FUNC_PTR(krb5_c_random_make_octets);
+extern DECL_FUNC_PTR(krb5_free_default_realm);
+extern DECL_FUNC_PTR(krb5_principal_compare);
+extern DECL_FUNC_PTR(krb5_string_to_deltat);
+
+#ifndef NO_KRB4
+// Krb524 functions
+extern DECL_FUNC_PTR(krb524_init_ets);
+extern DECL_FUNC_PTR(krb524_convert_creds_kdc);
+#endif
+
+// ComErr functions
+extern DECL_FUNC_PTR(com_err);
+extern DECL_FUNC_PTR(error_message);
+
+// Profile functions
+extern DECL_FUNC_PTR(profile_init);
+extern DECL_FUNC_PTR(profile_release);
+extern DECL_FUNC_PTR(profile_get_subsection_names);
+extern DECL_FUNC_PTR(profile_free_list);
+extern DECL_FUNC_PTR(profile_get_string);
+extern DECL_FUNC_PTR(profile_release_string);
+extern DECL_FUNC_PTR(profile_get_integer);
+
+// Service functions
+
+extern DECL_FUNC_PTR(OpenSCManagerA);
+extern DECL_FUNC_PTR(OpenServiceA);
+extern DECL_FUNC_PTR(QueryServiceStatus);
+extern DECL_FUNC_PTR(CloseServiceHandle);
+extern DECL_FUNC_PTR(LsaNtStatusToWinError);
+
+// LSA Functions
+
+extern DECL_FUNC_PTR(LsaConnectUntrusted);
+extern DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
+extern DECL_FUNC_PTR(LsaCallAuthenticationPackage);
+extern DECL_FUNC_PTR(LsaFreeReturnBuffer);
+extern DECL_FUNC_PTR(LsaGetLogonSessionData);
+
+#endif /* _LEASHDLL_H_ */
diff --git a/src/windows/leashdll/leasherr.c b/src/windows/leashdll/leasherr.c
new file mode 100644
index 0000000000..ec2616b21c
--- /dev/null
+++ b/src/windows/leashdll/leasherr.c
@@ -0,0 +1,119 @@
+// ATTENTION: someone in the past edited this file manually
+// I am continuing this tradition just to get the release out. 3/6/97
+// This needs to be revisited and repaired!!!XXXX
+// pbh
+
+
+ /*
+ * leasherr.c
+ * This file is the C file for leasherr.et.
+ * Please do not edit it as it is automatically generated.
+ */
+
+#ifndef NO_KRB4
+extern void (__cdecl *pinitialize_krb_error_func)();
+extern void (__cdecl *pinitialize_kadm_error_table)();
+#endif
+
+#include <stdlib.h>
+#include <windows.h>
+
+static const char* const text[] = {
+ "Only one instance of Leash can be run at a time.",
+ "Principal invalid.",
+ "Realm failed.",
+ "Instance invalid.",
+ "Realm invalid.",
+ "Unexpected end of Kerberos memory storage.",
+ "Warning! Your Kerberos tickets expire soon.",
+ "You did not type the same new password.",
+ "You can only use printable characters in a password.",
+ "Fatal error; cannot run this program.",
+ "Couldn't initialize WinSock.",
+ "Couldn't find the timeserver host entry.",
+ "Couldn't open a socket.",
+ "Couldn't connect to timeserver.",
+ "Couldn't get time from server.",
+ "Couldn't get local time of day.",
+ "Couldn't set local time of day.",
+ "Error while receiving time from server.",
+ "Protocol problem with timeserver.",
+ "The time was already reset. Try using a different program to synchronize the time.",
+ 0
+};
+
+typedef LPSTR (*err_func)(int, long);
+struct error_table {
+ char const * const * msgs;
+ err_func func;
+ long base;
+ int n_msgs;
+};
+struct et_list {
+#ifdef WINDOWS
+ HANDLE next;
+#else
+ struct et_list *next;
+#endif
+ const struct error_table * table;
+};
+
+static const struct error_table et = { text, (err_func)0, 40591872L, 20 };
+
+#ifdef WINDOWS
+void initialize_lsh_error_table(HANDLE *__et_list) {
+// struct et_list *_link,*_et_list;
+ struct et_list *_link;
+ HANDLE ghlink;
+
+ ghlink=GlobalAlloc(GHND,sizeof(struct et_list));
+ _link=GlobalLock(ghlink);
+ _link->next=*__et_list;
+ _link->table=&et;
+ GlobalUnlock(ghlink);
+ *__et_list=ghlink;
+}
+#else
+void initialize_lsh_error_table(struct et_list **__et_list) {
+ struct et_list *_link;
+
+ _link=malloc(sizeof(struct et_list));
+ _link->next=*__et_list;
+ _link->table=&et;
+ *__et_list=_link;
+}
+#endif
+
+#ifdef WINDOWS
+#include <krberr.h>
+
+void Leash_initialize_krb_error_func(err_func func, HANDLE *__et_list)
+{
+#ifndef NO_KRB4
+ (*pinitialize_krb_error_func)(func,__et_list);
+#endif
+}
+
+#include <kadm_err.h>
+
+void Leash_initialize_kadm_error_table(HANDLE *__et_list)
+{
+#ifndef NO_KRB4
+ (*pinitialize_kadm_error_table)(__et_list);
+#endif
+}
+#else
+#include <krberr.h>
+
+void Leash_initialize_krb_error_func(err_func func, struct et_list **__et_list)
+{
+ (*pinitialize_krb_error_func)(func,__et_list);
+}
+
+#include <kadm_err.h>
+
+void Leash_initialize_kadm_error_table(struct et_list **__et_list)
+{
+ initialize_kadm_error_table(__et_list);
+}
+#endif
diff --git a/src/windows/leashdll/leasherr.et b/src/windows/leashdll/leasherr.et
new file mode 100644
index 0000000000..d1d027bd1c
--- /dev/null
+++ b/src/windows/leashdll/leasherr.et
@@ -0,0 +1,22 @@
+ERROR_TABLE lsh
+ ERROR_CODE LSH_ONLYONEME, "Only one instance of Leash can be run at a time."
+ ERROR_CODE LSH_INVPRINCIPAL, "Principal invalid."
+ ERROR_CODE LSH_FAILEDREALM, "Realm failed."
+ ERROR_CODE LSH_INVINSTANCE, "Instance invalid."
+ ERROR_CODE LSH_INVREALM, "Realm invalid."
+ ERROR_CODE LSH_EOF, "Unexpected end of Kerberos memory storage."
+ ERROR_CODE LSH_EXPIRESOON, "Warning! Your Kerberos tickets expire soon."
+ ERROR_CODE LSH_NOMATCH, "You did not type the same new password."
+ ERROR_CODE LSH_BADCHARS, "You can only use printable characters in a password."
+ ERROR_CODE LSH_FATAL_ERROR, "Fatal error; cannot run this program."
+ ERROR_CODE LSH_BADWINSOCK, "Couldn't initialize WinSock."
+ ERROR_CODE LSH_BADTIMESERV, "Couldn't find the timeserver host entry."
+ ERROR_CODE LSH_NOSOCKET, "Couldn't open a socket."
+ ERROR_CODE LSH_NOCONNECT, "Couldn't connect to timeserver."
+ ERROR_CODE LSH_TIMEFAILED, "Couldn't get time from server."
+ ERROR_CODE LSH_GETTIMEOFDAY, "Couldn't get local time of day."
+ ERROR_CODE LSH_SETTIMEOFDAY, "Couldn't set local time of day."
+ ERROR_CODE LSH_RECVTIME, "Error while receiving time from server."
+ ERROR_CODE LSH_RECVBYTES, "Protocol problem with timeserver."
+ ERROR_CODE LSH_ALREADY_SETTIME, "The time was already reset. Try using a different program to synchronize the time."
+end
diff --git a/src/windows/leashdll/leashids.h b/src/windows/leashdll/leashids.h
new file mode 100644
index 0000000000..64c8641cbf
--- /dev/null
+++ b/src/windows/leashdll/leashids.h
@@ -0,0 +1,115 @@
+// *** Child Windows
+#define ID_MAINLIST 100
+#define ID_COUNTDOWN 101
+
+#define ID_DESTROY 111
+#define ID_CHANGEPASSWORD 112
+#define ID_INITTICKETS 113
+#define ID_SYNCTIME 114
+
+#define ID_UPDATESTATE 120
+#define ID_UPDATEDISPLAY 121
+#define ID_KRBDLL_DEBUG 122
+
+
+// *** Menus
+
+#define ID_EXIT 200
+
+#define ID_HELP_LEASH 210
+#define ID_HELP_KERBEROS 211
+#define ID_ABOUT 212
+
+#define ID_CHECKV 299
+
+// *** Password Dialog
+#define ID_PRINCIPAL 301
+#define ID_OLDPASSWORD 302
+#define ID_CONFIRMPASSWORD1 303
+#define ID_CONFIRMPASSWORD2 304
+#define ID_PICFRAME 305
+
+#define ID_PRINCCAPTION 311
+#define ID_OLDPCAPTION 312
+#define ID_CONFIRMCAPTION1 313
+#define ID_CONFIRMCAPTION2 314
+#define CAPTION_OFFSET 10
+
+#define ID_DURATION 320
+
+#define ID_RESTART 351
+
+#define ID_CLOSEME 380
+
+// *** About dialog stuff
+#define ID_LEASH_CPYRT 400
+#define ID_LEASH_AUTHOR 401
+#define ID_KERB_CPYRT 402
+#define ID_KERB_AUTHOR 403
+#define ID_LEGALESE 404
+#define ID_ASSISTANCE 405
+
+// *** Keyboard accelerator crud
+#define ID_HELP 1000
+#define ID_CONTEXTSENSITIVEHELP 1001
+#define ID_ENDCSHELP 1002
+#define ID_HELPFIRST 1000
+#define ID_HELPLAST 1002
+
+// *** window messages
+#define WM_STARTUP (WM_USER + 1)
+#define WM_F1DOWN (WM_USER + 2)
+#define WM_DOHELP (WM_USER + 3)
+#define WM_PAINTICON 0x0026
+
+// *** command messages
+#define ID_NEXTSTATE 10000
+
+#define LSH_TIME_HOST 1970
+#define LSH_DEFAULT_TICKET_LIFE 1971
+#define LSH_DEFAULT_TICKET_RENEW_TILL 1972
+#define LSH_DEFAULT_TICKET_FORWARD 1973
+#define LSH_DEFAULT_TICKET_NOADDRESS 1974
+#define LSH_DEFAULT_TICKET_PROXIABLE 1975
+#define LSH_DEFAULT_TICKET_PUBLICIP 1976
+#define LSH_DEFAULT_TICKET_USEKRB4 1977
+#define LSH_DEFAULT_DIALOG_KINIT_OPT 1978
+#define LSH_DEFAULT_DIALOG_LIFE_MIN 1979
+#define LSH_DEFAULT_DIALOG_LIFE_MAX 1980
+#define LSH_DEFAULT_DIALOG_RENEW_MIN 1981
+#define LSH_DEFAULT_DIALOG_RENEW_MAX 1982
+#define LSH_DEFAULT_TICKET_RENEW 1983
+#define LSH_DEFAULT_DIALOG_LOCK_LOCATION 1984
+#define LSH_DEFAULT_UPPERCASEREALM 1985
+#define LSH_DEFAULT_MSLSA_IMPORT 1986
+#define LSH_DEFAULT_PRESERVE_KINIT 1987
+
+// Authenticate Dialog
+#define IDD_AUTHENTICATE 1162
+#define IDC_STATIC_IPADDR 1163
+#define IDC_STATIC_NAME 1164
+#define IDC_STATIC_PWD 1165
+#define IDC_EDIT_PRINCIPAL 1166
+#define IDC_COMBO_REALM 1167
+#define IDC_EDIT_PASSWORD 1168
+#define IDC_STATIC_LIFETIME 1169
+#define IDC_SLIDER_LIFETIME 1170
+#define IDC_STATIC_KRB5 1171
+#define IDC_CHECK_FORWARDABLE 1172
+#define IDC_CHECK_NOADDRESS 1173
+#define IDC_CHECK_RENEWABLE 1174
+#define IDC_SLIDER_RENEWLIFE 1175
+#define IDC_STATIC_LIFETIME_VALUE 1176
+#define IDC_STATIC_RENEW_TILL_VALUE 1177
+#define IDC_PICTURE_LEASH 1179
+#define IDC_BUTTON_OPTIONS 1086
+#define IDC_STATIC_REALM 1087
+#define IDC_STATIC_COPYRIGHT 1088
+#define IDC_STATIC_NOTICE 1089
+#define IDC_STATIC_RENEW 1090
+#define IDD_PASSWORD 1091
+#define IDC_EDIT_PASSWORD2 1192
+#define IDC_STATIC_PWD2 1193
+#define IDC_EDIT_PASSWORD3 1194
+#define IDC_STATIC_PWD3 1195
+#define IDC_STATIC_VERSION 1196
diff --git a/src/windows/leashdll/leashw32.def b/src/windows/leashdll/leashw32.def
new file mode 100644
index 0000000000..25af0e2ea8
--- /dev/null
+++ b/src/windows/leashdll/leashw32.def
@@ -0,0 +1,108 @@
+LIBRARY LEASHW32
+
+DESCRIPTION 'DLL for Kerberos ticket initialization'
+
+HEAPSIZE 8092
+STACKSIZE 36864
+
+EXPORTS
+; DllMain @1
+ ; Leash_kinit_dlg @3
+ ; Leash_changepwd_dlg @4
+ ; Leash_kinit @48
+ ; Leash_kdestroy @49
+ ; Leash_klist @50
+ ; Leash_checkpwd @51
+ ; Leash_changepwd @52
+ ; Leash_get_lsh_errno @61
+ ; initialize_lsh_error_table @80
+ ; lsh_com_err_proc @81
+ ; Leash_initialize_krb_error_func @82
+ ; Leash_initialize_kadm_error_table @83
+ ; Leash_krb_err_func @84
+ ; Leash_load_com_err_callback @85
+ ; Leash_set_help_file @86
+ ; Leash_get_help_file @87
+ ; Leash_timesync @88
+; Leash_WhichOS @89
+
+ Leash_kinit_dlg
+ Leash_kinit_dlg_ex
+ Leash_changepwd_dlg
+ Leash_changepwd_dlg_ex
+ Leash_kinit
+ Leash_kinit_ex
+ Leash_kdestroy
+ Leash_klist
+ Leash_checkpwd
+ Leash_changepwd
+ Leash_get_lsh_errno
+ initialize_lsh_error_table
+ lsh_com_err_proc
+ Leash_initialize_krb_error_func
+ Leash_initialize_kadm_error_table
+ Leash_krb_err_func
+ Leash_load_com_err_callback
+ Leash_set_help_file
+ Leash_get_help_file
+ Leash_timesync
+ Leash_get_default_lifetime
+ Leash_set_default_lifetime
+ Leash_reset_default_lifetime
+ Leash_get_default_renew_till
+ Leash_set_default_renew_till
+ Leash_reset_default_renew_till
+ Leash_get_default_forwardable
+ Leash_set_default_forwardable
+ Leash_reset_default_forwardable
+ Leash_get_default_renewable
+ Leash_set_default_renewable
+ Leash_reset_default_renewable
+ Leash_get_default_noaddresses
+ Leash_set_default_noaddresses
+ Leash_reset_default_noaddresses
+ Leash_get_default_proxiable
+ Leash_set_default_proxiable
+ Leash_reset_default_proxiable
+ Leash_get_default_publicip
+ Leash_set_default_publicip
+ Leash_reset_default_publicip
+ Leash_get_default_use_krb4
+ Leash_set_default_use_krb4
+ Leash_reset_default_use_krb4
+ Leash_get_default_life_min
+ Leash_set_default_life_min
+ Leash_reset_default_life_min
+ Leash_get_default_life_max
+ Leash_set_default_life_max
+ Leash_reset_default_life_max
+ Leash_get_default_renew_min
+ Leash_set_default_renew_min
+ Leash_reset_default_renew_min
+ Leash_get_default_renew_max
+ Leash_set_default_renew_max
+ Leash_reset_default_renew_max
+ Leash_get_lock_file_locations
+ Leash_set_lock_file_locations
+ Leash_reset_lock_file_locations
+ Leash_get_default_uppercaserealm
+ Leash_set_default_uppercaserealm
+ Leash_reset_default_uppercaserealm
+ Leash_get_default_mslsa_import
+ Leash_set_default_mslsa_import
+ Leash_reset_default_mslsa_import
+ Leash_get_default_preserve_kinit_settings
+ Leash_set_default_preserve_kinit_settings
+ Leash_reset_default_preserve_kinit_settings
+ Leash_import
+ Leash_importable
+ Leash_renew
+ Leash_reset_defaults
+
+ ; XXX - These have to go...
+ not_an_API_LeashAFSGetToken
+ not_an_API_LeashKRB5GetTickets
+ not_an_API_LeashFreeTicketList
+ not_an_API_LeashKRB4GetTickets
+ not_an_API_LeashGetTimeServerName
+ not_an_API_Leash_AcquireInitialTicketsIfNeeded
diff --git a/src/windows/leashdll/loadfuncs.c b/src/windows/leashdll/loadfuncs.c
new file mode 100644
index 0000000000..44ec54dfaa
--- /dev/null
+++ b/src/windows/leashdll/loadfuncs.c
@@ -0,0 +1,88 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "loadfuncs.h"
+
+//
+// UnloadFuncs:
+//
+// This function will reset all the function pointers of a function loaded
+// by LaodFuncs and will free the DLL instance provided.
+//
+
+void
+UnloadFuncs(
+ FUNC_INFO fi[],
+ HINSTANCE h
+ )
+{
+ int n;
+ if (fi)
+ for (n = 0; fi[n].func_ptr_var; n++)
+ *(fi[n].func_ptr_var) = NULL;
+ if (h) FreeLibrary(h);
+}
+
+
+//
+// LoadFuncs:
+//
+// This function try to load the functions for a DLL. It returns 0 on failure
+// and non-zero on success. The parameters are descibed below.
+//
+
+int
+LoadFuncs(
+ const char* dll_name,
+ FUNC_INFO fi[],
+ HINSTANCE* ph, // [out, optional] - DLL handle
+ int* pindex, // [out, optional] - index of last func loaded (-1 if none)
+ int cleanup, // cleanup function pointers and unload on error
+ int go_on, // continue loading even if some functions cannot be loaded
+ int silent // do not pop-up a system dialog if DLL cannot be loaded
+
+ )
+{
+ HINSTANCE h;
+ int i, n, last_i;
+ int error = 0;
+ UINT em;
+
+ if (ph) *ph = 0;
+ if (pindex) *pindex = -1;
+
+ for (n = 0; fi[n].func_ptr_var; n++)
+ *(fi[n].func_ptr_var) = NULL;
+
+ if (silent)
+ em = SetErrorMode(SEM_FAILCRITICALERRORS);
+ h = LoadLibrary(dll_name);
+ if (silent)
+ SetErrorMode(em);
+
+ if (!h)
+ return 0;
+
+ last_i = -1;
+ for (i = 0; (go_on || !error) && (i < n); i++)
+ {
+ void* p = (void*)GetProcAddress(h, fi[i].func_name);
+ if (!p)
+ error = 1;
+ else
+ {
+ last_i = i;
+ *(fi[i].func_ptr_var) = p;
+ }
+ }
+ if (pindex) *pindex = last_i;
+ if (error && cleanup && !go_on) {
+ for (i = 0; i < n; i++) {
+ *(fi[i].func_ptr_var) = NULL;
+ }
+ FreeLibrary(h);
+ return 0;
+ }
+ if (ph) *ph = h;
+ if (error) return 0;
+ return 1;
+}
diff --git a/src/windows/leashdll/lsh_pwd.c b/src/windows/leashdll/lsh_pwd.c
new file mode 100644
index 0000000000..6be1ea3c0a
--- /dev/null
+++ b/src/windows/leashdll/lsh_pwd.c
@@ -0,0 +1,2430 @@
+#define SCALE_FACTOR 31/20
+
+/* LSH_PWD.C
+
+ Jason Hunter
+ 8/2/94
+ DCNS/IS MIT
+
+ Re-written for KFW 2.6 by Jeffrey Altman <jaltman@mit.edu>
+
+ Contains the callback functions for the EnterPassword an
+ ChangePassword dialog boxes and well as the API function
+ calls:
+
+ Lsh_Enter_Password_Dialog
+ Lsh_Change_Password_Dialog
+
+ for calling the dialogs.
+
+ Also contains the callback for the MITPasswordControl.
+
+*/
+
+/* Standard Include files */
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Private Inlclude files */
+#include "leashdll.h"
+#include <conf.h>
+#include <leashwin.h>
+#include "leash-int.h"
+#include "leashids.h"
+#include <leasherr.h>
+#include <krb.h>
+#ifndef NO_KRB5
+#include <krb5.h>
+#endif /* NO_KRB5 */
+#include <commctrl.h>
+
+/* Global Variables. */
+static long lsh_errno;
+static char *err_context; /* error context */
+extern HINSTANCE hLeashInst;
+extern HINSTANCE hKrb4;
+extern HINSTANCE hKrb5;
+
+
+INT_PTR
+CALLBACK
+PasswordProc(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+INT_PTR
+CALLBACK
+AuthenticateProc(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+INT_PTR
+CALLBACK
+NewPasswordProc(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+
+long Leash_get_lsh_errno(LONG *err_val)
+{
+ return lsh_errno;
+}
+
+/*/////// ******** API Calls follow here. ******** /////////*/
+
+static int
+NetId_dialog(LPLSH_DLGINFO lpdlginfo)
+{
+ LRESULT lrc;
+ HWND hNetIdMgr;
+ HWND hForeground;
+
+ hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
+ if (hNetIdMgr != NULL) {
+ char desiredPrincipal[512];
+ NETID_DLGINFO *dlginfo;
+ char *desiredName = 0;
+ char *desiredRealm = 0;
+ HANDLE hMap;
+ DWORD tid = GetCurrentThreadId();
+ char mapname[256];
+
+ strcpy(desiredPrincipal, lpdlginfo->principal);
+
+ /* do we want a specific client principal? */
+ if (desiredPrincipal[0]) {
+ char * p;
+ desiredName = desiredPrincipal;
+ for (p = desiredName; *p && *p != '@'; p++);
+ if ( *p == '@' ) {
+ *p = '\0';
+ desiredRealm = ++p;
+ }
+ }
+
+ sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
+
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+ 0, 4096, mapname);
+ if (hMap == NULL) {
+ return -1;
+ } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
+ 0, 0, 4096, NULL);
+ if (dlginfo == NULL) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ hForeground = GetForegroundWindow();
+
+ memset(dlginfo, 0, sizeof(NETID_DLGINFO));
+
+ dlginfo->size = sizeof(NETID_DLGINFO);
+ if (lpdlginfo->dlgtype == DLGTYPE_PASSWD)
+ dlginfo->dlgtype = NETID_DLGTYPE_TGT;
+ else
+ dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD;
+ dlginfo->in.use_defaults = 1;
+
+ if (lpdlginfo->title) {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ lpdlginfo->title, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
+ char mytitle[NETID_TITLE_SZ];
+ sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ mytitle, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ "Obtain Kerberos TGT", -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ }
+ if (desiredName)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredName, -1,
+ dlginfo->in.username, NETID_USERNAME_SZ);
+ if (desiredRealm)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredRealm, -1,
+ dlginfo->in.realm, NETID_REALM_SZ);
+ lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
+
+ UnmapViewOfFile(dlginfo);
+ CloseHandle(hMap);
+
+ SetForegroundWindow(hForeground);
+ return lrc;
+ }
+ return -1;
+}
+
+static int
+NetId_dialog_ex(LPLSH_DLGINFO_EX lpdlginfo)
+{
+ HWND hNetIdMgr;
+ HWND hForeground;
+
+ hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
+ if (hNetIdMgr != NULL) {
+ NETID_DLGINFO *dlginfo;
+ char *desiredName = lpdlginfo->username;
+ char *desiredRealm = lpdlginfo->realm;
+ LPSTR title;
+ char *ccache;
+ LRESULT lrc;
+ HANDLE hMap;
+ DWORD tid = GetCurrentThreadId();
+ char mapname[256];
+
+ sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
+
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+ 0, 4096, mapname);
+ if (hMap == NULL) {
+ return -1;
+ } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
+ 0, 0, 4096, NULL);
+ if (dlginfo == NULL) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ hForeground = GetForegroundWindow();
+
+ if (lpdlginfo->size == LSH_DLGINFO_EX_V1_SZ ||
+ lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ)
+ {
+ title = lpdlginfo->title;
+ desiredName = lpdlginfo->username;
+ desiredRealm = lpdlginfo->realm;
+ ccache = NULL;
+ } else {
+ title = lpdlginfo->in.title;
+ desiredName = lpdlginfo->in.username;
+ desiredRealm = lpdlginfo->in.realm;
+ ccache = lpdlginfo->in.ccache;
+ }
+
+ memset(dlginfo, 0, sizeof(NETID_DLGINFO));
+
+ dlginfo->size = sizeof(NETID_DLGINFO);
+ if (lpdlginfo->dlgtype == DLGTYPE_PASSWD)
+ dlginfo->dlgtype = NETID_DLGTYPE_TGT;
+ else
+ dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD;
+
+ dlginfo->in.use_defaults = lpdlginfo->use_defaults;
+ dlginfo->in.forwardable = lpdlginfo->forwardable;
+ dlginfo->in.noaddresses = lpdlginfo->noaddresses;
+ dlginfo->in.lifetime = lpdlginfo->lifetime;
+ dlginfo->in.renew_till = lpdlginfo->renew_till;
+ dlginfo->in.proxiable = lpdlginfo->proxiable;
+ dlginfo->in.publicip = lpdlginfo->publicip;
+
+ if (title) {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ title, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
+ char mytitle[NETID_TITLE_SZ];
+ sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ mytitle, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ "Obtain Kerberos TGT", -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ }
+ if (desiredName)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredName, -1,
+ dlginfo->in.username, NETID_USERNAME_SZ);
+ if (desiredRealm)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredRealm, -1,
+ dlginfo->in.realm, NETID_REALM_SZ);
+ if (ccache)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ ccache, -1,
+ dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
+ lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
+
+ if (lrc > 0) {
+ if (lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ)
+ {
+ WideCharToMultiByte(CP_ACP, 0, dlginfo->out.username, -1,
+ lpdlginfo->out.username, LEASH_USERNAME_SZ,
+ NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, dlginfo->out.realm, -1,
+ lpdlginfo->out.realm, LEASH_REALM_SZ,
+ NULL, NULL);
+ }
+ if (lpdlginfo->size == LSH_DLGINFO_EX_V3_SZ)
+ {
+ WideCharToMultiByte(CP_ACP, 0, dlginfo->out.ccache, -1,
+ lpdlginfo->out.ccache, LEASH_CCACHE_NAME_SZ,
+ NULL, NULL);
+ }
+ }
+
+ UnmapViewOfFile(dlginfo);
+ CloseHandle(hMap);
+
+ SetForegroundWindow(hForeground);
+ return lrc;
+ }
+ return -1;
+}
+
+
+#define LEASH_DLG_MUTEX_NAME TEXT("Leash_Dialog_Mutex")
+int Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo)
+{
+ int rc;
+ HANDLE hMutex;
+
+ rc = NetId_dialog(lpdlginfo);
+ if (rc > -1)
+ return rc;
+
+ hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+ if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
+ return -1;
+ }
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return 1; /* pretend the dialog was displayed and succeeded */
+ }
+
+ lpdlginfo->dlgtype = DLGTYPE_PASSWD;
+
+ /* set the help file */
+ Leash_set_help_file(NULL);
+
+ /* Call the Dialog box with the DLL's Password Callback and the
+ DLL's instance handle. */
+ rc = DialogBoxParam(hLeashInst, "EnterPasswordDlg", hParent,
+ PasswordProc, (LPARAM)lpdlginfo);
+
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return rc;
+}
+
+
+int Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo)
+{
+ int rc;
+ HANDLE hMutex;
+
+ rc = NetId_dialog_ex(lpdlginfo);
+ if (rc > -1)
+ return rc;
+
+ hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+ if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
+ return -1;
+ }
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return 1; /* pretend the dialog was displayed and succeeded */
+ }
+
+ lpdlginfo->dlgtype = DLGTYPE_PASSWD;
+
+ /* set the help file */
+ Leash_set_help_file(NULL);
+
+ /* Call the Dialog box with the DLL's Password Callback and the
+ DLL's instance handle. */
+ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_AUTHENTICATE), hParent,
+ AuthenticateProc, (LPARAM)lpdlginfo);
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return rc;
+}
+
+
+int Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo)
+{
+ int rc;
+ HANDLE hMutex;
+
+ rc = NetId_dialog(lpdlginfo);
+ if (rc > -1)
+ return rc;
+
+ hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+ if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
+ return -1;
+ }
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return 1; /* pretend the dialog was displayed and succeeded */
+ }
+
+ lpdlginfo->dlgtype = DLGTYPE_CHPASSWD;
+
+ /* Call the Dialog box with the DLL's Password Callback and the
+ DLL's instance handle. */
+ rc = DialogBoxParam(hLeashInst, "CHANGEPASSWORDDLG", hParent,
+ PasswordProc, (LPARAM)lpdlginfo);
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return rc;
+}
+
+int Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo)
+{
+ int rc;
+ HANDLE hMutex;
+
+ rc = NetId_dialog_ex(lpdlginfo);
+ if (rc > -1)
+ return rc;
+
+ hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+ if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
+ return -1;
+ }
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return 1; /* pretend the dialog was displayed and succeeded */
+ }
+
+ lpdlginfo->dlgtype = DLGTYPE_CHPASSWD;
+
+ /* Call the Dialog box with the DLL's Password Callback and the
+ DLL's instance handle. */
+ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_PASSWORD), hParent,
+ NewPasswordProc, (LPARAM)lpdlginfo);
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ return rc;
+}
+
+
+/* These little utils are taken from lshutil.c
+ they are added here for the Call back funtion.
+****** beginning of added utils from lshutil.c ******/
+
+BOOL IsDlgItem(HWND hWnd, WORD id)
+{
+ HWND hChild;
+
+ hChild = GetDlgItem(hWnd, id);
+ return hChild ? IsWindow(hChild) : 0;
+}
+
+int lsh_getkeystate(WORD keyid)
+{
+ static BYTE keys[256];
+
+ GetKeyboardState((LPBYTE) &keys);
+ return (int) keys[keyid];
+}
+
+LPSTR krb_err_func(int offset, long code)
+{
+#ifdef NO_KRB4
+ return(NULL);
+#else
+ return pget_krb_err_txt_entry(offset);
+#endif
+}
+
+/****** End of Added utils from leash.c ******/
+
+
+int PaintLogoBitmap( HANDLE hPicFrame )
+{
+ HBITMAP hBitmap;
+ HBITMAP hOldBitmap;
+ BITMAP Bitmap;
+ HDC hdc, hdcMem;
+ RECT rect;
+
+ /* Invalidate the drawing space of the picframe. */
+ InvalidateRect( hPicFrame, NULL, TRUE);
+ UpdateWindow( hPicFrame );
+
+ hdc = GetDC(hPicFrame);
+ hdcMem = CreateCompatibleDC(hdc);
+ GetClientRect(hPicFrame, &rect);
+ hBitmap = LoadBitmap(hLeashInst, "LOGOBITMAP");
+ hOldBitmap = SelectObject(hdcMem, hBitmap);
+ GetObject(hBitmap, sizeof(Bitmap), (LPSTR) &Bitmap);
+ StretchBlt(hdc, 0, 0, rect.right, rect.bottom, hdcMem, 0, 0,
+ Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);
+
+ SelectObject(hdcMem, hOldBitmap); /* pbh 8-15-94 */
+ ReleaseDC(hPicFrame, hdc);
+ DeleteObject( hBitmap ); /* pbh 8-15-94 */
+ DeleteDC( hdcMem ); /* pbh 8-15-94 */
+
+ return 0;
+}
+
+
+/* Callback function for the Password Dialog box that initilializes and
+ renews tickets. */
+
+INT_PTR
+CALLBACK
+PasswordProc(
+ HWND hDialog,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ static POINT Position = { -1, -1 };
+ static short state;
+ int lifetime;
+#define ISCHPASSWD (lpdi->dlgtype == DLGTYPE_CHPASSWD)
+#define STATE_INIT 0
+#define STATE_PRINCIPAL 1
+#define STATE_OLDPWD 2
+#define STATE_NEWPWD1 3
+#define STATE_NEWPWD2 4
+#define STATE_CLOSED 5
+#define NEXTSTATE(newstate) SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, newstate)
+ static int ids[STATE_NEWPWD2 + 1] = {
+ 0,
+ ID_PRINCIPAL, ID_OLDPASSWORD, ID_CONFIRMPASSWORD1,
+ ID_CONFIRMPASSWORD2};
+ static char principal[255], oldpassword[255], newpassword[255],
+ newpassword2[255];
+ static char *strings[STATE_NEWPWD2 + 1] = {
+ NULL, principal, oldpassword, newpassword, newpassword2};
+ static LPLSH_DLGINFO lpdi;
+ char gbuf[200]; /* global buffer for random stuff. */
+
+
+#define checkfirst(id, stuff) IsDlgItem(hDialog, id) ? stuff : 0
+#define CGetDlgItemText(hDlg, id, cp, len) checkfirst(id, GetDlgItemText(hDlg, id, cp, len))
+#define CSetDlgItemText(hDlg, id, cp) checkfirst(id, SetDlgItemText(hDlg, id, cp))
+#define CSetDlgItemInt(hDlg, id, i, b) checkfirst(id, SetDlgItemInt(hDlg, id, i, b))
+#define CSendDlgItemMessage(hDlg, id, m, w, l) checkfirst(id, SendDlgItemMessage(hDlg, id, m, w, l))
+#define CSendMessage(hwnd, m, w, l) IsWindow(hwnd) ? SendMessage(hwnd, m, w, l) : 0
+#define CShowWindow(hwnd, state) IsWindow(hwnd) ? ShowWindow(hwnd, state) : 0
+
+#define GETITEMTEXT(id, cp, maxlen) \
+ GetDlgItemText(hDialog, id, (LPSTR)(cp), maxlen)
+#define CloseMe(x) SendMessage(hDialog, WM_COMMAND, ID_CLOSEME, x)
+
+
+#define EDITFRAMEIDOFFSET 500
+
+ switch (message) {
+
+ case WM_INITDIALOG:
+
+ *( (LPLSH_DLGINFO far *)(&lpdi) ) = (LPLSH_DLGINFO)(LPSTR)lParam;
+ lpdi->dlgstatemax = ISCHPASSWD ? STATE_NEWPWD2
+ : STATE_OLDPWD;
+ SetWindowText(hDialog, lpdi->title);
+ /* stop at old password for normal password dlg */
+
+ SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
+
+ if (lpdi->principal)
+ lstrcpy(principal, lpdi->principal);
+ else
+ {
+ principal[0] = '\0';
+ /* is there a principal already being used? if so, use it. */
+ }
+
+ CSetDlgItemText(hDialog, ID_PRINCIPAL, principal);
+
+ lifetime = Leash_get_default_lifetime();
+ if (lifetime <= 0)
+ lifetime = 600; /* 10 hours */
+
+ CSetDlgItemInt(hDialog, ID_DURATION, lifetime, FALSE);
+
+ /* setup text of stuff. */
+
+ if (Position.x > 0 && Position.y > 0 &&
+ Position.x < GetSystemMetrics(SM_CXSCREEN) &&
+ Position.y < GetSystemMetrics(SM_CYSCREEN))
+ SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+
+ /* set window pos to last saved window pos */
+
+
+ /* replace standard edit control with our own password edit
+ control for password entry. */
+ {
+ RECT r;
+ POINT pxy, psz;
+ HWND hwnd;
+ int i;
+
+ for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++)
+ {
+ hwnd = GetDlgItem(hDialog, i);
+ GetWindowRect(hwnd, &r);
+ psz.x = r.right - r.left;
+ psz.y = r.bottom - r.top;
+
+ pxy.x = r.left; pxy.y = r.top;
+ ScreenToClient(hDialog, &pxy);
+
+ /* create a substitute window: */
+
+ DestroyWindow(hwnd);
+ /* kill off old edit window. */
+
+ CreateWindow(MIT_PWD_DLL_CLASS, /* our password window :o] */
+ "", /* no text */
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP, /* child window, visible,tabstop */
+ pxy.x, pxy.y, /* x, y coords */
+ psz.x, psz.y, /* width, height */
+ hDialog, /* the parent */
+ (HMENU)i, /* same id *//* id offset for the frames */
+ (HANDLE)hLeashInst,/* instance handles */
+ NULL); /* createstruct */
+ }
+ }
+
+ state = STATE_INIT;
+ NEXTSTATE(STATE_PRINCIPAL);
+ break;
+
+ case WM_PAINT:
+ PaintLogoBitmap( GetDlgItem(hDialog, ID_PICFRAME) );
+ break;
+
+ case WM_COMMAND:
+ switch (wParam) {
+ case ID_HELP:
+ {
+ WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
+ ISCHPASSWD ? ID_CHANGEPASSWORD : ID_INITTICKETS);
+ }
+ break;
+ case ID_CLOSEME:
+ {
+ int i;
+
+ for (i = STATE_PRINCIPAL; i <= lpdi->dlgstatemax; i++)
+ {
+ memset(strings[i], '\0', 255);
+ SetDlgItemText(hDialog, ids[i], "");
+ }
+ /* I claim these passwords in the name
+ of planet '\0'... */
+
+ RemoveProp(hDialog, "HANDLES_HELP");
+ state = STATE_CLOSED;
+ EndDialog(hDialog, (int)lParam);
+ return TRUE;
+ }
+ break;
+ case ID_DURATION:
+ break;
+ case ID_PRINCIPAL:
+ case ID_OLDPASSWORD:
+ case ID_CONFIRMPASSWORD1:
+ case ID_CONFIRMPASSWORD2:
+ if (HIWORD(lParam) == EN_SETFOCUS)
+ {
+ /* nothing, for now. */
+ }
+ break;
+ case ID_NEXTSTATE:
+ {
+ RECT rbtn, redit;
+ POINT p;
+ int idfocus, i, s;
+ HWND hfocus, hbtn;
+ int oldstate = state;
+
+ state = (int)lParam;
+ idfocus = ids[state];
+
+#ifdef ONE_NEWPWDBOX
+ if (state == STATE_NEWPWD2)
+ SendDlgItemMessage(hDialog, ID_CONFIRMPASSWORD1, WM_SETTEXT,
+ 0, (LONG)(LPSTR)"");
+#endif
+
+ for (s = STATE_PRINCIPAL; s <= lpdi->dlgstatemax; s++)
+ {
+ i = ids[s];
+
+ if (s > state)
+ SendDlgItemMessage(hDialog, i, WM_SETTEXT, 0,
+ (LONG)(LPSTR)"");
+ EnableWindow(GetDlgItem(hDialog, i), i == idfocus);
+ ShowWindow(GetDlgItem(hDialog, i),
+ (i <= idfocus ? SW_SHOW : SW_HIDE));
+ /* ShowWindow(GetDlgItem(hDialog, i + CAPTION_OFFSET),
+ (i <= idfocus ? SW_SHOW : SW_HIDE));*/
+ /* show caption? */
+ }
+#ifdef ONE_NEWPWDBOX
+ CSetDlgItemText(hDialog, ID_CONFIRMCAPTION1,
+ state < STATE_NEWPWD2 ?
+ "Enter new password:" :
+ "Enter new password again:");
+ if (state == STATE_NEWPWD2)
+ {
+ HWND htext;
+ htext = GetDlgItem(hDialog, ID_CONFIRMCAPTION1);
+ FlashAnyWindow(htext);
+ WinSleep(50);
+ FlashAnyWindow(htext);
+ }
+#endif
+
+ hfocus = GetDlgItem(hDialog, idfocus);
+ if ( hfocus != (HWND)NULL ){
+ SetFocus(hfocus); /* switch focus */
+ if (idfocus >= ID_OLDPASSWORD)
+ SendMessage(hfocus, WM_SETTEXT, 0, (LPARAM) (LPSTR) "");
+ else
+ {
+ SendMessage(hfocus, EM_SETSEL, 0, MAKELONG(0, -1));
+ }
+ GetWindowRect(hfocus, &redit);
+ }
+
+ hbtn = GetDlgItem(hDialog, IDOK);
+ if( IsWindow(hbtn) ){
+ GetWindowRect(hbtn, &rbtn);
+ p.x = rbtn.left; p.y = redit.top;
+ ScreenToClient(hDialog, &p);
+
+ SetWindowPos(hbtn, 0, p.x, p.y, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+ }
+ }
+ break;
+ case IDOK:
+ {
+ char* p_Principal;
+ DWORD value = 0;
+
+ GETITEMTEXT(ids[state], (LPSTR)strings[state], 255);
+
+ switch(state)
+ {
+ case STATE_PRINCIPAL:
+ {
+ if (!principal[0])
+ {
+ MessageBox(hDialog,
+ "You are not allowed to enter a blank principal.",
+ "Invalid Principal",
+ MB_OK | MB_ICONSTOP);
+ NEXTSTATE(STATE_PRINCIPAL);
+ return TRUE;
+ }
+
+ // Change 'principal' to upper case after checking
+ // "UpperCase" value in the Registry
+ p_Principal = strchr(principal, '@');
+
+ if (p_Principal && Leash_get_default_uppercaserealm())
+ strupr(p_Principal);
+ break;
+ }
+ case STATE_OLDPWD:
+ {
+ int duration;
+
+ if (!ISCHPASSWD)
+ duration = GetDlgItemInt(hDialog, ID_DURATION, 0, FALSE);
+ if (!oldpassword[0])
+ {
+ MessageBox(hDialog, "You are not allowed to enter a "
+ "blank password.",
+ "Invalid Password",
+ MB_OK | MB_ICONSTOP);
+ NEXTSTATE(STATE_OLDPWD);
+ return TRUE;
+ }
+ if (lpdi->dlgtype == DLGTYPE_CHPASSWD)
+ lsh_errno = Leash_int_checkpwd(principal, oldpassword, 1);
+ else
+ {
+ lsh_errno = Leash_int_kinit_ex( 0,
+ hDialog,
+ principal,
+ oldpassword,
+ duration,
+ Leash_get_default_forwardable(),
+ Leash_get_default_proxiable(),
+ Leash_get_default_renew_till(),
+ Leash_get_default_noaddresses(),
+ Leash_get_default_publicip(),
+ 1
+ );
+ }
+ if (lsh_errno != 0)
+ {
+ int next_state = state;
+ int capslock;
+ LONG check_time;
+ char *cp;
+
+ err_context = "";
+
+ switch(lsh_errno)
+ {
+ case LSH_INVPRINCIPAL:
+ case LSH_INVINSTANCE:
+ case LSH_INVREALM:
+#ifndef NO_KRB4
+ case KRBERR(KDC_PR_UNKNOWN):
+#endif
+ next_state = STATE_PRINCIPAL;
+ break;
+#ifndef NO_KRB4
+ case KRBERR(RD_AP_TIME):
+ case KRBERR(KDC_SERVICE_EXP):
+ check_time = Leash_timesync(1);
+ if( check_time == 0 ){
+ next_state = STATE_PRINCIPAL;
+ SendMessage(hDialog, WM_COMMAND, IDOK, state);
+ return(TRUE);
+ } else {
+ next_state = STATE_PRINCIPAL;
+ lsh_errno = check_time;
+ return(TRUE);
+ }
+ break;
+#endif
+ }
+ capslock = lsh_getkeystate(VK_CAPITAL);
+ /* low-order bit means caps lock is
+ toggled; if so, warn user since there's
+ been an error. */
+ if (capslock & 1)
+ {
+ lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
+ cp = gbuf + lstrlen((LPSTR)gbuf);
+ if (cp != gbuf)
+ *cp++ = ' ';
+ lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
+ err_context = gbuf;
+ }
+
+// XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
+// XXX : "Ticket initialization failed.");
+ NEXTSTATE(next_state);
+ return TRUE;
+ }
+ if (ISCHPASSWD)
+ break;
+ CloseMe(TRUE); /* success */
+ }
+ break;
+ case STATE_NEWPWD1:
+ {
+ int i = 0;
+ int bit8 = 0;
+
+ for( i = 0; i < 255; i++ ){
+ if( newpassword[i] == '\0' ){
+ if ( bit8 ) {
+ MessageBox(hDialog,
+ "Passwords should not contain non-ASCII characters.",
+ "Internationalization Warning",
+ MB_OK | MB_ICONINFORMATION);
+ }
+ i = 255;
+ break;
+ } else if( !isprint(newpassword[i]) ){
+ memset(newpassword, '\0', 255);
+ /* I claim these passwords in the name of planet '\0'... */
+ MessageBox(hDialog,
+ "Passwords may not contain non-printable characters.",
+ "Invalid Password",
+ MB_OK | MB_ICONSTOP);
+ NEXTSTATE(STATE_NEWPWD1);
+ return TRUE;
+ } else if ( newpassword[i] > 127 )
+ bit8 = 1;
+ }
+ }
+ break;
+ case STATE_NEWPWD2:
+ if (lstrcmp(newpassword, newpassword2))
+ {
+ NEXTSTATE(STATE_NEWPWD1);
+ MessageBox(hDialog,
+ "The new password was not entered the same way twice.",
+ "Password validation error",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+ else
+ {
+ /* make them type both pwds again if error */
+ int next_state = STATE_NEWPWD1;
+ int capslock;
+ char *cp;
+
+ capslock = lsh_getkeystate(VK_CAPITAL);
+ /* low-order bit means caps lock is
+ toggled; if so, warn user since there's
+ been an error. */
+ if (capslock & 1)
+ {
+ lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
+ cp = gbuf + lstrlen((LPSTR)gbuf);
+ if (cp != gbuf)
+ *cp++ = ' ';
+ lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
+ err_context = gbuf;
+ }
+
+ if ((lsh_errno =
+ Leash_int_changepwd(principal, oldpassword,
+ newpassword, 0, 1))
+ == 0){
+ CloseMe(TRUE);
+ }
+ else {
+ // XXX - DoNiftyErrorReport(lsh_errno, "Error while changing password.");
+ NEXTSTATE(next_state);
+ return TRUE;
+
+ }
+ }
+ break;
+ }
+ /* increment state, but send the old state as a
+ parameter */
+ SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, state + 1);
+ }
+ break;
+ case IDCANCEL:
+ CloseMe(FALSE);
+ break;
+ case ID_RESTART:
+ {
+ int i;
+
+ for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++)
+ SetDlgItemText(hDialog, i, "");
+ SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE,
+ STATE_PRINCIPAL);
+ }
+ break;
+ }
+ break;
+
+ case WM_MOVE:
+ if (state != STATE_CLOSED)
+#ifdef _WIN32
+#define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \
+ (pt).y=(SHORT)HIWORD(l))
+ LONG2POINT(lParam,Position);
+#else
+ Position = MAKEPOINT(lParam);
+#endif
+ break;
+ }
+ return FALSE;
+}
+
+
+#define KRB_FILE "KRB.CON"
+#define KRBREALM_FILE "KRBREALM.CON"
+#define KRB5_FILE "KRB5.INI"
+
+BOOL
+GetProfileFile(
+ LPSTR confname,
+ UINT szConfname
+ )
+{
+ char **configFile = NULL;
+ if (hKrb5 &&
+ pkrb5_get_default_config_files(&configFile))
+ {
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname, "\\",sizeof(confname)-strlen(confname));
+ confname[szConfname-1] = '\0';
+ strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname));
+ confname[szConfname-1] = '\0';
+ return FALSE;
+ }
+
+ *confname = 0;
+
+ if (hKrb5 && configFile)
+ {
+ strncpy(confname, *configFile, szConfname);
+ pkrb5_free_config_files(configFile);
+ }
+
+ if (!*confname)
+ {
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname, "\\",sizeof(confname)-strlen(confname));
+ confname[szConfname-1] = '\0';
+ strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname));
+ confname[szConfname-1] = '\0';
+ }
+
+ return FALSE;
+}
+
+BOOL
+GetKrb4ConFile(
+ LPSTR confname,
+ UINT szConfname
+ )
+{
+ if (hKrb5
+#ifndef NO_KRB4
+ && !hKrb4
+#endif
+ )
+ { // hold krb.con where krb5.ini is located
+ CHAR krbConFile[MAX_PATH]="";
+ LPSTR pFind;
+
+ //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename);
+ if (GetProfileFile(krbConFile, sizeof(krbConFile)))
+ {
+ GetWindowsDirectory(krbConFile,sizeof(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ strncat(krbConFile, KRB5_FILE,sizeof(krbConFile)-strlen(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ }
+
+ pFind = strrchr(krbConFile, '\\');
+ if (pFind)
+ {
+ *pFind = 0;
+ strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ strncat(krbConFile, KRB_FILE,sizeof(krbConFile)-strlen(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ }
+ else
+ krbConFile[0] = 0;
+
+ strncpy(confname, krbConFile, szConfname);
+ confname[szConfname-1] = '\0';
+ }
+#ifndef NO_KRB4
+ else if (hKrb4)
+ {
+ unsigned int size = szConfname;
+ memset(confname, '\0', szConfname);
+ if (!pkrb_get_krbconf2(confname, &size))
+ { // Error has happened
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname, "\\",szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ strncat(confname,KRB_FILE,szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ }
+ }
+#endif
+ return FALSE;
+}
+
+BOOL
+GetKrb4RealmFile(
+ LPSTR confname,
+ UINT szConfname
+ )
+{
+ if (hKrb5
+#ifndef NO_KRB4
+ && !hKrb4
+#endif
+ )
+ { // hold krb.con where krb5.ini is located
+ CHAR krbRealmConFile[MAX_PATH];
+ LPSTR pFind;
+
+ //strcpy(krbRealmConFile, CLeashApp::m_krbv5_profile->first_file->filename);
+ if (GetProfileFile(krbRealmConFile, sizeof(krbRealmConFile)))
+ {
+ GetWindowsDirectory(krbRealmConFile,sizeof(krbRealmConFile));
+ krbRealmConFile[MAX_PATH-1] = '\0';
+ strncat(krbRealmConFile, "\\",sizeof(krbRealmConFile)-strlen(krbRealmConFile));
+ krbRealmConFile[MAX_PATH-1] = '\0';
+ strncat(krbRealmConFile, KRB5_FILE,sizeof(krbRealmConFile)-strlen(krbRealmConFile));
+ krbRealmConFile[MAX_PATH-1] = '\0';
+ }
+
+ pFind = strrchr(krbRealmConFile, '\\');
+ if (pFind)
+ {
+ *pFind = 0;
+ strncat(krbRealmConFile, "\\", sizeof(krbRealmConFile)-strlen(krbRealmConFile));
+ krbRealmConFile[MAX_PATH-1] = '\0';
+ strncat(krbRealmConFile, KRBREALM_FILE, sizeof(krbRealmConFile)-strlen(krbRealmConFile));
+ krbRealmConFile[MAX_PATH-1] = '\0';
+ }
+ else
+ krbRealmConFile[0] = 0;
+
+ strncpy(confname, krbRealmConFile, szConfname);
+ confname[szConfname-1] = '\0';
+ }
+#ifndef NO_KRB4
+ else if (hKrb4)
+ {
+ unsigned int size = szConfname;
+ memset(confname, '\0', szConfname);
+ if (!pkrb_get_krbrealm2(confname, &size))
+ {
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname, "\\",szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ strncat(confname,KRBREALM_FILE,szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static BOOL
+FindDLLName(CHAR * filename, UINT len)
+{
+ if ( !filename || len == 0 )
+ return 0;
+
+ filename[0] = 0;
+
+ if ( pEnumProcessModules ) {
+ char checkName[1024];
+ HMODULE hMods[1024];
+ HANDLE hProcess;
+ DWORD cbNeeded;
+ unsigned int i;
+
+ /* Get a list of all the modules in this process. */
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
+
+ if (pEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
+ {
+ for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
+ {
+ char szModName[2048];
+
+ /* Get the full path to the module's file. */
+ if (pGetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)))
+ {
+ lstrcpyn(checkName, szModName, sizeof(checkName));
+ strupr(checkName);
+
+ if (strstr(checkName, "LEASHW32")) {
+ lstrcpyn(filename, checkName, len);
+ break;
+ }
+ }
+ }
+ }
+
+ CloseHandle(hProcess);
+ } else if (pCreateToolhelp32Snapshot && pModule32First && pModule32Next ) {
+ char checkName[1024];
+ MODULEENTRY32 me32 = {0};
+ HANDLE hProcessSnap = NULL;
+
+ hProcessSnap = pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
+ if (hProcessSnap == (HANDLE)-1)
+ return FALSE;
+
+ me32.dwSize = sizeof(MODULEENTRY32);
+ if (pModule32First(hProcessSnap, &me32))
+ {
+ do
+ {
+ lstrcpyn(checkName, me32.szExePath, sizeof(checkName));
+ strupr(checkName);
+
+ if (strstr(checkName, "LEASHW32")) {
+ lstrcpyn(filename, checkName, len);
+ break;
+ }
+ }
+ while (pModule32Next(hProcessSnap, &me32));
+ }
+ }
+
+ return filename[0] ? 1 : 0;
+}
+
+static DWORD
+SetVersionInfo(
+ HWND hDialog,
+ UINT id_version,
+ UINT id_copyright
+ )
+{
+ CHAR filename[1024];
+ DWORD dwVersionHandle;
+ LPVOID pVersionInfo = 0;
+ DWORD retval = 0;
+ LPDWORD pLangInfo = 0;
+ LPTSTR szVersion = 0;
+ LPTSTR szCopyright = 0;
+ UINT len = 0;
+ CHAR sname_version[] = "FileVersion";
+ CHAR sname_copyright[] = "LegalCopyright";
+ CHAR szVerQ[(sizeof("\\StringFileInfo\\12345678\\") +
+ max(sizeof(sname_version) / sizeof(CHAR),
+ sizeof(sname_copyright) / sizeof(CHAR)))];
+ CHAR szVerCopy[128] = "";
+ CHAR * cp = szVerQ;
+ DWORD size;
+
+ if (!FindDLLName(filename, sizeof(filename)))
+ return GetLastError();
+
+ size = GetFileVersionInfoSize(filename, &dwVersionHandle);
+
+ if (!size)
+ return GetLastError();
+
+ pVersionInfo = malloc(size);
+ if (!pVersionInfo)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ if (!GetFileVersionInfo(filename, dwVersionHandle, size, pVersionInfo))
+ {
+ retval = GetLastError();
+ goto cleanup;
+ }
+
+ if (!VerQueryValue(pVersionInfo, "\\VarFileInfo\\Translation",
+ (LPVOID*)&pLangInfo, &len))
+ {
+ retval = GetLastError();
+ goto cleanup;
+ }
+
+
+ cp += wsprintf(szVerQ,
+ "\\StringFileInfo\\%04x%04x\\",
+ LOWORD(*pLangInfo), HIWORD(*pLangInfo));
+
+ lstrcpy(cp, sname_version);
+ if (!VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len))
+ {
+ retval = GetLastError() || ERROR_NOT_ENOUGH_MEMORY;
+ goto cleanup;
+ }
+
+ lstrcpy(cp, sname_copyright);
+ if (!VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szCopyright, &len))
+ {
+ retval = GetLastError() || ERROR_NOT_ENOUGH_MEMORY;
+ goto cleanup;
+ }
+
+ if ( strlen(szVersion) < sizeof(szVerCopy) - 8 ) {
+ wsprintf(szVerCopy, "Version %s", szVersion);
+ szVerCopy[sizeof(szVerCopy) - 1] = 0;
+
+ SetWindowText(GetDlgItem(hDialog,id_version),szVerCopy);
+ }
+ SetWindowText(GetDlgItem(hDialog,id_copyright),szCopyright);
+
+ cleanup:
+ if (pVersionInfo)
+ free(pVersionInfo);
+ return retval;
+}
+
+
+int
+readstring(FILE * file, char * buf, int len)
+{
+ int c,i;
+ memset(buf, '\0', sizeof(buf));
+ for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++)
+ {
+ if (i < sizeof(buf)) {
+ if (c == '\n') {
+ buf[i] = '\0';
+ return i;
+ } else {
+ buf[i] = c;
+ }
+ } else {
+ if (c == '\n') {
+ buf[len-1] = '\0';
+ return(i);
+ }
+ }
+ }
+ if (c == EOF) {
+ if (i > 0 && i < len) {
+ buf[i] = '\0';
+ return(i);
+ } else {
+ buf[len-1] = '\0';
+ return(-1);
+ }
+ }
+ return(-1);
+}
+
+typedef struct _slider_info {
+ int slider_id;
+ int text_id;
+ int min;
+ int max;
+ int increment;
+ struct _slider_info * next;
+} slider_info;
+static slider_info * sliders = NULL;
+
+static slider_info *
+FreeSlider(slider_info * s)
+{
+ slider_info * n = NULL;
+
+ if (s) {
+ n = s->next;
+ free(s);
+ }
+ return n;
+}
+
+static void
+CleanupSliders(void)
+{
+ while(sliders)
+ sliders = FreeSlider(sliders);
+}
+
+
+static unsigned short
+NewSliderValue(HWND hDialog, int id)
+{
+ int value = 0;
+ slider_info * s = sliders;
+ while(s) {
+ if (s->slider_id == id) {
+ int pos = CSendDlgItemMessage( hDialog, id,
+ TBM_GETPOS,
+ (WPARAM) 0, (LPARAM) 0);
+ value = s->min + (pos * s->increment);
+ break;
+ }
+ s = s->next;
+ }
+ return(value);
+}
+
+static const char *
+NewSliderString(int id, int pos)
+{
+ static char buf[64]="";
+ char * p = buf;
+ int value = 0;
+ int must_hours = 0;
+ slider_info * s = sliders;
+ while(s) {
+ if (s->slider_id == id) {
+ value = s->min + pos * s->increment;
+ *p = 0;
+ if (value >= 60 * 24) {
+ sprintf(p,"%d day(s) ",value / (60 * 24));
+ value %= (60 * 24);
+ p += strlen(p);
+ must_hours = 1;
+ }
+ if (must_hours || value >= 60) {
+ sprintf(p,"%d hour(s) ",value / 60);
+ value %= 60;
+ p += strlen(p);
+ }
+ sprintf(p,"%d minute(s) ",value);
+ break;
+ }
+ s = s->next;
+ }
+ return(buf);
+}
+
+static void
+SetupSlider( HWND hDialog,
+ int sliderID,
+ int textFieldID,
+ int minimum,
+ int maximum,
+ int value)
+{
+ int min = minimum;
+ int max = maximum;
+ int increment = 0;
+ int range;
+ int roundedMinimum;
+ int roundedMaximum;
+ int roundedValue;
+ slider_info * new_info;
+
+ if (max < min) {
+ // swap values
+ int temp = max;
+ max = min;
+ min = temp;
+ }
+ range = max - min;
+
+ if (range < 5*60) { increment = 1; // 1 s if under 5 m
+ } else if (range < 30*60) { increment = 5; // 5 s if under 30 m
+ } else if (range < 60*60) { increment = 15; // 15 s if under 1 h
+ } else if (range < 2*60*60) { increment = 30; // 30 s if under 2 h
+ } else if (range < 5*60*60) { increment = 60; // 1 m if under 5 h
+ } else if (range < 50*60*60) { increment = 5*60; // 5 m if under 50 h
+ } else if (range < 200*60*60) { increment = 15*60; // 15 m if under 200 h
+ } else if (range < 500*60*60) { increment = 30*60; // 30 m if under 500 h
+ } else { increment = 60*60; } // 1 h otherwise
+
+ roundedMinimum = (min / increment) * increment;
+ if (roundedMinimum > min) { roundedMinimum -= increment; }
+ if (roundedMinimum <= 0) { roundedMinimum += increment; } // make positive
+
+ roundedMaximum = (max / increment) * increment;
+ if (roundedMaximum < max) { roundedMaximum += increment; }
+
+ roundedValue = (value / increment) * increment;
+ if (roundedValue < roundedMinimum) { roundedValue = roundedMinimum; }
+ if (roundedValue > roundedMaximum) { roundedValue = roundedMaximum; }
+
+ if (roundedMinimum == roundedMaximum) {
+ // [textField setTextColor: [NSColor grayColor]];
+ EnableWindow(GetDlgItem(hDialog,sliderID),FALSE);
+ } else {
+ // [textField setTextColor: [NSColor blackColor]];
+ EnableWindow(GetDlgItem(hDialog,sliderID),TRUE);
+ }
+
+ CSendDlgItemMessage( hDialog, sliderID,
+ TBM_SETRANGEMIN,
+ (WPARAM) FALSE,
+ (LPARAM) 0 );
+ CSendDlgItemMessage( hDialog, sliderID,
+ TBM_SETRANGEMAX,
+ (WPARAM) FALSE,
+ (LPARAM) (roundedMaximum - roundedMinimum) / increment );
+ CSendDlgItemMessage( hDialog, sliderID,
+ TBM_SETPOS,
+ (WPARAM) TRUE,
+ (LPARAM) (roundedValue - roundedMinimum) / increment);
+
+ new_info = (slider_info *) malloc(sizeof(slider_info));
+ new_info->slider_id = sliderID;
+ new_info->text_id = textFieldID;
+ new_info->min = roundedMinimum;
+ new_info->max = roundedMaximum;
+ new_info->increment = increment;
+ new_info->next = sliders;
+ sliders = new_info;
+
+ SetWindowText(GetDlgItem(hDialog, textFieldID),
+ NewSliderString(sliderID,(roundedValue - roundedMinimum) / increment));
+}
+
+
+static void
+AdjustOptions(HWND hDialog, int show, int hideDiff)
+{
+ RECT rect;
+ RECT dlgRect;
+ HWND hwnd;
+ int diff;
+
+ Leash_set_hide_kinit_options(!show);
+
+ ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME_VALUE),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_LIFETIME),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW_TILL_VALUE),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_CHECK_FORWARDABLE),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_CHECK_RENEWABLE),show);
+ ShowWindow(GetDlgItem(hDialog,IDC_STATIC_KRB5),show);
+
+ GetWindowRect( hDialog, &dlgRect );
+ diff = dlgRect.top + GetSystemMetrics(SM_CYCAPTION)
+ + GetSystemMetrics(SM_CYDLGFRAME) + (show ? -1 : 1) * hideDiff;
+
+ hwnd = GetDlgItem(hDialog,IDOK);
+ GetWindowRect(hwnd,&rect);
+ SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ hwnd = GetDlgItem(hDialog,IDCANCEL);
+ GetWindowRect(hwnd,&rect);
+ SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ hwnd = GetDlgItem(hDialog,IDC_BUTTON_OPTIONS);
+ GetWindowRect(hwnd,&rect);
+ SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ hwnd = GetDlgItem(hDialog,IDC_STATIC_VERSION);
+ GetWindowRect(hwnd,&rect);
+ SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ hwnd = GetDlgItem(hDialog,IDC_STATIC_COPYRIGHT);
+ GetWindowRect(hwnd,&rect);
+ SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ SetWindowPos(hDialog,0,0,0,
+ dlgRect.right-dlgRect.left,
+ dlgRect.bottom-dlgRect.top+(show ? 1 : - 1) * hideDiff,
+ SWP_NOZORDER|SWP_NOMOVE);
+
+ CSetDlgItemText(hDialog, IDC_BUTTON_OPTIONS, show ? "Hide Options" : "Show Options");
+
+}
+
+
+/* Callback function for the Authentication Dialog box that initializes and
+ renews tickets. */
+
+INT_PTR
+CALLBACK
+AuthenticateProc(
+ HWND hDialog,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ static POINT Position = { -1, -1 };
+ static char username[LEASH_USERNAME_SZ]="";
+ static char realm[LEASH_REALM_SZ]="";
+ static char password[256]="";
+ static int lifetime=0;
+ static int renew_till=0;
+ static int forwardable=0;
+ static int noaddresses=0;
+ static int proxiable=0;
+ static int publicip=0;
+ static LPLSH_DLGINFO_EX lpdi;
+ static HWND hDlg=0;
+ static HWND hSliderLifetime=0;
+ static HWND hSliderRenew=0;
+ static RECT dlgRect;
+ static int hideDiff = 0;
+ char principal[256];
+ long realm_count = 0;
+ int disable_noaddresses = 0;
+
+ switch (message) {
+
+ case WM_INITDIALOG:
+ hDlg = hDialog;
+
+ SetVersionInfo(hDialog,IDC_STATIC_VERSION,IDC_STATIC_COPYRIGHT);
+ hSliderLifetime = GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE);
+ hSliderRenew = GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE);
+
+ *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam;
+
+ if ((lpdi->size != LSH_DLGINFO_EX_V1_SZ &&
+ lpdi->size != LSH_DLGINFO_EX_V2_SZ &&
+ lpdi->size < LSH_DLGINFO_EX_V3_SZ) ||
+ lpdi->dlgtype != DLGTYPE_PASSWD) {
+
+ MessageBox(hDialog, "An incorrect initialization data structure was provided.",
+ "AuthenticateProc()",
+ MB_OK | MB_ICONSTOP);
+ return FALSE;
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
+ lpdi->out.username[0] = 0;
+ lpdi->out.realm[0] = 0;
+ }
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) {
+ lpdi->out.ccache[0] = 0;
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ SetWindowText(hDialog, lpdi->in.title);
+ else
+ SetWindowText(hDialog, lpdi->title);
+
+ SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ lstrcpy(username, lpdi->in.username);
+ else if (lpdi->username)
+ lstrcpy(username, lpdi->username);
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ lstrcpy(realm, lpdi->in.realm);
+ else if (lpdi->realm)
+ lstrcpy(realm, lpdi->realm);
+
+ if (lpdi->use_defaults) {
+ lifetime = Leash_get_default_lifetime();
+ if (lifetime <= 0)
+ lifetime = 600; /* 10 hours */
+ if (Leash_get_default_renewable()) {
+ renew_till = Leash_get_default_renew_till();
+ if (renew_till < 0)
+ renew_till = 10800; /* 7 days */
+ } else
+ renew_till = 0;
+ forwardable = Leash_get_default_forwardable();
+ if (forwardable < 0)
+ forwardable = 0;
+ noaddresses = Leash_get_default_noaddresses();
+ if (noaddresses < 0)
+ noaddresses = 0;
+ proxiable = Leash_get_default_proxiable();
+ if (proxiable < 0)
+ proxiable = 0;
+ publicip = Leash_get_default_publicip();
+ if (publicip < 0)
+ publicip = 0;
+ } else {
+ forwardable = lpdi->forwardable;
+ noaddresses = lpdi->noaddresses;
+ lifetime = lpdi->lifetime;
+ renew_till = lpdi->renew_till;
+ proxiable = lpdi->proxiable;
+ publicip = lpdi->publicip;
+ }
+
+ CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, username);
+ CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, "");
+
+#if 0 /* 20030619 - mjv wishes to return to the default character */
+ /* echo spaces */
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0);
+#endif
+
+ /* Populate list of Realms */
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_RESETCONTENT, 0, 0);
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_LIMITTEXT, 192, 0);
+
+ if (pprofile_get_subsection_names && pprofile_free_list) {
+ const char* rootSection[] = {"realms", NULL};
+ const char** rootsec = rootSection;
+ char **sections = NULL, **cpp = NULL, *value = NULL;
+
+ char krb5_conf[MAX_PATH+1];
+
+ if (!GetProfileFile(krb5_conf,sizeof(krb5_conf))) {
+ profile_t profile;
+ long retval;
+ const char *filenames[2];
+
+ filenames[0] = krb5_conf;
+ filenames[1] = NULL;
+ retval = pprofile_init(filenames, &profile);
+ if (!retval) {
+ retval = pprofile_get_subsection_names(profile, rootsec, &sections);
+
+ if (!retval)
+ {
+ for (cpp = sections; *cpp; cpp++)
+ {
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)*cpp);
+ realm_count++;
+ }
+ }
+ pprofile_free_list(sections);
+
+ retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
+ if ( value ) {
+ disable_noaddresses = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ }
+
+ pprofile_release(profile);
+ }
+ }
+ } else {
+ FILE * file;
+ char krb_conf[MAX_PATH+1];
+ char * p;
+
+ if (!GetKrb4ConFile(krb_conf,sizeof(krb_conf)) &&
+ (file = fopen(krb_conf, "rt")))
+ {
+ char lineBuf[256];
+ // Skip the default realm
+ readstring(file,lineBuf,sizeof(lineBuf));
+
+ // Read the defined realms
+ while (TRUE)
+ {
+ if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
+ break;
+
+ if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
+ *(lineBuf + strlen(lineBuf) - 1) = 0;
+
+ for (p=lineBuf; *p ; p++)
+ {
+ if (isspace(*p)) {
+ *p = 0;
+ break;
+ }
+ }
+
+ if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)lineBuf);
+ realm_count++;
+ }
+ }
+
+ fclose(file);
+ }
+ }
+ if (realm_count == 0)
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)realm);
+
+ /* Select the default Realm */
+ if (!realm[0] && hKrb5) {
+ krb5_context ctx=0;
+ char * def = 0;
+ pkrb5_init_context(&ctx);
+ pkrb5_get_default_realm(ctx,&def);
+ if (def) {
+ lstrcpy(realm, def);
+ free(def);
+ }
+ pkrb5_free_context(ctx);
+ }
+ CSetDlgItemText(hDialog, IDC_COMBO_REALM, realm);
+
+ /* Set Lifetime Slider
+ * min value = 5
+ * max value = 1440
+ * current value
+ */
+
+ SetupSlider( hDialog,
+ IDC_SLIDER_LIFETIME,
+ IDC_STATIC_LIFETIME_VALUE,
+ Leash_get_default_life_min(),
+ Leash_get_default_life_max(),
+ lifetime );
+
+ /* Set Forwardable checkbox */
+ CheckDlgButton(hDialog, IDC_CHECK_FORWARDABLE, forwardable);
+ /* Set NoAddress checkbox */
+ CheckDlgButton(hDialog, IDC_CHECK_NOADDRESS, noaddresses);
+ if ( disable_noaddresses )
+ EnableWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),FALSE);
+ /* Set Renewable checkbox */
+ CheckDlgButton(hDialog, IDC_CHECK_RENEWABLE, renew_till);
+ /* if not renewable, disable Renew Till slider */
+ /* if renewable, set Renew Till slider
+ * min value
+ * max value
+ * current value
+ */
+ SetupSlider( hDialog,
+ IDC_SLIDER_RENEWLIFE,
+ IDC_STATIC_RENEW_TILL_VALUE,
+ Leash_get_default_renew_min(),
+ Leash_get_default_renew_max(),
+ renew_till);
+ if (renew_till) {
+ EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),TRUE);
+ } else {
+ EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),FALSE);
+ }
+
+ // Compute sizes of items necessary to show/hide the advanced options
+ GetWindowRect( hDialog, &dlgRect );
+ {
+ RECT okRect, staticRect;
+ GetWindowRect(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),&staticRect);
+ GetWindowRect(GetDlgItem(hDialog,IDOK),&okRect);
+ hideDiff = okRect.top - staticRect.top;
+ }
+
+ if ( hKrb5 ) {
+ if (Leash_get_hide_kinit_options())
+ AdjustOptions(hDialog,0,hideDiff);
+ } else {
+ AdjustOptions(hDialog,0,hideDiff);
+ EnableWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),FALSE);
+ ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),SW_HIDE);
+ }
+
+ /* setup text of stuff. */
+
+ if (Position.x > 0 && Position.y > 0 &&
+ Position.x < GetSystemMetrics(SM_CXSCREEN) &&
+ Position.y < GetSystemMetrics(SM_CYSCREEN))
+ SetWindowPos(hDialog, HWND_TOP, Position.x, Position.y, 0, 0, SWP_NOSIZE);
+ else /* Center the window on the desktop */
+ SetWindowPos(hDialog, HWND_TOP,
+ (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2,
+ (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2,
+ 0, 0,
+ SWP_NOSIZE);
+
+ /* Take keyboard focus */
+ SetActiveWindow(hDialog);
+ SetForegroundWindow(hDialog);
+ if (GetDlgCtrlID((HWND) wParam) != IDC_EDIT_PRINCIPAL)
+ {
+ SetFocus(GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL));
+ }
+ break;
+
+ case WM_HSCROLL:
+ switch (LOWORD(wParam)) {
+ case TB_THUMBTRACK:
+ case TB_THUMBPOSITION:
+ {
+ long pos = HIWORD(wParam); // the position of the slider
+ int ctrlID = GetDlgCtrlID((HWND)lParam);
+
+ if (ctrlID == IDC_SLIDER_RENEWLIFE) {
+ SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE),
+ NewSliderString(IDC_SLIDER_RENEWLIFE,pos));
+ }
+ if (ctrlID == IDC_SLIDER_LIFETIME) {
+ SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE),
+ NewSliderString(IDC_SLIDER_LIFETIME,pos));
+ }
+ }
+ break;
+ case TB_BOTTOM:
+ case TB_TOP:
+ case TB_ENDTRACK:
+ case TB_LINEDOWN:
+ case TB_LINEUP:
+ case TB_PAGEDOWN:
+ case TB_PAGEUP:
+ default:
+ {
+ int ctrlID = GetDlgCtrlID((HWND)lParam);
+ long pos = SendMessage(GetDlgItem(hDialog,ctrlID), TBM_GETPOS, 0, 0); // the position of the slider
+
+ if (ctrlID == IDC_SLIDER_RENEWLIFE) {
+ SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE),
+ NewSliderString(IDC_SLIDER_RENEWLIFE,pos));
+ }
+ if (ctrlID == IDC_SLIDER_LIFETIME) {
+ SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE),
+ NewSliderString(IDC_SLIDER_LIFETIME,pos));
+ }
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (wParam) {
+ case IDC_BUTTON_OPTIONS:
+ {
+ AdjustOptions(hDialog,Leash_get_hide_kinit_options(),hideDiff);
+ GetWindowRect(hDialog,&dlgRect);
+ if ( dlgRect.bottom > GetSystemMetrics(SM_CYSCREEN))
+ SetWindowPos( hDialog,0,
+ dlgRect.left,
+ GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top,
+ 0,0,
+ SWP_NOZORDER|SWP_NOSIZE);
+
+ }
+ break;
+ case IDC_CHECK_RENEWABLE:
+ {
+ if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) {
+ EnableWindow(hSliderRenew,TRUE);
+ } else {
+ EnableWindow(hSliderRenew,FALSE);
+ }
+ }
+ break;
+ case ID_HELP:
+ {
+ WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
+ ID_INITTICKETS);
+ }
+ break;
+ case ID_CLOSEME:
+ {
+ CleanupSliders();
+ memset(password,0,sizeof(password));
+ RemoveProp(hDialog, "HANDLES_HELP");
+ EndDialog(hDialog, (int)lParam);
+ return TRUE;
+ }
+ break;
+ case IDOK:
+ {
+ DWORD value = 0;
+
+ CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, username, sizeof(username));
+ CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password));
+ CGetDlgItemText(hDialog, IDC_COMBO_REALM, realm, sizeof(realm));
+
+ if (!username[0])
+ {
+ MessageBox(hDialog,
+ "You are not allowed to enter a blank username.",
+ "Invalid Principal",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+ if (!realm[0])
+ {
+ MessageBox(hDialog,
+ "You are not allowed to enter a blank realm.",
+ "Invalid Principal",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+
+ if (Leash_get_default_uppercaserealm())
+ {
+ // found
+ strupr(realm);
+ }
+
+ if (!password[0])
+ {
+ MessageBox(hDialog,
+ "You are not allowed to enter a blank password.",
+ "Invalid Password",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+
+ lifetime = NewSliderValue(hDialog, IDC_SLIDER_LIFETIME);
+
+ forwardable = IsDlgButtonChecked(hDialog, IDC_CHECK_FORWARDABLE);
+ noaddresses = IsDlgButtonChecked(hDialog, IDC_CHECK_NOADDRESS);
+ if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) {
+ renew_till = NewSliderValue(hDialog, IDC_SLIDER_RENEWLIFE);
+ } else {
+ renew_till= 0;
+ }
+
+ sprintf(principal,"%s@%s",username,realm);
+ lsh_errno = Leash_int_kinit_ex( 0,
+ hDialog,
+ principal, password, lifetime,
+ forwardable,
+ proxiable,
+ renew_till,
+ noaddresses,
+ publicip,
+ 1
+ );
+ if (lsh_errno != 0)
+ {
+ LONG check_time;
+#ifdef COMMENT
+ char gbuf[256];
+ int capslock;
+ char *cp;
+#endif
+ err_context = "";
+ switch(lsh_errno)
+ {
+ case LSH_INVPRINCIPAL:
+ case LSH_INVINSTANCE:
+#ifndef NO_KRB4
+ case KRBERR(KDC_PR_UNKNOWN):
+#endif
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PRINCIPAL, EM_SETSEL, 0, 256);
+ SetFocus(GetDlgItem(hDialog,IDC_EDIT_PRINCIPAL));
+ break;
+ case LSH_INVREALM:
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, EM_SETSEL, 0, 256);
+ SetFocus(GetDlgItem(hDialog,IDC_COMBO_REALM));
+ break;
+#ifndef NO_KRB4
+ case KRBERR(RD_AP_TIME):
+ case KRBERR(KDC_SERVICE_EXP):
+ check_time = Leash_timesync(1);
+ if( check_time == 0 ){
+ SendMessage(hDialog, WM_COMMAND, IDOK, 0);
+ return(TRUE);
+ } else {
+ lsh_errno = check_time;
+ return(TRUE);
+ }
+ break;
+#endif
+ default:
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETSEL, 0, 256);
+ SetFocus(GetDlgItem(hDialog,IDC_EDIT_PASSWORD));
+ return(TRUE);
+ }
+#ifdef COMMENT
+ capslock = lsh_getkeystate(VK_CAPITAL);
+ /* low-order bit means caps lock is
+ toggled; if so, warn user since there's
+ been an error. */
+ if (capslock & 1)
+ {
+ lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
+ cp = gbuf + lstrlen((LPSTR)gbuf);
+ if (cp != gbuf)
+ *cp++ = ' ';
+ lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
+ err_context = gbuf;
+ }
+
+ // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
+ // XXX : "Ticket initialization failed.");
+#endif /* COMMENT */
+ return TRUE;
+ }
+
+ if ( Leash_get_default_preserve_kinit_settings() )
+ {
+ Leash_set_default_lifetime(lifetime);
+ if ( renew_till > 0 ) {
+ Leash_set_default_renew_till(renew_till);
+ Leash_set_default_renewable(1);
+ } else {
+ Leash_set_default_renewable(0);
+ }
+ Leash_set_default_forwardable(forwardable);
+ Leash_set_default_noaddresses(noaddresses);
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
+ strncpy(lpdi->out.username, username, LEASH_USERNAME_SZ);
+ lpdi->out.username[LEASH_USERNAME_SZ-1] = 0;
+ strncpy(lpdi->out.realm, realm, LEASH_REALM_SZ);
+ lpdi->out.realm[LEASH_REALM_SZ-1] = 0;
+ }
+
+ CloseMe(TRUE); /* success */
+ return FALSE;
+ }
+ break;
+ case IDCANCEL:
+ CloseMe(FALSE);
+ break;
+ }
+ break;
+
+ case WM_MOVE:
+#ifdef _WIN32
+#define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \
+ (pt).y=(SHORT)HIWORD(l))
+ LONG2POINT(lParam,Position);
+#else
+ Position = MAKEPOINT(lParam);
+#endif
+ break;
+ }
+ return FALSE;
+}
+
+/* Callback function for the Change Password Dialog box */
+
+INT_PTR
+CALLBACK
+NewPasswordProc(
+ HWND hDialog,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ static POINT Position = { -1, -1 };
+ static char username[LEASH_USERNAME_SZ]="";
+ static char realm[LEASH_REALM_SZ]="";
+ static char password[256]="";
+ static char password2[256]="";
+ static char password3[256]="";
+ static LPLSH_DLGINFO_EX lpdi;
+ static HWND hDlg=0;
+ char principal[256];
+ long realm_count = 0;
+
+ switch (message) {
+
+ case WM_INITDIALOG:
+ hDlg = hDialog;
+
+ SetVersionInfo(hDialog,IDC_STATIC_VERSION,IDC_STATIC_COPYRIGHT);
+
+ *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam;
+
+ if ((lpdi->size < LSH_DLGINFO_EX_V3_SZ &&
+ lpdi->size != LSH_DLGINFO_EX_V1_SZ &&
+ lpdi->size != LSH_DLGINFO_EX_V2_SZ) ||
+ lpdi->dlgtype != DLGTYPE_CHPASSWD) {
+
+ MessageBox(hDialog, "An incorrect initialization data structure was provided.",
+ "PasswordProc()",
+ MB_OK | MB_ICONSTOP);
+ return FALSE;
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
+ lpdi->out.username[0] = 0;
+ lpdi->out.realm[0] = 0;
+ }
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) {
+ lpdi->out.ccache[0] = 0;
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ SetWindowText(hDialog, lpdi->in.title);
+ else
+ SetWindowText(hDialog, lpdi->title);
+
+ SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ lstrcpy(username, lpdi->in.username);
+ else if (lpdi->username)
+ lstrcpy(username, lpdi->username);
+ if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
+ lstrcpy(realm, lpdi->in.realm);
+ else if (lpdi->realm)
+ lstrcpy(realm, lpdi->realm);
+
+ CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, username);
+ CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, "");
+ CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, "");
+ CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, "");
+
+#if 0 /* 20030619 - mjv wishes to return to the default character */
+ /* echo spaces */
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0);
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD2, EM_SETPASSWORDCHAR, 32, 0);
+ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD3, EM_SETPASSWORDCHAR, 32, 0);
+#endif
+
+ /* Populate list of Realms */
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_RESETCONTENT, 0, 0);
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_LIMITTEXT, 192, 0);
+
+ if (pprofile_get_subsection_names && pprofile_free_list) {
+ const char* rootSection[] = {"realms", NULL};
+ const char** rootsec = rootSection;
+ char **sections = NULL, **cpp = NULL, *value = NULL;
+
+ char krb5_conf[MAX_PATH+1];
+
+ if (!GetProfileFile(krb5_conf,sizeof(krb5_conf))) {
+ profile_t profile;
+ long retval;
+ const char *filenames[2];
+
+ filenames[0] = krb5_conf;
+ filenames[1] = NULL;
+ retval = pprofile_init(filenames, &profile);
+ if (!retval) {
+ retval = pprofile_get_subsection_names(profile, rootsec, &sections);
+
+ if (!retval)
+ {
+ for (cpp = sections; *cpp; cpp++)
+ {
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)*cpp);
+ realm_count++;
+ }
+ }
+ pprofile_free_list(sections);
+ pprofile_release(profile);
+ }
+ }
+ } else {
+ FILE * file;
+ char krb_conf[MAX_PATH+1];
+ char * p;
+
+ if (!GetKrb4ConFile(krb_conf,sizeof(krb_conf)) &&
+ (file = fopen(krb_conf, "rt")))
+ {
+ char lineBuf[256];
+ // Skip the default realm
+ readstring(file,lineBuf,sizeof(lineBuf));
+
+ // Read the defined realms
+ while (TRUE)
+ {
+ if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
+ break;
+
+ if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
+ *(lineBuf + strlen(lineBuf) - 1) = 0;
+
+ for (p=lineBuf; *p ; p++)
+ {
+ if (isspace(*p)) {
+ *p = 0;
+ break;
+ }
+ }
+
+ if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)lineBuf);
+ realm_count++;
+ }
+ }
+
+ fclose(file);
+ }
+ }
+ if (realm_count == 0)
+ CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, CB_ADDSTRING, 0, (LPARAM)realm);
+
+ /* Select the default Realm */
+ if (!realm[0] && hKrb5) {
+ krb5_context ctx=0;
+ char * def = 0;
+ pkrb5_init_context(&ctx);
+ pkrb5_get_default_realm(ctx,&def);
+ if (def) {
+ lstrcpy(realm, def);
+ free(def);
+ }
+ pkrb5_free_context(ctx);
+ }
+ CSetDlgItemText(hDialog, IDC_COMBO_REALM, realm);
+
+ /* setup text of stuff. */
+
+ if (Position.x > 0 && Position.y > 0 &&
+ Position.x < GetSystemMetrics(SM_CXSCREEN) &&
+ Position.y < GetSystemMetrics(SM_CYSCREEN))
+ SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+ else { /* Center the window on the desktop */
+ RECT dlgRect;
+ GetWindowRect( hDialog, &dlgRect );
+ SetWindowPos(hDialog, 0,
+ (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2,
+ (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2,
+ 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+ }
+ /* set window pos to last saved window pos */
+ break;
+
+ case WM_COMMAND:
+ switch (wParam) {
+ case ID_HELP:
+ {
+ WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
+ ID_INITTICKETS);
+ }
+ break;
+ case ID_CLOSEME:
+ {
+ CleanupSliders();
+ memset(password,0,sizeof(password));
+ memset(password2,0,sizeof(password2));
+ memset(password3,0,sizeof(password3));
+ RemoveProp(hDialog, "HANDLES_HELP");
+ EndDialog(hDialog, (int)lParam);
+ return TRUE;
+ }
+ break;
+ case IDOK:
+ {
+ DWORD value = 0;
+ int i = 0;
+ int bit8 = 0;
+
+ CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, username, sizeof(username));
+ CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password));
+ CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, password2, sizeof(password2));
+ CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, password3, sizeof(password3));
+ CGetDlgItemText(hDialog, IDC_COMBO_REALM, realm, sizeof(realm));
+
+ if (!username[0])
+ {
+ MessageBox(hDialog, "You are not allowed to enter a "
+ "blank username.",
+ "Invalid Principal",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+ if (!realm[0])
+ {
+ MessageBox(hDialog, "You are not allowed to enter a "
+ "blank realm.",
+ "Invalid Principal",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+
+ if (Leash_get_default_uppercaserealm())
+ {
+ // found
+ strupr(realm);
+ }
+
+ if (!password[0] || !password2[0] || !password3[0])
+ {
+ MessageBox(hDialog, "You are not allowed to enter a "
+ "blank password.",
+ "Invalid Password",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+
+ for( i = 0; i < 255; i++ ){
+ if( password2[i] == '\0' ){
+ if ( bit8 ) {
+ MessageBox(hDialog,
+ "Passwords should not contain non-ASCII characters.",
+ "Internationalization Warning",
+ MB_OK | MB_ICONINFORMATION);
+ }
+ i = 255;
+ break;
+ } else if( !isprint(password2[i]) ){
+ memset(password2, '\0', sizeof(password2));
+ memset(password3, '\0', sizeof(password3));
+ /* I claim these passwords in the name of planet '\0'... */
+ MessageBox(hDialog,
+ "Passwords may not contain non-printable characters.",
+ "Invalid Password",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ } else if ( password2[i] > 127 )
+ bit8 = 1;
+ }
+
+ if (lstrcmp(password2, password3))
+ {
+ MessageBox(hDialog,
+ "The new password was not entered the same way twice.",
+ "Password validation error",
+ MB_OK | MB_ICONSTOP);
+ return TRUE;
+ }
+
+ sprintf(principal,"%s@%s",username,realm);
+
+ lsh_errno = Leash_int_changepwd(principal, password, password2, 0, 1);
+ if (lsh_errno != 0)
+ {
+#ifdef COMMENT
+ char gbuf[256];
+ int capslock;
+ char *cp;
+#endif /* COMMENT */
+ LONG check_time;
+
+ err_context = "";
+ switch(lsh_errno)
+ {
+ case LSH_INVPRINCIPAL:
+ case LSH_INVINSTANCE:
+ case LSH_INVREALM:
+#ifndef NO_KRB4
+ case KRBERR(KDC_PR_UNKNOWN):
+#endif
+ break;
+#ifndef NO_KRB4
+ case KRBERR(RD_AP_TIME):
+ case KRBERR(KDC_SERVICE_EXP):
+ check_time = Leash_timesync(1);
+ if( check_time == 0 ){
+ SendMessage(hDialog, WM_COMMAND, IDOK, 0);
+ return(TRUE);
+ } else {
+ lsh_errno = check_time;
+ return(TRUE);
+ }
+ break;
+#endif
+ default:
+ return(TRUE);
+ }
+#ifdef COMMENT
+ capslock = lsh_getkeystate(VK_CAPITAL);
+ /* low-order bit means caps lock is
+ toggled; if so, warn user since there's
+ been an error. */
+ if (capslock & 1)
+ {
+ lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
+ cp = gbuf + lstrlen((LPSTR)gbuf);
+ if (cp != gbuf)
+ *cp++ = ' ';
+ lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
+ err_context = gbuf;
+ }
+
+ // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
+ // XXX : "Ticket initialization failed.");
+#endif /* COMMENT */
+ return TRUE;
+ }
+
+ if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
+ strncpy(lpdi->out.username, username, LEASH_USERNAME_SZ);
+ lpdi->out.username[LEASH_USERNAME_SZ-1] = 0;
+ strncpy(lpdi->out.realm, realm, LEASH_REALM_SZ);
+ lpdi->out.realm[LEASH_REALM_SZ-1] = 0;
+ }
+
+ CloseMe(TRUE); /* success */
+ }
+ break;
+ case IDCANCEL:
+ CloseMe(FALSE);
+ break;
+ }
+ break;
+
+ case WM_MOVE:
+#ifdef _WIN32
+#define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \
+ (pt).y=(SHORT)HIWORD(l))
+ LONG2POINT(lParam,Position);
+#else
+ Position = MAKEPOINT(lParam);
+#endif
+ break;
+ }
+ return FALSE;
+}
diff --git a/src/windows/leashdll/lsh_pwd.rc b/src/windows/leashdll/lsh_pwd.rc
new file mode 100644
index 0000000000..c6d5a1bf13
--- /dev/null
+++ b/src/windows/leashdll/lsh_pwd.rc
@@ -0,0 +1,261 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "leashids.h"
+#include "winver.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+LOGOBITMAP BITMAP DISCARDABLE "res\\islogo.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+LEASHICON ICON DISCARDABLE "res\\leash.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+ENTERPASSWORDDLG DIALOG DISCARDABLE 23, 48, 262, 108
+STYLE DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
+CAPTION "Enter Password"
+FONT 10, "System"
+BEGIN
+ EDITTEXT ID_PRINCIPAL,6,17,96,12,ES_AUTOHSCROLL
+ LTEXT "Enter your username:",ID_PRINCCAPTION,6,7,140,8
+ DEFPUSHBUTTON "OK",IDOK,110,42,32,14
+ EDITTEXT ID_OLDPASSWORD,6,43,96,12,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Enter your password:",ID_OLDPCAPTION,6,33,91,8
+ EDITTEXT ID_DURATION,40,59,20,12
+ LTEXT "Duration:",-1,6,61,30,8
+ LTEXT "minutes",-1,62,61,64,8
+ ICON "LeashIcon",-1,6,78,18,20
+ PUSHBUTTON "&Cancel",IDCANCEL,30,78,32,14
+ PUSHBUTTON "&Restart",ID_RESTART,70,78,32,14
+ PUSHBUTTON "&Help",ID_HELP,110,78,32,14
+ CONTROL "",ID_PICFRAME,"Static",SS_BLACKFRAME,153,4,100,100
+END
+
+CHANGEPASSWORDDLG DIALOG DISCARDABLE 27, 41, 270, 155
+STYLE DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
+CAPTION "Change Password"
+FONT 8, "System"
+BEGIN
+ EDITTEXT ID_PRINCIPAL,6,35,96,12,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "OK",IDOK,110,60,32,14
+ EDITTEXT ID_OLDPASSWORD,6,61,96,12,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT ID_CONFIRMPASSWORD1,6,87,96,12,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ EDITTEXT ID_CONFIRMPASSWORD2,6,113,96,12,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ LTEXT "Enter your username:",ID_PRINCCAPTION,6,25,140,8
+ LTEXT "Enter your old password:",ID_OLDPCAPTION,6,51,91,8
+ LTEXT "Enter your new password:",ID_CONFIRMCAPTION1,6,77,96,8
+ LTEXT "Retype your new password:",ID_CONFIRMCAPTION2,6,103,100,
+ 8
+ ICON "LeashIcon",-1,6,134,18,20
+ PUSHBUTTON "&Cancel",IDCANCEL,30,134,32,14
+ PUSHBUTTON "&Restart",ID_RESTART,70,134,32,14
+ PUSHBUTTON "&Help",ID_HELP,110,134,32,14
+ LTEXT "To change your password, fill in the following fields as they appear.",
+ -1,6,3,140,21
+ CONTROL "",ID_PICFRAME,"Static",SS_BLACKFRAME,157,27,100,100
+END
+
+IDD_AUTHENTICATE DIALOGEX 0, 0, 370, 268
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Authenticate to Kerberos"
+FONT 8, "Microsoft Sans Serif"
+BEGIN
+ EDITTEXT IDC_EDIT_PRINCIPAL,89,42,259,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_PASSWORD,89,74,259,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ COMBOBOX IDC_COMBO_REALM,89,57,259,79,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,302,235,49,14
+ PUSHBUTTON "Cancel",IDCANCEL,249,235,49,14
+ PUSHBUTTON "Hide Options",IDC_BUTTON_OPTIONS,186,235,49,14
+ CONTROL "Ticket Lifetime",IDC_SLIDER_LIFETIME,"msctls_trackbar32",
+ TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,90,113,258,15
+ CONTROL "Get tickets that can be forwarded to other machines",
+ IDC_CHECK_FORWARDABLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,89,150,203,10
+ CONTROL "Get tickets without IP addresses (NAT mode)",
+ IDC_CHECK_NOADDRESS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,89,163,228,10
+ CONTROL "Get tickets that can be renewed for:",
+ IDC_CHECK_RENEWABLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,89,176,186,10
+ CONTROL "Slider2",IDC_SLIDER_RENEWLIFE,"msctls_trackbar32",
+ TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,100,207,246,15
+ RTEXT "Name:",IDC_STATIC_NAME,63,44,21,8
+ RTEXT "Realm:",IDC_STATIC_REALM,62,60,23,8
+ RTEXT "Password:",IDC_STATIC_PWD,13,76,74,8
+ RTEXT "Ticket Lifetime:",IDC_STATIC_LIFETIME,19,103,65,8,0,
+ WS_EX_RIGHT
+ LTEXT "Kerberos 5 Options:",IDC_STATIC_KRB5,22,139,101,8
+ LTEXT "HMS",IDC_STATIC_LIFETIME_VALUE,89,103,131,8
+ LTEXT "HMS",IDC_STATIC_RENEW_TILL_VALUE,102,193,141,8
+ LTEXT "",IDC_STATIC_VERSION,7,244,143,8
+ ICON LEASHICON,IDC_PICTURE_LEASH,21,15,20,20
+ LTEXT "You are required to type your Kerberos Password",
+ IDC_STATIC_NOTICE,51,23,276,8
+ RTEXT "Renew Till:",IDC_STATIC_RENEW,37,193,59,8
+ LTEXT "",IDC_STATIC_COPYRIGHT,7,256,323,8
+END
+
+IDD_PASSWORD DIALOG DISCARDABLE 0, 0, 382, 198
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Change Password"
+FONT 8, "Microsoft Sans Serif"
+BEGIN
+ EDITTEXT IDC_EDIT_PRINCIPAL,99,52,259,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_PASSWORD,99,84,259,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_PASSWORD2,99,112,259,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_PASSWORD3,99,135,259,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ COMBOBOX IDC_COMBO_REALM,99,67,259,79,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,313,165,49,14
+ PUSHBUTTON "Cancel",IDCANCEL,256,165,49,14
+ RTEXT "Name:",IDC_STATIC_NAME,73,55,21,8
+ RTEXT "Realm:",IDC_STATIC_REALM,72,71,23,8
+ RTEXT "Old Password:",IDC_STATIC_PWD,19,85,74,21
+ LTEXT "Copyright 2003 MIT",IDC_STATIC_COPYRIGHT,7,183,329,8
+ ICON LEASHICON,IDC_PICTURE_LEASH,15,15,20,20
+ LTEXT "Change your Kerberos password or phrase",
+ IDC_STATIC_NOTICE,48,20,276,8
+ RTEXT "New Password:",IDC_STATIC_PWD2,23,112,74,16
+ RTEXT "New Password (again):",IDC_STATIC_PWD3,22,135,74,18
+ LTEXT "Version",IDC_STATIC_VERSION,7,170,172,8
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""leashids.h""\r\n"
+ "#include ""ver.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "#include ""ver.rc""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_PASSWORD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 375
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 191
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ LSH_TIME_HOST "time"
+ LSH_DEFAULT_TICKET_LIFE "600"
+ LSH_DEFAULT_TICKET_RENEW_TILL "10080"
+ LSH_DEFAULT_TICKET_FORWARD "1"
+ LSH_DEFAULT_TICKET_NOADDRESS "1"
+ LSH_DEFAULT_TICKET_PROXIABLE "0"
+ LSH_DEFAULT_TICKET_PUBLICIP "0"
+ LSH_DEFAULT_TICKET_USEKRB4 "0"
+ LSH_DEFAULT_DIALOG_KINIT_OPT "1"
+ LSH_DEFAULT_DIALOG_LIFE_MIN "30"
+ LSH_DEFAULT_DIALOG_LIFE_MAX "1440"
+ LSH_DEFAULT_DIALOG_RENEW_MIN "600"
+ LSH_DEFAULT_DIALOG_RENEW_MAX "43200"
+ LSH_DEFAULT_TICKET_RENEW "1"
+ LSH_DEFAULT_UPPERCASEREALM "1"
+ LSH_DEFAULT_MSLSA_IMPORT "2"
+ LSH_DEFAULT_PRESERVE_KINIT "0"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ LSH_DEFAULT_DIALOG_LOCK_LOCATION "0"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+#include "ver.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/src/windows/leashdll/lshcallb.c b/src/windows/leashdll/lshcallb.c
new file mode 100644
index 0000000000..3f2afb3459
--- /dev/null
+++ b/src/windows/leashdll/lshcallb.c
@@ -0,0 +1,15 @@
+#include <windows.h>
+#include <krb.h>
+
+int (*Lcom_err)(LPSTR,long,LPSTR,...);
+LPSTR (*Lerror_message)(long);
+LPSTR (*Lerror_table_name)(long);
+
+void Leash_load_com_err_callback(FARPROC ce,
+ FARPROC em,
+ FARPROC etn)
+{
+ (FARPROC)Lcom_err=ce;
+ (FARPROC)Lerror_message=em;
+ (FARPROC)Lerror_table_name=etn;
+}
diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c
new file mode 100644
index 0000000000..73b10c3579
--- /dev/null
+++ b/src/windows/leashdll/lshfunc.c
@@ -0,0 +1,3867 @@
+#include <windows.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <winsock.h>
+#include "leashdll.h"
+#include <KerberosIV/krb.h>
+#include <prot.h>
+#include <time.h>
+
+#include <leashwin.h>
+#include "leasherr.h"
+#include "leash-int.h"
+#include "leashids.h"
+
+#include <mitwhich.h>
+
+#include <winkrbid.h>
+#include "reminder.h"
+
+static char FAR *err_context;
+
+char KRB_HelpFile[_MAX_PATH] = HELPFILE;
+
+#define LEN 64 /* Maximum Hostname Length */
+
+#define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */
+
+#ifndef NO_KRB4
+char *
+short_date(dp)
+ long *dp;
+{
+ register char *cp;
+ cp = ctime(dp) + 4; // skip day of week
+ // cp[15] = '\0';
+ cp[12] = '\0'; // Don't display seconds
+ return (cp);
+}
+#endif
+
+static
+char*
+clean_string(
+ char* s
+ )
+{
+ char* p = s;
+ char* b = s;
+
+ if (!s) return s;
+
+ for (p = s; *p; p++) {
+ switch (*p) {
+ case '\007':
+ /* Add more cases here */
+ break;
+ default:
+ *b = *p;
+ b++;
+ }
+ }
+ *b = *p;
+ return s;
+}
+
+static
+int
+leash_error_message(
+ const char *error,
+ int rcL,
+ int rc4,
+ int rc5,
+ int rcA,
+ char* result_string,
+ int displayMB
+ )
+{
+ char message[2048];
+ char *p = message;
+ int size = sizeof(message);
+ int n;
+
+ // XXX: ignore AFS for now.
+
+ if (!rc5 && !rc4 && !rcL)
+ return 0;
+
+ n = _snprintf(p, size, "%s\n\n", error);
+ p += n;
+ size -= n;
+
+ if (rc5 && !result_string)
+ {
+ n = _snprintf(p, size,
+ "Kerberos 5: %s (error %ld)\n",
+ perror_message(rc5),
+ rc5 & 255 // XXX: & 255??!!!
+ );
+ p += n;
+ size -= n;
+ }
+ if (rc4 && !result_string)
+ {
+ char buffer[1024];
+ n = _snprintf(p, size,
+ "Kerberos 4: %s\n",
+ err_describe(buffer, rc4)
+ );
+ p += n;
+ size -= n;
+ }
+ if (rcL)
+ {
+ char buffer[1024];
+ n = _snprintf(p, size,
+ "\n%s\n",
+ err_describe(buffer, rcL)
+ );
+ p += n;
+ size -= n;
+ }
+ if (result_string)
+ {
+ n = _snprintf(p, size,
+ "%s\n",
+ result_string);
+ p += n;
+ size -= n;
+ }
+ if ( displayMB )
+ MessageBox(NULL, message, "Leash", MB_OK | MB_ICONERROR | MB_TASKMODAL |
+ MB_SETFOREGROUND);
+
+ if (rc5) return rc5;
+ if (rc4) return rc4;
+ if (rcL) return rcL;
+ return 0;
+}
+
+
+static
+char *
+make_postfix(
+ const char * base,
+ const char * postfix,
+ char ** rcopy
+ )
+{
+ int base_size;
+ int ret_size;
+ char * copy = 0;
+ char * ret = 0;
+
+ base_size = strlen(base) + 1;
+ ret_size = base_size + strlen(postfix) + 1;
+ copy = malloc(base_size);
+ ret = malloc(ret_size);
+
+ if (!copy || !ret)
+ goto cleanup;
+
+ strncpy(copy, base, base_size);
+ copy[base_size - 1] = 0;
+
+ strncpy(ret, base, base_size);
+ strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1));
+ ret[ret_size - 1] = 0;
+
+ cleanup:
+ if (!copy || !ret) {
+ if (copy)
+ free(copy);
+ if (ret)
+ free(ret);
+ copy = ret = 0;
+ }
+ // INVARIANT: (ret ==> copy) && (copy ==> ret)
+ *rcopy = copy;
+ return ret;
+}
+
+#ifndef NO_KRB4
+static
+long
+make_temp_cache_v4(
+ const char * postfix
+ )
+{
+ static char * old_cache = 0;
+
+ if (!pkrb_set_tkt_string || !ptkt_string || !pdest_tkt)
+ return 0; // XXX - is this appropriate?
+
+ if (old_cache) {
+ pdest_tkt();
+ pkrb_set_tkt_string(old_cache);
+ free(old_cache);
+ old_cache = 0;
+ }
+
+ if (postfix)
+ {
+ char * tmp_cache = make_postfix(ptkt_string(), postfix, &old_cache);
+
+ if (!tmp_cache)
+ return KFAILURE;
+
+ pkrb_set_tkt_string(tmp_cache);
+ free(tmp_cache);
+ }
+ return 0;
+}
+#endif
+
+static
+long
+make_temp_cache_v5(
+ const char * postfix,
+ krb5_context * pctx
+ )
+{
+ static krb5_context ctx = 0;
+ static char * old_cache = 0;
+
+ // INVARIANT: old_cache ==> ctx && ctx ==> old_cache
+
+ if (pctx)
+ *pctx = 0;
+
+ if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve ||
+ !pkrb5_cc_default_name || !pkrb5_cc_set_default_name)
+ return 0;
+
+ if (old_cache) {
+ krb5_ccache cc = 0;
+ if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc))
+ pkrb5_cc_destroy(ctx, cc);
+ pkrb5_cc_set_default_name(ctx, old_cache);
+ free(old_cache);
+ old_cache = 0;
+ }
+ if (ctx) {
+ pkrb5_free_context(ctx);
+ ctx = 0;
+ }
+
+ if (postfix)
+ {
+ char * tmp_cache = 0;
+ krb5_error_code rc = 0;
+
+ rc = pkrb5_init_context(&ctx);
+ if (rc) goto cleanup;
+
+ tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix,
+ &old_cache);
+
+ if (!tmp_cache) {
+ rc = ENOMEM;
+ goto cleanup;
+ }
+
+ rc = pkrb5_cc_set_default_name(ctx, tmp_cache);
+
+ cleanup:
+ if (rc && ctx) {
+ pkrb5_free_context(ctx);
+ ctx = 0;
+ }
+ if (tmp_cache)
+ free(tmp_cache);
+ if (pctx)
+ *pctx = ctx;
+ return rc;
+ }
+ return 0;
+}
+
+long
+Leash_checkpwd(
+ char *principal,
+ char *password
+ )
+{
+ return Leash_int_checkpwd(principal, password, 0);
+}
+
+long
+Leash_int_checkpwd(
+ char * principal,
+ char * password,
+ int displayErrors
+ )
+{
+ long rc = 0;
+ krb5_context ctx = 0; // statically allocated in make_temp_cache_v5
+ // XXX - we ignore errors in make_temp_cache_v? This is BAD!!!
+#ifndef NO_KRB4
+ make_temp_cache_v4("_checkpwd");
+#endif
+ make_temp_cache_v5("_checkpwd", &ctx);
+ rc = Leash_int_kinit_ex( ctx, 0,
+ principal, password, 0, 0, 0, 0,
+ Leash_get_default_noaddresses(),
+ Leash_get_default_publicip(),
+ displayErrors
+ );
+#ifndef NO_KRB4
+ make_temp_cache_v4(0);
+#endif
+ make_temp_cache_v5(0, &ctx);
+ return rc;
+}
+
+static
+long
+Leash_changepwd_v5(
+ char * principal,
+ char * password,
+ char * newpassword,
+ char** error_str
+ )
+{
+ krb5_error_code rc = 0;
+ int result_code;
+ krb5_data result_code_string, result_string;
+ krb5_context context = 0;
+ krb5_principal princ = 0;
+ krb5_get_init_creds_opt opts;
+ krb5_creds creds;
+ DWORD addressless = 0;
+
+ result_string.data = 0;
+ result_code_string.data = 0;
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ if (rc = pkrb5_init_context(&context)) {
+#if 0
+ com_err(argv[0], ret, "initializing kerberos library");
+#endif
+ goto cleanup;
+ }
+
+ if (rc = pkrb5_parse_name(context, principal, &princ)) {
+#if 0
+ com_err(argv[0], ret, "parsing client name");
+#endif
+ goto cleanup;
+ }
+
+ pkrb5_get_init_creds_opt_init(&opts);
+ pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
+ pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
+ pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
+ pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
+
+ addressless = Leash_get_default_noaddresses();
+ if (addressless)
+ pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
+
+
+ if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password,
+ 0, 0, 0, "kadmin/changepw", &opts)) {
+ if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+#if 0
+ com_err(argv[0], 0,
+ "Password incorrect while getting initial ticket");
+#endif
+ }
+ else {
+#if 0
+ com_err(argv[0], ret, "getting initial ticket");
+#endif
+ }
+ goto cleanup;
+ }
+
+ if (rc = pkrb5_change_password(context, &creds, newpassword,
+ &result_code, &result_code_string,
+ &result_string)) {
+#if 0
+ com_err(argv[0], ret, "changing password");
+#endif
+ goto cleanup;
+ }
+
+ if (result_code) {
+ int len = result_code_string.length +
+ (result_string.length ? (sizeof(": ") - 1) : 0) +
+ result_string.length;
+ if (len && error_str) {
+ *error_str = malloc(len + 1);
+ if (*error_str)
+ _snprintf(*error_str, len + 1,
+ "%.*s%s%.*s",
+ result_code_string.length, result_code_string.data,
+ result_string.length?": ":"",
+ result_string.length, result_string.data);
+ }
+ rc = result_code;
+ goto cleanup;
+ }
+
+ cleanup:
+ if (result_string.data)
+ pkrb5_free_data_contents(context, &result_string);
+
+ if (result_code_string.data)
+ pkrb5_free_data_contents(context, &result_code_string);
+
+ if (princ)
+ pkrb5_free_principal(context, princ);
+
+ if (context)
+ pkrb5_free_context(context);
+
+ return rc;
+}
+
+#ifndef NO_KRB4
+static
+long
+Leash_changepwd_v4(
+ char * principal,
+ char * password,
+ char * newpassword,
+ char** error_str
+ )
+{
+ long k_errno;
+
+ if (!pkrb_set_tkt_string || !ptkt_string || !pkadm_change_your_password ||
+ !pdest_tkt)
+ return KFAILURE;
+
+ k_errno = make_temp_cache_v4("_chgpwd");
+ if (k_errno) return k_errno;
+ k_errno = pkadm_change_your_password(principal, password, newpassword,
+ error_str);
+ make_temp_cache_v4(0);
+ return k_errno;
+}
+#endif
+
+/*
+ * Leash_changepwd
+ *
+ * Try to change the password using one of krb5 or krb4 -- whichever one
+ * works. We return ok on the first one that works.
+ */
+long
+Leash_changepwd(
+ char * principal,
+ char * password,
+ char * newpassword,
+ char** result_string
+ )
+{
+ return Leash_int_changepwd(principal, password, newpassword, result_string, 0);
+}
+
+long
+Leash_int_changepwd(
+ char * principal,
+ char * password,
+ char * newpassword,
+ char** result_string,
+ int displayErrors
+ )
+{
+ char* v5_error_str = 0;
+ char* v4_error_str = 0;
+ char* error_str = 0;
+ int rc4 = 0;
+ int rc5 = 0;
+ int rc = 0;
+ if (hKrb5)
+ rc = rc5 = Leash_changepwd_v5(principal, password, newpassword,
+ &v5_error_str);
+#ifndef NO_KRB4
+ if (hKrb4 &&
+ Leash_get_default_use_krb4() &&
+ (!hKrb5 || rc5))
+ rc = rc4 = Leash_changepwd_v4(principal, password, newpassword,
+ &v4_error_str);
+#endif
+ if (!rc)
+ return 0;
+ if (v5_error_str || v4_error_str) {
+ int len = 0;
+ char v5_prefix[] = "Kerberos 5: ";
+ char sep[] = "\n";
+ char v4_prefix[] = "Kerberos 4: ";
+
+ clean_string(v5_error_str);
+ clean_string(v4_error_str);
+
+ if (v5_error_str)
+ len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) +
+ sizeof(sep);
+ if (v4_error_str)
+ len += sizeof(sep) + sizeof(v4_prefix) + strlen(v4_error_str) +
+ sizeof(sep);
+ error_str = malloc(len + 1);
+ if (error_str) {
+ char* p = error_str;
+ int size = len + 1;
+ int n;
+ if (v5_error_str) {
+ n = _snprintf(p, size, "%s%s%s%s",
+ sep, v5_prefix, v5_error_str, sep);
+ p += n;
+ size -= n;
+ }
+ if (v4_error_str) {
+ n = _snprintf(p, size, "%s%s%s%s",
+ sep, v4_prefix, v4_error_str, sep);
+ p += n;
+ size -= n;
+ }
+ if (result_string)
+ *result_string = error_str;
+ }
+ }
+ return leash_error_message("Error while changing password.",
+ rc4, rc4, rc5, 0, error_str,
+ displayErrors
+ );
+}
+
+int (*Lcom_err)(LPSTR,long,LPSTR,...);
+LPSTR (*Lerror_message)(long);
+LPSTR (*Lerror_table_name)(long);
+
+
+long
+Leash_kinit(
+ char * principal,
+ char * password,
+ int lifetime
+ )
+{
+ return Leash_int_kinit_ex( 0, 0,
+ principal,
+ password,
+ lifetime,
+ Leash_get_default_forwardable(),
+ Leash_get_default_proxiable(),
+ Leash_get_default_renew_till(),
+ Leash_get_default_noaddresses(),
+ Leash_get_default_publicip(),
+ 0
+ );
+}
+
+long
+Leash_kinit_ex(
+ char * principal,
+ char * password,
+ int lifetime,
+ int forwardable,
+ int proxiable,
+ int renew_life,
+ int addressless,
+ unsigned long publicip
+ )
+{
+ return Leash_int_kinit_ex( 0, /* krb5 context */
+ 0, /* parent window */
+ principal,
+ password,
+ lifetime,
+ forwardable,
+ proxiable,
+ renew_life,
+ addressless,
+ publicip,
+ 0
+ );
+}
+
+long
+Leash_int_kinit_ex(
+ krb5_context ctx,
+ HWND hParent,
+ char * principal,
+ char * password,
+ int lifetime,
+ int forwardable,
+ int proxiable,
+ int renew_life,
+ int addressless,
+ unsigned long publicip,
+ int displayErrors
+ )
+{
+ LPCSTR functionName;
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char first_part[256];
+ char second_part[256];
+ char temp[1024];
+ int count;
+ int i;
+ int rc4 = 0;
+ int rc5 = 0;
+ int rcA = 0;
+ int rcB = 0;
+ int rcL = 0;
+
+ if (lifetime < 5)
+ lifetime = 1;
+ else
+ lifetime /= 5;
+
+ if (renew_life > 0 && renew_life < 5)
+ renew_life = 1;
+ else
+ renew_life /= 5;
+
+ /* This should be changed if the maximum ticket lifetime */
+ /* changes */
+
+ if (lifetime > 255)
+ lifetime = 255;
+
+ err_context = "parsing principal";
+
+ memset(temp, '\0', sizeof(temp));
+ memset(inst, '\0', sizeof(inst));
+ memset(realm, '\0', sizeof(realm));
+ memset(first_part, '\0', sizeof(first_part));
+ memset(second_part, '\0', sizeof(second_part));
+
+ sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part);
+ strcpy(temp, first_part);
+ strcpy(realm, second_part);
+ memset(first_part, '\0', sizeof(first_part));
+ memset(second_part, '\0', sizeof(second_part));
+ if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2)
+ {
+ strcpy(aname, first_part);
+ strcpy(inst, second_part);
+ }
+ else
+ {
+ count = 0;
+ i = 0;
+ for (i = 0; temp[i]; i++)
+ {
+ if (temp[i] == '.')
+ ++count;
+ }
+ if (count > 1)
+ {
+ strcpy(aname, temp);
+ }
+ else
+ {
+#ifndef NO_KRB4
+ if (pkname_parse != NULL)
+ {
+ memset(first_part, '\0', sizeof(first_part));
+ memset(second_part, '\0', sizeof(second_part));
+ sscanf(temp, "%[@/0-9a-zA-Z_-].%[@/0-9a-zA-Z_-]", first_part, second_part);
+ strcpy(aname, first_part);
+ strcpy(inst, second_part);
+ }
+ else
+#endif
+ {
+ strcpy(aname, temp);
+ }
+ }
+ }
+
+ memset(temp, '\0', sizeof(temp));
+ strcpy(temp, aname);
+ if (strlen(inst) != 0)
+ {
+ strcat(temp, "/");
+ strcat(temp, inst);
+ }
+ if (strlen(realm) != 0)
+ {
+ strcat(temp, "@");
+ strcat(temp, realm);
+ }
+
+ rc5 = Leash_krb5_kinit(ctx, hParent,
+ temp, password, lifetime,
+ forwardable,
+ proxiable,
+ renew_life,
+ addressless,
+ publicip
+ );
+#ifndef NO_KRB4
+ if ( Leash_get_default_use_krb4() ) {
+ rc4 = KSUCCESS;
+
+ if ( !rc5 ) {
+ if (!Leash_convert524(ctx))
+ rc4 = KFAILURE;
+ }
+
+ if (rc4 != KSUCCESS) {
+ if (pkname_parse == NULL)
+ {
+ goto cleanup;
+ }
+
+ err_context = "getting realm";
+ if (!*realm && (rc4 = (int)(*pkrb_get_lrealm)(realm, 1)))
+ {
+ functionName = "krb_get_lrealm()";
+ rcL = LSH_FAILEDREALM;
+ goto cleanup;
+ }
+
+ err_context = "checking principal";
+ if ((!*aname) || (!(rc4 = (int)(*pk_isname)(aname))))
+ {
+ functionName = "krb_get_lrealm()";
+ rcL = LSH_INVPRINCIPAL;
+ goto cleanup;
+ }
+
+ /* optional instance */
+ if (!(rc4 = (int)(*pk_isinst)(inst)))
+ {
+ functionName = "k_isinst()";
+ rcL = LSH_INVINSTANCE;
+ goto cleanup;
+ }
+
+ if (!(rc4 = (int)(*pk_isrealm)(realm)))
+ {
+ functionName = "k_isrealm()";
+ rcL = LSH_INVREALM;
+ goto cleanup;
+ }
+
+ err_context = "fetching ticket";
+ rc4 = (*pkrb_get_pw_in_tkt)(aname, inst, "", "krbtgt", realm,
+ lifetime, password);
+ if (rc4) /* XXX: do we want: && (rc != NO_TKT_FIL) as well? */
+ {
+ functionName = "krb_get_pw_in_tkt()";
+ rcL = KRBERR(rc4);
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#ifndef NO_AFS
+ if ( !rc5 || (Leash_get_default_use_krb4() && !rc4) ) {
+ char c;
+ char *r;
+ char *t;
+ for ( r=realm, t=temp; c=*r; r++,t++ )
+ *t = isupper(c) ? tolower(c) : c;
+ *t = '\0';
+
+ rcA = Leash_afs_klog("afs", temp, "", lifetime);
+ rcB = Leash_afs_klog("afs", "", "", lifetime);
+ if (!(rcA && rcB))
+ rcA = 0;
+ else if (!rcA)
+ rcA = rcB;
+ }
+#endif /* NO_AFS */
+
+ cleanup:
+ return leash_error_message("Ticket initialization failed.",
+ rcL,
+#ifdef NO_KRB4
+ 0,
+#else
+ (rc5 && rc4)?KRBERR(rc4):0,
+#endif
+ rc5, rcA, 0,
+ displayErrors);
+}
+
+long FAR
+Leash_renew(void)
+{
+ if ( hKrb5 && !LeashKRB5_renew() ) {
+ int lifetime;
+ lifetime = Leash_get_default_lifetime() / 5;
+#ifndef NO_KRB4
+ if (hKrb4 && Leash_get_default_use_krb4())
+ Leash_convert524(0);
+#endif
+#ifndef NO_AFS
+ {
+ TicketList * list = NULL, * token;
+ not_an_API_LeashAFSGetToken(NULL,&list,NULL);
+ for ( token = list ; token ; token = token->next )
+ Leash_afs_klog("afs", token->realm, "", lifetime);
+ not_an_API_LeashFreeTicketList(&list);
+ }
+#endif /* NO_AFS */
+ return 1;
+ }
+ return 0;
+}
+
+BOOL
+GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+{
+ NTSTATUS Status = 0;
+ HANDLE TokenHandle;
+ TOKEN_STATISTICS Stats;
+ DWORD ReqLen;
+ BOOL Success;
+ PSECURITY_LOGON_SESSION_DATA pSessionData;
+
+ if (!ppSessionData)
+ return FALSE;
+ *ppSessionData = NULL;
+
+ Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+ if ( !Success )
+ return FALSE;
+
+ Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
+ CloseHandle( TokenHandle );
+ if ( !Success )
+ return FALSE;
+
+ Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData );
+ if ( FAILED(Status) || !pSessionData )
+ return FALSE;
+
+ *ppSessionData = pSessionData;
+ return TRUE;
+}
+
+// IsKerberosLogon() does not validate whether or not there are valid tickets in the
+// cache. It validates whether or not it is reasonable to assume that if we
+// attempted to retrieve valid tickets we could do so. Microsoft does not
+// automatically renew expired tickets. Therefore, the cache could contain
+// expired or invalid tickets. Microsoft also caches the user's password
+// and will use it to retrieve new TGTs if the cache is empty and tickets
+// are requested.
+
+BOOL
+IsKerberosLogon(VOID)
+{
+ PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
+ BOOL Success = FALSE;
+
+ if ( GetSecurityLogonSessionData(&pSessionData) ) {
+ if ( pSessionData->AuthenticationPackage.Buffer ) {
+ WCHAR buffer[256];
+ WCHAR *usBuffer;
+ int usLength;
+
+ Success = FALSE;
+ usBuffer = (pSessionData->AuthenticationPackage).Buffer;
+ usLength = (pSessionData->AuthenticationPackage).Length;
+ if (usLength < 256)
+ {
+ lstrcpynW (buffer, usBuffer, usLength);
+ lstrcatW (buffer,L"");
+ if ( !lstrcmpW(L"Kerberos",buffer) )
+ Success = TRUE;
+ }
+ }
+ pLsaFreeReturnBuffer(pSessionData);
+ }
+ return Success;
+}
+
+static BOOL
+IsWindowsVista (void)
+{
+ static BOOL fChecked = FALSE;
+ static BOOL fIsVista = FALSE;
+
+ if (!fChecked)
+ {
+ OSVERSIONINFO Version;
+
+ memset (&Version, 0x00, sizeof(Version));
+ Version.dwOSVersionInfoSize = sizeof(Version);
+
+ if (GetVersionEx (&Version))
+ {
+ if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)
+ fIsVista = TRUE;
+ }
+ fChecked = TRUE;
+ }
+
+ return fIsVista;
+}
+
+static BOOL
+IsProcessUacLimited (void)
+{
+ static BOOL fChecked = FALSE;
+ static BOOL fIsUAC = FALSE;
+
+ if (!fChecked)
+ {
+ NTSTATUS Status = 0;
+ HANDLE TokenHandle;
+ DWORD ElevationLevel;
+ DWORD ReqLen;
+ BOOL Success;
+
+ if (IsWindowsVista()) {
+ Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+ if ( Success ) {
+ Success = GetTokenInformation( TokenHandle,
+ TokenOrigin+1 /* ElevationLevel */,
+ &ElevationLevel, sizeof(DWORD), &ReqLen );
+ CloseHandle( TokenHandle );
+ if ( Success && ElevationLevel == 3 /* Limited */ )
+ fIsUAC = TRUE;
+ }
+ }
+ fChecked = TRUE;
+ }
+ return fIsUAC;
+
+}
+
+// This looks really ugly because it is. The result of IsKerberosLogon()
+// does not prove whether or not there are Kerberos tickets available to
+// be imported. Only the call to Leash_ms2mit() which actually attempts
+// to import tickets can do that. However, calling Leash_ms2mit() can
+// result in a TGS_REQ being sent to the KDC and since Leash_importable()
+// is called quite often we want to avoid this if at all possible.
+// Unfortunately, we have be shown at least one case in which the primary
+// authentication package was not Kerberos and yet there were Kerberos
+// tickets available. Therefore, if IsKerberosLogon() is not TRUE we
+// must call Leash_ms2mit() but we still do not want to call it in a
+// tight loop so we cache the response and assume it won't change.
+
+// 2007-03-21
+// And the nightmare goes on. On Vista the Lsa call we use to determine
+// whether or not Kerberos was used for logon fails to return and worse
+// corrupts the stack. Therefore, we must now test to see if the
+// operating system is Vista and skip the call to IsKerberosLogon()
+// if it is.
+long FAR
+Leash_importable(void)
+{
+ if (IsProcessUacLimited())
+ return FALSE;
+
+ if ( !IsWindowsVista() && IsKerberosLogon() )
+ return TRUE;
+ else {
+ static int response = -1;
+ if (response == -1) {
+ response = Leash_ms2mit(0);
+ }
+ return response;
+ }
+}
+
+long FAR
+Leash_import(void)
+{
+ if ( Leash_ms2mit(1) ) {
+ int lifetime;
+ lifetime = Leash_get_default_lifetime() / 5;
+#ifndef NO_KRB4
+ if (hKrb4 && Leash_get_default_use_krb4())
+ Leash_convert524(0);
+#endif
+#ifndef NO_AFS
+ {
+ char c;
+ char *r;
+ char *t;
+ char cell[256];
+ char realm[256];
+ int i = 0;
+ int rcA = 0;
+ int rcB = 0;
+
+ krb5_context ctx = 0;
+ krb5_error_code code = 0;
+ krb5_ccache cc = 0;
+ krb5_principal me = 0;
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ code = pkrb5_init_context(&ctx);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_default(ctx, &cc);
+ if (code) goto cleanup;
+
+ if (code = pkrb5_cc_get_principal(ctx, cc, &me))
+ goto cleanup;
+
+ for ( r=realm, t=cell, i=0; i<krb5_princ_realm(ctx, me)->length; r++,t++,i++ ) {
+ c = krb5_princ_realm(ctx, me)->data[i];
+ *r = c;
+ *t = isupper(c) ? tolower(c) : c;
+ }
+ *r = *t = '\0';
+
+ rcA = Leash_afs_klog("afs", cell, "", lifetime);
+ rcB = Leash_afs_klog("afs", "", "", lifetime);
+ if (!(rcA && rcB))
+ rcA = 0;
+ else if (!rcA)
+ rcA = rcB;
+
+ cleanup:
+ if (me)
+ pkrb5_free_principal(ctx, me);
+ if (cc)
+ pkrb5_cc_close(ctx, cc);
+ if (ctx)
+ pkrb5_free_context(ctx);
+ }
+#endif /* NO_AFS */
+ return 1;
+ }
+ return 0;
+}
+
+long
+Leash_kdestroy(void)
+{
+#ifdef NO_KRB4
+ return 0;
+#else
+ int k_errno;
+
+ Leash_afs_unlog();
+ Leash_krb5_kdestroy();
+
+ if (pdest_tkt != NULL)
+ {
+ k_errno = (*pdest_tkt)();
+ if (k_errno && (k_errno != RET_TKFIL))
+ return KRBERR(k_errno);
+ }
+
+ return 0;
+#endif
+}
+
+#ifndef NO_KRB4
+int com_addr(void)
+{
+ long ipAddr;
+ char loc_addr[ADDR_SZ];
+ CREDENTIALS cred;
+ char service[40];
+ char instance[40];
+// char addr[40];
+ char realm[40];
+ struct in_addr LocAddr;
+ int k_errno;
+
+ if (pkrb_get_cred == NULL)
+ return(KSUCCESS);
+
+ k_errno = (*pkrb_get_cred)(service,instance,realm,&cred);
+ if (k_errno)
+ return KRBERR(k_errno);
+
+
+ while(1) {
+ ipAddr = (*pLocalHostAddr)();
+ LocAddr.s_addr = ipAddr;
+ strcpy(loc_addr,inet_ntoa(LocAddr));
+ if ( strcmp(cred.address,loc_addr) != 0) {
+ Leash_kdestroy ();
+ break;
+ }
+ break;
+ } // while()
+ return 0;
+}
+#endif
+
+long FAR
+not_an_API_LeashFreeTicketList(TicketList** ticketList)
+{
+ TicketList* tempList = *ticketList, *killList;
+
+ //if (tempList == NULL)
+ //return -1;
+
+ while (tempList)
+ {
+ killList = tempList;
+
+ tempList = (TicketList*)tempList->next;
+ free(killList->theTicket);
+ if (killList->tktEncType)
+ free(killList->tktEncType);
+ if (killList->keyEncType)
+ free(killList->keyEncType);
+ if (killList->addrCount) {
+ int n;
+ for ( n=0; n<killList->addrCount; n++) {
+ if (killList->addrList[n])
+ free(killList->addrList[n]);
+ }
+ }
+ if (killList->addrList)
+ free(killList->addrList);
+ if (killList->name)
+ free(killList->name);
+ if (killList->inst)
+ free(killList->inst);
+ if (killList->realm)
+ free(killList->realm);
+ free(killList);
+ }
+
+ *ticketList = NULL;
+ return 0;
+}
+
+long
+not_an_API_LeashKRB4GetTickets(TICKETINFO FAR* ticketinfo,
+ TicketList** ticketList)
+{
+#ifdef NO_KRB4
+ return(KFAILURE);
+#else
+ // Puts tickets in a returned linklist - Can be used with many
+ // diff. controls
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ char buf[MAX_K_NAME_SZ+40];
+ LPSTR cp;
+ LPSTR functionName;
+ long expdate;
+ int k_errno;
+ CREDENTIALS c;
+ int newtickets = 0;
+ int open = 0;
+
+ TicketList* list = NULL;
+ if ( ticketinfo ) {
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal[0] = '\0';
+ }
+
+ // Since krb_get_tf_realm will return a ticket_file error,
+ // we will call tf_init and tf_close first to filter out
+ // things like no ticket file. Otherwise, the error that
+ // the user would see would be
+ // klist: can't find realm of ticket file: No ticket file (tf_util)
+ // instead of klist: No ticket file (tf_util)
+ if (ptf_init == NULL)
+ return(KSUCCESS);
+
+ com_addr();
+ err_context = (LPSTR)"tktf1";
+
+ // Open ticket file
+ if ((k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL)))
+ {
+ functionName = "ptf_init()";
+ goto cleanup;
+ }
+ // Close ticket file
+ (void) (*ptf_close)();
+
+ // We must find the realm of the ticket file here before calling
+ // tf_init because since the realm of the ticket file is not
+ // really stored in the principal section of the file, the
+ // routine we use must itself call tf_init and tf_close.
+
+ err_context = "tf realm";
+ if ((k_errno = (*pkrb_get_tf_realm)((*ptkt_string)(), prealm)) != KSUCCESS)
+ {
+ functionName = "pkrb_get_tf_realm()";
+ goto cleanup;
+ }
+
+ // Open ticket file
+ err_context = "tf init";
+ if (k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL))
+ {
+ functionName = "sptf_init()";
+ goto cleanup;
+ }
+
+ open = 1;
+ err_context = "tf pname";
+
+ // Get principal name and instance
+ if ((k_errno = (*ptf_get_pname)(pname)) || (k_errno = (*ptf_get_pinst)(pinst)))
+ {
+ functionName = "ptf_get_pname()";
+ goto cleanup;
+ }
+
+ // You may think that this is the obvious place to get the
+ // realm of the ticket file, but it can't be done here as the
+ // routine to do this must open the ticket file. This is why
+ // it was done before tf_init.
+ wsprintf((LPSTR)ticketinfo->principal,"%s%s%s%s%s", (LPSTR)pname,
+ (LPSTR)(pinst[0] ? "." : ""), (LPSTR)pinst,
+ (LPSTR)(prealm[0] ? "@" : ""), (LPSTR)prealm);
+
+ newtickets = NO_TICKETS;
+ err_context = "tf cred";
+
+ // Get KRB4 tickets
+ while ((k_errno = (*ptf_get_cred)(&c)) == KSUCCESS)
+ {
+ if (!list)
+ {
+ list = (TicketList*) calloc(1, sizeof(TicketList));
+ (*ticketList) = list;
+ }
+ else
+ {
+ list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
+ list = (TicketList*) list->next;
+ }
+
+ expdate = c.issue_date + c.lifetime * 5L * 60L;
+
+ if (!lstrcmp((LPSTR)c.service, (LPSTR)TICKET_GRANTING_TICKET) && !lstrcmp((LPSTR)c.instance, (LPSTR)prealm))
+ {
+ ticketinfo->issue_date = c.issue_date;
+ ticketinfo->lifetime = c.lifetime * 5L * 60L;
+ ticketinfo->renew_till = 0;
+ }
+
+ _tzset();
+ if ( ticketinfo->issue_date + ticketinfo->lifetime - time(0) <= 0L )
+ newtickets = EXPD_TICKETS;
+ else
+ newtickets = GOOD_TICKETS;
+
+ cp = (LPSTR)buf;
+ cp += wsprintf(cp, "%s ",
+ short_date(&c.issue_date));
+ wsprintf(cp, "%s %s%s%s%s%s",
+ short_date(&expdate),
+ c.service,
+ (c.instance[0] ? "." : ""),
+ c.instance,
+ (c.realm[0] ? "@" : ""),
+ c.realm);
+
+ list->theTicket = (char*) calloc(1, sizeof(buf));
+ if (!list->theTicket)
+ {
+ MessageBox(NULL, "Memory Error", "Error", MB_OK);
+ return ENOMEM;
+ }
+
+ strcpy(list->theTicket, buf);
+ list->name = NULL;
+ list->inst = NULL;
+ list->realm = NULL;
+ list->tktEncType = NULL;
+ list->keyEncType = NULL;
+ list->addrCount = 0;
+ list->addrList = NULL;
+
+ } // while
+ functionName = "not_an_API_LeashKRB4GetTickets()";
+
+cleanup:
+ if (ptf_close == NULL)
+ return(KSUCCESS);
+
+ if (open)
+ (*ptf_close)(); //close ticket file
+
+ if (k_errno == EOF)
+ k_errno = 0;
+
+ // XXX the if statement directly below was inserted to eliminate
+ // an error NO_TKT_FIL on Leash startup. The error occurs from an
+ // error number thrown from krb_get_tf_realm. We believe this
+ // change does not eliminate other errors, but it may.
+
+ if (k_errno == NO_TKT_FIL)
+ k_errno = 0;
+
+ ticketinfo->btickets = newtickets;
+
+ if (k_errno)
+ {
+ CHAR message[256];
+ CHAR errBuf[256];
+ LPCSTR errText;
+
+ if (!Lerror_message)
+ return -1;
+
+ errText = err_describe(errBuf, KRBERR(k_errno));
+
+ sprintf(message, "%s\n\n%s failed", errText, functionName);
+ MessageBox(NULL, message, "Kerberos Four",
+ MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
+ }
+ return k_errno;
+#endif
+}
+
+long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo)
+{
+#ifdef NO_KRB4
+ return(KFAILURE);
+#else
+ // Don't think this function will be used anymore - ADL 5-15-99
+ // Old fucntion to put tickets in a listbox control
+ // Use function "not_an_API_LeashKRB4GetTickets()" instead!
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ char buf[MAX_K_NAME_SZ+40];
+ LPSTR cp;
+ long expdate;
+ int k_errno;
+ CREDENTIALS c;
+ int newtickets = 0;
+ int open = 0;
+
+ /*
+ * Since krb_get_tf_realm will return a ticket_file error,
+ * we will call tf_init and tf_close first to filter out
+ * things like no ticket file. Otherwise, the error that
+ * the user would see would be
+ * klist: can't find realm of ticket file: No ticket file (tf_util)
+ * instead of
+ * klist: No ticket file (tf_util)
+ */
+ if (ptf_init == NULL)
+ return(KSUCCESS);
+
+ if (hlist)
+ {
+ SendMessage(hlist, WM_SETREDRAW, FALSE, 0L);
+ SendMessage(hlist, LB_RESETCONTENT, 0, 0L);
+ }
+ com_addr();
+ newtickets = NO_TICKETS;
+
+ err_context = (LPSTR)"tktf1";
+
+ /* Open ticket file */
+ if (k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL))
+ {
+ goto cleanup;
+ }
+ /* Close ticket file */
+ (void) (*ptf_close)();
+ /*
+ * We must find the realm of the ticket file here before calling
+ * tf_init because since the realm of the ticket file is not
+ * really stored in the principal section of the file, the
+ * routine we use must itself call tf_init and tf_close.
+ */
+ err_context = "tf realm";
+ if ((k_errno = (*pkrb_get_tf_realm)((*ptkt_string)(), prealm)) != KSUCCESS)
+ {
+ goto cleanup;
+ }
+ /* Open ticket file */
+ err_context = "tf init";
+ if (k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL))
+ {
+ goto cleanup;
+ }
+
+ open = 1;
+ err_context = "tf pname";
+ /* Get principal name and instance */
+ if ((k_errno = (*ptf_get_pname)(pname)) || (k_errno = (*ptf_get_pinst)(pinst)))
+ {
+ goto cleanup;
+ }
+
+ /*
+ * You may think that this is the obvious place to get the
+ * realm of the ticket file, but it can't be done here as the
+ * routine to do this must open the ticket file. This is why
+ * it was done before tf_init.
+ */
+
+ wsprintf((LPSTR)ticketinfo->principal,"%s%s%s%s%s", (LPSTR)pname,
+ (LPSTR)(pinst[0] ? "." : ""), (LPSTR)pinst,
+ (LPSTR)(prealm[0] ? "@" : ""), (LPSTR)prealm);
+ newtickets = GOOD_TICKETS;
+
+ err_context = "tf cred";
+ while ((k_errno = (*ptf_get_cred)(&c)) == KSUCCESS)
+ {
+ expdate = c.issue_date + c.lifetime * 5L * 60L;
+
+ if (!lstrcmp((LPSTR)c.service, (LPSTR)TICKET_GRANTING_TICKET) && !lstrcmp((LPSTR)c.instance, (LPSTR)prealm))
+ {
+ ticketinfo->issue_date = c.issue_date;
+ ticketinfo->lifetime = c.lifetime * 5L * 60L;
+ ticketinfo->renew_till = 0;
+ }
+
+ cp = (LPSTR)buf;
+ lstrcpy(cp, (LPSTR)short_date(&c.issue_date));
+ cp += lstrlen(cp);
+ wsprintf(cp,"\t%s\t%s%s%s%s%s",
+ (LPSTR)short_date(&expdate), (LPSTR)c.service,
+ (LPSTR)(c.instance[0] ? "." : ""),
+ (LPSTR)c.instance, (LPSTR)(c.realm[0] ? "@" : ""),
+ (LPSTR) c.realm);
+ if (hlist)
+ SendMessage(hlist, LB_ADDSTRING, 0, (LONG)(LPSTR)buf);
+ } /* WHILE */
+
+cleanup:
+
+ if (open)
+ (*ptf_close)(); /* close ticket file */
+
+ if (hlist)
+ {
+ SendMessage(hlist, WM_SETREDRAW, TRUE, 0L);
+ InvalidateRect(hlist, NULL, TRUE);
+ UpdateWindow(hlist);
+ }
+ if (k_errno == EOF)
+ k_errno = 0;
+
+ /* XXX the if statement directly below was inserted to eliminate
+ an error 20 on Leash startup. The error occurs from an error
+ number thrown from krb_get_tf_realm. We believe this change
+ does not eliminate other errors, but it may. */
+
+ if (k_errno == RET_NOTKT)
+ k_errno = 0;
+
+ ticketinfo->btickets = newtickets;
+ if (k_errno != 0)
+ return KRBERR(k_errno);
+ return 0;
+#endif
+}
+
+
+// This function can be used to set the help file that will be
+// referenced the DLL's PasswordProcDLL function and err_describe
+// function. Returns true if the help file has been set to the
+// argument or the environment variable KERB_HELP. Returns FALSE if
+// the default helpfile as defined in by HELPFILE in lsh_pwd.h is
+// used.
+BOOL Leash_set_help_file( char *szHelpFile )
+{
+ char tmpHelpFile[256];
+ BOOL ret = 0;
+
+ if( szHelpFile == NULL ){
+ GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile));
+ } else {
+ strcpy( KRB_HelpFile, szHelpFile );
+ ret++;
+ }
+
+ if( !ret && tmpHelpFile[0] ){
+ strcpy( KRB_HelpFile, tmpHelpFile );
+ ret++;
+ }
+
+ if( !ret){
+ strcpy( KRB_HelpFile, HELPFILE );
+ }
+
+ return(ret);
+}
+
+
+
+LPSTR Leash_get_help_file(void)
+{
+ return( KRB_HelpFile);
+}
+
+#if 0
+/**************************************/
+/* LeashKrb4ErrorMessage(): */
+/**************************************/
+long
+LeashKrb4ErrorMessage(LONG rc, LPCSTR FailedFunctionName)
+{
+ // At this time the Leashw32.dll. takes care of all error messages. We
+ // may want to add a flag latter on so the .exe can handle it's own
+ // errors.
+
+ CHAR message[256];
+ CHAR errBuf[256];
+ LPCSTR errText;
+
+ if (!Lerror_message)
+ return -1;
+
+ errText = err_describe(errBuf, rc);
+
+ sprintf(message, "%s\n\n%s failed", errText, FailedFunctionName);
+ MessageBox(NULL, message, "Kerberos Four", MB_OK |
+ MB_ICONERROR |
+ MB_TASKMODAL |
+ MB_SETFOREGROUND);
+ return rc;
+}
+#endif
+
+int
+Leash_debug(
+ int class,
+ int priority,
+ char* fmt, ...
+ )
+{
+
+ return 0;
+}
+
+
+static int
+get_profile_file(LPSTR confname, UINT szConfname)
+{
+ char **configFile = NULL;
+ if (hKrb5) {
+ if (pkrb5_get_default_config_files(&configFile))
+ {
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ return FALSE;
+ }
+
+ *confname = 0;
+
+ if (configFile)
+ {
+ strncpy(confname, *configFile, szConfname);
+ confname[szConfname-1] = '\0';
+ pkrb5_free_config_files(configFile);
+ }
+ }
+
+ if (!*confname)
+ {
+ GetWindowsDirectory(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
+ confname[szConfname-1] = '\0';
+ }
+
+ return FALSE;
+}
+
+static const char *const conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static const char *const conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+int
+config_boolean_to_int(const char *s)
+{
+ const char *const *p;
+
+ for(p=conf_yes; *p; p++) {
+ if (!strcasecmp(*p,s))
+ return 1;
+ }
+
+ for(p=conf_no; *p; p++) {
+ if (!strcasecmp(*p,s))
+ return 0;
+ }
+
+ /* Default to "no" */
+ return 0;
+}
+
+/*
+ * Leash_get_default_lifetime:
+ *
+ * This function is used to get the default ticket lifetime for this
+ * process in minutes. A return value of 0 indicates no setting or
+ * "default" setting obtained.
+ *
+ * Here is where we look in order:
+ *
+ * - LIFETIME environment variable
+ * - HKCU\Software\MIT\Leash,lifetime
+ * - HKLM\Software\MIT\Leash,lifetime
+ * - string resource in the leash DLL
+ */
+
+BOOL
+get_DWORD_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ DWORD * result
+ )
+{
+ HKEY hKey;
+ DWORD dwCount;
+ LONG rc;
+
+ rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
+ if (rc)
+ return FALSE;
+
+ dwCount = sizeof(DWORD);
+ rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount);
+ RegCloseKey(hKey);
+
+ return rc?FALSE:TRUE;
+}
+
+BOOL
+get_STRING_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ char * outbuf,
+ DWORD outlen
+ )
+{
+ HKEY hKey;
+ DWORD dwCount;
+ LONG rc;
+
+ if (!outbuf || outlen == 0)
+ return FALSE;
+
+ rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
+ if (rc)
+ return FALSE;
+
+ dwCount = outlen;
+ rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) outbuf, &dwCount);
+ RegCloseKey(hKey);
+
+ return rc?FALSE:TRUE;
+}
+
+static
+BOOL
+get_default_lifetime_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_LIFETIME,
+ result);
+}
+
+DWORD
+Leash_reset_default_lifetime(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_lifetime(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_lifetime(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+
+ if (GetEnvironmentVariable("LIFETIME",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+
+ if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ if ( hKrb5 ) {
+ CHAR confname[MAX_PATH];
+
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ long retval;
+
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ if (!pprofile_init(filenames, &profile)) {
+ char * value = NULL;
+
+ retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value);
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+
+ if (retval == KRB5_DELTAT_BADFORMAT) {
+ /* Historically some sites use relations of
+ the form 'ticket_lifetime = 24000' where
+ the unit is left out but is assumed to be
+ seconds. Then there are other sites which
+ use the form 'ticket_lifetime = 600' where
+ the unit is assumed to be minutes. While
+ these are technically wrong (a unit needs
+ to be specified), we try to accomodate for
+ this using the safe assumption that the
+ unit is seconds and tack an 's' to the end
+ and see if that works. */
+
+ /* Of course, Leash is one of the platforms
+ that historically assumed no units and minutes
+ so this change is going to break some people
+ but its better to be consistent. */
+ size_t cch;
+ char buf[256];
+
+ do {
+ cch = strlen(value) + 2; /* NUL and new 's' */
+ if (cch > sizeof(buf))
+ break;
+
+ strcpy(buf, value);
+ strcat(buf, "s");
+
+ retval = pkrb5_string_to_deltat(buf, &d);
+
+ if (retval == 0) {
+ result = d / 60;
+ }
+ } while(0);
+ } else if (retval == 0) {
+ result = d / 60;
+ }
+
+ pprofile_release_string(value);
+ }
+ pprofile_release(profile);
+ /* value has been released but we can still use a check for
+ * non-NULL to see if we were able to read a value.
+ */
+ if (retval == 0 && value)
+ return result;
+ }
+ }
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char lifetime[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE,
+ lifetime, sizeof(lifetime)))
+ {
+ lifetime[sizeof(lifetime) - 1] = 0;
+ return atoi(lifetime);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_renew_till_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_RENEW_TILL,
+ result);
+}
+
+DWORD
+Leash_reset_default_renew_till(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_renew_till(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_renew_till(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ if ( hKrb5 ) {
+ CHAR confname[MAX_PATH];
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ int value=0;
+ long retval;
+ filenames[0] = confname;
+ filenames[1] = NULL;
+
+ if (!pprofile_init(filenames, &profile)) {
+ char * value = NULL;
+
+ retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value);
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+ if (retval == KRB5_DELTAT_BADFORMAT) {
+ /* Historically some sites use relations of
+ the form 'ticket_lifetime = 24000' where
+ the unit is left out but is assumed to be
+ seconds. Then there are other sites which
+ use the form 'ticket_lifetime = 600' where
+ the unit is assumed to be minutes. While
+ these are technically wrong (a unit needs
+ to be specified), we try to accomodate for
+ this using the safe assumption that the
+ unit is seconds and tack an 's' to the end
+ and see if that works. */
+
+ /* Of course, Leash is one of the platforms
+ that historically assumed no units and minutes
+ so this change is going to break some people
+ but its better to be consistent. */
+ size_t cch;
+ char buf[256];
+ do {
+ cch = strlen(value) + 2; /* NUL and new 's' */
+ if (cch > sizeof(buf))
+ break;
+
+ strcpy(buf, value);
+ strcat(buf, "s");
+
+ retval = pkrb5_string_to_deltat(buf, &d);
+ if (retval == 0) {
+ result = d / 60;
+ }
+ } while(0);
+ } else if (retval == 0) {
+ result = d / 60;
+ }
+ pprofile_release_string(value);
+ }
+ pprofile_release(profile);
+ /* value has been released but we can still use a check for
+ * non-NULL to see if we were able to read a value.
+ */
+ if (retval == 0 && value)
+ return result;
+
+ pprofile_release(profile);
+ }
+ }
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char renew_till[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL,
+ renew_till, sizeof(renew_till)))
+ {
+ renew_till[sizeof(renew_till) - 1] = 0;
+ return atoi(renew_till);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_forwardable_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_FORWARDABLE,
+ result);
+}
+
+DWORD
+Leash_reset_default_forwardable(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_forwardable(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_forwardable(
+ )
+{
+ HMODULE hmLeash;
+
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ if ( hKrb5 ) {
+ CHAR confname[MAX_PATH];
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ char *value=0;
+ long retval;
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ if (!pprofile_init(filenames, &profile)) {
+ retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value);
+ if ( value ) {
+ result = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ pprofile_release(profile);
+ return result;
+ }
+ pprofile_release(profile);
+ }
+ }
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char forwardable[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD,
+ forwardable, sizeof(forwardable)))
+ {
+ forwardable[sizeof(forwardable) - 1] = 0;
+ return atoi(forwardable);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_renewable_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_RENEWABLE,
+ result);
+}
+
+DWORD
+Leash_reset_default_renewable(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_renewable(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_renewable(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ if ( hKrb5 ) {
+ CHAR confname[MAX_PATH];
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ char *value=0;
+ long retval;
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ if (!pprofile_init(filenames, &profile)) {
+ retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value);
+ if ( value ) {
+ result = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ pprofile_release(profile);
+ return result;
+ }
+ pprofile_release(profile);
+ }
+ }
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char renewable[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW,
+ renewable, sizeof(renewable)))
+ {
+ renewable[sizeof(renewable) - 1] = 0;
+ return atoi(renewable);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_noaddresses_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_NOADDRESSES,
+ result);
+}
+
+DWORD
+Leash_reset_default_noaddresses(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_noaddresses(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_noaddresses(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if ( hKrb5 ) {
+ // if the profile file cannot be opened then the value will be true
+ // if the noaddresses name cannot be found then the value will be true
+ // if true in the library, we can't alter it by other means
+ CHAR confname[MAX_PATH];
+ result = 1;
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ char *value=0;
+ long retval;
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ if (!pprofile_init(filenames, &profile)) {
+ retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
+ if ( value ) {
+ result = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ }
+ pprofile_release(profile);
+ }
+ }
+
+ if ( result )
+ return 1;
+ }
+
+ // The library default is false, check other locations
+
+ if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char noaddresses[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS,
+ noaddresses, sizeof(noaddresses)))
+ {
+ noaddresses[sizeof(noaddresses) - 1] = 0;
+ }
+ }
+ return 1;
+}
+
+static
+BOOL
+get_default_proxiable_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_PROXIABLE,
+ result);
+}
+
+DWORD
+Leash_reset_default_proxiable(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_proxiable(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_proxiable(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ if ( hKrb5 ) {
+ CHAR confname[MAX_PATH];
+ if (!get_profile_file(confname, sizeof(confname)))
+ {
+ profile_t profile;
+ const char *filenames[2];
+ char *value=0;
+ long retval;
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ if (!pprofile_init(filenames, &profile)) {
+ retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value);
+ if ( value ) {
+ result = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ pprofile_release(profile);
+ return result;
+ }
+ pprofile_release(profile);
+ }
+ }
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char proxiable[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE,
+ proxiable, sizeof(proxiable)))
+ {
+ proxiable[sizeof(proxiable) - 1] = 0;
+ return atoi(proxiable);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_publicip_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_PUBLICIP,
+ result);
+}
+
+DWORD
+Leash_reset_default_publicip(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_publicip(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_publicip(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char publicip[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP,
+ publicip, sizeof(publicip)))
+ {
+ publicip[sizeof(publicip) - 1] = 0;
+ return atoi(publicip);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_use_krb4_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_USEKRB4,
+ result);
+}
+
+DWORD
+Leash_reset_default_use_krb4(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_USEKRB4);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_use_krb4(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_USEKRB4, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_use_krb4(
+ )
+{
+ HMODULE hmLeash;
+ char env[32];
+ DWORD result;
+
+ if(GetEnvironmentVariable("USEKRB4",env,sizeof(env)))
+ {
+ return atoi(env);
+ }
+
+ if (get_default_use_krb4_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_use_krb4_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_TICKET_USEKRB4,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 1; /* use krb4 unless otherwise specified */
+}
+
+static
+BOOL
+get_hide_kinit_options_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_KINIT_OPT,
+ result);
+}
+
+DWORD
+Leash_reset_hide_kinit_options(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_hide_kinit_options(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_hide_kinit_options(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 0; /* hide unless otherwise indicated */
+}
+
+
+
+static
+BOOL
+get_default_life_min_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_LIFE_MIN,
+ result);
+}
+
+DWORD
+Leash_reset_default_life_min(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_life_min(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_life_min(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 5; /* 5 minutes */
+}
+
+static
+BOOL
+get_default_life_max_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_LIFE_MAX,
+ result);
+}
+
+DWORD
+Leash_reset_default_life_max(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_life_max(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_life_max(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 1440;
+}
+
+static
+BOOL
+get_default_renew_min_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_RENEW_MIN,
+ result);
+}
+
+DWORD
+Leash_reset_default_renew_min(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_renew_min(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_renew_min(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 600; /* 10 hours */
+}
+
+static
+BOOL
+get_default_renew_max_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_RENEW_MAX,
+ result);
+}
+
+DWORD
+Leash_reset_default_renew_max(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_renew_max(
+ DWORD minutes
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD,
+ (LPBYTE) &minutes, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_renew_max(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char use_krb4[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX,
+ use_krb4, sizeof(use_krb4)))
+ {
+ use_krb4[sizeof(use_krb4) - 1] = 0;
+ return atoi(use_krb4);
+ }
+ }
+ return 60 * 24 * 30;
+}
+
+static
+BOOL
+get_lock_file_locations_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_LOCK_LOCATION,
+ result);
+}
+
+DWORD
+Leash_reset_lock_file_locations(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_lock_file_locations(
+ DWORD onoff
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION, 0, REG_DWORD,
+ (LPBYTE) &onoff, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_lock_file_locations(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_lock_file_locations_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_lock_file_locations_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char lock_file_locations[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LOCK_LOCATION,
+ lock_file_locations, sizeof(lock_file_locations)))
+ {
+ lock_file_locations[sizeof(lock_file_locations) - 1] = 0;
+ return atoi(lock_file_locations);
+ }
+ }
+ return 0;
+}
+
+static
+BOOL
+get_default_uppercaserealm_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_SETTINGS_REGISTRY_KEY_NAME,
+ LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM,
+ result);
+}
+
+DWORD
+Leash_reset_default_uppercaserealm(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_uppercaserealm(
+ DWORD onoff
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD,
+ (LPBYTE) &onoff, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_uppercaserealm(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char uppercaserealm[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM,
+ uppercaserealm, sizeof(uppercaserealm)))
+ {
+ uppercaserealm[sizeof(uppercaserealm) - 1] = 0;
+ return atoi(uppercaserealm);
+ }
+ }
+ return 1;
+}
+
+static
+BOOL
+get_default_mslsa_import_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_SETTINGS_REGISTRY_KEY_NAME,
+ LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT,
+ result);
+}
+
+DWORD
+Leash_reset_default_mslsa_import(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_mslsa_import(
+ DWORD onoffmatch
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT, 0, REG_DWORD,
+ (LPBYTE) &onoffmatch, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_mslsa_import(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_mslsa_import_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_mslsa_import_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char mslsa_import[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_MSLSA_IMPORT,
+ mslsa_import, sizeof(mslsa_import)))
+ {
+ mslsa_import[sizeof(mslsa_import) - 1] = 0;
+ return atoi(mslsa_import);
+ }
+ }
+ return 2; /* import only when mslsa realm matches default */
+}
+
+
+static
+BOOL
+get_default_preserve_kinit_settings_from_registry(
+ HKEY hBaseKey,
+ DWORD * result
+ )
+{
+ return get_DWORD_from_registry(hBaseKey,
+ LEASH_REGISTRY_KEY_NAME,
+ LEASH_REGISTRY_VALUE_PRESERVE_KINIT,
+ result);
+}
+
+DWORD
+Leash_reset_default_preserve_kinit_settings(
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
+ if (rc)
+ return rc;
+
+ rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT);
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_set_default_preserve_kinit_settings(
+ DWORD onoff
+ )
+{
+ HKEY hKey;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
+ 0, 0, KEY_WRITE, 0, &hKey, 0);
+ if (rc)
+ return rc;
+
+ rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD,
+ (LPBYTE) &onoff, sizeof(DWORD));
+ RegCloseKey(hKey);
+
+ return rc;
+}
+
+DWORD
+Leash_get_default_preserve_kinit_settings(
+ )
+{
+ HMODULE hmLeash;
+ DWORD result;
+
+ if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) ||
+ get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result))
+ {
+ return result;
+ }
+
+ hmLeash = GetModuleHandle(LEASH_DLL);
+ if (hmLeash)
+ {
+ char preserve_kinit_settings[80];
+ if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT,
+ preserve_kinit_settings, sizeof(preserve_kinit_settings)))
+ {
+ preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0;
+ return atoi(preserve_kinit_settings);
+ }
+ }
+ return 1;
+}
+
+void
+Leash_reset_defaults(void)
+{
+ Leash_reset_default_lifetime();
+ Leash_reset_default_renew_till();
+ Leash_reset_default_renewable();
+ Leash_reset_default_forwardable();
+ Leash_reset_default_noaddresses();
+ Leash_reset_default_proxiable();
+ Leash_reset_default_publicip();
+ Leash_reset_default_use_krb4();
+ Leash_reset_hide_kinit_options();
+ Leash_reset_default_life_min();
+ Leash_reset_default_life_max();
+ Leash_reset_default_renew_min();
+ Leash_reset_default_renew_max();
+ Leash_reset_default_uppercaserealm();
+ Leash_reset_default_mslsa_import();
+ Leash_reset_default_preserve_kinit_settings();
+}
+
+static BOOL CALLBACK
+EnumChildProc(HWND hwnd, LPARAM lParam)
+{
+ HWND * h = (HWND *)lParam;
+ *h = hwnd;
+ return FALSE;
+}
+
+
+static HWND
+FindFirstChildWindow(HWND parent)
+{
+ HWND hFirstChild = 0;
+ EnumChildWindows(parent, EnumChildProc, (LPARAM) &hFirstChild);
+ return hFirstChild;
+}
+
+static int
+acquire_tkt_send_msg(krb5_context ctx, const char * title,
+ const char * ccachename,
+ krb5_principal desiredKrb5Principal,
+ const char * out_ccname, int out_cclen)
+{
+ krb5_error_code err;
+ HWND hNetIdMgr;
+ HWND hForeground;
+ char *desiredName = 0;
+ char *desiredRealm = 0;
+
+ /* do we want a specific client principal? */
+ if (desiredKrb5Principal != NULL) {
+ err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName);
+ if (!err) {
+ char * p;
+ for (p = desiredName; *p && *p != '@'; p++);
+ if ( *p == '@' ) {
+ *p = '\0';
+ desiredRealm = ++p;
+ }
+ }
+ }
+
+ hForeground = GetForegroundWindow();
+ hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
+ if (hNetIdMgr != NULL) {
+ HANDLE hMap;
+ DWORD tid = GetCurrentThreadId();
+ char mapname[256];
+ NETID_DLGINFO *dlginfo;
+
+ sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
+
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+ 0, 4096, mapname);
+ if (hMap == NULL) {
+ return -1;
+ } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
+ 0, 0, 4096, NULL);
+ if (dlginfo == NULL) {
+ CloseHandle(hMap);
+ return -1;
+ }
+
+ memset(dlginfo, 0, sizeof(NETID_DLGINFO));
+
+ dlginfo->size = sizeof(NETID_DLGINFO);
+ dlginfo->dlgtype = NETID_DLGTYPE_TGT;
+ dlginfo->in.use_defaults = 1;
+
+ if (title) {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ title, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
+ char mytitle[NETID_TITLE_SZ];
+ sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ mytitle, -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ } else {
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ "Obtain Kerberos TGT", -1,
+ dlginfo->in.title, NETID_TITLE_SZ);
+ }
+ if (desiredName)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredName, -1,
+ dlginfo->in.username, NETID_USERNAME_SZ);
+ if (desiredRealm)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ desiredRealm, -1,
+ dlginfo->in.realm, NETID_REALM_SZ);
+ if (ccachename)
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ ccachename, -1,
+ dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
+ SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
+
+ if (out_ccname && out_cclen > 0) {
+ WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1,
+ out_ccname, out_cclen, NULL, NULL);
+ }
+
+ UnmapViewOfFile(dlginfo);
+ CloseHandle(hMap);
+ } else {
+ HGLOBAL hData;
+ HWND hLeash = FindWindow("LEASH.0WNDCLASS", NULL);
+ hLeash = FindFirstChildWindow(hLeash);
+
+ /* construct a marshalling of data
+ * <title><principal><realm><ccache>
+ * then send to Leash
+ */
+
+ hData = GlobalAlloc( GHND, 4096 );
+ SetForegroundWindow(hLeash);
+ if ( hData && hLeash ) {
+ char * strs = GlobalLock(hData);
+ if ( strs ) {
+ if (title)
+ strcpy(strs, title);
+ else if (desiredName)
+ sprintf(strs, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
+ else
+ strcpy(strs, "Obtain Kerberos TGT");
+ strs += strlen(strs) + 1;
+ if ( desiredName ) {
+ strcpy(strs, desiredName);
+ strs += strlen(strs) + 1;
+ if (desiredRealm) {
+ strcpy(strs, desiredRealm);
+ strs += strlen(strs) + 1;
+ }
+ } else {
+ *strs = 0;
+ strs++;
+ *strs = 0;
+ strs++;
+ }
+
+ /* Append the ccache name */
+ if (ccachename)
+ strcpy(strs, ccachename);
+ else
+ *strs = 0;
+ strs++;
+
+ GlobalUnlock( hData );
+ SendMessage(hLeash, 32810, 0, (LPARAM) hData);
+ }
+ }
+ GlobalFree( hData );
+ }
+
+ SetForegroundWindow(hForeground);
+ if (desiredName != NULL)
+ pkrb5_free_unparsed_name(ctx, desiredName);
+
+ return 0;
+}
+
+static void
+acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
+{
+ TicketList *list = NULL;
+ TICKETINFO ticketinfo;
+ krb5_context ctx;
+ DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
+ DWORD gle;
+ char ccachename[272]="";
+ char loginenv[16];
+ BOOL prompt;
+
+ GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
+ prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
+
+ ctx = context;
+
+ SetLastError(0);
+ GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
+ gle = GetLastError();
+ if ( (gle == ERROR_ENVVAR_NOT_FOUND) && context ) {
+ SetEnvironmentVariable("KRB5CCNAME", pkrb5_cc_default_name(ctx));
+ GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
+ }
+
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
+ not_an_API_LeashFreeTicketList(&list);
+
+ if ( ticketinfo.btickets != GOOD_TICKETS &&
+ dwMsLsaImport && Leash_importable() ) {
+ // We have the option of importing tickets from the MSLSA
+ // but should we? Do the tickets in the MSLSA cache belong
+ // to the default realm used by Leash? Does the default
+ // ccache name specify a principal name? Only import if we
+ // aren't going to break the default identity as specified
+ // by the user in Network Identity Manager.
+ int import = 0;
+ BOOL isCCPrinc;
+
+ /* Determine if the default ccachename is principal name. If so, don't
+ * import the MSLSA: credentials into it unless the names match.
+ */
+ isCCPrinc = (strncmp("API:",ccachename, 4) == 0 && strchr(ccachename, '@'));
+
+ if ( dwMsLsaImport == 1 && !isCCPrinc ) { /* always import */
+ import = 1;
+ } else if ( dwMsLsaImport ) { /* import when realms match */
+ krb5_error_code code;
+ krb5_ccache mslsa_ccache=NULL;
+ krb5_principal princ = NULL;
+ char *mslsa_principal = NULL;
+ char ms_realm[128] = "", *def_realm = NULL, *r;
+ int i;
+
+ if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
+ goto cleanup;
+
+ if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
+ goto cleanup;
+
+ for ( r=ms_realm, i=0; i<krb5_princ_realm(ctx, princ)->length; r++, i++ ) {
+ *r = krb5_princ_realm(ctx, princ)->data[i];
+ }
+ *r = '\0';
+
+ if (code = pkrb5_get_default_realm(ctx, &def_realm))
+ goto cleanup;
+
+ if (code = pkrb5_unparse_name(ctx, princ, &mslsa_principal))
+ goto cleanup;
+
+ import = (!isCCPrinc && !strcmp(def_realm, ms_realm)) ||
+ (isCCPrinc && !strcmp(&ccachename[4], mslsa_principal));
+
+ cleanup:
+ if (mslsa_principal)
+ pkrb5_free_unparsed_name(ctx, mslsa_principal);
+
+ if (def_realm)
+ pkrb5_free_default_realm(ctx, def_realm);
+
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+
+ if (mslsa_ccache)
+ pkrb5_cc_close(ctx, mslsa_ccache);
+ }
+
+ if ( import ) {
+ Leash_import();
+
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
+ not_an_API_LeashFreeTicketList(&list);
+ }
+ }
+
+ if ( prompt && ticketinfo.btickets != GOOD_TICKETS ) {
+ acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen);
+ } else if (ccachename[0] && ccname) {
+ strncpy(ccname, ccachename, cclen);
+ ccname[cclen-1] = '\0';
+ }
+
+ if ( ccname && strcmp(ccachename,ccname) ) {
+ SetEnvironmentVariable("KRB5CCNAME",ccname);
+ }
+
+ if ( !context )
+ pkrb5_free_context(ctx);
+}
+
+
+static void
+acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
+ char * ccname, int cclen)
+{
+ TicketList *list = NULL;
+ TICKETINFO ticketinfo;
+ krb5_context ctx;
+ DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
+ DWORD gle;
+ char ccachename[272]="";
+ char loginenv[16];
+ BOOL prompt;
+ char *name = NULL;
+
+ GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
+ prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
+
+ ctx = context;
+
+ SetLastError(0);
+ GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
+ gle = GetLastError();
+ if ( (gle == ERROR_ENVVAR_NOT_FOUND) && context ) {
+ SetEnvironmentVariable("KRB5CCNAME", pkrb5_cc_default_name(ctx));
+ GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
+ }
+
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
+ not_an_API_LeashFreeTicketList(&list);
+
+ pkrb5_unparse_name(ctx, desiredPrincipal, &name);
+
+ if ( ticketinfo.btickets != GOOD_TICKETS &&
+ dwMsLsaImport && Leash_importable() ) {
+ // We have the option of importing tickets from the MSLSA
+ // but should we? Does the MSLSA principal match the requested
+ // principal? If not, there is no benefit to importing.
+ int import = 0;
+ krb5_error_code code;
+ krb5_ccache mslsa_ccache=NULL;
+ krb5_principal princ = NULL;
+
+ if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
+ goto cleanup;
+
+ if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
+ goto cleanup;
+
+ import = pkrb5_principal_compare(ctx, desiredPrincipal, princ);
+
+ cleanup:
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+
+ if (mslsa_ccache)
+ pkrb5_cc_close(ctx, mslsa_ccache);
+
+
+ if ( import ) {
+ /* Construct a new default ccache name into which the MSLSA:
+ * credentials can be imported, set the default ccache to that
+ * ccache, and then only import if that ccache does not already
+ * contain valid tickets */
+ sprintf(ccachename, "API:%s", name);
+
+ SetEnvironmentVariable("KRB5CCNAME", ccachename);
+
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
+ not_an_API_LeashFreeTicketList(&list);
+
+ if (ticketinfo.btickets != GOOD_TICKETS) {
+ Leash_import();
+
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
+ not_an_API_LeashFreeTicketList(&list);
+ }
+ }
+ }
+
+ if (prompt) {
+ if (ticketinfo.btickets != GOOD_TICKETS || strcmp(name,ticketinfo.principal)) {
+ acquire_tkt_send_msg(ctx, NULL, ccachename, desiredPrincipal, ccname, cclen);
+ } else if (ccachename[0] && ccname) {
+ strncpy(ccname, ccachename, cclen);
+ ccname[cclen-1] = '\0';
+ }
+ }
+
+ if ( ccname && strcmp(ccachename,ccname) ) {
+ SetEnvironmentVariable("KRB5CCNAME",ccname);
+ }
+
+
+ if (name)
+ pkrb5_free_unparsed_name(ctx, name);
+
+ if ( !context )
+ pkrb5_free_context(ctx);
+}
+
+
+static int
+leash_int_get_princ_expiration_time(krb5_context ctx, krb5_ccache cc,
+ krb5_principal desiredPrincipal,
+ krb5_timestamp * pexpiration)
+{
+ krb5_principal principal = 0;
+ char * princ_name = NULL;
+ char * desired_name = NULL;
+ krb5_creds creds;
+ krb5_error_code code, code2;
+ krb5_error_code cc_code;
+ krb5_cc_cursor cur;
+ krb5_timestamp now, expiration = 0;
+
+ int rv = -1;
+
+ if (!ctx || !cc || !desiredPrincipal || !pexpiration)
+ return -1;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &principal);
+ if ( code )
+ return -1;
+
+
+ code = pkrb5_unparse_name(ctx, desiredPrincipal, &desired_name);
+ code2 = pkrb5_unparse_name(ctx, principal, &princ_name);
+
+ /* compare principal to ident. */
+ if ( code || !princ_name || code2 || !desired_name ||
+ strcmp(princ_name, desired_name) ) {
+ if (princ_name)
+ pkrb5_free_unparsed_name(ctx, princ_name);
+ if (desired_name)
+ pkrb5_free_unparsed_name(ctx, desired_name);
+ pkrb5_free_principal(ctx, principal);
+ return -1;
+ }
+
+ pkrb5_free_unparsed_name(ctx, princ_name);
+ pkrb5_free_unparsed_name(ctx, desired_name);
+ pkrb5_free_principal(ctx, principal);
+
+ code = pkrb5_timeofday(ctx, &now);
+
+ if (code)
+ return -1;
+
+ cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);
+
+ while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
+ krb5_data * c0 = krb5_princ_name(ctx, creds.server);
+ krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1);
+ krb5_data * r = krb5_princ_realm(ctx, creds.server);
+
+ if ( c0 && c1 && r && c1->length == r->length &&
+ !strncmp(c1->data,r->data,r->length) &&
+ !strncmp("krbtgt",c0->data,c0->length) ) {
+
+ /* we have a TGT, check for the expiration time.
+ * if it is valid and renewable, use the renew time
+ */
+
+ if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
+ creds.times.starttime < now && creds.times.endtime > now) {
+ expiration = creds.times.endtime;
+
+ if ((creds.ticket_flags & TKT_FLG_RENEWABLE) &&
+ (creds.times.renew_till > creds.times.endtime)) {
+ expiration = creds.times.renew_till;
+ }
+ }
+ }
+ }
+
+ if (cc_code == KRB5_CC_END) {
+ cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
+ rv = 0;
+ *pexpiration = expiration;
+ }
+
+ return rv;
+}
+
+/* returns 0 on success */
+static int
+leash_int_find_ccache_for_princ(krb5_context ctx, krb5_principal princ,
+ char * buffer, int * pcbbuf)
+{
+ krb5_ccache cache = 0;
+ krb5_error_code code;
+ apiCB * cc_ctx = 0;
+ struct _infoNC ** pNCi = NULL;
+ int i;
+ krb5_timestamp expiration = 0;
+ krb5_timestamp best_match_expiration = 0;
+ char best_match_ccname[256] = "";
+ DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
+
+ if (!buffer || !pcbbuf)
+ return -1;
+
+ code = cc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
+ if (code)
+ goto _exit;
+
+ code = cc_get_NC_info(cc_ctx, &pNCi);
+ if (code)
+ goto _exit;
+
+ for(i=0; pNCi[i]; i++) {
+ if (pNCi[i]->vers != CC_CRED_V5)
+ continue;
+
+ code = pkrb5_cc_resolve(ctx, pNCi[i]->name, &cache);
+ if (code)
+ continue;
+
+ /* need a function to check the cache for the identity
+ * and determine if it has valid tickets. If it has
+ * the right identity and valid tickets, store the
+ * expiration time and the cache name. If it has the
+ * right identity but no valid tickets, store the ccache
+ * name and an expiration time of zero. if it does not
+ * have the right identity don't save the name.
+ *
+ * Keep searching to find the best cache available.
+ */
+
+ if (!leash_int_get_princ_expiration_time(ctx, cache, princ,
+ &expiration)) {
+ if ( expiration > best_match_expiration ) {
+ best_match_expiration = expiration;
+ strncpy(best_match_ccname, "API:",
+ sizeof(best_match_ccname));
+ strncat(best_match_ccname, pNCi[i]->name,
+ sizeof(best_match_ccname));
+ best_match_ccname[sizeof(best_match_ccname)-1] = '\0';
+ expiration = 0;
+ }
+ }
+
+ if(ctx != NULL && cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+ cache = 0;
+ }
+
+ if (dwMsLsaImport) {
+ code = pkrb5_cc_resolve(ctx, "MSLSA:", &cache);
+ if (code == 0 && cache) {
+ if (!leash_int_get_princ_expiration_time(ctx, cache, princ,
+ &expiration)) {
+ if ( expiration > best_match_expiration ) {
+ best_match_expiration = expiration;
+ strcpy(best_match_ccname, "MSLSA:");
+ expiration = 0;
+ }
+ }
+ }
+ }
+
+ if (ctx != NULL && cache != NULL)
+ pkrb5_cc_close(ctx, cache);
+
+ cache = 0;
+
+ _exit:
+ if (pNCi)
+ cc_free_NC_info(cc_ctx, &pNCi);
+
+ if (cc_ctx)
+ cc_shutdown(&cc_ctx);
+
+ if (best_match_ccname[0]) {
+ strncpy(buffer, best_match_ccname, *pcbbuf);
+ buffer[*pcbbuf-1]='\0';
+
+ *pcbbuf = strlen(buffer) + 1;
+ return 0;
+ }
+
+ return -1;
+}
+
+void FAR
+not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,
+ krb5_principal desiredKrb5Principal,
+ char * ccname, int cclen)
+{
+ char *desiredName = 0;
+ char *desiredRealm = 0;
+ TicketList *list = NULL;
+ char ccachename[272]="";
+
+ if (!desiredKrb5Principal) {
+ acquire_tkt_no_princ(context, ccname, cclen);
+ } else {
+ if (leash_int_find_ccache_for_princ(context, desiredKrb5Principal, ccname, &cclen))
+ acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen);
+ }
+ return;
+}
diff --git a/src/windows/leashdll/registry.c b/src/windows/leashdll/registry.c
new file mode 100644
index 0000000000..7113d056e0
--- /dev/null
+++ b/src/windows/leashdll/registry.c
@@ -0,0 +1,105 @@
+#include <windows.h>
+#include "leash-int.h"
+
+static
+LONG
+write_registry_setting_ex(
+ HKEY hRoot,
+ char* setting,
+ DWORD type,
+ void* buffer,
+ size_t size
+ )
+{
+ HKEY hKey = 0;
+ LONG rc = 0;
+
+ if (rc = RegCreateKeyEx(hRoot, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, 0, 0,
+ KEY_ALL_ACCESS, 0, &hKey, 0))
+ goto cleanup;
+
+ rc = RegSetValueEx(hKey, setting, 0, type, (LPBYTE)buffer, size);
+ cleanup:
+ if (hKey)
+ RegCloseKey(hKey);
+ return rc;
+}
+
+LONG
+write_registry_setting(
+ char* setting,
+ DWORD type,
+ void* buffer,
+ size_t size
+ )
+{
+ return write_registry_setting_ex(HKEY_CURRENT_USER,
+ setting,
+ type,
+ buffer,
+ size);
+}
+
+static
+LONG
+read_registry_setting_ex(
+ HKEY hRoot,
+ char* setting,
+ void* buffer,
+ size_t size
+ )
+{
+ HKEY hKey = 0;
+ LONG rc = 0;
+ DWORD dwType;
+ DWORD dwCount;
+
+ if (rc = RegOpenKeyEx(hRoot,
+ LEASH_SETTINGS_REGISTRY_KEY_NAME,
+ 0, KEY_QUERY_VALUE, &hKey))
+ goto cleanup;
+
+ memset(buffer, 0, size);
+ dwCount = size;
+ rc = RegQueryValueEx(hKey, setting, NULL, &dwType, (LPBYTE)buffer,
+ &dwCount);
+ cleanup:
+ if (hKey)
+ RegCloseKey(hKey);
+ return rc;
+}
+
+LONG
+read_registry_setting_user(
+ char* setting,
+ void* buffer,
+ size_t size
+ )
+{
+ return read_registry_setting_ex(HKEY_CURRENT_USER, setting, buffer, size);
+}
+
+static
+LONG
+read_registry_setting_machine(
+ char* setting,
+ void* buffer,
+ size_t size
+ )
+{
+ return read_registry_setting_ex(HKEY_LOCAL_MACHINE, setting, buffer, size);
+}
+
+LONG
+read_registry_setting(
+ char* setting,
+ void* buffer,
+ size_t size
+ )
+{
+ LONG rc;
+ rc = read_registry_setting_user(setting, buffer, size);
+ if (!rc) return rc;
+ rc = read_registry_setting_machine(setting, buffer, size);
+ return rc;
+}
diff --git a/src/windows/leashdll/reminder.h b/src/windows/leashdll/reminder.h
new file mode 100644
index 0000000000..05dd4bddda
--- /dev/null
+++ b/src/windows/leashdll/reminder.h
@@ -0,0 +1,12 @@
+#ifndef __REMINDER_H__
+#define __REMINDER_H__
+
+#define Stringize( L ) #L
+#define MakeString( M, L ) M(L)
+#define $LINE MakeString( Stringize, __LINE__ )
+#define Reminder __FILE__ "(" $LINE ") : Reminder: "
+
+#endif
+
+//Put this in your .cpp file where ever you need it (NOTE: Don't end this statement with a ';' char)
+//i.e. -->> #pragma message(Reminder "Your message reminder here!!!")
diff --git a/src/windows/leashdll/res/islogo.bmp b/src/windows/leashdll/res/islogo.bmp
new file mode 100644
index 0000000000..c4af48f233
--- /dev/null
+++ b/src/windows/leashdll/res/islogo.bmp
Binary files differ
diff --git a/src/windows/leashdll/res/leash.ico b/src/windows/leashdll/res/leash.ico
new file mode 100644
index 0000000000..9ef4f96ffc
--- /dev/null
+++ b/src/windows/leashdll/res/leash.ico
Binary files differ
diff --git a/src/windows/leashdll/resource.h b/src/windows/leashdll/resource.h
new file mode 100644
index 0000000000..637c93878b
--- /dev/null
+++ b/src/windows/leashdll/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by lsh_pwd.rc
+//
+#define IDOK2 5
+#define IDCANCEL2 6
+#define LEASHICON 100
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/windows/leashdll/timesync.c b/src/windows/leashdll/timesync.c
new file mode 100644
index 0000000000..c9feadb3e8
--- /dev/null
+++ b/src/windows/leashdll/timesync.c
@@ -0,0 +1,297 @@
+/* timesync stuff for leash - 7/28/94 - evanr */
+
+#include <windows.h>
+#include "leashdll.h"
+
+#include <time.h>
+#include <sys\timeb.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <winkrbid.h>
+
+#ifdef WSHELPER
+#include <wshelper.h>
+#endif
+
+#include <stdio.h>
+#include "leasherr.h"
+#include "leashids.h"
+
+int ProcessTimeSync(char *, int, char *);
+
+#define TM_OFFSET 2208988800
+
+/* timezone.h has a winsock.h conflict */
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+/************************************/
+/* settimeofday(): */
+/************************************/
+int
+settimeofday(
+ struct timeval *tv,
+ struct timezone *tz
+ )
+{
+ SYSTEMTIME systime;
+ struct tm *newtime;
+
+ newtime = gmtime((time_t *)&(tv->tv_sec));
+ systime.wYear = 1900+newtime->tm_year;
+ systime.wMonth = 1+newtime->tm_mon;
+ systime.wDay = newtime->tm_mday;
+ systime.wHour = newtime->tm_hour;
+ systime.wMinute = newtime->tm_min;
+ systime.wSecond = newtime->tm_sec;
+ systime.wMilliseconds = 0;
+ return SetSystemTime(&systime);
+}
+
+/************************************/
+/* gettimeofday(): */
+/************************************/
+int
+gettimeofday(
+ struct timeval *tv,
+ struct timezone *tz
+ )
+{
+ struct _timeb tb;
+ _tzset();
+ _ftime(&tb);
+ if (tv) {
+ tv->tv_sec = tb.time;
+ tv->tv_usec = tb.millitm * 1000;
+ }
+ if (tz) {
+ tz->tz_minuteswest = tb.timezone;
+ tz->tz_dsttime = tb.dstflag;
+ }
+ return 0;
+}
+
+
+LONG
+not_an_API_LeashGetTimeServerName(
+ char *timeServerName,
+ const char *valueName
+ )
+{
+ HMODULE hmLeash;
+ char hostname[128];
+ char value[80];
+ DWORD dwType;
+ DWORD dwCount;
+ int check = 0;
+ HKEY hKey;
+ HKEY rKey1;
+ HKEY rKey2;
+ LONG lResult;
+ BOOL bEnv;
+
+ memset(value, '\0', sizeof(value));
+ memset(hostname, '\0', sizeof(hostname));
+
+ GetEnvironmentVariable("TIMEHOST", hostname, sizeof(hostname));
+ bEnv = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
+
+ if (!(bEnv && hostname[0]))
+ {
+ // Check registry for TIMEHOST
+ rKey1 = HKEY_CURRENT_USER;
+ rKey2 = HKEY_LOCAL_MACHINE;
+
+ for (check = 0; check < 2; check++)
+ {
+ if (ERROR_SUCCESS == RegOpenKeyEx(check == 0 ? rKey1 : rKey2,
+ "Software\\MIT\\Leash32\\Settings",
+ 0, KEY_QUERY_VALUE, &hKey))
+ {
+ memset(value, '\0', sizeof(value));
+ lResult = RegQueryValueEx(hKey, (LPTSTR)valueName, NULL,
+ &dwType, NULL, &dwCount);
+ if (lResult == ERROR_SUCCESS)
+ {
+ lResult = RegQueryValueEx(hKey, (LPTSTR)valueName,
+ NULL, &dwType,
+ (LPTSTR)value, &dwCount);
+ if (lResult == ERROR_SUCCESS && *value)
+ {
+ // found
+ strcpy(hostname, value);
+ break;
+ }
+ }
+ }
+ }
+
+ if (!*hostname)
+ {
+ // Check resource string for TIMEHOST
+ if ((hmLeash = GetModuleHandle(LEASH_DLL)) != NULL)
+ {
+ if (!LoadString(hmLeash, LSH_TIME_HOST, hostname,
+ sizeof(hostname)))
+ memset(hostname, '\0', sizeof(hostname));
+ }
+ }
+ if (!*hostname)
+ {
+ // OK, _Default_ it will be! :)
+ strcpy(hostname, "time");
+ }
+ }
+ strcpy(timeServerName, hostname);
+ return 0;
+}
+
+/************************************/
+/* Leash_timesync(): */
+/************************************/
+LONG Leash_timesync(int MessageP)
+{
+ char tmpstr[2048];
+ char tmpstr1[2048];
+ char hostname[128];
+ int Port;
+ int rc;
+ struct servent *sp;
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ char name[80];
+
+ if ((pkrb5_init_context == NULL)
+#ifndef NO_KRB4
+ && (ptkt_string == NULL)
+#endif
+ )
+ return(0);
+
+ wVersionRequested = 0x0101;
+ memset(name, '\0', sizeof(name));
+ memset(hostname, '\0', sizeof(hostname));
+ memset(tmpstr, '\0', sizeof(tmpstr));
+
+ if ((rc = WSAStartup(wVersionRequested, &wsaData)))
+ {
+ wsprintf(tmpstr, "Couldn't initialize WinSock to synchronize time\n\rError Number: %d", rc);
+ WSACleanup();
+ return(LSH_BADWINSOCK);
+ }
+
+ sp = getservbyname("time", "udp");
+ if (sp == 0)
+ Port = htons(IPPORT_TIMESERVER);
+ else
+ Port = sp->s_port;
+
+ not_an_API_LeashGetTimeServerName(hostname, TIMEHOST);
+
+ rc = ProcessTimeSync(hostname, Port, tmpstr);
+
+ if(MessageP != 0)
+ {
+ if (rc && !*tmpstr)
+ {
+ strcpy(tmpstr, "Unable to syncronize time!\n\n");
+ if (*hostname)
+ {
+ memset(tmpstr1, '\0', sizeof(tmpstr1));
+ sprintf(tmpstr1, "Unreachable server: %s\n", hostname);
+ strcat(tmpstr, tmpstr1);
+ }
+ }
+
+ MessageBox(NULL, tmpstr, "Time Server",
+ MB_ICONERROR | MB_OK);
+ }
+ WSACleanup();
+ return(rc);
+}
+
+
+/************************************/
+/* ProcessTimeSync(): */
+/************************************/
+int ProcessTimeSync(char *hostname, int Port, char *tmpstr)
+{
+ char buffer[512];
+ int cc;
+ register long *nettime;
+ register int s;
+ long hosttime;
+ struct hostent *host;
+ struct timeval tv;
+ struct timezone tz;
+ u_long argp;
+ struct sockaddr_in sin;
+ int i;
+
+ if ((host = gethostbyname(hostname)) == NULL)
+ return(LSH_BADTIMESERV);
+
+ sin.sin_port = (short)Port;
+ sin.sin_family = host->h_addrtype;
+ memcpy((struct sockaddr *)&sin.sin_addr, host->h_addr, host->h_length);
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ return(LSH_NOSOCKET);
+ }
+
+ argp = 1;
+ if (ioctlsocket(s, FIONBIO, &argp) != 0)
+ {
+ closesocket(s);
+ return(LSH_NOCONNECT);
+ }
+
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ closesocket(s);
+ return(LSH_NOCONNECT);
+ }
+ send(s, buffer, 40, 0);
+ if (gettimeofday (&tv, &tz) < 0)
+ {
+ closesocket(s);
+ return(LSH_GETTIMEOFDAY);
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if ((cc = recv(s, buffer, 512, 0)) > 0)
+ break;
+ Sleep(500);
+ }
+ if (i == 4)
+ {
+ closesocket(s);
+ return(LSH_RECVTIME);
+ }
+
+ if (cc != 4)
+ {
+ closesocket(s);
+ return(LSH_RECVBYTES);
+ }
+
+ nettime = (long *)buffer;
+ hosttime = (long) ntohl (*nettime) - TM_OFFSET;
+ (&tv)->tv_sec = hosttime;
+ if (settimeofday(&tv, &tz) < 0)
+ {
+ closesocket(s);
+ return(LSH_SETTIMEOFDAY);
+ }
+
+ sprintf(tmpstr, "The time has been syncronized with the server: %s\n\n", hostname);
+ strcat(tmpstr, "To be able to use the Kerberos server, it was necessary to \nset the system time to: ") ;
+ strcat(tmpstr, ctime((time_t *)&hosttime));
+ strcat(tmpstr, "\n");
+ closesocket(s);
+ return(0);
+}
diff --git a/src/windows/leashdll/ver.rc b/src/windows/leashdll/ver.rc
new file mode 100644
index 0000000000..88bb7d9431
--- /dev/null
+++ b/src/windows/leashdll/ver.rc
@@ -0,0 +1,4 @@
+#define VER_FILEDESCRIPTION_STR "Leash Helper DLL"
+
+#include <kerberos.ver>
+#include <ver.inc>
diff --git a/src/windows/leashdll/winerr.c b/src/windows/leashdll/winerr.c
new file mode 100644
index 0000000000..10806d8b88
--- /dev/null
+++ b/src/windows/leashdll/winerr.c
@@ -0,0 +1,240 @@
+/* WINERR.C
+
+ Jason Hunter
+ 8/2/94
+ DCNS/IS MIT
+
+
+ Contains the error functions for leash and kerberos. Prints out keen windows
+ error messages in english.
+
+*/
+
+#include <stdio.h>
+#include "conf.h"
+
+// Private Include files
+#include "leashdll.h"
+#include <krb.h>
+#include <leashwin.h>
+
+// Global Variables.
+static long lsh_errno;
+static char *err_context; /* error context */
+extern int (*Lcom_err)(LPSTR,long,LPSTR,...);
+extern LPSTR (*Lerror_message)(long);
+extern LPSTR (*Lerror_table_name)(long);
+
+#ifdef WIN16
+#define UNDERSCORE "_"
+#else
+#define UNDERSCORE
+#endif
+
+HWND GetRootParent (HWND Child)
+{
+ HWND Last;
+ while (Child)
+ {
+ Last = Child;
+ Child = GetParent (Child);
+ }
+ return Last;
+}
+
+
+LPSTR err_describe(LPSTR buf, long code)
+{
+ LPSTR cp, com_err_msg;
+ int offset;
+ long table_num;
+ char *etype;
+
+ offset = (int) (code & 255);
+ table_num = code - offset;
+ com_err_msg = Lerror_message(code);
+
+ switch(table_num)
+ {
+#ifndef NO_KRB4
+ case krb_err_base:
+ case kadm_err_base:
+ break;
+#endif
+ default:
+ lstrcpy(buf, com_err_msg);
+ return buf;
+ }
+
+ cp = buf;
+#ifndef NO_KRB4
+ if (table_num == krb_err_base)
+ switch(offset)
+ {
+ case KDC_NAME_EXP: /* 001 Principal expired */
+ case KDC_SERVICE_EXP: /* 002 Service expired */
+ case KDC_AUTH_EXP: /* 003 Auth expired */
+ case KDC_PKT_VER: /* 004 Protocol version unknown */
+ case KDC_P_MKEY_VER: /* 005 Wrong master key version */
+ case KDC_S_MKEY_VER: /* 006 Wrong master key version */
+ case KDC_BYTE_ORDER: /* 007 Byte order unknown */
+ case KDC_PR_N_UNIQUE: /* 009 Principal not unique */
+ case KDC_NULL_KEY: /* 010 Principal has null key */
+ case KDC_GEN_ERR: /* 011 Generic error from KDC */
+ case INTK_W_NOTALL : /* 061 Not ALL tickets returned */
+ case INTK_PROT : /* 063 Protocol Error */
+ case INTK_ERR : /* 070 Other error */
+ com_err_msg = "Something weird happened... try again, and if Leash"
+ " continues to fail, contact Network Services as listed in the "
+ "About box.";
+ break;
+ case KDC_PR_UNKNOWN: /* 008 Principal unknown */
+ com_err_msg = "You have entered an unknown username/instance/realm"
+ " combination.";
+ break;
+ case GC_TKFIL : /* 021 Can't read ticket file */
+ case GC_NOTKT : /* 022 Can't find ticket or TGT */
+ com_err_msg = "Something is wrong with the memory where your "
+ "tickets are stored. Try exiting Windows and restarting your "
+ "computer.";
+ break;
+ case MK_AP_TGTEXP : /* 026 TGT Expired */
+ /* no extra error msg */
+ break;
+ case RD_AP_TIME : /* 037 delta_t too big */
+ com_err_msg = "Your computer's clock is out of sync with the "
+ "Kerberos server. Please see the help file about correcting "
+ "your clock.";
+ break;
+
+ case RD_AP_UNDEC : /* 031 Can't decode authenticator */
+ case RD_AP_EXP : /* 032 Ticket expired */
+ case RD_AP_NYV : /* 033 Ticket not yet valid */
+ case RD_AP_REPEAT : /* 034 Repeated request */
+ case RD_AP_NOT_US : /* 035 The ticket isn't for us */
+ case RD_AP_INCON : /* 036 Request is inconsistent */
+ case RD_AP_BADD : /* 038 Incorrect net address */
+ case RD_AP_VERSION : /* 039 protocol version mismatch */
+ case RD_AP_MSG_TYPE : /* 040 invalid msg type */
+ case RD_AP_MODIFIED : /* 041 message stream modified */
+ case RD_AP_ORDER : /* 042 message out of order */
+ case RD_AP_UNAUTHOR : /* 043 unauthorized request */
+ /* no extra error msg */
+ break;
+ case GT_PW_NULL: /* 51 Current PW is null */
+ case GT_PW_BADPW: /* 52 Incorrect current password */
+ case GT_PW_PROT: /* 53 Protocol Error */
+ case GT_PW_KDCERR: /* 54 Error returned by KDC */
+ case GT_PW_NULLTKT: /* 55 Null tkt returned by KDC */
+ /* no error msg yet */
+ break;
+
+ /* Values returned by send_to_kdc */
+ case SKDC_RETRY : /* 56 Retry count exceeded */
+ case SKDC_CANT : /* 57 Can't send request */
+ com_err_msg = "Cannot contact the kerberos server for the selected realm.";
+ break;
+ /* no error message on purpose: */
+ case INTK_BADPW : /* 062 Incorrect password */
+ break;
+ default:
+ /* no extra error msg */
+ break;
+ }
+ else
+ switch(code)
+ {
+ case KADM_INSECURE_PW:
+ /* if( kadm_info != NULL ){
+ * wsprintf(buf, "%s\n%s", com_err_msg, kadm_info);
+ * } else {
+ * wsprintf(buf, "%s\nPlease see the help file for information "
+ * "about secure passwords.", com_err_msg);
+ * }
+ * com_err_msg = buf;
+ */
+
+ /* The above code would be preferred since it allows site specific
+ * information to be delivered from the Kerberos server. However the
+ * message box is too small for VGA screens.
+ * It does work well if we only have to support 1024x768
+ */
+
+ com_err_msg = "You have entered an insecure or weak password.";
+ default:
+ /* no extra error msg */
+ break;
+ }
+#endif /* NO_KRB4 */
+ if(com_err_msg != buf)
+ lstrcpy(buf, com_err_msg);
+ cp = buf + lstrlen(buf);
+ *cp++ = '\n';
+ switch(table_num) {
+#ifndef NO_KRB4
+ case krb_err_base:
+ etype = "Kerberos";
+ break;
+ case kadm_err_base:
+ etype = "Kerberos supplemental";
+ break;
+#endif
+ default:
+ etype = Lerror_table_name(table_num);
+ break;
+ }
+ wsprintf((LPSTR) cp, (LPSTR) "(%s error %d"
+#ifdef DEBUG_COM_ERR
+ " (absolute error %ld)"
+#endif
+ ")", etype, offset
+ //")\nPress F1 for help on this error.", etype, offset
+#ifdef DEBUG_COM_ERR
+ , code
+#endif
+ );
+
+ return (LPSTR)buf;
+}
+
+int _export lsh_com_err_proc (LPSTR whoami, long code,
+ LPSTR fmt, va_list args)
+{
+ int retval;
+ HWND hOldFocus;
+ char buf[1024], *cp; /* changed to 512 by jms 8/23/93 */
+ WORD mbformat = MB_OK | MB_ICONEXCLAMATION;
+
+ cp = buf;
+ memset(buf, '\0', sizeof(buf));
+ cp[0] = '\0';
+
+ if (code)
+ {
+ err_describe(buf, code);
+ while (*cp)
+ cp++;
+ }
+
+ if (fmt)
+ {
+ if (fmt[0] == '%' && fmt[1] == 'b')
+ {
+ fmt += 2;
+ mbformat = va_arg(args, WORD);
+ /* if the first arg is a %b, we use it for the message
+ box MB_??? flags. */
+ }
+ if (code)
+ {
+ *cp++ = '\n';
+ *cp++ = '\n';
+ }
+ wvsprintf((LPSTR)cp, fmt, args);
+ }
+ hOldFocus = GetFocus();
+ retval = MessageBox(/*GetRootParent(hOldFocus)*/NULL, buf, whoami,
+ mbformat | MB_ICONHAND | MB_TASKMODAL);
+ SetFocus(hOldFocus);
+ return retval;
+}
diff --git a/src/windows/leashdll/winutil.c b/src/windows/leashdll/winutil.c
new file mode 100644
index 0000000000..65609bcdf0
--- /dev/null
+++ b/src/windows/leashdll/winutil.c
@@ -0,0 +1,138 @@
+#include <windows.h>
+#include "leash-int.h"
+
+//#include <string.h>
+
+static ATOM sAtom = 0;
+static HINSTANCE shInstance = 0;
+
+/* Callback for the MITPasswordControl
+This is a replacement for the normal edit control. It does not show the
+annoying password char in the edit box so that the number of chars in the
+password are not known.
+*/
+
+#define PASSWORDCHAR '#'
+#define DLGHT(ht) (HIWORD(GetDialogBaseUnits())*(ht)/8)
+#define DLGWD(wd) (LOWORD(GetDialogBaseUnits())*(wd)/4)
+
+static
+LRESULT
+CALLBACK
+MITPasswordEditProc(
+ HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ static SIZE pwdcharsz;
+ BOOL pass_the_buck = FALSE;
+
+ if (message > WM_USER && message < 0x7FFF)
+ pass_the_buck = TRUE;
+
+ switch(message)
+ {
+ case WM_GETTEXT:
+ case WM_GETTEXTLENGTH:
+ case WM_SETTEXT:
+ pass_the_buck = TRUE;
+ break;
+ case WM_PAINT:
+ {
+ HDC hdc;
+ PAINTSTRUCT ps;
+ RECT r;
+
+ hdc = BeginPaint(hWnd, &ps);
+ GetClientRect(hWnd, &r);
+ Rectangle(hdc, 0, 0, r.right, r.bottom);
+ EndPaint(hWnd, &ps);
+ }
+ break;
+ case WM_SIZE:
+ {
+ MoveWindow(GetDlgItem(hWnd, 1), DLGWD(2), DLGHT(2),
+ pwdcharsz.cx / 2, pwdcharsz.cy, TRUE);
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ case WM_SETFOCUS:
+ {
+ SetFocus(GetDlgItem(hWnd, 1));
+ }
+ break;
+ case WM_CREATE:
+ {
+ HWND heditchild;
+ char pwdchar = PASSWORDCHAR;
+ HDC hdc;
+ /* Create a child window of this control for default processing. */
+ hdc = GetDC(hWnd);
+ GetTextExtentPoint32(hdc, &pwdchar, 1, &pwdcharsz);
+ ReleaseDC(hWnd, hdc);
+
+ heditchild =
+ CreateWindow("edit", "", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL |
+ ES_LEFT | ES_PASSWORD | WS_TABSTOP,
+ 0, 0, 0, 0,
+ hWnd,
+ (HMENU)1,
+ ((LPCREATESTRUCT)lParam)->hInstance,
+ NULL);
+ SendMessage(heditchild, EM_SETPASSWORDCHAR, PASSWORDCHAR, 0L);
+ }
+ break;
+ }
+
+ if (pass_the_buck)
+ return SendMessage(GetDlgItem(hWnd, 1), message, wParam, lParam);
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+BOOL
+Register_MITPasswordEditControl(
+ HINSTANCE hInst
+ )
+{
+ if (!sAtom) {
+ WNDCLASS wndclass;
+
+ memset(&wndclass, 0, sizeof(WNDCLASS));
+
+ shInstance = hInst;
+
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = (WNDPROC)MITPasswordEditProc;
+ wndclass.cbClsExtra = sizeof(HWND);
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = shInstance;
+ wndclass.hbrBackground = (void *)(COLOR_WINDOW + 1);
+ wndclass.lpszClassName = MIT_PWD_DLL_CLASS;
+ wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_IBEAM);
+
+ sAtom = RegisterClass(&wndclass);
+ }
+ return sAtom ? TRUE : FALSE;
+}
+
+BOOL
+Unregister_MITPasswordEditControl(
+ HINSTANCE hInst
+ )
+{
+ BOOL result = TRUE;
+
+ if ((hInst != shInstance) || !sAtom) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ result = UnregisterClass(MIT_PWD_DLL_CLASS, hInst);
+ if (result) {
+ sAtom = 0;
+ shInstance = 0;
+ }
+ return result;
+}