--- /dev/null
+/*
+ * @doc
+ * @module nameser.h |
+ * Copyright (c) 1983, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nameser.h 5.25 (Berkeley) 4/3/91
+ */
+
+#ifndef _NAMESER_H_
+#define _NAMESER_H_
+
+/*
+ * Define constants based on rfc883
+ */
+#define PACKETSZ 512 /* maximum packet size */
+#define MAXDNAME 256 /* maximum domain name */
+#define MAXCDNAME 255 /* maximum compressed domain name */
+#define MAXLABEL 63 /* maximum length of domain label */
+ /* Number of bytes of fixed size data in query structure */
+#define QFIXEDSZ 4
+ /* number of bytes of fixed size data in resource record */
+#define RRFIXEDSZ 10
+
+#if !defined(MAXHOSTNAME)
+#define MAXHOSTNAME MAXCDNAME
+#endif
+
+/*
+ * Internet nameserver port number
+ */
+#define NAMESERVER_PORT 53
+
+/*
+ * Currently defined opcodes
+ */
+#define QUERY 0x0 /* standard query */
+#define IQUERY 0x1 /* inverse query */
+#define STATUS 0x2 /* nameserver status query */
+/*#define xxx 0x3 /* 0x3 reserved */
+ /* non standard */
+#define UPDATEA 0x9 /* add resource record */
+#define UPDATED 0xa /* delete a specific resource record */
+#define UPDATEDA 0xb /* delete all nemed resource record */
+#define UPDATEM 0xc /* modify a specific resource record */
+#define UPDATEMA 0xd /* modify all named resource record */
+
+#define ZONEINIT 0xe /* initial zone transfer */
+#define ZONEREF 0xf /* incremental zone referesh */
+
+/*
+ * Currently defined response codes
+ */
+#define NOERROR 0 /* no error */
+#define FORMERR 1 /* format error */
+#define SERVFAIL 2 /* server failure */
+#define NXDOMAIN 3 /* non existent domain */
+#define NOTIMP 4 /* not implemented */
+#define REFUSED 5 /* query refused */
+ /* non standard */
+#define NOCHANGE 0xf /* update failed to change db */
+
+/*
+ * Type values for resources and queries
+ */
+#define T_A 1 /* host address */
+#define T_NS 2 /* authoritative server */
+#define T_MD 3 /* mail destination */
+#define T_MF 4 /* mail forwarder */
+#define T_CNAME 5 /* connonical name */
+#define T_SOA 6 /* start of authority zone */
+#define T_MB 7 /* mailbox domain name */
+#define T_MG 8 /* mail group member */
+#define T_MR 9 /* mail rename name */
+#define T_NULL 10 /* null resource record */
+#define T_WKS 11 /* well known service */
+#define T_PTR 12 /* domain name pointer */
+#define T_HINFO 13 /* host information */
+#define T_MINFO 14 /* mailbox information */
+#define T_MX 15 /* mail routing information */
+#define T_TXT 16 /* text strings */
+ /* non standard */
+#define T_UINFO 100 /* user (finger) information */
+#define T_UID 101 /* user ID */
+#define T_GID 102 /* group ID */
+#define T_UNSPEC 103 /* Unspecified format (binary data) */
+ /* Query type values which do not appear in resource records */
+#define T_AXFR 252 /* transfer zone of authority */
+#define T_MAILB 253 /* transfer mailbox records */
+#define T_MAILA 254 /* transfer mail agent records */
+#define T_ANY 255 /* wildcard match */
+
+/*
+ * Values for class field
+ */
+
+#define C_IN 1 /* the arpa internet */
+#define C_CHAOS 3 /* for chaos net at MIT */
+#define C_HS 4 /* for Hesiod name server at MIT */
+ /* Query class values which do not appear in resource records */
+#define C_ANY 255 /* wildcard match */
+
+/*
+ * Status return codes for T_UNSPEC conversion routines
+ */
+#define CONV_SUCCESS 0
+#define CONV_OVERFLOW -1
+#define CONV_BADFMT -2
+#define CONV_BADCKSUM -3
+#define CONV_BADBUFLEN -4
+
+#ifndef BYTE_ORDER
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(MIPSEL) || \
+ defined(BIT_ZERO_ON_RIGHT)
+#define BYTE_ORDER LITTLE_ENDIAN
+
+#endif
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
+ defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
+ defined(MIPSEB) || defined (BIT_ZERO_ON_LEFT)
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif /* BYTE_ORDER */
+
+#ifndef BYTE_ORDER
+ /* you must determine what the correct bit order is for your compiler */
+ #define BYTE_ORDER LITTLE_ENDIAN /* for Intel x86 series */
+#endif
+/*
+ * Structure for query header, the order of the fields is machine and
+ * compiler dependent, in our case, the bits within a byte are assignd
+ * least significant first, while the order of transmition is most
+ * significant first. This requires a somewhat confusing rearrangement.
+ */
+
+#if defined (_WINDLL) || (_WIN32)
+/* define UNIX types */
+#include <winsock.h>
+#endif
+
+typedef struct {
+ u_short id; /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ u_char qr:1; /* response flag */
+ u_char opcode:4; /* purpose of message */
+ u_char aa:1; /* authoritive answer */
+ u_char tc:1; /* truncated message */
+ u_char rd:1; /* recursion desired */
+ /* fields in fourth byte */
+ u_char ra:1; /* recursion available */
+ u_char pr:1; /* primary server required (non standard) */
+ u_char unused:2; /* unused bits */
+ u_char rcode:4; /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ u_char rd:1; /* recursion desired */
+ u_char tc:1; /* truncated message */
+ u_char aa:1; /* authoritive answer */
+ u_char opcode:4; /* purpose of message */
+ u_char qr:1; /* response flag */
+ /* fields in fourth byte */
+ u_char rcode:4; /* response code */
+ u_char unused:2; /* unused bits */
+ u_char pr:1; /* primary server required (non standard) */
+ u_char ra:1; /* recursion available */
+#endif
+ /* remaining bytes */
+ u_short qdcount; /* number of question entries */
+ u_short ancount; /* number of answer entries */
+ u_short nscount; /* number of authority entries */
+ u_short arcount; /* number of resource entries */
+} HEADER;
+
+/*
+ * Defines for handling compressed domain names
+ */
+#define INDIR_MASK 0xc0
+
+/*
+ * Structure for passing resource records around.
+ */
+struct rrec {
+ short r_zone; /* zone number */
+ short r_class; /* class number */
+ short r_type; /* type number */
+ u_long r_ttl; /* time to live */
+ int r_size; /* size of data area */
+ char *r_data; /* pointer to data */
+};
+
+extern u_short _getshort();
+extern u_long _getlong();
+
+/*
+ * Inline versions of get/put short/long.
+ * Pointer is advanced; we assume that both arguments
+ * are lvalues and will already be in registers.
+ * cp MUST be u_char *.
+ */
+#define GETSHORT(s, cp) { \
+ (s) = *(cp)++ << 8; \
+ (s) |= *(cp)++; \
+}
+
+#define GETLONG(l, cp) { \
+ (l) = *(cp)++ << 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; \
+}
+
+
+#define PUTSHORT(s, cp) { \
+ *(cp)++ = (s) >> 8; \
+ *(cp)++ = (s); \
+}
+
+/*
+ * Warning: PUTLONG destroys its first argument.
+ */
+#define PUTLONG(l, cp) { \
+ (cp)[3] = l; \
+ (cp)[2] = (l >>= 8); \
+ (cp)[1] = (l >>= 8); \
+ (cp)[0] = l >> 8; \
+ (cp) += sizeof(u_long); \
+}
+
+#endif /* !_NAMESER_H_ */
--- /dev/null
+/*! \file hesiod.h
+ * WSHelper DNS/Hesiod Library
+ *
+ * This file contains the function declaration for: \n
+ * hes_to_bind() \n
+ * hes_resolve() \n
+ * hes_error() \n
+ * hes_free() \n
+ * hes_getmailhost() \n
+ * hes_getservbyname() \n
+ * hes_getpwnam() \n
+ * hes_getpwuid() \n
+*/
+
+#ifndef _HESIOD_
+#define _HESIOD_
+
+
+#include <windows.h>
+
+/*! \def HESIOD_CONF
+ * name of the hesiod configuration file. We will look at the file to determine the RHS AND LHS value before using the default.
+ * Here is a sample hesiod.cfg file: \n
+ * lhs .ns \n
+ * rhs .ATHENA.MIT.EDU \n
+ */
+#define HESIOD_CONF "c:\\net\\tcp\\hesiod.cfg"
+
+/*! \def DEF_RHS
+ * default RHS value is the hesiod configuration file is not present
+ */
+#define DEF_RHS ".Athena.MIT.EDU"
+
+/*! \def DEF_LHS
+ * default LHS value is the hesiod configuration file is not present
+ */
+#define DEF_LHS ".ns"
+
+/*! \def HES_ER_UNINIT
+ * HES error code: uninitialized
+ */
+#define HES_ER_UNINIT -1
+
+/*! \def HES_ER_OK
+ * HES error code: no error
+ */
+#define HES_ER_OK 0
+
+/*! \def HES_ER_NOTFOUND
+ * HES error code: Hesiod name not found by server
+ */
+#define HES_ER_NOTFOUND 1
+
+/*! \def HES_ER_CONFIG
+ * HES error code: local problem (no config file?)
+ */
+#define HES_ER_CONFIG 2
+
+/*! \def HES_ER_NET
+ * HES error code: network problem
+ */
+#define HES_ER_NET 3
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! \fn LPSTR WINAPI hes_to_bind(LPSTR HesiodName, LPSTR HesiodNameType)
+ * hes_to_bind function use the LHS and RHS values and
+ * binds them with the parameters so that a well formed DNS query may
+ * be performed.
+ *
+ * defined in hesiod.c
+ *
+ * \param[in] HesiodName The Hesiod name such as a username or service name
+ * \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc
+ * \retval Returns NULL if there was an error. Otherwise the pointer to a string containing a valid query is returned.
+ *
+ */
+LPSTR WINAPI
+hes_to_bind(
+ LPSTR HesiodName,
+ LPSTR HesiodNameType
+ );
+
+
+/*! \fn LPSTR * WINAPI hes_resolve(LPSTR HesiodName, LPSTR HesiodNameType)
+ * This function calls hes_to_bind to form a valid hesiod query, then queries the dns database.
+ *
+ * defined in hesiod.c
+ *
+ * \param[in] HesiodName The Hesiod name such as a username or service name
+ * \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc
+ * \retval returns a NULL terminated vector of strings (a la argv),
+ * one for each resource record containing Hesiod data, or NULL if
+ * there is any error. If there is an error call hes_error() to get
+ * further information. You will need to call hes_free to free the result
+ *
+ */
+
+LPSTR * WINAPI
+hes_resolve(
+ LPSTR HesiodName,
+ LPSTR HesiodNameType
+ );
+
+/*! \fn int WINAPI hes_error(void)
+ * The function hes_error may be called to determine the
+ * source of the error. It does not take an argument.
+ *
+ * defined in hesiod.c
+ *
+ * \retval return one of the HES_ER_* codes defined in hesiod.h.
+ */
+
+int WINAPI
+hes_error(
+ void
+ );
+
+
+/*! \fn void WINAPI hes_free(LPSTR* hesinfo)
+ * The function hes_free should be called to free up memeory returned by hes_resolve
+ *
+ * defined in hesiod.c
+ *
+ * \param[in] hesinfo a NULL terminiated array of strings returned by hes_resolve
+ */
+void WINAPI
+hes_free(
+ LPSTR* hesinfo
+ );
+
+
+/*! \struct hes_postoffice
+ * For use in getting post-office information.
+ */
+struct hes_postoffice {
+ /*! The post office type, e.g. POP, IMAP */
+ LPSTR po_type;
+ /*! The post office host, e.g. PO10.MIT.EDU */
+ LPSTR po_host;
+ /*! The account name on the post office, e.g. tom */
+ LPSTR po_name;
+};
+
+/*! \fn struct hes_postoffice * WINAPI hes_getmailhost(LPSTR user)
+ * This call is used to obtain a user's type of mail account and the location of that
+ * account. E.g. POP PO10.MIT.EDU or IMAP IMAP-TEST.MIT.EDU
+ *
+ * defined in hesmailh.c
+ *
+ * \param[in] user The username to be used when querying for the Hesiod Name Type POBOX.
+ * \retval NULL if there was an error or if there was no entry for the
+ * username. Otherwise a pointer to a hes_postoffice structure is
+ * returned. The caller must never attempt to modify this structure or to free
+ * any of its components. Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another getmailhost call
+ */
+struct hes_postoffice * WINAPI hes_getmailhost(LPSTR user);
+
+/*! \fn struct servent * WINAPI hes_getservbyname(LPSTR name, LPSTR proto)
+ * This function will query a Hesiod server for a servent structure given
+ * a service name and protocol. This is a replacement for the Winsock
+ * getservbyname function which normally just uses a local services
+ * file. This allows a site to use a centralized database for adding new
+ * services.
+ *
+ * defined in hesservb.c
+ *
+ * \param[in] name pointer to the official name of the service, eg "POP3".
+ * \param[in] proto pointer to the protocol to use when contacting the service, e.g. "TCP"
+ * \retval NULL if there was an error or a pointer to a servent structure. The caller must
+ * never attempt to modify this structure or to free any of its components.
+ * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another hes_getservbyname call
+ *
+ */
+struct servent * WINAPI hes_getservbyname(LPSTR name,
+ LPSTR proto);
+
+/*! \fn struct passwd * WINAPI hes_getpwnam(LPSTR nam)
+ * Given a username this function will return the pwd information, eg
+ * username, uid, gid, fullname, office location, phone number, home
+ * directory, and default shell
+ *
+ * defined in hespwnam.c
+ *
+ * \param nam a pointer to the username
+ * \retval NULL if there was an error or a pointer to the passwd structure. The caller must
+ * never attempt to modify this structure or to free any of its components.
+ * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another hes_getpwnam call
+ *
+ */
+struct passwd * WINAPI hes_getpwnam(LPSTR nam);
+
+/*! struct passwd * WINAPI hes_getpwuid(int uid)
+ * Given a UID this function will return the pwd information, eg username, uid,
+ * gid, fullname, office location, phone number, home directory, and default shell
+ *
+ * defined in hespwnam.c
+ *
+ * \param uid The user ID
+ * \retval NULL if there was an error or a pointer to the passwd structure. The caller must
+ * never attempt to modify this structure or to free any of its components.
+ * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another hes_getpwuid call
+ */
+struct passwd * WINAPI hes_getpwuid(int uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HESIOD_ */
--- /dev/null
+/*! \file mitwhich.h
+ * some defines so that we can figure out which MS OS and subsystem an
+ * application is running under. Also support for finding out which
+ * TCP/IP stack is being used. This is useful when you need to find out
+ * about the domain or the nameservers.
+ */
+
+#if !defined( __MIT_WHICH_H )
+#define __MIT_WHICH_H
+
+// these should become resources and loaded at run time
+#define NT_32 "Winsock 2.0"
+#define NT_16 "Windows NT 16-bit Windows Sockets"
+#define W95_32 "Microsoft Windows Sockets Version 1.1."
+#define W95_16 "Microsoft Windows Sockets Version 1.1."
+#define LWP_16 "Novell Winsock version 1.1"
+// Note that these are currently in wshelper.h and should be somewhere else
+#define MS_NT_32 1
+#define MS_NT_16 2
+#define MS_95_32 3
+#define MS_95_16 4
+#define NOVELL_LWP_16 5
+
+#define MS_OS_WIN 1
+#define MS_OS_95 2
+#define MS_OS_NT 4
+#define MS_OS_2000 12
+#define MS_OS_XP 28
+#define MS_OS_2003 60
+#define MS_OS_NT_UNKNOWN 124
+#define MS_OS_UNKNOWN 0
+
+#define STACK_UNKNOWN 0
+#define UNKNOWN_16_UNDER_32 -2
+#define UNKNOWN_16_UNDER_16 -3
+#define UNKNOWN_32_UNDER_32 -4
+#define UNKNOWN_32_UNDER_16 -5
+
+
+/*
+ @comm these are the current MIT DNS servers, the wshelper and
+ wshelp32 DLLs will do their best to find the correct DNS servers
+ for the local machine however, if all else fails these will be used
+ as a last resort. Site administrators outside of the MIT domain
+ should change these defaults to their own defaults either by
+ editing this file and recompiling or by editing the string tables
+ of the binaries. Don't use App Studio to edit the .RC files.
+\n
+ #define DNS1 "18.70.0.160" \n
+ #define DNS2 "18.71.0.151" \n
+ #define DNS3 "18.72.0.3" \n
+\n
+ #define DEFAULT_DOMAIN "mit.edu" \n
+*/
+
+#define DNS1 "18.70.0.160"
+#define DNS2 "18.71.0.151"
+#define DNS3 "18.72.0.3"
+
+#define DEFAULT_DOMAIN "mit.edu"
+
+
+#ifndef _PATH_RESCONF
+#if !defined(WINDOWS) && !defined(_WINDOWS) && !defined(_WIN32)
+#define _PATH_RESCONF "/etc/resolv.conf"
+#else
+#define _PATH_RESCONF "c:/net/tcp/resolv.cfg"
+#endif
+#endif
+
+
+/* Microsoft TCP/IP registry values that we care about */
+#define NT_TCP_PATH "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define NT_TCP_PATH_TRANS "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Transient"
+#define W95_TCP_PATH "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
+
+#define NT_DOMAIN_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Domain"
+#define NT_NS_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\NameServer"
+
+#define W95_DOMAIN_KEY "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP\\Domain"
+#define W95_NS_KEY "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP\\NameServer"
+
+
+#endif // __MIT_WHICH_H
--- /dev/null
+/*! \file resolv.h
+ * WSHelper DNS/Hesiod Library header
+ * This file contains the function declaration for:\n
+ * res_init() \n
+ * res_search() \n
+ * dn_comp() \n
+ * rdn_expand() \n \n
+ * and unsupported functions: \n
+ * res_setopts() \n
+ * res_getopts() \n
+ * res_querydomain() \n
+ * res_mkquery() \n
+ * res_send() \n
+*/
+
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <windows.h>
+#ifndef MAXDNAME
+#include <arpa/nameser.h>
+#endif
+
+/*! \def MAXNS
+ * max # name servers we'll track
+ */
+#define MAXNS 3
+
+/*! \def MAXDFLSRCH
+ * # default domain levels to try
+ */
+#define MAXDFLSRCH 3
+
+/*! \def MAXDNSRCH
+ * max # domains in search path
+ */
+#define MAXDNSRCH 6
+
+/*! \def LOCALDOMAINPARTS
+ * min levels in name that is "local"
+ */
+#define LOCALDOMAINPARTS 2
+
+/*! \def RES_TIMEOUT
+ * min. seconds between retries
+ */
+#define RES_TIMEOUT 5
+
+/*! \def MAXMXRECS
+ * number of records in the preference array in the MX record
+ */
+#define MAXMXRECS 8
+
+/*! \struct mxent
+ * structure to hold the MX record
+ */
+struct mxent {
+ /*! number of records in the preference field */
+ int numrecs;
+ /*! holds a 16 bit integer which specifies the preference given to this RR */
+ u_short pref[MAXMXRECS];
+ /*! a host willing to act as a mail exchange */
+ char ** hostname;
+};
+
+
+/*! \struct state
+ * This structure holds the state for the resolver query
+ */
+struct state {
+ /*! retransmition time interval */
+ int retrans;
+ /*! number of times to retransmit */
+ int retry;
+ /*! field option flags - see below. */
+ long options;
+ /*! field number of name servers */
+ int nscount;
+ /*! address of name server */
+ struct sockaddr_in nsaddr_list[MAXNS];
+#define nsaddr nsaddr_list[0]
+ /*! current packet id */
+ u_short id;
+ /*! field default domain */
+ char defdname[MAXDNAME];
+ /*! field components of domain to search */
+ char *dnsrch[MAXDNSRCH+1];
+};
+
+/*! \def RES_INIT
+ * resolver option: address initialized
+ */
+#define RES_INIT 0x0001
+
+/*! \def RES_DEBUG
+ * resolver option: print debug messages
+ */
+#define RES_DEBUG 0x0002
+
+/*! \def RES_AAONLY
+ * resolver option: authoritative answers only
+ */
+#define RES_AAONLY 0x0004
+
+/*! \def RES_USEVC
+ * resolver option: use virtual circuit
+ */
+#define RES_USEVC 0x0008
+
+/*! \def RES_PRIMARY
+ * resolver option: query primary server only
+ */
+#define RES_PRIMARY 0x0010
+
+/*! \def RES_IGNTC
+ * resolver option: ignore trucation errors
+ */
+#define RES_IGNTC 0x0020
+
+/*! \def RES_RECURSE
+ * resolver option: recursion desired
+ */
+#define RES_RECURSE 0x0040
+
+/*! \def RES_DEFNAMES
+ * resolver option: use default domain name
+ */
+#define RES_DEFNAMES 0x0080
+
+/*! \def RES_STAYOPEN
+ * resolver option: Keep TCP socket ope
+ */
+#define RES_STAYOPEN 0x0100
+
+/*! \def RES_DNSRCH
+ * resolver option: search up local domain tree
+ */
+#define RES_DNSRCH 0x0200
+
+/*! \def RES_DEFAULT
+ * resolver option: Default RES options (RES_RECURSE + RES_DEFNAMES + RES_DNSRCH)
+ */
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
+
+extern struct state _res;
+
+#include <stdio.h>
+
+/* Private routines shared between libc/net, named, nslookup and others. */
+#define fp_query __fp_query
+#define hostalias __hostalias
+#define putlong __putlong
+#define putshort __putshort
+#define p_class __p_class
+#define p_time __p_time
+#define p_type __p_type
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! \fn int WINAPI res_init()
+ * \brief retrieves the default domain name and search order. It will look to see if an environment variable LOCALDOMAIN is defined. Otherwise,
+ * the domain associated with the local host is used. Otherwise, it will try to find the domain name from the registry
+ *
+ * defined in res_init.c
+ *
+ * \retval The return value is 0 if the operation was successful. Otherwise the value -1 is returned.
+ */
+int WINAPI res_init();
+
+
+/*! \fn int WINAPI res_search(const char* name, int qclass, int type, u_char* answer, int anslen)
+ * \brief a generic query interface to the DNS name space. The query is performed with the dnsapi and
+ * the answer buffer is populated based on the returned RR set.
+ *
+ * defined in res_quer.c
+
+ * \param[in] name domain name
+ * \param[in] qclass class of query(such as DNS_CLASS_INTERNET, DNS_CLASS_CSNET, DNS_CLASS_CHAOS,
+ * DNS_CLASS_HESIOD. Defined in windns.h)
+ * \param[in] type type of query(such as DNS_TYPE_A, DNS_TYPE_NS, DNS_TYPE_MX, DNS_TYPE_SRV. Defined in
+ * windns.h)
+ * \param[in] answer buffer to put answer in
+ * \param[in] anslen size of the answer buffer. compare the anslen with the return value, if the return
+ * value is bigger than anslen, it means the answer buffer doesn't contain the complete
+ * response. You will need to call this function again with a bigger answer buffer if
+ * you care about the complete response
+ *
+ * \retval return the size of the response on success, -1 on error
+ *
+ */
+int WINAPI res_search(const char *name,
+ int qclass, int type,
+ u_char *answer, int anslen);
+
+/*! \fn int WINAPI dn_comp(const u_char* exp_dn, u_char* comp_dn, int length, u_char** dnptrs, u_char** lastdnptr)
+ * \brief Compress domain name 'exp_dn' into 'comp_dn'
+ *
+ * defined in res_comp.c
+ *
+ * \param[in] exp_dn name to compress
+ * \param[in, out] comp_dn result of the compression
+ * \param[in] length the size of the array pointed to by 'comp_dn'.
+ * \param[in, out] dnptrs a list of pointers to previous compressed names. dnptrs[0]
+ * is a pointer to the beginning of the message. The list ends with NULL.
+ * \param[in] lastdnptr a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect
+ * is to update the list of pointers for labels inserted into the
+ * message as we compress the name. If 'dnptr' is NULL, we don't try to
+ * compress names. If 'lastdnptr' is NULL, we don't update the list.
+ * \retval Return the size of the compressed name or -1
+ */
+int WINAPI dn_comp(const u_char *exp_dn,
+ u_char *comp_dn,
+ int length, u_char **dnptrs,
+ u_char * *lastdnptr);
+
+/*! \fn int WINAPI rdn_expand(const u_char *msg, const u_char *eomorig, const u_char *comp_dn, u_char *exp_dn,
+ int length);
+ * \brief replacement for dn_expand called rdn_expand. Older versions of the DLL used to this as dn_expand
+ * but this has caused some conflict with more recent versions of the MSDEV libraries. rdn_expand()
+ * expands the compressed domain name comp_dn to a full domain name. Expanded names are converted to upper case.
+ *
+ * defined in res_comp.c
+ *
+ * \param[in] msg msg is a pointer to the beginning of the message
+ * \param[in] eomorig
+ * \param[in] comp_dn the compressed domain name.
+ * \param[in, out] exp_dn a pointer to the result buffer
+ * \param[in] length size of the result in expn_dn
+ * \retval the size of compressed name is returned or -1 if there was an error.
+*/
+int WINAPI rdn_expand(const u_char *msg,
+ const u_char *eomorig,
+ const u_char *comp_dn,
+ u_char *exp_dn,
+ int length);
+/* Microsoft includes an implementation of dn_expand() in winsock */
+/* Make sure we do not use it. jaltman@columbia.edu */
+#define dn_expand(a,b,c,d,e) rdn_expand(a,b,c,d,e)
+
+
+/*! \fn void WINAPI res_setopts(long opts)
+ * unsupported
+*/
+void WINAPI res_setopts(long opts);
+
+/*! \fn long WINAPI res_getopts(void)
+ * unsupported
+*/
+long WINAPI res_getopts(void);
+
+/*! \fn int WINAPI res_mkquery(int op, const char *dname, int qclass, int type, const char *data, int datalen,
+ * const struct rrec *newrr, char *buf, int buflen)
+ * unsupported
+ */
+int WINAPI res_mkquery(int op, const char *dname,
+ int qclass, int type,
+ const char *data, int datalen,
+ const struct rrec *newrr,
+ char *buf, int buflen);
+
+/*! \fn int WINAPI res_send(const char *msg, int msglen, char *answer, int anslen)
+ * unsupported
+*/
+int WINAPI res_send(const char *msg, int msglen,
+ char *answer, int anslen);
+
+/*! \fn int WINAPI res_querydomain(const char *name, const char *domain, int qclass, int type,
+ u_char *answer, int anslen);
+* unsupported
+*/
+int WINAPI res_querydomain(const char *name,
+ const char *domain,
+ int qclass, int type,
+ u_char *answer, int anslen);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_RESOLV_H_ */
--- /dev/null
+/*! \file wshelper.h
+ * WSHelper DNS/Hesiod Library
+ *
+ * This file contains the function declaration for: \n
+ * rgethostbyname() \n
+ * rgethostbyaddr() \n
+ * rgetservbyname() \n
+ * inet_aton() \n
+ * wsh_gethostname() \n
+ * wsh_getdomainname() \n \n
+ * and unsupported functions: \n
+ * gethinfobyname() \n
+ * getmxbyname() \n
+ * getrecordbyname() \n
+ * rrhost() \n
+ */
+
+#ifndef _WSHELPER_
+#define _WSHELPER_
+
+#include <winsock.h>
+#include <mitwhich.h>
+#include <resolv.h>
+#include <hesiod.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*! \fn struct hostent * WINAPI rgethostbyname(char *name)
+ * retrieves host information corresponding to a host name in the DNS database
+ *
+ * defined in gethna.c
+ *
+ * \param[in] name Pointer to the null-terminated name of the host to resolve. It can be a fully qualified host name such as x.mit.edu
+ * or it can be a simple host name such as x. If it is a simple host name, the default domain name is
+ * appended to do the search.
+ * \retval a pointer to the structure hostent. a structure allocated by the library. The hostent structure contains
+ * the results of a successful search for the host specified in the name parameter. The caller must never
+ * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ * structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another rgethostbyname.
+ * NULL if the search has failed
+ *
+*/
+struct hostent * WINAPI rgethostbyname(char *name);
+
+/*! \fn struct hostent * WINAPI rgethostbyaddr(char *addr, int len, int type)
+ * retrieves the host information corresponding to a network address in the DNS database
+ *
+ * defined in gethna.c
+ *
+ * \param[in] addr Pointer to an address in network byte order
+ * \param[in] len Length of the address, in bytes
+ * \param[in] type Type of the address, such as the AF_INET address family type (defined as TCP,
+ * UDP, and other associated Internet protocols). Address family types and their corresponding
+ * values are defined in the Winsock2.h header file.
+ * \retval returns a pointer to the hostent structure that contains the name and address corresponding
+ * to the given network address. The structure is allocated by the library. The caller must never
+ * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ * structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another rgethostbyaddr.
+ * NULL if the search has failed
+ *
+*/
+struct hostent * WINAPI rgethostbyaddr(char *addr, int len, int type);
+
+/*! \fn struct servent * WINAPI rgetservbyname(LPSTR name, LPSTR proto)
+ * retrieves service information corresponding to a service name and protocol.
+ *
+ * defined in gethna.c
+ *
+ * \param[in] name Pointer to a null-terminated service name.
+ * \param[in] proto pointer to a null-terminated protocol name. getservbyname should match both
+ * the name and the proto.
+ * \retval a pointer to the servent structure containing the name(s) and service number that match the name and proto
+ * parameters. The structure is allocated by the library. The caller must never
+ * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ * structure is allocated per call per thread, so the application should copy any information it needs before
+ * issuing another rgetservbyname.
+ * NULL if the search has failed
+ *
+ */
+struct servent * WINAPI rgetservbyname(LPSTR name, LPSTR proto);
+
+/*! \fn LPSTR WINAPI gethinfobyname(LPSTR name)
+ * unsupported
+ */
+LPSTR WINAPI gethinfobyname(LPSTR name);
+
+/*! \fn LPSTR WINAPI getmxbyname(LPSTR name)
+ * unsupported
+ */
+LPSTR WINAPI getmxbyname(LPSTR name);
+
+/*! \fn LPSTR WINAPI getrecordbyname(LPSTR name, int rectype)
+ * unsupported
+ */
+LPSTR WINAPI getrecordbyname(LPSTR name, int rectype);
+
+/*! \fn DWORD WINAPI rrhost( LPSTR lpHost )
+ * unsupported
+ */
+DWORD WINAPI rrhost( LPSTR lpHost );
+
+/*! \fn unsigned long WINAPI inet_aton(register const char *cp, struct in_addr *addr)
+ * converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the in_addr structure
+ *
+ * defined in inetaton.c
+ *
+ * \param[in] cp Null-terminated character string representing a number expressed in the
+ * Internet standard ".'' (dotted) notation.
+ * \param[in, out] addr pointer to the in_addr structure. The s_addr memeber will be populated
+ * \retval Returns 1 if the address is valid, 0 if not.
+ */
+unsigned long WINAPI inet_aton(register const char *cp, struct in_addr *addr);
+
+
+/*! \fn int WINAPI wsh_gethostname(char* name, int size)
+ * Gets the base part of the hostname
+ *
+ * defined in res_init.c
+ *
+ * \param[in, out] name pointer to a buffer that receives a null-terminated string containing the computer name
+ * \param[in] size specifies the size of the buffer, in chars (must be large
+ * enough to hold NULL-terminated host name)
+ * \retval return 0 ifsuccess, -1 on error.
+*/
+int WINAPI wsh_gethostname(char* name, int size);
+
+/*! \fn int WINAPI wsh_getdomainname(char* name, int size)
+ * Gets the machine's domain name
+ *
+ * defined in res_init.c
+ *
+ * \param[in, out] name pointer to a buffer that receives a null-terminated string containing the domain name
+ * \param[in] size specifies the size of the buffer, in chars (must be large
+ * enough to hold NULL-terminated domain name)
+ *
+ * \retval return 0 ifsuccess, -1 on error.
+ */
+int WINAPI wsh_getdomainname(char* name, int size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WSHELPER_ */
--- /dev/null
+//* 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
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+#define LSH_TIME_HOST 1970
+#define LSH_DEFAULT_TICKET_LIFE 1971
--- /dev/null
+#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 */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+// 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
--- /dev/null
+#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__ */
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+#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_ */
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+// *** 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
--- /dev/null
+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
--- /dev/null
+#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;
+}
--- /dev/null
+#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, §ions);
+
+ 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, §ions);
+
+ 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;
+}
--- /dev/null
+//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
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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!!!")
--- /dev/null
+//{{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
--- /dev/null
+/* 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);
+}
--- /dev/null
+#define VER_FILEDESCRIPTION_STR "Leash Helper DLL"
+
+#include <kerberos.ver>
+#include <ver.inc>
--- /dev/null
+/* 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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock.h>
+#include "wsh-int.h"
+#include <windns.h>
+#include "hesiod.h"
+#include "pwd.h"
+
+
+DWORD dwHesIndex; // for hes_to_bind
+DWORD dwHesMailIndex; // for hes_getmailhost
+DWORD dwHesServIndex; // for hes_getservbyname
+DWORD dwHesPwNamIndex; // for hes_getpwnam;
+DWORD dwHesPwUidIndex; // for hes_getpwuid
+DWORD dwGhnIndex; // for rgethostbyname
+DWORD dwGhaIndex; // for rgethostbyaddr
+
+#define LISTSIZE 15
+
+void FreeThreadLocalMemory();
+void AllocateThreadLocalMemory();
+void FreePasswdStruct(LPVOID lpvData);
+void FreeHostentStruct(LPVOID lpvData);
+
+BOOL
+WINAPI
+DllMain(
+ HINSTANCE hinstDLL, // handle to DLL module
+ DWORD fdwReason, // reason for calling function
+ LPVOID lpvReserved // reserved
+)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ if ((dwHesIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwHesMailIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwHesServIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwHesPwNamIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwHesPwUidIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwHesPwUidIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwGhnIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ if ((dwGhaIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ res_init_startup();
+ case DLL_THREAD_ATTACH:
+ // Initialize the TLS index for this thread.
+ AllocateThreadLocalMemory();
+ break;
+
+ case DLL_THREAD_DETACH:
+
+ // Release the allocated memory for this thread.
+ FreeThreadLocalMemory();
+ break;
+
+
+ case DLL_PROCESS_DETACH:
+ // Release the TLS index.
+ FreeThreadLocalMemory();
+ TlsFree(dwHesIndex);
+ TlsFree(dwHesMailIndex);
+ TlsFree(dwHesServIndex);
+ TlsFree(dwHesPwNamIndex);
+ TlsFree(dwHesPwUidIndex);
+ TlsFree(dwGhnIndex);
+ TlsFree(dwGhaIndex);
+
+ res_init_cleanup();
+ break;
+ }
+ return TRUE;
+}
+
+void AllocateThreadLocalMemory()
+{
+ LPVOID lpvData;
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, DNS_MAX_NAME_BUFFER_LENGTH);
+ if (lpvData != NULL)
+ TlsSetValue(dwHesIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hes_postoffice));
+ if (lpvData != NULL)
+ TlsSetValue(dwHesMailIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent));
+ if (lpvData != NULL)
+ TlsSetValue(dwHesServIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL)
+ TlsSetValue(dwHesPwNamIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL)
+ TlsSetValue(dwHesPwUidIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL)
+ TlsSetValue(dwGhnIndex, lpvData);
+
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL)
+ TlsSetValue(dwGhaIndex, lpvData);
+
+}
+void FreeThreadLocalMemory()
+{
+ LPVOID lpvData;
+ int i;
+
+ lpvData = TlsGetValue(dwHesIndex);
+ if (lpvData != NULL)
+ LocalFree((HLOCAL) lpvData);
+
+ // free hes_postoffice
+ lpvData = TlsGetValue(dwHesMailIndex);
+ if (lpvData)
+ {
+ struct hes_postoffice* p = (struct hes_postoffice*) lpvData;
+ if (p->po_type)
+ {
+ LocalFree(p->po_type);
+ p->po_type = NULL;
+ }
+ if (p->po_host)
+ {
+ LocalFree(p->po_host);
+ p->po_host = NULL;
+ }
+ if (p->po_name)
+ {
+ LocalFree(p->po_name);
+ p->po_name = NULL;
+ }
+ LocalFree((HLOCAL) lpvData);
+ }
+
+ // free servent
+ lpvData = TlsGetValue(dwHesServIndex);
+ if (lpvData)
+ {
+ struct servent* s = (struct servent*) lpvData;
+ if (s->s_name)
+ {
+ LocalFree(s->s_name);
+ s->s_name = NULL;
+ }
+ if (s->s_proto)
+ {
+ LocalFree(s->s_proto);
+ s->s_proto = NULL;
+ }
+ if (s->s_aliases)
+ {
+ for (i = 0; i<LISTSIZE; i++)
+ {
+ if (s->s_aliases[i])
+ {
+ LocalFree(s->s_aliases[i]);
+ s->s_aliases[i] = NULL;
+ }
+ }
+ LocalFree(s->s_aliases);
+ }
+ LocalFree((HLOCAL) lpvData);
+ }
+
+ // free struct passwd
+ lpvData = TlsGetValue(dwHesPwNamIndex);
+ FreePasswdStruct(lpvData);
+
+ lpvData = TlsGetValue(dwHesPwUidIndex);
+ FreePasswdStruct(lpvData);
+
+ // free struct hostent
+ lpvData = TlsGetValue(dwGhnIndex);
+ FreeHostentStruct(lpvData);
+
+ lpvData = TlsGetValue(dwGhaIndex);
+ FreeHostentStruct(lpvData);
+
+}
+
+
+void FreeHostentStruct(LPVOID lpvData)
+{
+ if (lpvData)
+ {
+ int i = 0;
+ struct hostent* host = (struct hostent*) lpvData;
+ if (host->h_name)
+ LocalFree(host->h_name);
+ if (host->h_aliases)
+ {
+ while(host->h_aliases[i])
+ {
+ LocalFree(host->h_aliases[i]);
+ host->h_aliases[i] = NULL;
+ i++;
+ }
+ LocalFree(host->h_aliases);
+ }
+ if (host->h_addr_list)
+ {
+ i = 0;
+ while (host->h_addr_list[i])
+ {
+ LocalFree(host->h_addr_list[i]);
+ host->h_addr_list[i] = NULL;
+ i++;
+ }
+ LocalFree(host->h_addr_list);
+ }
+ LocalFree((HLOCAL) lpvData);
+ }
+}
+
+void FreePasswdStruct(LPVOID lpvData)
+{
+ if (lpvData)
+ {
+ struct passwd* p = (struct passwd*) lpvData;
+ if (p->pw_name)
+ {
+ LocalFree(p->pw_name);
+ p->pw_name = NULL;
+ }
+ if (p->pw_passwd)
+ {
+ LocalFree(p->pw_passwd);
+ p->pw_passwd = NULL;
+ }
+ if (p->pw_comment)
+ {
+ LocalFree(p->pw_comment);
+ p->pw_comment = NULL;
+ }
+ if (p->pw_gecos)
+ {
+ LocalFree(p->pw_gecos);
+ p->pw_gecos = NULL;
+ }
+ if (p->pw_dir)
+ {
+ LocalFree(p->pw_dir);
+ p->pw_dir = NULL;
+ }
+ if (p->pw_shell)
+ {
+ LocalFree(p->pw_shell);
+ p->pw_shell = NULL;
+ }
+ LocalFree((HLOCAL) lpvData);
+ }
+}
--- /dev/null
+/*
+* @doc RESOLVE
+*
+* @module gethna.c |
+*
+* This file contains the function definitions for:
+* rgethostbyname,
+* rgethostbyaddr,
+* rdn_expand,
+* gethinfobyname,
+* getmxbyname,
+* getrecordbyname,
+* rrhost,
+* rgetservbyname,
+* and some other internal functions called by these functions.
+*
+*
+* WSHelper DNS/Hesiod Library for WINSOCK
+*
+*/
+
+/*
+ * Copyright (c) 1985, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 6.48 (Berkeley) 1/10/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <windns.h>
+
+#ifdef _WIN32
+#include <mitwhich.h>
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+extern DWORD dwGhnIndex;
+extern DWORD dwGhaIndex;
+
+unsigned long WINAPI inet_aton(register const char *, struct in_addr *);
+
+
+#ifdef _DEBUG
+#ifndef DEBUG
+#define DEBUG
+#endif
+#endif
+
+
+extern int WINAPI hes_error( void );
+DNS_STATUS doquery(const char* queryname, struct hostent* host);
+
+/*
+ query the dns name space for a host given the host name
+ \param[in] name Pointer to the null-terminated name of the host to resolve. It can be a fully qualified host name such as x.mit.edu
+ or it can be a simple host name such as x. If it is a simple host name, the default domain name is
+ appended to do the search.
+ \retval a pointer to the structure hostent. a structure allocated by the library. The hostent structure contains
+ the results of a successful search for the host specified in the name parameter. The caller must never
+ attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another rgethostbyname.
+ NULL if the search has failed
+
+*/
+struct hostent *
+WINAPI
+rgethostbyname(char *name)
+{
+ struct hostent* host;
+ DNS_STATUS status;
+ const char *cp;
+ char queryname[DNS_MAX_NAME_BUFFER_LENGTH ];
+#ifdef DEBUG
+ char debstr[80];
+#endif
+ char** domain;
+ struct in_addr host_addr;
+
+ host = (struct hostent*)(TlsGetValue(dwGhnIndex));
+ if (host == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwGhnIndex, lpvData);
+ host = (struct hostent*)lpvData;
+ } else
+ return NULL;
+ }
+
+ if (host->h_name == NULL)
+ host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ if (host->h_aliases == NULL)
+ host->h_aliases = LocalAlloc(LPTR, 1*sizeof(LPSTR));
+ if (host->h_addr_list == NULL)
+ {
+ host->h_addr_list = LocalAlloc(LPTR, 2*sizeof(LPSTR));
+ host->h_addr_list[0] = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ }
+
+
+ /*
+ * disallow names consisting only of digits/dots, unless
+ * they end in a dot.
+ */
+ if (isdigit(name[0])) {
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-numeric, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (!inet_aton(name, &host_addr)) {
+ return((struct hostent *) NULL);
+ }
+ strcpy(host->h_name, name);
+ host->h_aliases[0] = NULL;
+ host->h_addrtype = AF_INET;
+ host->h_length = sizeof(u_long);
+ memcpy(host->h_addr_list[0], &host_addr, sizeof(host_addr));
+ host->h_addr_list[1] = NULL;
+ return (host);
+ }
+ if (!isdigit(*cp) && *cp != '.')
+ break;
+ }
+ }
+
+ strcpy(queryname, name);
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return NULL;
+ if (strchr(name, '.') == NULL)
+ {
+ if (_res.options & RES_DEFNAMES)
+ {
+ for (domain = _res.dnsrch; *domain; domain++) {
+ strcpy(queryname, name);
+ strcat(queryname, ".");
+ strcat(queryname, *domain);
+ status = doquery(queryname, host);
+ if (status == 0)
+ break;
+ }
+ }
+ }
+ else {
+ status = doquery(queryname, host);
+ }
+
+ if (status) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ {
+ wsprintf(debstr, "res_query failed\n");
+ OutputDebugString(debstr);
+ }
+#endif
+ return NULL;
+ }
+ return host;
+}
+
+
+/*
+ an internal function used by rgethostbyname that does the actual DnsQuery call and populates the hostent
+ structure.
+
+ \param[in] Name of the owner of the record set being queried
+ \param[in, out] populated hostent structure
+
+ \retval DNS_STATUS value returned by DnsQuery
+
+*/
+DNS_STATUS doquery(const char* queryname, struct hostent* host)
+{
+ DNS_STATUS status;
+ PDNS_RECORD pDnsRecord, pDnsIter;
+ DNS_FREE_TYPE freetype ;
+ struct in_addr host_addr;
+ char querynamecp[DNS_MAX_NAME_BUFFER_LENGTH];
+ size_t len;
+
+ freetype = DnsFreeRecordListDeep;
+ strcpy(querynamecp, queryname);
+ status = DnsQuery_A(queryname, //pointer to OwnerName
+ DNS_TYPE_A, //Type of the record to be queried
+ DNS_QUERY_STANDARD,
+ NULL, //contains DNS server IP address
+ &pDnsRecord, //Resource record comprising the response
+ NULL); //reserved for future use
+
+ if (status)
+ return status;
+
+ /* If the query name includes a trailing separator in order to prevent
+ * a local domain search, remove the separator during the file name
+ * comparisons. */
+ len = strlen(querynamecp);
+ if (querynamecp[len-1] == '.')
+ querynamecp[len-1] = '\0';
+
+ for (pDnsIter = pDnsRecord; pDnsIter; pDnsIter=pDnsIter->pNext) {
+ /* if we get an A record, keep it */
+ if (pDnsIter->wType == DNS_TYPE_A && stricmp(querynamecp, pDnsIter->pName)==0)
+ break;
+
+ /* if we get a CNAME, look for a corresponding A record */
+ if (pDnsIter->wType == DNS_TYPE_CNAME && stricmp(queryname, pDnsIter->pName)==0) {
+ strcpy(querynamecp, pDnsIter->Data.CNAME.pNameHost);
+ }
+ }
+ if (pDnsIter == NULL)
+ return DNS_ERROR_RCODE_NAME_ERROR;
+
+ strcpy(host->h_name, pDnsIter->pName);
+ host->h_addrtype = AF_INET;
+ host->h_length = sizeof(u_long);
+ host->h_aliases[0] = NULL;
+ host_addr.S_un.S_addr = (pDnsIter->Data.A.IpAddress);
+ memcpy(host->h_addr_list[0], (char*)&host_addr, sizeof(pDnsIter->Data.A.IpAddress));
+ host->h_addr_list[1] = NULL;
+ DnsRecordListFree(pDnsRecord, freetype);
+
+ return 0;
+}
+
+
+/*
+ retrieves the host information corresponding to a network address in the DNS database
+ \param[in] addr Pointer to an address in network byte order
+ \param[in] len Length of the address, in bytes
+ \param[in] type Type of the address, such as the AF_INET address family type (defined as TCP,
+ UDP, and other associated Internet protocols). Address family types and their corresponding
+ values are defined in the Winsock2.h header file.
+ \retval returns a pointer to the hostent structure that contains the name and address corresponding
+ to the given network address. The structure is allocated by the library. The caller must never
+ attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another rgethostbyaddr.
+ NULL if the search has failed
+
+*/
+
+struct hostent *
+WINAPI
+rgethostbyaddr(const char *addr, int len, int type)
+{
+ DNS_STATUS status;
+ struct hostent* host;
+#ifdef DEBUG
+ char debstr[80];
+#endif
+
+ PDNS_RECORD pDnsRecord;
+ DNS_FREE_TYPE freetype ;
+ char qbuf[BUFSIZ];
+
+ if (type != AF_INET)
+ return ((struct hostent *) NULL);
+
+ wsprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ ((unsigned)addr[3] & 0xff),
+ ((unsigned)addr[2] & 0xff),
+ ((unsigned)addr[1] & 0xff),
+ ((unsigned)addr[0] & 0xff));
+
+
+ freetype = DnsFreeRecordListDeep;
+
+
+ status = DnsQuery_A(qbuf, //pointer to OwnerName
+ DNS_TYPE_PTR, //Type of the record to be queried
+ DNS_QUERY_STANDARD,
+ NULL, //contains DNS server IP address
+ &pDnsRecord, //Resource record comprising the response
+ NULL); //reserved for future use
+
+ if (status) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ {
+ wsprintf(debstr, "res_query failed\n");
+ OutputDebugString(debstr);
+ }
+#endif
+
+ return NULL;
+ }
+
+ host = (struct hostent*)(TlsGetValue(dwGhaIndex));
+ if (host == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwGhaIndex, lpvData);
+ host = (struct hostent*)lpvData;
+ } else
+ return NULL;
+ }
+
+ if (host->h_name == NULL)
+ host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ if (host->h_aliases == NULL)
+ host->h_aliases = LocalAlloc(LPTR, 1*sizeof(LPSTR));
+ if (host->h_addr_list == NULL)
+ {
+ host->h_addr_list = LocalAlloc(LPTR, 2*sizeof(LPSTR));
+ host->h_addr_list[0] = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ }
+
+ strcpy(host->h_name, pDnsRecord->Data.Ptr.pNameHost);
+ host->h_addrtype = type;
+ host->h_length = len;
+ host->h_aliases[0] = NULL;
+ memcpy(host->h_addr_list[0], addr, sizeof(unsigned long));
+ host->h_addr_list[1] = NULL;
+ DnsRecordListFree(pDnsRecord, freetype);
+
+ return host;
+
+}
+
+
+/*
+
+ @doc MISC
+
+ @func LPSTR WINAPI | gethinfobyname | Given the name
+ of a host query the nameservers for the T_HINFO information
+ associated with the host. unsupported
+
+ @parm LPSTR | name | pointer to the name of the host that the query is about.
+
+ @rdesc NULL or a pointer to the T_HINFO.
+
+
+*/
+
+LPSTR
+WINAPI
+gethinfobyname(LPSTR name)
+{
+ return NULL;
+
+}
+
+
+/*
+
+ @func struct mxent * WINAPI | getmxbyname | This
+ function will query the nameservers for the MX records associated
+ with the given hostname. Note that the return is a pointer to the
+ mxent structure so an application making this call can iterate
+ through the different records returned and can also reference the
+ preference information associated with each hostname returned. unsupported
+
+ @parm LPSTR | name | The name of the host for which we want MX records.
+
+ @rdesc NULL or a pointer to a mxent structure.
+
+ */
+
+struct mxent *
+WINAPI
+getmxbyname(LPSTR name)
+{
+ return NULL;
+}
+
+
+/*
+
+ @func LPSTR WINAPI | getrecordbyname | This function
+ will query the nameservers about the given hostname for and DNS
+ record type that the application wishes to query. unsupported
+
+ @parm LPSTR | name | a pointer to the hostname
+
+ @parm int | rectype | a DNS record type, e.g. T_MX, T_HINFO, ...
+
+ @rdesc The return is NULL or a pointer to a string containing the
+ data returned. It is up to the calling application to parse the
+ string appropriately for the rectype queried.
+
+*/
+
+LPSTR
+WINAPI
+getrecordbyname(LPSTR name, int rectype)
+{
+ return NULL;
+}
+
+
+/*
+
+ @func DWORD WINAPI | rrhost | This function emulates the
+ rhost function that was part of Excelan / Novell's LAN WorkPlace TCP/IP API.
+ Given a pointer to an IP hostname it will return the IP address as a 32 bit
+ integer.
+
+
+ @parm LPSTR | lpHost | a pointer to the hostname.
+
+ @rdesc 0 or the IP address as a 32 bit integer.
+
+*/
+
+DWORD WINAPI rrhost( LPSTR lpHost )
+{
+ return (DWORD) 0;
+}
+
+
+/*
+ retrieves service information corresponding to a service name and protocol.
+
+ \param[in] name Pointer to a null-terminated service name.
+ \param[in] proto pointer to a null-terminated protocol name. getservbyname should match both
+ the name and the proto.
+
+ \retval a pointer to the servent structure containing the name(s) and service number that match the name and proto
+ parameters. The structure is allocated by the library. The caller must never
+ attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+ structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another rgetservbyname.
+ NULL if the search has failed
+
+*/
+
+struct servent * WINAPI rgetservbyname(LPCSTR name, LPCSTR proto)
+{
+ struct servent * WINAPI hes_getservbyname(LPCSTR name, LPCSTR proto);
+ struct servent *tmpent;
+
+ tmpent = hes_getservbyname(name, proto);
+ return (!hes_error()) ? tmpent : getservbyname(name, proto);
+}
--- /dev/null
+/*
+ @doc HESIOD
+
+ @module hesiod.c |
+
+ This module contains the defintions for the exported functions:
+ hes_to_bind
+ hes_resolve
+ hes_error
+ hes_free
+ as well as the internal function hes_init. The hes_init function
+ is the one that determines what the Hesiod servers are for your
+ site and will parse the configuration files, if any are
+ present.
+
+ WSHelper DNS/Hesiod Library for WINSOCK
+
+*/
+
+/* This file is part of the Hesiod library.
+ *
+ * The BIND 4.8.1 implementation of T_TXT is incorrect; BIND 4.8.1 declares
+ * it as a NULL terminated string. The RFC defines T_TXT to be a length
+ * byte followed by arbitrary changes.
+ *
+ * Because of this incorrect declaration in BIND 4.8.1, when this bug is fixed,
+ * T_TXT requests between machines running different versions of BIND will
+ * not be compatible (nor is there any way of adding compatibility).
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology. See the
+ * file <mit-copyright.h> for copying and distribution information.
+ */
+
+#define index(str, c) strchr(str,c)
+#include <stdio.h>
+#include <errno.h>
+
+#include <windows.h>
+#include <winsock.h>
+#include <string.h>
+#include <hesiod.h>
+#include <resolv.h>
+#include <windns.h>
+
+#include "resource.h"
+
+
+#define USE_HS_QUERY /* undefine this if your higher-level name servers */
+ /* don't know class HS */
+
+char HesConfigFile[_MAX_PATH];
+static char Hes_LHS[256];
+static char Hes_RHS[256];
+static int Hes_Errno = HES_ER_UNINIT;
+
+extern DWORD dwHesIndex;
+
+
+
+/*
+
+ @func int | hes_init |
+
+ This function is not exported. It takes no arguments. However it is
+ important to understand how this works. It sets the global variables
+ Hes_LHS and Hes_RHS which are used to form the Hesiod
+ queries. Understanding how this works and setting up the correct
+ configuration will determine if the Hesiod queries will work at your
+ site. Settings can be configured by makgin source code changes and
+ rebuilding the DLL, editing resources in the DLL, using a
+ configuration file, or setting an environment variable.
+
+ The function first tries to open the HesConfigFile and set the
+ Hes_RHS and Hes_LHS variables from this. If there is no config file
+ then the function tries to load a string resource from the DLL to
+ set the LHS and RHS. If the string resources cannot be loaded then
+ the LHS and RHS will be set by the values of DEF_LHS and DEF_RHS,
+ these are defined in hesiod.h. Note that the string resources are by
+ default set to these same values since the RC files include hesiod.h
+
+ Finally if the user sets the environment variable HES_DOMAIN the RHS
+ will be overridden by the value of the HES_DOMAIN value.
+
+ Note that LoadString requires us to first find the module handle of
+ the DLL. We have to use the internal module name as defined in the
+ DEF file. If you change the library name within the DEF file you
+ also need to change the appropriate string in hesiod.c
+
+*/
+int hes_init( void )
+{
+ register FILE *fp;
+ register char *key;
+ register char *cp;
+ char buf[MAXDNAME+7];
+ HMODULE hModWSHelp;
+
+
+ Hes_Errno = HES_ER_UNINIT;
+ Hes_LHS[0] = '\0';
+ Hes_RHS[0] = '\0';
+
+ // Note: these must match the DEF file entries
+#if defined(_WIN64)
+ hModWSHelp = GetModuleHandle( "WSHELP64" );
+#else
+ hModWSHelp = GetModuleHandle( "WSHELP32" );
+#endif
+
+ if(!LoadString( hModWSHelp, IDS_DEF_HES_CONFIG_FILE,
+ HesConfigFile, sizeof(HesConfigFile) )){
+ strcpy( HesConfigFile, HESIOD_CONF);
+ }
+
+ if ((fp = fopen(HesConfigFile, "r")) == NULL) {
+ /* use defaults compiled in */
+ /* no file or no access uses defaults */
+ /* but poorly formed file returns error */
+
+ if(!LoadString( hModWSHelp, IDS_DEF_HES_RHS, Hes_RHS, sizeof(Hes_RHS) )){
+ strcpy( Hes_RHS, DEF_RHS);
+ }
+
+ if(!LoadString( hModWSHelp, IDS_DEF_HES_LHS, Hes_LHS, sizeof(Hes_LHS) )){
+ strcpy( Hes_LHS, DEF_LHS);
+ }
+ } else {
+ while(fgets((LPSTR) buf, MAXDNAME+7, fp) != NULL) {
+ cp = (LPSTR) buf;
+ if (*cp == '#' || *cp == '\n'){
+ continue;
+ }
+ while(*cp == ' ' || *cp == '\t'){
+ cp++;
+ }
+ key = cp;
+ while(*cp != ' ' && *cp != '\t' && *cp != '='){
+ cp++;
+ }
+ *cp++ = '\0';
+ if (strcmp(key, "lhs") == 0){
+ strncpy(&Hes_LHS[0], cp, (strlen(cp)-1));
+ } else if (strcmp(key, "rhs") == 0){
+ strncpy(&Hes_RHS[0], cp, (strlen(cp)-1));
+ } else {
+ continue;
+ }
+ while(*cp == ' ' || *cp == '\t' || *cp == '='){
+ cp++;
+ }
+ if (*cp != '.') {
+ Hes_Errno = HES_ER_CONFIG;
+ fclose(fp);
+ return(Hes_Errno);
+ }
+ // len = strlen(cp);
+ // *cpp = calloc((unsigned int) len, sizeof(char));
+ // (void) strncpy(*cpp, cp, len-1);
+ }
+ fclose(fp);
+ }
+ /* see if the RHS is overridden by environment variable */
+ if ((cp = getenv("HES_DOMAIN")) != NULL){
+ // Hes_RHS = strcpy(malloc(strlen(cp)+1),cp);
+ strcpy(Hes_RHS,cp);
+ }
+ /* the LHS may be null, the RHS must not be null */
+ if (Hes_RHS == NULL)
+ Hes_Errno = HES_ER_CONFIG;
+ else
+ Hes_Errno = HES_ER_OK;
+ return(Hes_Errno);
+}
+
+
+/*
+ hes_to_bind function use the LHS and RHS values and
+ binds them with the parameters so that a well formed DNS query may
+ be performed.
+
+ \param[in] HesiodName The Hesiod name such as a username or service name
+ \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc
+
+ \retval Returns NULL if there was an error. Otherwise the pointer to a string containing a valid query is returned.
+
+*/
+char *
+WINAPI
+hes_to_bind(LPSTR HesiodName,
+ LPSTR HesiodNameType)
+{
+ register char *cp, **cpp;
+ char* bindname;
+ LPVOID lpvData;
+ char *RHS;
+
+ cp = NULL;
+ cpp = NULL;
+
+ bindname = (LPSTR)(TlsGetValue(dwHesIndex));
+ if (bindname == NULL)
+ {
+ lpvData = LocalAlloc(LPTR, DNS_MAX_NAME_BUFFER_LENGTH);
+ if (lpvData != NULL)
+ {
+ TlsSetValue(dwHesIndex, lpvData);
+ bindname = (LPSTR)lpvData;
+ }
+ else
+ return NULL;
+ }
+ if (Hes_Errno == HES_ER_UNINIT || Hes_Errno == HES_ER_CONFIG)
+ (void) hes_init();
+ if (Hes_Errno == HES_ER_CONFIG)
+ return(NULL);
+ if (cp = index(HesiodName,'@')) {
+ if (index(++cp,'.'))
+ RHS = cp;
+ else
+ if (cpp = hes_resolve(cp, "rhs-extension"))
+ RHS = *cpp;
+ else {
+ Hes_Errno = HES_ER_NOTFOUND;
+ return(NULL);
+ }
+ (void) strcpy(bindname,HesiodName);
+ (*index(bindname,'@')) = '\0';
+ } else {
+ RHS = Hes_RHS;
+ (void) strcpy(bindname, HesiodName);
+ }
+ (void) strcat(bindname, ".");
+ (void) strcat(bindname, HesiodNameType);
+ if (Hes_LHS) {
+ if (Hes_LHS[0] != '.')
+ (void) strcat(bindname,".");
+ (void) strcat(bindname, Hes_LHS);
+ }
+ if (RHS[0] != '.')
+ (void) strcat(bindname,".");
+ (void) strcat(bindname, RHS);
+
+ if(cpp != NULL )
+ hes_free(cpp);
+
+ return(bindname);
+}
+
+
+/*
+ This function calls hes_to_bind to form a valid hesiod query, then queries the dns database.
+ defined in hesiod.c
+
+ \param[in] HesiodName The Hesiod name such as a username or service name
+ \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc
+
+ \retval returns a NULL terminated vector of strings (a la argv),
+ one for each resource record containing Hesiod data, or NULL if
+ there is any error. If there is an error call hes_error() to get
+ further information. You will need to call hes_free to free the result
+
+*/
+char **
+WINAPI
+hes_resolve(LPSTR HesiodName, LPSTR HesiodNameType)
+{
+ register char *cp;
+ LPSTR* retvec;
+ DNS_STATUS status;
+
+ PDNS_RECORD pDnsRecord;
+ PDNS_RECORD pR;
+ DNS_FREE_TYPE freetype ;
+ int i = 0;
+ freetype = DnsFreeRecordListDeep;
+
+
+ cp = hes_to_bind(HesiodName, HesiodNameType);
+ if (cp == NULL) return(NULL);
+ errno = 0;
+
+
+ status = DnsQuery_A(cp, //pointer to OwnerName
+ DNS_TYPE_TEXT, //Type of the record to be queried
+ DNS_QUERY_STANDARD, // Bypasses the resolver cache on the lookup.
+ NULL, //contains DNS server IP address
+ &pDnsRecord, //Resource record comprising the response
+ NULL); //reserved for future use
+
+ if (status) {
+ errno = status;
+ Hes_Errno = HES_ER_NOTFOUND;
+ return NULL;
+ }
+
+ pR = pDnsRecord;
+ while (pR)
+ {
+ if (pR->wType == DNS_TYPE_TEXT)
+ i++;
+ pR = pR->pNext;
+ }
+ i++;
+ retvec = LocalAlloc(LPTR, i*sizeof(LPSTR));
+ pR = pDnsRecord;
+ i = 0;
+ while (pR)
+ {
+ if (pR->wType == DNS_TYPE_TEXT){
+ SIZE_T l = strlen(((pR->Data).Txt.pStringArray)[0]);
+ retvec[i] = LocalAlloc(LPTR, l+1);
+ strcpy(retvec[i], ((pR->Data).Txt.pStringArray)[0]);
+ i++;
+ }
+ pR = pR->pNext;
+ }
+ retvec[i] = NULL;
+ DnsRecordListFree(pDnsRecord, freetype);
+ return retvec;
+
+}
+
+
+/*
+ The function hes_error may be called to determine the
+ source of the error. It does not take an argument.
+
+ \retval return one of the HES_ER_* codes defined in hesiod.h.
+*/
+
+int
+WINAPI
+hes_error(void)
+{
+ return(Hes_Errno);
+}
+
+
+/*
+
+ The function hes_free should be called to free up memeory returned by
+ hes_resolve
+
+ \param[in] hesinfo a NULL terminiated array of strings returned by hes_resolve
+
+
+*/
+void
+WINAPI
+hes_free(LPSTR* info)
+{
+ int i= 0;
+ for (; info[i]; i++)
+ {
+ LocalFree(info[i]);
+ }
+ LocalFree(info);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @doc HESIOD
+ *
+ * @module hesmailh.c |
+ *
+ * This file contains hes_postoffice, which retrieves post-office information
+ * for a user.
+ *
+ * For copying and distribution information, see the file
+ * <lt> mit-copyright.h <gt>
+ *
+ * Original version by Steve Dyer, IBM/Project Athena.
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h> /*s*/
+
+#include <hesiod.h>
+
+
+#define LINESIZE 80
+
+extern DWORD dwHesMailIndex;
+
+
+/*
+ This call is used to obtain a user's type of mail account and the location of that
+ account. E.g. POP PO10.MIT.EDU or IMAP IMAP-TEST.MIT.EDU
+
+ defined in hesmailh.c
+
+ \param[in] user The username to be used when querying for the Hesiod Name Type POBOX.
+
+ \retval NULL if there was an error or if there was no entry for the
+ username. Otherwise a pointer to a hes_postoffice structure is
+ returned. The caller must never attempt to modify this structure or to free
+ any of its components. Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another getmailhost call
+
+*/
+struct hes_postoffice *
+WINAPI
+hes_getmailhost(LPSTR user)
+{
+ struct hes_postoffice* ret;
+ char linebuf[LINESIZE];
+ char *p, *tmp;
+ char **cp;
+
+
+ cp = hes_resolve(user, "pobox");
+ if (cp == NULL) return(NULL);
+
+ ret = (struct hes_postoffice*)(TlsGetValue(dwHesMailIndex));
+ if (ret == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hes_postoffice));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesMailIndex, lpvData);
+ ret = (struct hes_postoffice*)lpvData;
+ } else
+ return NULL;
+ }
+ if (!ret->po_type)
+ ret->po_type = LocalAlloc(LPTR, LINESIZE);
+ if (!ret->po_host)
+ ret->po_host = LocalAlloc(LPTR, LINESIZE);
+ if (!ret->po_name)
+ ret->po_name = LocalAlloc(LPTR, LINESIZE);
+ strcpy(linebuf, *cp);
+
+ p = linebuf;
+ tmp = linebuf;
+ while(!isspace(*p)) p++;
+ *p++ = '\0';
+ strcpy(ret->po_type, tmp);
+ tmp = p;
+ while(!isspace(*p)) p++;
+ *p++ = '\0';
+ strcpy(ret->po_host, tmp);
+ strcpy(ret->po_name, p);
+ if (cp)
+ hes_free(cp);
+ return(ret);
+}
--- /dev/null
+/*
+ * @doc HESIOD
+ *
+ * @module hespwnam.c |
+ *
+ * This file contains hes_getpwnam, for retrieving passwd information about
+ * a user.
+ *
+ * For copying and distribution information, see the file
+ * <lt> mit-copyright.h <gt>
+ *
+ * Original version by Steve Dyer, IBM/Project Athena.
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ *
+ */
+
+/* This file contains hes_getpwnam, for retrieving passwd information about
+ * a user.
+ *
+ * For copying and distribution information, see the file <mit-copyright.h>
+ *
+ * Original version by Steve Dyer, IBM/Project Athena.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h> /*s*/
+
+#include <stdlib.h>
+
+#include <windows.h>
+#include <hesiod.h>
+
+#include "pwd.h"
+
+extern DWORD dwHesPwNamIndex;
+extern DWORD dwHesPwUidIndex;
+
+#define MAX_PW_BUFFER_LENGTH 64
+
+static char *
+_NextPWField(char *ptr);
+
+struct passwd * GetPasswdStruct(struct passwd* pw, char* buf);
+
+
+
+
+/*
+ Given a UID this function will return the pwd information, eg username, uid,
+ gid, fullname, office location, phone number, home directory, and default shell
+
+ defined in hespwnam.c
+ \param uid The user ID
+ \retval NULL if there was an error or a pointer to the passwd structure. The caller must
+ never attempt to modify this structure or to free any of its components.
+ Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another hes_getpwuid call
+*/
+struct passwd *
+WINAPI
+hes_getpwuid(int uid)
+{
+ char **pp;
+ struct passwd* pw = NULL;
+ char buf[256];
+
+ char nam[8];
+ sprintf(nam, "%d", uid);
+
+ pp = hes_resolve(nam, "uid");
+ if (pp == NULL || *pp == NULL)
+ return(NULL);
+
+ pw = (struct passwd*)(TlsGetValue(dwHesPwUidIndex));
+ if (pw == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesPwUidIndex, lpvData);
+ pw = (struct passwd*)lpvData;
+ } else
+ return NULL;
+ }
+
+ strcpy(buf, pp[0]);
+ hes_free(pp);
+ return GetPasswdStruct(pw, buf);
+}
+
+
+/*
+ Given a username this function will return the pwd information, eg
+ username, uid, gid, fullname, office location, phone number, home
+ directory, and default shell
+
+ defined in hespwnam.c
+
+ \param nam a pointer to the username
+
+ \retval NULL if there was an error or a pointer to the passwd structure. The caller must
+ never attempt to modify this structure or to free any of its components.
+ Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another hes_getpwnam call
+
+*/
+struct passwd *
+WINAPI
+hes_getpwnam(char *nam)
+{
+
+ char **pp;
+ struct passwd* pw = NULL;
+ char buf[256];
+
+ pp = hes_resolve(nam, "passwd");
+ if (pp == NULL || *pp == NULL)
+ return(NULL);
+
+ pw = (struct passwd*)(TlsGetValue(dwHesPwNamIndex));
+ if (pw == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesPwNamIndex, lpvData);
+ pw = (struct passwd*)lpvData;
+ } else
+ return NULL;
+ }
+
+ strcpy(buf, pp[0]);
+ hes_free(pp);
+ return GetPasswdStruct(pw, buf);
+}
+
+
+struct passwd* GetPasswdStruct(struct passwd* pw, char* buf)
+{
+ char* temp;
+ char* p;
+
+ if (pw->pw_name == NULL)
+ pw->pw_name = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ if (pw->pw_passwd == NULL)
+ pw->pw_passwd = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ if (pw->pw_comment == NULL)
+ pw->pw_comment = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ if (pw->pw_gecos == NULL)
+ pw->pw_gecos = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ if (pw->pw_dir == NULL)
+ pw->pw_dir = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ if (pw->pw_shell == NULL)
+ pw->pw_shell = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+ /* choose only the first response (only 1 expected) */
+ p = buf;
+ temp = p;
+ p = _NextPWField(p);
+ strcpy(pw->pw_name, temp);
+ temp = p;
+ p = _NextPWField(p);
+ strcpy(pw->pw_passwd, temp);
+ pw->pw_uid = atoi(p);
+ p = _NextPWField(p);
+ pw->pw_gid = atoi(p);
+ pw->pw_quota = 0;
+ strcpy(pw->pw_comment, "");
+ p = _NextPWField(p);
+ temp = p;
+ p = _NextPWField(p);
+ strcpy(pw->pw_gecos, temp);
+ temp = p;
+ p = _NextPWField(p);
+ strcpy(pw->pw_dir, temp);
+ temp = p;
+ while (*p && *p != '\n')
+ p++;
+ *p = '\0';
+ strcpy(pw->pw_shell, temp);
+ return pw;
+
+
+}
+
+/* Move the pointer forward to the next colon-separated field in the
+ * password entry.
+ */
+
+static char *
+_NextPWField(char *ptr)
+{
+ while (*ptr && *ptr != '\n' && *ptr != ':')
+ ptr++;
+ if (*ptr)
+ *ptr++ = '\0';
+ return(ptr);
+}
--- /dev/null
+/*
+ * @doc HESIOD
+ *
+ * @module hesservb.c |
+ *
+ *
+ * Contains the definition for hes_getservbyname,
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyname.c 5.3 (Berkeley) 5/19/86";
+#endif /* LIBC_SCCS and not lint */
+
+#include <hesiod.h>
+#include <windows.h>
+#include <winsock.h>
+#include <windns.h>
+
+#include <string.h>
+
+#include <stdio.h>
+#include <ctype.h>
+
+#define cistrcmp stricmp
+
+#define LISTSIZE 15
+
+
+/*
+ This function will query a Hesiod server for a servent structure given
+ a service name and protocol. This is a replacement for the Winsock
+ getservbyname function which normally just uses a local services
+ file. This allows a site to use a centralized database for adding new
+ services.
+
+ defined in hesservb.c
+
+ \param[in] name pointer to the official name of the service, eg "POP3".
+ \param[in] proto pointer to the protocol to use when contacting the service, e.g. "TCP"
+
+ \retval NULL if there was an error or a pointer to a servent structure. The caller must
+ never attempt to modify this structure or to free any of its components.
+ Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+ issuing another hes_getservbyname call
+
+*/
+
+extern DWORD dwHesServIndex;
+struct servent *
+WINAPI
+hes_getservbyname(char *name, char *proto)
+{
+ struct servent *p;
+ register char **cp;
+ register char** hesinfo;
+ register int i = 0;
+
+ char buf[DNS_MAX_NAME_BUFFER_LENGTH];
+ char* l;
+
+ hesinfo = hes_resolve(name, "service");
+ cp = hesinfo;
+ if (cp == NULL)
+ return(NULL);
+ p = (struct servent*)(TlsGetValue(dwHesServIndex));
+ if (p == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesServIndex, lpvData);
+ p = (struct servent*)lpvData;
+ } else
+ return NULL;
+ }
+ if (!p->s_name)
+ p->s_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ if (!p->s_proto)
+ p->s_proto = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+ if (!p->s_aliases)
+ p->s_aliases = LocalAlloc(LPTR, LISTSIZE*sizeof(LPSTR));
+
+ for (;*cp; cp++) {
+ register char *servicename, *protoname, *port;
+ strcpy(buf, *cp);
+ l = buf;
+ while(*l && (*l == ' ' || *l == '\t')) l++;
+ servicename = l;
+ while(*l && *l != ' ' && *l != '\t' && *l != ';') l++;
+ if (*l == '\0') continue; /* malformed entry */
+ *l++ = '\0';
+ while(*l && (*l == ' ' || *l == '\t')) l++;
+ protoname = l;
+ while(*l && *l != ' ' && *l != ';') l++;
+ if (*l == '\0') continue; /* malformed entry */
+ *l++ = '\0';
+ if (cistrcmp(proto, protoname)) continue; /* wrong port */
+ while(*l && (*l == ' ' || *l == '\t' || *l == ';')) l++;
+ if (*l == '\0') continue; /* malformed entry */
+ port = l;
+ while(*l && (*l != ' ' && *l != '\t' && *l != ';')) l++;
+ if (*l) *l++ = '\0';
+ if (*l != '\0') {
+ do {
+ char* tmp = l;
+ while(*l && !isspace(*l)) l++;
+ if (*l) *l++ = 0;
+ if (p->s_aliases[i])
+ p->s_aliases[i] = LocalAlloc(LPTR, strlen(tmp));
+ strcpy(p->s_aliases[i], tmp);
+ i++;
+ } while(*l);
+ }
+ p->s_aliases[i] = NULL;
+ for (; i<LISTSIZE; i++)
+ {
+ if (p->s_aliases[i]){
+ LocalFree(p->s_aliases[i]);
+ p->s_aliases[i] = NULL;
+ }
+ }
+ strcpy(p->s_name, servicename);
+ p->s_port = htons((u_short)atoi(port));
+ strcpy(p->s_proto, protoname);
+ if (hesinfo)
+ hes_free(hesinfo);
+ return (p);
+ }
+ return(NULL);
+}
--- /dev/null
+/*
+ *
+ * @doc RESOLVE
+ *
+ * @module inetaton.c |
+ *
+ * from the BIND 4.9.x inetaddr.c
+ *
+ * Contains implementation of inet_aton
+
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1983, 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 5.11 (Berkeley) 12/9/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <ctype.h>
+
+
+/*
+ converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the in_addr structure
+
+ \param[in] cp Null-terminated character string representing a number expressed in the
+ Internet standard ".'' (dotted) notation.
+ \param[in, out] addr pointer to the in_addr structure. The s_addr memeber will be populated
+
+
+ \retval Returns 1 if the address is valid, 0 if not.
+
+ */
+unsigned long
+WINAPI
+inet_aton(register const char *cp, struct in_addr *addr)
+{
+ register u_long val, base;
+ ULONG_PTR n;
+ register char c;
+ u_long parts[4], *pp = parts;
+
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0; base = 10;
+ if (*cp == '0') {
+ if (*++cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ else
+ base = 8;
+ }
+ while ((c = *cp) != '\0') {
+ if (isascii(c) && isdigit(c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) +
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return (0);
+ *pp++ = val, cp++;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (*cp && (!isascii(*cp) || !isspace(*cp)))
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr)
+ addr->s_addr = htonl(val);
+ return (1);
+}
--- /dev/null
+/* pwd.h 4.1 83/05/03 */
+
+struct passwd { /* see getpwent(3) */
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ int pw_quota;
+ char *pw_comment;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+};
+
+struct passwd *getpwent(), *getpwuid(), *getpwnam();
--- /dev/null
+/*
+ *
+ * @doc RESOLVE
+ *
+ * @module res_comp.c |
+ *
+ * Contains the implementations for dn_comp and rdn_expand as well as
+ * some other functions used internally by these two functions.
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c 6.22 (Berkeley) 3/19/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+
+
+static dn_find();
+
+/*
+ replacement for dn_expand called rdn_expand. Older versions of
+ the DLL used to this as dn_expand but this has caused some
+ conflict with more recent versions of the MSDEV
+ libraries. rdn_expand() expands the compressed domain name comp_dn to
+ a full domain name. Expanded names are converted to upper case.
+
+ \param[in] msg msg is a pointer to the beginning of the message
+ \param[in] eomorig
+ \param[in] comp_dn the compressed domain name.
+ \param[in, out] expn_dn a pointer to the result buffer
+ \param[in] length size of the result in expn_dn
+
+ \retval the size of compressed name is returned or -1 if there was an error.
+*/
+
+
+
+int WINAPI
+rdn_expand(const u_char *msg, const u_char *eomorig,
+ const u_char *comp_dn, u_char *exp_dn, int length)
+{
+ register u_char *cp, *dn;
+ register int n, c;
+ u_char *eom;
+ INT_PTR len = -1;
+ int checked = 0;
+
+ dn = exp_dn;
+ cp = (u_char *)comp_dn;
+ eom = exp_dn + length;
+ /*
+ * fetch next label in domain name
+ */
+ while (n = *cp++) {
+ /*
+ * Check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0:
+ if (dn != exp_dn) {
+ if (dn >= eom)
+ return (-1);
+ *dn++ = '.';
+ }
+ if (dn+n >= eom)
+ return (-1);
+ checked += n + 1;
+ while (--n >= 0) {
+ if ((c = *cp++) == '.') {
+ if (dn + n + 2 >= eom)
+ return (-1);
+ *dn++ = '\\';
+ }
+ *dn++ = c;
+ if (cp >= eomorig) /* out of range */
+ return(-1);
+ }
+ break;
+
+ case INDIR_MASK:
+ if (len < 0)
+ len = cp - comp_dn + 1;
+ cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
+ if (cp < msg || cp >= eomorig) /* out of range */
+ return(-1);
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eomorig - msg)
+ return (-1);
+ break;
+
+ default:
+ return (-1); /* flag error */
+ }
+ }
+ *dn = '\0';
+ if (len < 0)
+ len = cp - comp_dn;
+ return (int)(len);
+}
+
+
+/*
+ Compress domain name 'exp_dn' into 'comp_dn'
+ \param[in] exp_dn name to compress
+ \param[in, out] comp_dn result of the compression
+ \paramp[in] length the size of the array pointed to by 'comp_dn'.
+ \param[in, out] dnptrs a list of pointers to previous compressed names. dnptrs[0]
+ is a pointer to the beginning of the message. The list ends with NULL.
+ \param[in] lastdnptr a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect
+ is to update the list of pointers for labels inserted into the
+ message as we compress the name. If 'dnptr' is NULL, we don't try to
+ compress names. If 'lastdnptr' is NULL, we don't update the list.
+ \retval Return the size of the compressed name or -1
+ */
+int WINAPI
+dn_comp(const u_char *exp_dn, u_char *comp_dn, int length,
+ u_char **dnptrs, u_char **lastdnptr)
+{
+ register u_char *cp, *dn;
+ register int c, l;
+ u_char **cpp, **lpp, *sp, *eob;
+ u_char *msg;
+
+ dn = (u_char *)exp_dn;
+ cp = comp_dn;
+ eob = cp + length;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ ;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+ for (c = *dn++; c != '\0'; ) {
+ /* look to see if we can use pointers */
+ if (msg != NULL) {
+ if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
+ if (cp+1 >= eob)
+ return (-1);
+ *cp++ = (l >> 8) | INDIR_MASK;
+ *cp++ = l % 256;
+ return (int)(cp - comp_dn);
+ }
+ /* not found, save it */
+ if (lastdnptr != NULL && cpp < lastdnptr-1) {
+ *cpp++ = cp;
+ *cpp = NULL;
+ }
+ }
+ sp = cp++; /* save ptr to length byte */
+ do {
+ if (c == '.') {
+ c = *dn++;
+ break;
+ }
+ if (c == '\\') {
+ if ((c = *dn++) == '\0')
+ break;
+ }
+ if (cp >= eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *cp++ = c;
+ } while ((c = *dn++) != '\0');
+ /* catch trailing '.'s but not '..' */
+ if ((l =(int)( cp - sp - 1)) == 0 && c == '\0') {
+ cp--;
+ break;
+ }
+ if (l <= 0 || l > MAXLABEL) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *sp = l;
+ }
+ if (cp >= eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *cp++ = '\0';
+ return (int)(cp - comp_dn);
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+__dn_skipname(const u_char *comp_dn, const u_char *eom)
+{
+ register u_char *cp;
+ register int n;
+
+ cp = (u_char *)comp_dn;
+ while (cp < eom && (n = *cp++)) {
+ /*
+ * check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ default: /* illegal type */
+ return (-1);
+ case INDIR_MASK: /* indirection */
+ cp++;
+ }
+ break;
+ }
+ return (int)(cp - comp_dn);
+}
+
+/*
+ * Search for expanded name from a list of previously compressed names.
+ * Return the offset from msg if found or -1.
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static
+dn_find(u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)
+{
+ register u_char *dn, *cp, **cpp;
+ register int n;
+ u_char *sp;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+ dn = exp_dn;
+ sp = cp = *cpp;
+ while (n = *cp++) {
+ /*
+ * check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0: /* normal case, n == len */
+ while (--n >= 0) {
+ if (*dn == '.')
+ goto next;
+ if (*dn == '\\')
+ dn++;
+ if (*dn++ != *cp++)
+ goto next;
+ }
+ if ((n = *dn++) == '\0' && *cp == '\0')
+ return (int)(sp - msg);
+ if (n == '.')
+ continue;
+ goto next;
+
+ default: /* illegal type */
+ return (-1);
+
+ case INDIR_MASK: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ }
+ }
+ if (*dn == '\0')
+ return (int)(sp - msg);
+ next: ;
+ }
+ return (-1);
+}
+
+/*
+ * Routines to insert/extract short/long's. Must account for byte
+ * order and non-alignment problems. This code at least has the
+ * advantage of being portable.
+ *
+ * used by sendmail.
+ */
+
+u_short
+_getshort(u_char *msgp)
+{
+ register u_char *p = (u_char *) msgp;
+#ifdef vax
+ /*
+ * vax compiler doesn't put shorts in registers
+ */
+ register u_long u;
+#else
+ register u_short u;
+#endif
+
+ u = *p++ << 8;
+ return ((u_short)(u | *p));
+}
+
+u_long
+_getlong(u_char *msgp)
+{
+ register u_char *p = (u_char *) msgp;
+ register u_long u;
+
+ u = *p++; u <<= 8;
+ u |= *p++; u <<= 8;
+ u |= *p++; u <<= 8;
+ return (u | *p);
+}
+
+void
+#ifdef __STDC__
+__putshort(register u_short s, register u_char *msgp)
+#else
+__putshort(s, msgp)
+ register u_short s;
+ register u_char *msgp;
+#endif
+{
+ msgp[1] = LOBYTE(s);
+ msgp[0] = HIBYTE(s);
+}
+
+void
+__putlong(l, msgp)
+ register u_long l;
+ register u_char *msgp;
+{
+ msgp[3] = LOBYTE(LOWORD(l));
+ msgp[2] = HIBYTE(LOWORD(l));
+ msgp[1] = LOBYTE(HIWORD(l));
+ msgp[0] = HIBYTE(HIWORD(l));
+}
--- /dev/null
+/*
+ * @doc RESOLVE
+ *
+ * @module res_init.c |
+ *
+ * Contains the implementation for res_init, res_getopts, res_setopts
+ * and supplementary internal functions. If you are adding support for a
+ * new TCP/IP stack of resolver configuration information this is where
+ * it will go.
+ * @xref <f res_init> <f res_setopts> <f res_getopts> <f WhichOS> <f getRegKey>
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*-
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c 6.15 (Berkeley) 2/24/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windns.h> //DNS api's
+
+#include <shellapi.h>
+
+
+#include <mitwhich.h>
+
+#include "resource.h"
+
+char debstr[80];
+
+#define index strchr
+
+#ifndef MAKELONG
+#define MAKELONG(a, b) ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
+#endif
+
+#define TCPIP_PATH "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define HKEY_MIT_PRIVATE HKEY_CLASSES_ROOT
+#define WSH_MIT_PRIVATE_DOMAIN_SUBKEY TCPIP_PATH"\\Domain"
+#define WSH_MIT_PRIVATE_NAMESERVER_SUBKEY TCPIP_PATH"\\NameServer"
+
+DWORD WhichOS( DWORD *check);
+
+static int const getRegKeyEx(const HKEY key, const char *subkey, const char *value, char *buf, unsigned int len);
+
+int WINAPI wsh_getdomainname(char* name, int size);
+
+static HMODULE this_module();
+
+
+/*
+ * Resolver state default settings
+ */
+// @struct _res | a structure of this type holds the state information for the
+// resolver options
+struct state _res = {
+ RES_TIMEOUT, /* @field retransmition time interval */
+ 4, /* @field number of times to retransmit */
+ RES_DEFAULT, /* @field options flags */
+ 1, /* @field number of name servers */
+};
+
+#ifndef _MSC_VER
+
+#define _upcase(c) (((c) <= 'Z' && (c) >= 'A') ? (c) + 'a' - 'A' : (c))
+#define _chricmp(a, b) (_upcase(a) - _upcase(b))
+
+int
+#ifdef __cplusplus
+inline
+#endif
+_strnicmp( register const char *a, register const char *b, register size_t n)
+{
+ register int cmp = 0; /* equal */
+ while( n-- && !(cmp = _chricmp(*a, *b)) && (a++, *b++) /* *a == *b anyways */ );
+ return cmp;
+};
+
+#endif
+
+
+/*
+ This function retrieves the default domain name and search order. It will look to see if an
+ environment variable LOCALDOMAIN is defined. Otherwise, the domain associated with the local host
+ is used. Otherwise, it will try to find the domain name from the registry
+
+ \retval The return value is 0 if the operation was successful.
+ Otherwise the value -1 is returned.
+
+*/
+int
+WINAPI
+res_init()
+{
+ register char *cp, **pp;
+
+ register int n;
+
+ int haveenv = 0; /* have an environment variable for local domain */
+ int havedomain = 0; /* 0 or 1 do we have a value for the domain */
+
+ LONG result1 = -1995;
+
+#define WSH_SPACES " \t,;="
+
+ _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _res.nscount = 1;
+
+
+ /* Allow user to override the local domain definition */
+ if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+ strncpy(_res.defdname, cp, sizeof(_res.defdname));
+ haveenv++;
+ havedomain++;
+ };
+
+ if (!havedomain) {
+ if (!wsh_getdomainname(_res.defdname, sizeof(_res.defdname)))
+ havedomain++;
+ }
+
+
+
+ if( 0 != havedomain){
+ // return early, we've done our job
+ /* find components of local domain that might be searched */
+
+ pp = _res.dnsrch;
+ *pp++ = _res.defdname;
+ for (cp = _res.defdname, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+ cp = _res.defdname;
+ for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
+ n--) {
+ cp = index(cp, '.');
+ *pp++ = ++cp;
+ }
+ *pp++ = 0;
+ }
+
+ _res.options |= RES_INIT;
+ return(0);
+}
+
+
+/*
+ res_setopts -- unsupported
+*/
+
+void
+WINAPI
+res_setopts(long opts)
+{
+}
+
+
+
+/*
+ res_getopts -- unsupported
+*/
+
+long
+WINAPI
+res_getopts()
+{
+ return -1;
+}
+
+/* --------------------------------------------------------------------------*/
+/* Excerpt from IPTYPES.H */
+#define MAX_HOSTNAME_LEN 128 // arb.
+#define MAX_DOMAIN_NAME_LEN 128 // arb.
+#define MAX_SCOPE_ID_LEN 256 // arb.
+
+
+
+/*
+
+ @doc MISC
+
+ @func DWORD | WhichOS | This function will attempt to
+ determine which Operating System and subsystem is being used by the
+ application. It should function under Win16, Windows NT amd Windows
+ 95 at least. It does call WSAStartup() and WSACleanup(). This
+ function does have side effects on some global variables. See the
+ comments below.
+
+ @parm DWORD *| check | a pointer to a DWORD, a value indicating
+ which operating system and/or subsystem is being used will be stored
+ in this parameter upon return.
+
+ @rdesc a NULL will indicate that we could not determine what OS is
+ being used. The high word contains:
+
+
+ @flag MS_OS_WIN (1) | The application is running under Windows or WFWG
+ @flag MS_OS_95 (2) | The application is running under Windows 95
+ @flag MS_OS_NT (3) | The application is running under Windows NT
+ @flag MS_OS_2000 (4) | The application is running under Windows 2000
+ @flag MS_OS_XP (5) | The application is running under Windows XP
+ @flag MS_OS_2003 (6) | The application is running under Windows 2003
+ @flag MS_OS_NT_UNKNOWN (7) | The application is running under Windows NT family beyond 2003
+ @flag MS_OS_UNKNOWN (0) | It looks like Windows but not any version that
+ we know of.
+
+ <nl>these are defined in mitwhich.h<nl>
+
+The low word contains one of the following, which is derived from the winsock implementation: <nl>
+
+ @flag MS_NT_32 (1) | The MS 32 bit Winsock stack for NT is being used
+ @flag MS_NT_16 (2) | The MS 16 bit Winsock stack under NT is being used
+ @flag MS_95_32 (3) | The MS 32 bit Winsock stack under 95 is being used
+ @flag MS_95_16 (4) | The MS 16 bit Winsock stack under 95 is being used
+ @flag NOVELL_LWP_16 (5) | The Novell 16 Winsock stack is being used
+ @flag UNKNOWN_16_UNDER_32 (-2) | We don't know the stack.
+ @flag UNKNOWN_16_UNDER_16 (-3) | We don't know the stack.
+ @flag UNKNOWN_32_UNDER_32 (-4) | We don't know the stack.
+ @flag UNKNOWN_32_UNDER_16 (-5) | We don't know the stack.
+
+*/
+DWORD
+WhichOS(
+ DWORD *check
+ )
+{
+ WORD wVersionRequested;
+ WSADATA wsaData; // should be a global?
+ int err;
+
+ int checkStack = 0;
+ int checkOS = 0;
+ static DWORD dwCheck = 0xFFFFFFFF;
+
+ if ( dwCheck != 0xFFFFFFFF ) {
+ if ( check )
+ *check = dwCheck;
+ return dwCheck;
+ }
+
+ // first get the information from WSAStartup because it may give
+ // more consistent information than Microsoft APIs.
+
+ wVersionRequested = 0x0101;
+
+ err = WSAStartup( wVersionRequested, &wsaData );
+
+ if( err != 0 ){
+ MessageBox( NULL,
+ "It looks like a useable winsock.dll\n"
+ "could not be located by the wshelp*.dll\n"
+ "Please check your system configuration.",
+ "Problem in wshelper.dll", MB_OK );
+ check = 0;
+ return(0);
+ }
+
+ WSACleanup();
+
+ if( _res.options & RES_DEBUG ){
+ wsprintf( debstr, wsaData.szDescription );
+ OutputDebugString( debstr );
+ }
+
+ if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, NT_32 ))){
+ // OK we appear to be running under NT in the 32 bit subsystem
+ // so we must be a 32 bit application.
+ // This also implies that we can get the TCPIP parameters out
+ // of the NT registry.
+ checkStack = MS_NT_32;
+ }
+
+ if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, NT_16 ))){
+ // this implies we're running under NT in the 16 bit subsystem
+ // so we must be a 16 bit application
+ // This means we have to go through some strange gyrations to read the
+ // TCPIP parameters out of the NT 32 bit registry.
+ checkStack = MS_NT_16;
+ checkOS = MS_OS_NT;
+ }
+
+ if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, W95_32 ))){
+ // get the TCPIP parameters out of the Win95 registry
+ checkStack = MS_95_32;
+ checkOS = MS_OS_95; // ??
+ }
+
+ if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, W95_16 ))){
+ // go through the pain of getting the TCPIP parameters out of the Win95
+ // 32 bit registry
+ checkStack = MS_95_16;
+ checkOS = MS_OS_95;
+ }
+
+ if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, LWP_16 ))){
+ // get the information out of the %NDIR%\TCP\RESOLV.CFG file
+ checkStack = NOVELL_LWP_16;
+ checkOS = MS_OS_WIN;
+ }
+
+ if( 0 == checkStack ){
+ // at this time we don't easily know how to support this stack
+ checkStack = STACK_UNKNOWN;
+ }
+
+#if !defined(_WIN32)
+ // Note, if this is the 32 bit DLL we can't use the following
+ // functions to determine the OS because they are
+ // obsolete. However, we should be able to use them in the 16 bit
+ // DLL.
+ {
+ DWORD dwVersion = 0;
+ DWORD dwFlags = 0;
+
+ dwFlags = GetWinFlags();
+ if( _res.options & RES_DEBUG ){
+ wsprintf( debstr, "dwFlags = %x ", dwFlags );
+ OutputDebugString( debstr );
+ }
+
+ dwVersion = GetVersion();
+
+ if( _res.options & RES_DEBUG ){
+ wsprintf( debstr, "dwVersion = %8lx ", dwVersion );
+ OutputDebugString( debstr );
+ }
+
+ if( 95 == (DWORD)(HIBYTE(LOWORD(dwVersion))) ){
+ // OK, we're a 16 bit app running on 95?
+ checkOS = MS_OS_95;
+ }
+
+ if( dwFlags & 0x4000 ){
+ // This means that this is a 16 bit application running
+ // under WOW layer on NT.
+
+ // So, we're going to get the TCPIP parameters out of the
+ // 32 bit registry, but we don't know which set of
+ // registry entries yet.
+
+ // Since we see these version numbers and we're under WOW
+ // we must be under NT 4.0 but we don't necessarily know
+ // the stack
+ checkOS = MS_OS_NT;
+ }
+
+
+ if( checkOS == 0 ){
+ // We are a 16 bit application running on a 16 bit operating system
+ checkOS = MS_OS_WIN; // assumption, but we're not under 95 and not under NT, it looks like
+ if( checkStack == STACK_UNKNOWN ){
+ checkStack = UNKNOWN_16_UNDER_16;
+ }
+ }
+ }
+#endif // !_WIN32
+
+#if defined(_WIN32)
+ // This must be a 32 bit application so we are either under NT,
+ // Win95, or WIN32s
+ {
+ OSVERSIONINFO osvi;
+
+ memset( &osvi, 0, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx( &osvi );
+
+ if( osvi.dwPlatformId == VER_PLATFORM_WIN32s ){
+ if( checkStack == STACK_UNKNOWN ){
+ checkStack = UNKNOWN_16_UNDER_16;
+ }
+ checkOS = MS_OS_WIN;
+ wsprintf( debstr, "Microsoft Win32s %d.%d (Build %d)\n",
+ osvi.dwMajorVersion,
+ osvi.dwMinorVersion,
+ osvi.dwBuildNumber & 0xFFFF );
+ }
+
+ if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
+ if( checkStack == STACK_UNKNOWN ){
+ checkStack = UNKNOWN_32_UNDER_32;
+ }
+ checkOS = MS_OS_95;
+ wsprintf( debstr, "Microsoft Windows 95 %d.%d (Build %d)\n",
+ osvi.dwMajorVersion,
+ osvi.dwMinorVersion,
+ osvi.dwBuildNumber & 0xFFFF );
+ }
+
+ if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ){
+ if( checkStack == STACK_UNKNOWN ){
+ checkStack = UNKNOWN_32_UNDER_32;
+ }
+ if ( osvi.dwMajorVersion <= 4 )
+ checkOS = MS_OS_NT;
+ else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
+ checkOS = MS_OS_2000;
+ else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
+ checkOS = MS_OS_XP;
+ else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
+ checkOS = MS_OS_2003;
+ else
+ checkOS = MS_OS_NT_UNKNOWN;
+ wsprintf( debstr, "Microsoft Windows NT family %d.%d (Build %d)\n",
+ osvi.dwMajorVersion,
+ osvi.dwMinorVersion,
+ osvi.dwBuildNumber & 0xFFFF );
+ }
+
+ if( _res.options & RES_DEBUG ){
+ OutputDebugString( debstr );
+ }
+ }
+
+#endif // _WIN32
+
+ // At this point we should know the OS.
+ // We should also know the subsystem but not always the stack.
+
+ dwCheck = MAKELONG(checkOS, checkStack);
+ if ( check )
+ *check = dwCheck;
+ return( dwCheck );
+}
+
+
+static
+BOOL
+get_nt5_adapter_param(
+ char* param,
+ WORD skip,
+ char* buf,
+ unsigned int len
+ )
+{
+ static char linkage[BUFSIZ*4];
+ char* p;
+ char* q;
+ HKEY hAdapters;
+
+ char* DEVICE_STR = "\\Device\\";
+ SIZE_T DEVICE_LEN = strlen(DEVICE_STR);
+
+#define TCPIP_PATH_ADAPTERS "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
+#define TCPIP_PATH_LINKAGE "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"
+
+ if (!getRegKeyEx(HKEY_LOCAL_MACHINE, TCPIP_PATH_LINKAGE, "Bind", linkage, sizeof(linkage)))
+ return FALSE;
+
+ p = linkage;
+
+ RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIP_PATH_ADAPTERS, 0,
+ KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
+ &hAdapters);
+
+ while (*p) {
+ q = strstr(p, DEVICE_STR);
+ if (!q) {
+ while (*p) p++;
+ p++;
+ continue;
+ }
+ q += DEVICE_LEN;
+ p = q;
+ while (*p) p++;
+ p++;
+ buf[0] = '\0';
+ if (getRegKeyEx(hAdapters, q, param, buf, len) && !buf[0]) {
+ if (!skip) {
+ RegCloseKey(hAdapters);
+ return TRUE;
+ }
+ else
+ skip--;
+ }
+ }
+ RegCloseKey(hAdapters);
+
+ // Bottom out by looking at default parameters
+ {
+ char Tcpip_path[_MAX_PATH];
+
+ if(!LoadString(this_module(), IDS_TCPIP_PATH_NT,
+ Tcpip_path, sizeof(Tcpip_path)))
+ strcpy(Tcpip_path, NT_TCP_PATH);
+ return getRegKeyEx(HKEY_LOCAL_MACHINE, Tcpip_path, param, buf, len);
+ }
+ return FALSE;
+}
+
+
+
+static
+BOOL
+_getdomainname(
+ char* name,
+ int size
+ )
+{
+ char buf[BUFSIZ];
+
+ char* dhcp_param = "DhcpDomain";
+ char* param = "Domain";
+ BOOL ok = FALSE;
+ char* rbuf;
+ unsigned int rlen;
+
+ if (!name || (size <= 0))
+ return FALSE;
+
+ rbuf = (size >= sizeof(buf))?name:buf;
+ rlen = (size >= sizeof(buf))?size:sizeof(buf);
+
+
+ ok = get_nt5_adapter_param(dhcp_param, 0, rbuf, rlen);
+ if (!ok || !rbuf[0])
+ ok = get_nt5_adapter_param(param, 0, rbuf, rlen);
+
+ if (ok && rbuf[0]) {
+ if (size < (lstrlen(rbuf) + 1))
+ return FALSE;
+ if (rbuf != name)
+ strncpy(name, rbuf, size);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ Gets the base part of the hostname
+ defined in wshelper\res_init.c
+
+ \param[in, out] name pointer to a buffer that receives a null-terminated string containing the computer name
+ \param[in] size specifies the size of the buffer, in chars (must be large
+ enough to hold NULL-terminated host name)
+
+ \retval return 0 ifsuccess, -1 on error.
+
+*/
+int WINAPI
+wsh_gethostname(char* name, int size)
+{
+ if (name){
+ // Get and display the name of the computer.
+
+ if( GetComputerName(name, &size) )
+ {
+ while (*name && (*name != '.'))
+ {
+ *name = tolower(*name);
+ name++;
+ }
+ if (*name == '.') *name = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/*
+ Gets the machine's domain name
+
+ \param[in, out] name pointer to a buffer that receives a null-terminated string containing the domain name
+ \param[in] size specifies the size of the buffer, in chars (must be large
+ enough to hold NULL-terminated domain name)
+
+ \retval return 0 ifsuccess, -1 on error.
+
+
+*/
+int WINAPI
+wsh_getdomainname(char* name, int size)
+{
+ DNS_STATUS status;
+
+ PDNS_RECORD pDnsRecord;
+ DNS_FREE_TYPE freetype ;
+
+ DWORD length;
+ char hostName[BUFSIZ];
+
+ length = BUFSIZ;
+ freetype = DnsFreeRecordListDeep;
+
+
+ // Get and display the name of the computer.
+
+ if( GetComputerName(hostName, &length) )
+ {
+
+ status = DnsQuery_A(hostName, //pointer to OwnerName
+ DNS_TYPE_A, //Type of the record to be queried
+ DNS_QUERY_BYPASS_CACHE|DNS_QUERY_NO_LOCAL_NAME, // Bypasses the resolver cache on the lookup.
+ NULL, //contains DNS server IP address
+ &pDnsRecord, //Resource record comprising the response
+ NULL); //reserved for future use
+
+ if (status)
+ return -1;
+ else
+ {
+ char* cp;
+ cp = index(pDnsRecord->pName, '.');
+ if (cp)
+ {
+ cp++;
+ strncpy(name, cp, size);
+ name[size-1] = '\0';
+ DnsRecordListFree(pDnsRecord, freetype);
+ return(0);
+ }
+ DnsRecordListFree(pDnsRecord, freetype);
+
+ }
+ }
+
+ /* try to get local domain from the registry */
+ if (_getdomainname(name, size))
+ return 0;
+ else
+ return -1;
+}
+
+
+
+
+
+
+
+
+// @func int | getRegKeyEx | This function is only used when the library is
+// running under a known 32-bit Microsoft Operating
+// system
+
+// @parm const HKEY | key | Specifies a a currently open key or any
+// of the following predefined reserved handle values:
+// HKEY_CLASSES_ROOT
+// KEY_CURRENT_USER
+// HKEY_LOCAL_MACHINE
+// HKEY_USERS
+//
+// @parm const char * | subkey | Specifies a pointer to a null-terminated
+// string containing the name of the subkey to open. If this parameter is NULL
+// or a pointer to an empty string, the function will open a new handle
+// of the key identified by the key parameter.
+//
+// @parm const char * | value | Specifiea a pointer to a null-terminated
+// string containing the name of the value to be queried.
+//
+// @parm char * | buf | Specifies a pointer to a buffer that recieves the
+// key's data. This parameter can be NULL if the data is not required.
+//
+// @parm unsigned int | len | Specifies the size of buffer 'buf'.
+//
+// @rdesc Returns an int that can mean:
+//
+// FALSE - if the subkey cannot be queried or possibly opened.
+// TRUE - if the subkey can be queried but it is not of type: REG_EXPAND_SZ
+// If the subkey can be queried, and its type is REG_EXPAND_SZ, and it can
+// be expanded the return value is the number of characters stored in the
+// buf parameter. If the number of characters is greater than the size of the
+// of the destination buffer, the return value should be the size of the
+// buffer required to hold the value.
+
+static
+int const
+getRegKeyEx(
+ const HKEY key,
+ const char *subkey,
+ const char *value,
+ char *buf,
+ unsigned int len
+ )
+{
+ HKEY hkTcpipParameters;
+ LONG err;
+ DWORD type, cb;
+ char *env_buf;
+
+
+ if (RegOpenKey(key, subkey, &hkTcpipParameters) == ERROR_SUCCESS) {
+ cb = len;
+ err = RegQueryValueEx(hkTcpipParameters, value, 0, &type, buf, &cb);
+ RegCloseKey(hkTcpipParameters);
+ if( err == ERROR_SUCCESS ){
+ if( type == REG_EXPAND_SZ ){
+ if( env_buf = malloc( cb ) ){
+ err = ExpandEnvironmentStrings( strcpy( env_buf, buf ), buf, len );
+ free( env_buf );
+ return err;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE; // subkey could be queried but it was not of type REG_EXPAND_SZ
+ } else {
+ return FALSE; // subkey exists but could not be queried
+ }
+ }
+ else
+
+// #endif // WIN32
+
+ return FALSE; // subkey could not be opened
+}
+
+#ifdef __cplusplus
+inline
+#endif
+
+#include "wsh-int.h"
+
+static
+HMODULE
+this_module()
+{
+ static HMODULE hModWSHelp = 0;
+ if (!hModWSHelp)
+ {
+ // Note: these must match the DEF file entries
+#if defined (_WIN32)
+ hModWSHelp = GetModuleHandle("WSHELP32");
+#else
+ hModWSHelp = GetModuleHandle("WSHELPER");
+#endif
+ }
+ return hModWSHelp;
+}
+
+static
+int
+try_registry(
+ HKEY hBaseKey,
+ const char * name,
+ DWORD * value
+ )
+{
+ HKEY hKey;
+ LONG err;
+ DWORD size;
+
+ err = RegOpenKeyEx(hBaseKey,
+ "Software\\MIT\\WsHelper",
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (err)
+ return 0;
+ size = sizeof(value);
+ err = RegQueryValueEx(hKey, name, 0, 0, value, &size);
+ RegCloseKey(hKey);
+ return !err;
+}
+
+void
+res_init_startup()
+{
+ DWORD debug_on = 0;
+
+
+ if (try_registry(HKEY_CURRENT_USER, "DebugOn", &debug_on) ||
+ try_registry(HKEY_LOCAL_MACHINE, "DebugOn", &debug_on))
+ {
+ if (debug_on)
+ _res.options |= RES_DEBUG;
+ }
+}
+
+void
+res_init_cleanup()
+{
+
+}
--- /dev/null
+/*
+ *
+ * @doc RESOLVE
+ *
+ *
+ * @module res_quer.c | Contains the implementation of res_query,
+ * res_search, and res_querydomain
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c 5.11 (Berkeley) 3/6/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windns.h>
+
+#define MAX_MSG_SIZE 0x2003
+
+#define strcasecmp stricmp
+
+#ifdef _DEBUG
+#define DEBUG
+#endif
+int
+__hostalias(register const char *name, char* abuf);
+DNS_STATUS do_res_search(const char *name, int qclass, int type, u_char *retanswer, int retanswerlen, int* anslen);
+void __putshort(register u_short, register u_char *);
+void __putlong(register u_long, u_char *);
+int build_rr(char* p, PDNS_RECORD ptr, int qclass);
+int put_qname(char* p, char* qname);
+
+
+
+/*
+ a generic query interface to the DNS name space. The query is performed with the dnsapi and
+ the answer buffer is populated based on the returned RR set.
+
+ \param[in] name domain name
+ \param[in] qclass class of query(such as DNS_CLASS_INTERNET, DNS_CLASS_CSNET, DNS_CLASS_CHAOS,
+ DNS_CLASS_HESIOD. Defined in windns.h)
+ \param[in] type type of query(such as DNS_TYPE_A, DNS_TYPE_NS, DNS_TYPE_MX, DNS_TYPE_SRV. Defined in
+ windns.h)
+ \param[in] answer buffer to put answer in
+ \param[in] anslen size of the answer buffer. compare the anslen with the return value, if the return
+ value is bigger than anslen, it means the answer buffer doesn't contain the complete
+ response. You will need to call this function again with a bigger answer buffer if
+ you care about the complete response
+
+ \retval return the size of the response on success, -1 on error
+
+
+ */
+int WINAPI
+res_search(const char *name, int qclass, int type, u_char *answer, int anslen)
+ /* domain name, class and type of query, buffer to put answer, size of answer */
+{
+ char debstr[80];
+ int n = 0;
+ DNS_STATUS status;
+ char queryname[DNS_MAX_NAME_BUFFER_LENGTH ];
+ register const char *cp;
+ int len = 0;
+
+ char** domain;
+
+ status = -1;
+ memset(answer, 0, anslen);
+ memset(queryname, 0, sizeof(queryname));
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return (-1);
+
+ for (cp = name, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+
+ if (n == 0 && !__hostalias(name, queryname) && strlen(queryname)>0)
+ {
+ status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+ if (status == 0)
+ return len;
+ }
+
+ if ((n == 0 && _res.options & RES_DEFNAMES))
+ // (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
+ {
+ for (domain = _res.dnsrch; *domain; domain++) {
+ strcpy(queryname, name);
+ strcat(queryname, ".");
+ strcat(queryname, *domain);
+ status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+ if (status == 0)
+ return len;
+ }
+ }
+
+
+ strcpy(queryname, name);
+ status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+
+
+ if (status)
+ {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ {
+ wsprintf(debstr, "res_query failed\n");
+ OutputDebugString(debstr);
+ }
+#endif
+ return -1;
+ }
+ return len;
+}
+
+int
+put_qname(char* cp, char* qname)
+{
+ char* p;
+ char* temp;
+ INT_PTR n = 0;
+ INT_PTR i = 0;
+ temp = qname;
+ while (p = strchr(temp, '.'))
+ {
+ n = p - temp;
+ if (n == 0)
+ {
+ temp++;
+ break;
+ }
+ cp[0] = (int)n;
+ cp++;
+ i++;
+ strncpy(cp, temp, n);
+ temp = p+1;
+ cp = cp + n;
+ i = i + n;
+ }
+ n = strlen(temp);
+ if (n > 0)
+ {
+ cp[0] = (int)n;
+ cp++;
+ i++;
+ strcpy(cp, temp);
+ cp = cp+n;
+ }
+ cp[0] = 0;
+ i = i+n+1;
+ return (int)i;
+}
+
+DNS_STATUS
+do_res_search(const char *queryname, int qclass, int type, u_char *retanswer, int retanswerlen, int* anslen)
+{
+ PDNS_RECORD pDnsRecord;
+ PDNS_RECORD ptr;
+ DNS_STATUS status;
+ DNS_FREE_TYPE freetype ;
+ HEADER *hp;
+ char *cp;
+ int n;
+ int i;
+ u_char answer[MAX_MSG_SIZE];
+ DWORD options = DNS_QUERY_STANDARD;
+ freetype = DnsFreeRecordListDeep;
+
+ memset(answer, 0, MAX_MSG_SIZE);
+ if (!(_res.options & RES_RECURSE))
+ options = options | DNS_QUERY_NO_RECURSION;
+ if (_res.options & RES_USEVC)
+ options = options | DNS_QUERY_USE_TCP_ONLY;
+ if (_res.options & RES_IGNTC)
+ options = options | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE;
+
+ status = DnsQuery_A(queryname, //pointer to OwnerName
+ type, //Type of the record to be queried
+ options,
+ NULL, //contains DNS server IP address
+ &pDnsRecord, //Resource record comprising the response
+ NULL); //reserved for future use
+
+ if (status)
+ return status;
+
+
+ hp = (HEADER *) answer;
+ cp = answer + sizeof(HEADER);
+
+ // populating the header
+ hp->id = htons(++_res.id); // query id
+ hp->qr = 1; // 0 for query 1 for response
+ hp->opcode = 0; // standard query
+ hp->aa = 1; // authoritative answer
+ hp->tc = 0; // no truncation
+ hp->rd = (_res.options & RES_RECURSE) != 0; // resursion desired
+ hp->ra = 1; // recursion available
+ hp->pr = (_res.options & RES_PRIMARY) != 0; // primary server required
+ hp->rcode = NOERROR;
+ hp->qdcount = htons(1); // number of question entries
+ i = put_qname(cp, (char*)queryname);
+ cp = cp + i;
+ __putshort(type, (u_char *)cp);
+ cp += sizeof(u_short);
+ __putshort(qclass, (u_char *)cp);
+ cp += sizeof(u_short);
+
+ // get the answer
+ for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+ {
+ if ((ptr->Flags).S.Section == DNSREC_ANSWER ||
+ (type == DNS_TYPE_PTR && (ptr->Flags).S.Section==DNSREC_QUESTION))
+ {
+ i = build_rr(cp, ptr, qclass);
+ cp = cp + i;
+ //strcpy(cp, pDnsRecord->pName);
+ //cp += strlen(pDnsRecord->pName);
+ //cp++;
+
+ n++;
+ }
+ }
+ hp->ancount = htons(n);
+
+ // get the authority
+ for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+ {
+ if ((ptr->Flags).S.Section == DNSREC_AUTHORITY )
+ {
+ i = build_rr(cp, ptr, qclass);
+ cp = cp + i;
+
+ n++;
+ }
+ }
+ hp->nscount = htons(n);
+
+ // get the additional resource
+ for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+ {
+ if ((ptr->Flags).S.Section == DNSREC_ADDITIONAL)
+ {
+ i = build_rr(cp, ptr, qclass);
+ cp = cp + i;
+
+ n++;
+ }
+
+ }
+ hp->arcount = htons(n);
+
+ *anslen = (int)(cp - answer);
+ if (*anslen > retanswerlen)
+ memcpy(retanswer, answer, retanswerlen); // partial copy
+ else
+ memcpy(retanswer, answer, *anslen);
+ DnsRecordListFree(pDnsRecord, freetype);
+ return status;
+}
+
+int
+build_rr(char* p, PDNS_RECORD ptr, int qclass)
+{
+ int i = 0;
+ int n = 0;
+ char* cp = p;
+ char* temp = NULL;
+ unsigned int index = 0;
+
+ i = put_qname(cp, ptr->pName);
+ cp = p + i;
+
+ __putshort(ptr->wType, (u_char *)cp);
+ i += sizeof(u_short);
+ cp = p + i;
+ __putshort(qclass, (u_char *)cp);
+ i += sizeof(u_short);
+ cp = p + i;
+ __putlong(ptr->dwTtl, (u_char*)cp);
+ i += sizeof(u_long);
+ cp = p + i;
+ switch (ptr->wType)
+ {
+ case DNS_TYPE_A:
+ __putshort(sizeof(ptr->Data.A), (u_char*)cp); //RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ memcpy(cp, &(ptr->Data.A), sizeof(ptr->Data.A));
+ i += sizeof(ptr->Data.A);
+ break;
+ case DNS_TYPE_NS:
+ case DNS_TYPE_MD:
+ case DNS_TYPE_MF:
+ case DNS_TYPE_CNAME:
+ case DNS_TYPE_MB:
+ case DNS_TYPE_MG:
+ case DNS_TYPE_MR:
+ case DNS_TYPE_PTR:
+ temp = cp; // hold the spot for RD length
+ i += sizeof(u_short);
+ cp = p+i;
+ n = put_qname(cp, ptr->Data.Ptr.pNameHost);
+ i += n;
+ __putshort(n, (u_char*)temp); //set RDLENGTH
+ break;
+ case DNS_TYPE_TEXT:
+ case DNS_TYPE_HINFO:
+ case DNS_TYPE_ISDN:
+ case DNS_TYPE_X25:
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ n = 0;
+ for (index = 0; index < ptr->Data.Txt.dwStringCount; index++)
+ {
+ *cp = (int)(strlen(ptr->Data.Txt.pStringArray[index]));
+ n += *cp;
+ n++;
+ strcpy(++cp, ptr->Data.Txt.pStringArray[index]);
+ }
+ i += n;
+ __putshort(n,(u_char*)temp); // set RDLENGTH
+ break;
+ case DNS_TYPE_SRV:
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ // priority
+ __putshort(ptr->Data.Srv.wPriority, (u_char*)cp);
+ i += sizeof(u_short);
+ cp = p + i;
+ //weight
+ __putshort(ptr->Data.Srv.wWeight, (u_char*)cp);
+ i += sizeof(u_short);
+ cp = p + i;
+ //port
+ __putshort(ptr->Data.Srv.wPort, (u_char*)cp);
+ i += sizeof(u_short);
+ cp = p + i;
+
+ n = put_qname(cp, ptr->Data.Srv.pNameTarget);
+ i+=n;
+ __putshort((u_short)(n + sizeof(u_short)*3),(u_char*)temp);
+
+ break;
+ case DNS_TYPE_MX:
+ case DNS_TYPE_AFSDB:
+ case DNS_TYPE_RT:
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ __putshort(ptr->Data.Mx.wPreference, (u_char*)cp); // put wPreference
+ i += sizeof(u_short);
+ cp = p + i;
+ n = put_qname(cp, ptr->Data.Mx.pNameExchange);
+ i+=n;
+ __putshort((u_short)(n+sizeof(u_short)),(u_char*)temp);
+ break;
+ case DNS_TYPE_SOA:
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ // primary server name
+ n = put_qname(cp, ptr->Data.Soa.pNamePrimaryServer);
+ i+= n;
+ cp = p + i;
+ //the person responsible for this zone.
+ n += put_qname(cp, ptr->Data.Soa.pNameAdministrator);
+ i += n;
+ cp = p + i;
+ //SERIAL
+ __putlong(ptr->Data.Soa.dwSerialNo, cp);
+ n += sizeof(u_long);
+ i += sizeof(u_long);
+ cp = p + i;
+ //refresh
+ __putlong(ptr->Data.Soa.dwRefresh, cp);
+ n += sizeof(u_long);
+ i += sizeof(u_long);
+ cp = p + i;
+ //retry
+ __putlong(ptr->Data.Soa.dwRetry, cp);
+ n += sizeof(u_long);
+ i += sizeof(u_long);
+ cp = p + i;
+ // expire
+ __putlong(ptr->Data.Soa.dwExpire, cp);
+ n += sizeof(u_long);
+ i += sizeof(u_long);
+ cp = p + i;
+ // minimum TTL
+ __putlong(ptr->Data.Soa.dwDefaultTtl, cp);
+ n += sizeof(u_long);
+ i += sizeof(u_long);
+ // set RDLength
+ __putshort(n,(u_char*)temp);
+ break;
+ case DNS_TYPE_NULL:
+ __putshort((short)ptr->Data.Null.dwByteCount, (u_char*)cp); //RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ memcpy(cp, ptr->Data.Null.Data, ptr->Data.Null.dwByteCount);
+ i += ptr->Data.Null.dwByteCount;
+ break;
+ case DNS_TYPE_WKS: // needs more work
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ // address
+ memcpy(cp, &(ptr->Data.Wks.IpAddress), sizeof(ptr->Data.Wks.IpAddress));
+ n = sizeof(ptr->Data.Wks.IpAddress);
+ i += sizeof(ptr->Data.Wks.IpAddress);
+ cp = p + i;
+ // protocol
+ *cp = ptr->Data.Wks.chProtocol;
+ i++;
+ n++;
+ cp = p + i;
+ //bit mask
+ memcpy(cp, &(ptr->Data.Wks.BitMask), sizeof(ptr->Data.Wks.BitMask));
+ n+=sizeof(ptr->Data.Wks.BitMask);
+ i += n;
+ // set RDLength
+ __putshort(n,(u_char*)temp);
+ break;
+ case DNS_TYPE_MINFO:
+ case DNS_TYPE_RP:
+ temp = cp; // hold the spot for RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ // pNameMailbox
+ n = put_qname(cp, ptr->Data.Minfo.pNameMailbox);
+ i+= n;
+ cp = p + i;
+ // pNameErrorsMailbox;
+ n += put_qname(cp, ptr->Data.Minfo.pNameMailbox);
+ i += n;
+ // set RDLength
+ __putshort(n,(u_char*)temp);
+ break;
+ case DNS_TYPE_AAAA:
+ __putshort(sizeof(ptr->Data.AAAA), (u_char*)cp); //RDLENGTH
+ i += sizeof(u_short);
+ cp = p + i;
+ memcpy(cp, &(ptr->Data.AAAA), sizeof(ptr->Data.AAAA));
+ i += sizeof(ptr->Data.AAAA);
+
+ break;
+ }
+ return i;
+}
+
+
+int
+__hostalias(register const char *name, char* abuf)
+{
+ register char *C1, *C2;
+ FILE *fp;
+ char *file;
+// char *getenv(), *strcpy(), *strncpy(); // pbh XXX 11/1/96
+ char buf[BUFSIZ];
+
+
+ file = getenv("HOSTALIASES");
+ if (file == NULL || (fp = fopen(file, "r")) == NULL)
+ return -1;
+ buf[sizeof(buf) - 1] = '\0';
+ while (fgets(buf, sizeof(buf), fp)) {
+ for (C1 = buf; *C1 && !isspace(*C1); ++C1);
+ if (!*C1)
+ break;
+ *C1 = '\0';
+ if (!strcasecmp(buf, name)) {
+ while (isspace(*++C1));
+ if (!*C1)
+ break;
+ for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
+ abuf[sizeof(abuf) - 1] = *C2 = '\0';
+ (void)strncpy(abuf, C1, sizeof(abuf) - 1);
+ fclose(fp);
+ return 0;
+ }
+ }
+ fclose(fp);
+ return -1;
+}
+
+int WINAPI
+res_mkquery(int op, const char *dname,
+ int qclass, int type,
+ const char *data, int datalen,
+ const struct rrec *newrr,
+ char *buf, int buflen)
+{
+ return -1;
+}
+
+int WINAPI
+res_querydomain(const char *name,
+ const char *domain,
+ int qclass, int type,
+ u_char *answer, int anslen)
+{
+ return -1;
+}
+
+int WINAPI
+res_send(const char *msg, int msglen,
+ char *answer, int anslen)
+{
+ return -1;
+}
+
+int WINAPI
+res_query(char *name, int qclass, int type, u_char *answer, int anslen)
+{
+ return -1;
+}
--- /dev/null
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDS_DEF_HES_RHS 1
+#define IDS_DEF_HES_LHS 2
+#define IDS_DEF_HES_CONFIG_FILE 3
+#define IDS_DEF_RESCONF_PATH 4
+#define IDS_DEF_DNS1 5
+#define IDS_DEF_DNS2 6
+#define IDS_DEF_DNS3 7
+#define IDS_TCPIP_PATH_NT 8
+#define IDS_TCPIP_PATH_95 9
+#define IDS_NT_DOMAIN_KEY 10
+#define IDS_NT_NS_KEY 11
+#define IDS_W95_DOMAIN_KEY 12
+#define IDS_W95_NS_KEY 13
+#define IDS_TCPIP_PATH_NT_TRANSIENT 14
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
--- /dev/null
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <afxres.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
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include <afxres.h>\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""version.rc""\r\n"
+ "#include ""string.rc""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc"
+#include "string.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
--- /dev/null
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by App Studio
+#endif // APSTUDIO_INVOKED
+
+#include <hesiod.h>
+#include <mitwhich.h>
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_DEF_HES_RHS DEF_RHS
+ IDS_DEF_HES_LHS DEF_LHS
+ IDS_DEF_HES_CONFIG_FILE HESIOD_CONF
+ IDS_DEF_RESCONF_PATH _PATH_RESCONF
+ IDS_DEF_DNS1 DNS1
+ IDS_DEF_DNS2 DNS2
+ IDS_DEF_DNS3 DNS3
+ IDS_TCPIP_PATH_NT NT_TCP_PATH
+ IDS_TCPIP_PATH_95 W95_TCP_PATH
+ IDS_NT_DOMAIN_KEY NT_DOMAIN_KEY
+ IDS_NT_NS_KEY NT_NS_KEY
+ IDS_W95_DOMAIN_KEY W95_DOMAIN_KEY
+ IDS_W95_NS_KEY W95_NS_KEY
+ IDS_TCPIP_PATH_NT_TRANSIENT NT_TCP_PATH_TRANS
+END
--- /dev/null
+#ifdef RC_INVOKED
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEFLAGSMASK VER_FILEFLAGSMASK
+FILEFLAGS VER_FILEFLAGS
+FILEOS VER_FILEOS
+FILETYPE VER_FILETYPE
+FILESUBTYPE VER_FILESUBTYPE
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 0x04B0
+ END
+
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
+ BEGIN
+#if defined(VER_EXTRA_LABEL) && defined(VER_EXTRA_VALUE)
+ VALUE VER_EXTRA_LABEL, VER_EXTRA_VALUE
+#endif
+#ifdef VER_COMMENT
+ VALUE "Comment", VER_COMMENT
+#endif
+#ifdef VER_USERNAME
+ VALUE "Built By", VER_USERNAME
+#endif
+#ifdef VER_HOSTNAME
+ VALUE "Build Host", VER_HOSTNAME
+#endif
+#ifdef VER_DATE
+ VALUE "Build Time", VER_DATE
+#endif
+#ifdef VER_VENDOR
+ VALUE "Modified by Vendor", VER_VENDOR
+#endif
+ VALUE "CompanyName", VER_COMPANYNAME_STR
+ VALUE "FileDescription", VER_FILEDESCRIPTION_STR EXPORT_TAG
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", VER_INTERNALNAME_STR
+ VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
+#ifdef VER_LEGALTRADEMARK_STR
+ VALUE "LegalTrademark", VER_LEGALTRADEMARK_STR
+#endif
+ VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR
+ VALUE "ProductName", VER_PRODUCTNAME_STR
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+#ifdef VER_SPECIALBUILD
+ VALUE "SpecialBuild", VER_SPECIALBUILD
+#endif
+ END
+ END
+END
+
+#endif
--- /dev/null
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by App Studio
+#endif // APSTUDIO_INVOKED
+
+#define VER_FILEDESCRIPTION_STR "Winsock Helper (wshelper) API DLL"
+
+#include <wshelper.ver>
+#include <ver.inc>
--- /dev/null
+void res_init_startup();
+void res_init_cleanup();
--- /dev/null
+LIBRARY WSHELP32
+
+HEAPSIZE 1024
+EXPORTS
+; WEP @1 RESIDENTNAME
+ res_init @2
+ res_query @3
+ res_search @4
+ res_querydomain @5
+ res_mkquery @6
+ res_send @7
+ dn_comp @8
+ rdn_expand @9
+ rgethostbyname @10
+ rgethostbyaddr @11
+ hes_to_bind @12
+ hes_resolve @13
+ hes_error @14
+ hes_getmailhost @15
+ hes_getservbyname @16
+ hes_getpwnam @17
+ res_getopts @18
+ res_setopts @19
+ inet_aton @20
+ gethinfobyname @21
+ getmxbyname @22
+ getrecordbyname @23
+ rrhost @24
+ rgetservbyname @25
+ hes_getpwuid @26
+ wsh_gethostname
+ wsh_getdomainname
+ hes_free
--- /dev/null
+LIBRARY WSHELP64
+
+HEAPSIZE 1024
+EXPORTS
+; WEP @1 RESIDENTNAME
+ res_init @2
+ res_query @3
+ res_search @4
+ res_querydomain @5
+ res_mkquery @6
+ res_send @7
+ dn_comp @8
+ rdn_expand @9
+ rgethostbyname @10
+ rgethostbyaddr @11
+ hes_to_bind @12
+ hes_resolve @13
+ hes_error @14
+ hes_getmailhost @15
+ hes_getservbyname @16
+ hes_getpwnam @17
+ res_getopts @18
+ res_setopts @19
+ inet_aton @20
+ gethinfobyname @21
+ getmxbyname @22
+ getrecordbyname @23
+ rrhost @24
+ rgetservbyname @25
+ hes_getpwuid @26
+ wsh_gethostname
+ wsh_getdomainname
+ hes_free
--- /dev/null
+LIBRARY WSHELPER
+
+DESCRIPTION 'WINSOCK DNS/Hesiod Resolver Library'
+EXETYPE WINDOWS
+CODE LOADONCALL MOVEABLE DISCARDABLE
+DATA LOADONCALL PRELOAD FIXED SINGLE
+HEAPSIZE 1024
+SEGMENTS _TEXT PRELOAD FIXED
+EXPORTS
+ WEP @1 RESIDENTNAME
+ res_init @2
+ res_query @3
+ res_search @4
+ res_querydomain @5
+ res_mkquery @6
+ res_send @7
+ dn_comp @8
+ rdn_expand @9
+ rgethostbyname @10
+ rgethostbyaddr @11
+ hes_to_bind @12
+ hes_resolve @13
+ hes_error @14
+ hes_getmailhost @15
+ hes_getservbyname @16
+ hes_getpwnam @17
+ res_getopts @18
+ res_setopts @19
+ inet_aton @20
+ gethinfobyname @21
+ getmxbyname @22
+ getrecordbyname @23
+ rrhost @24
+ rgetservbyname @25
+ hes_getpwuid @26
+
+
+IMPORTS
+ kernel.LoadLibraryEx32W
+ kernel.FreeLibrary32W
+ kernel._CallProcEx32W
+ kernel.GetProcAddress32W