From: no author Date: Thu, 12 Feb 2004 20:37:48 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create tag X-Git-Tag: kfw-2.6-beta5 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b3a8a5ced4064251fca903d88a51667fd6e74b65;p=krb5.git This commit was manufactured by cvs2svn to create tag 'kfw-2_6-beta-5'. git-svn-id: svn://anonsvn.mit.edu/krb5/tags/kfw-2_6-beta-5@16068 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/README b/README index a74353d10..664c12d1d 100644 --- a/README +++ b/README @@ -1,43 +1,26 @@ -these were the - Kerberos Version 5, Release 1.2 + Kerberos Version 5, Release 1.3.2 Release Notes -which are be updated for the next release by The MIT Kerberos Team Unpacking the Source Distribution --------------------------------- -The source distribution of Kerberos 5 comes in three gzipped tarfiles, -krb5-1.2.src.tar.gz, krb5-1.2.doc.tar.gz, and krb5-1.2.crypto.tar.gz. -The krb5-1.2.doc.tar.gz contains the doc/ directory and this README -file. The krb5-1.2.src.tar.gz contains the src/ directory and this -README file, except for the crypto library sources, which are in -krb5-1.2.crypto.tar.gz. - -Instruction on how to extract the entire distribution follow. These -directions assume that you want to extract into a directory called -DIST. +The source distribution of Kerberos 5 comes in a gzipped tarfile, +krb5-1.3.2.tar.gz. Instructions on how to extract the entire +distribution follow. If you have the GNU tar program and gzip installed, you can simply do: - mkdir DIST - cd DIST - gtar zxpf krb5-1.2.src.tar.gz - gtar zxpf krb5-1.2.crypto.tar.gz - gtar zxpf krb5-1.2.doc.tar.gz + gtar zxpf krb5-1.3.2.tar.gz If you don't have GNU tar, you will need to get the FSF gzip distribution and use gzcat: - mkdir DIST - cd DIST - gzcat krb5-1.2.src.tar.gz | tar xpf - - gzcat krb5-1.2.crypto.tar.gz | tar xpf - - gzcat krb5-1.2.doc.tar.gz | tar xpf - + gzcat krb5-1.3.2.tar.gz | tar xpf - -Both of these methods will extract the sources into DIST/krb5-1.2/src -and the documentation into DIST/krb5-1.2/doc. +Both of these methods will extract the sources into krb5-1.3.2/src and +the documentation into krb5-1.3.2/doc. Building and Installing Kerberos 5 ---------------------------------- @@ -70,8 +53,228 @@ If you are not able to use krb5-send-pr because you haven't been able compile and install Kerberos V5 on any platform, you may send mail to krb5-bugs@mit.edu. +You may view bug reports by visiting + +http://krbdev.mit.edu/rt/ + +and logging in as "guest" with password "guest". + +Major changes in 1.3.2 +---------------------- + +* [2040, 1471, 2067, 2077, 2079, 2166, 2167, 2220] Support for AES in + GSSAPI has been implemented. This corresponds to the in-progress + work in the IETF (CFX). + +* [2049, 2139, 2148, 2153, 2182, 2183, 2184, 2190, 2202] Added a new + ccache type "MSLSA:" for read-only access to the MS Windows LSA + cache. + +* [982] On windows, krb5.exe now has a checkbox to request addressless + tickets. + +* [2189] To avoid compatibility problems, unrecognized TGS options + will now be ignored. + +* [2218] 128-bit AES has been added to the default enctypes. + +* [2223] AES cryptosystem now chains IVs. This WILL break backwards + compatibility for the kcmd applications, if they are using AES + session keys. + +Minor changes in 1.3.2 +---------------------- + +* [1437] Applied patch from Stephen Grau so kinit returns non-zero + status under certain failure conditions where it had previously + returned zero. + +* [1586] On Windows, the krb4 CREDENTIALS structure has been changed + to align with KfW's version of the structure. + +* [1613] Applied patch from Dave Shrimpton to avoid truncation of + dates output from the kadmin CLI when long time zone names are + used. + +* [1622] krshd no longer calls syslog from inside a signal handler, in + an effort to avoid deadlocks on exit. + +* [1649] A com_err test program compiles properly on Darwin now. + +* [1692] A new configuration file tag "master_kdc" has been added to + allow master KDCs to be designated separately from admin servers. + +* [1702] krb5_get_host_realm() and krb5_free_host_realm() are no + longer marked as KRB5_PRIVATE. + +* [1711] Applied patch from Harry McGavran Jr to allow fake-addrinfo.h + to compile on libc5 Linux platforms. + +* [1712] Applied patch from Cesar Garcia to fix lifetime computation + in krb524 ticket conversion. + +* [1714] Fixed a 64-bit endianness bug in ticket starttime encoding in + krb524d. Found by Cesar Garcia. + +* [1715] kadmind4 and v5passwdd are no longer installed on Mac OS X. + +* [1718] The krb4 library configure script now recognizes + OpenDarwin/x86. Bug found by Rob Braun. + +* [1721] krb5_get_init_creds_password() no longer returns a spurious + KRB5_REALM_UNKNOWN if DNS SRV record support is turned off. + +* [1730] krb_mk_auth() no longer overzealously clears the key + schedule. + +* [1731] A double-free related to reading forwarded credentials has + been fixed. Found by Joseph Galbraith. + +* [1770] Applied patch from Maurice Massar to fix a foreachaddr() + problem that was causing the KDC to segfault on startup. + +* [1790] The Linux build uses $(CC) to create shared libraries, + avoiding a libgcc problem when building libdb. + +* [1792] The lib/kadm5 unit tests now work around a Solaris 9 + pty-close bug. + +* [1799] kadmind supports callouts to the Apple password server. + +* [1893] KRB-SAFE messages from older releases can now be read + successfully. Prior 1.3.x releases did not save the encoded + KRB-SAFE message, and experienced problems when re-encoding. Found + by Scooter Morris. + +* [1962] MS LSA tickets with short remaining lifetimes will be + rejected in favor of retrieving tickets bypassing the LSA cache. + +* [1973] sendto_kdc.c now closes sockets with closesocket() instead of + close(), avoiding a descriptor leak on Windows. + +* [1979] An erroneously short initial sequence number mask has been + fixed. + +* [2028] KfW now displays a kinit dialog when GSS fails to find + tickets. + +* [2051] Missing exports have been added to krb4_32.def on Windows. + +* [2058] Some problems with krb4 ticket lifetime backdating have + fixed. + +* [2060] GSSAPI's idea of the default ccache is less sticky now. + +* [2068] The profile library includes prof-int.h before conditionals + that rely on it. + +* [2084] The resolver library is no longer referenced by library code + if not building with DNS SRV record support. + +* [2085] Updated Windows README file to reflect current compliation + requirements, etc. + +* [2104] On Windows, only define strcasecmp and strncasecmp + replacement macros if said functions are missing. + +* [2106] Return an error for unimplemented ccache functions, rather + than calling through a null pointer. + +* [2118] Applied patch from Will Fiveash to use correct parameter for + KDC TCP listening sockets. + +* [2144] Memory management errors in the Windows gss.exe test client + have been fixed. + +* [2171] krb5_locate_kpasswd() now correctly calls htons() on the + kpasswd port number. Found by Arlene Berry. + +* [2180] The profile library now includes pthread.h when compiled with + USE_PTHREADS. + +* [2181, 2224] A timeout has been added to gss-server, and a missing + parameter to sign_server() has been added. + +* [2196] config.{guess,sub} have been updated from autoconf-2.59. + +* [2204] Windows gss.exe now has support for specifying credentials + cache, as well as some minor bugfixes. + +* [2210] GSSAPI accept_sec_context() no longer unconditionally sets + INTEG and CONF flags in contradiction to what the initiator sent. + +* [2212] The GSS sample application has some additional options to + support testing of SSPI vs GSSAPI. + +* [2217] Windows gss.exe has new UI elements to support more flag + settings. + +* [2225] In the gss sample client, some extraneous parameters have + been removed from client_establish_context(). + +* [2228] Copyright notices updated in GSS sample apps. + +Notes, Major Changes, and Known Bugs for 1.3.1 +---------------------------------------------- + +* [1681] The incorrect encoding of the ETYPE-INFO2 preauthentication + hint is no longer emitted, and the both the incorrect and the + correct encodings of ETYPE-INFO2 are now accepted. We STRONGLY + encourage deploying krb5-1.3.1 in preference to 1.3, especially on + client installations, as the 1.3 release did not conform to the + internet-draft for the revised Kerberos protocol in its encoding of + ETYPE-INFO2. + +* [1683] The non-caching getaddrinfo() API on Mac OS X, which was + causing significant slowdowns under some circumstances, has been + worked around. + +Minor changes in 1.3.1 +---------------------- + +* [1015] gss_accept_sec_context() now passes correct arguments to + TREAD_STR() when reading options beyond the forwarded credential + option. Thanks to Emily Ratliff. + +* [1365] The GSSAPI initiator credentials are no longer cached inside + the GSSAPI library. + +* [1651] A buffer overflow in krb_get_admhst() has been fixed. + +* [1655] krb5_get_permitted_enctypes() and krb5_set_real_time() are + now exported for use by Samba. + +* [1656] gss_init_sec_context() no longer leaks credentials under some + error conditions. + +* [1657] krb_get_lrealm() no longer returns "ATHENA.MIT.EDU" + inappropriately. + +* [1664] The crypto library no longer has bogus dependencies on + com_err. + +* [1665] krb5_init_context() no longer multiply registers error tables + when called more than once, preventing a memory leak. + +* [1666] The GSS_C_NT_* symbols are now exported from gssapi32.dll on + Windows. + +* [1667] ms2mit now imports any tickets with supported enctypes, and + does not import invalid tickets. + +* [1677] krb5_gss_register_acceptor_identity() no longer has an + off-by-one in its memory allocation. + +* [1679] krb5_principal2salt is now exported on all platforms. + +* [1684] The file credentials cache is now supported if USE_CCAPI is + defined, i.e., for KfM and KfW. + +* [1691] Documentation for the obsolete kdc_supported_enctypes config + variable has been removed. + Notes, Major Changes, and Known Bugs for 1.3 ------------------------------------- +-------------------------------------------- * We now install the compile_et program, so other packages can use the installed com_err library with their own error tables. (If you use @@ -83,8 +286,13 @@ Notes, Major Changes, and Known Bugs for 1.3 that will probably frustrate any attempts to run this code under SunOS 4 or other pre-C89 systems. -* Some new code, bug fixes, and cleanup for IPv6 support. [[TODO: - Insert list of (non-)supporting programs and libraries here.]] +* Some new code, bug fixes, and cleanup for IPv6 support. Most of the + code should support IPv6 transparently now. The RPC code (and + therefore the admin system, which is based on it) does not yet + support IPv6. The support for Kerberos 4 may work with IPv6 in very + limited ways, if the address checking is turned off. The FTP client + and server do not have support for the new protocol messages needed + for IPv6 support (RFC 2428). * We have upgraded to autoconf 2.52 (or later), and the syntax for specifying certain configuration options have changed. For example, @@ -96,204 +304,489 @@ Notes, Major Changes, and Known Bugs for 1.3 may be necessary when talking to Microsoft KDCs (domain controllers), if they issue you tickets with lots of PAC data. -* If you have versions of the com_err, ss, or Berkeley DB packages - installed locally, you can use the --with-system-et, - --with-system-ss, and --with-system-db configure options to use them - rather than using the versions supplied here. Note that the - interfaces are assumed to be similar to those we supply; in +* If you have versions of the com_err or ss installed locally, you can + use the --with-system-et and --with-system-ss configure options to + use them rather than using the versions supplied here. Note that + the interfaces are assumed to be similar to those we supply; in particular, some older, divergent versions of the com_err library may not work with the krb5 sources. Many configure-time variables can be used to help the compiler and linker find the installed packages; see the build documentation for details. -Notes, Major Changes, and Known Bugs for 1.2, delete before shipping 1.3 ------------------------------------- - -* Triple DES support, for session keys as well as user or service - keys, should be nearly complete in this release. Much of the work - that has been needed is generic multiple-cryptosystem support, so - the addition of another cryptosystem should be much easier. - - * GSSAPI support for 3DES has been added. An Internet Draft is - being worked on that will describe how this works; it is not - currently standardized. Some backwards-compatibility issues in - this area mean that enabling 3DES support must be done with - caution; service keys that are used for GSSAPI must not be updated - to 3DES until the services themselves are upgraded to support 3DES - under GSSAPI. - -* DNS support for locating KDCs is enabled by default. DNS support - for looking up the realm of a host is compiled in but disabled by - default (due to some concerns with DNS spoofing). - - We recommend that you publish your KDC information through DNS even - if you intend to rely on config files at your own site; otherwise, - sites that wish to communicate with you will have to keep their - config files updated with your information. One of the goals of - this code is to reduce the client-side configuration maintenance - requirements as much as is possible, without compromising security. - - See the administrator's guide for information on setting up DNS - information for your realm. - - One important effect of this for developers is that on many systems, - "-lresolv" must be added to the compiler command line when linking - Kerberos programs. - - Configure-time options are available to control the inclusion of the - DNS code and the setting of the defaults. Entries in krb5.conf will - also modify the behavior if the code has been compiled in. - -* Numerous buffer-overrun problems have been found and fixed. Many of - these were in locations we don't expect can be exploited in any - useful way (for example, overrunning a buffer of MAXPATHLEN bytes if - a compiled-in pathname is too long, in a program that has no special - privileges). It may be possible to exploit a few of these to - compromise system security. - -* Partial support for IPv6 addresses has been added. It can be - enabled or disabled at configure time with --enable-ipv6 or - --disable-ipv6; by default, the configure script will search for - certain types and macros, and enable the IPv6 code if they're found. - The IPv6 support at this time mostly consists of including the - addresses in credentials. - -* A protocol change has been made to the "rcmd" suite (rlogin, rsh, - rcp) to address several security problems described in Kris - Hildrum's paper presented at NDSS 2000. New command-line options - have been added to control the selection of protocol, since the - revised protocol is not compatible with the old one. - -* A security problem in login.krb5 has been fixed. This problem was - only present if the krb4 compatibility code was not compiled in. - -* A security problem with ftpd has been fixed. An error in the in the - yacc grammar permitted potential root access. - -* The client programs kinit, klist and kdestroy have been changed to - incorporate krb4 support. New command-line options control whether - krb4 behavior, krb5 behavior, or both are used. - -* Patches from Frank Cusack for much better hardware preauth support - have been incorporated. - -* Patches from Matt Crawford extend the kadmin ACL syntax so that - restrictions can be imposed on what certain administrators may do to - certain accounts. - -* A KDC on a host with multiple network addresses will now respond to - a client from the address that the client used to contact it. The - means used to implement this will however cause the KDC not to - listen on network addresses configured after the KDC has started. - -Minor changes -------------- - -* New software using com_err should use the {add,remove}_error_table - interface rather than init_XXX_error_table; in fact, the latter - function in the generate C files will now call add_error_table - instead of messing with unprotected global variables. - - Karl Ramm has offered to look into reconciling the various - extensions and changes that have been made in different versions of - the MIT library, and the API used in the Heimdal equivalent. No - timeline is set for this work. - -* Some source files (including some header files we install) now have - annotations for use with the LCLint package from the University of - Virginia. LCLint, as of version 2.5q, is not capable of handling - much of the Kerberos code in its current form, at least not without - significantly restructuring the Kerberos code, but it has been used - in limited cases and has uncovered some bugs. We may try adding - more annotations in the future. - -Minor changes for 1.2, delete this section before shipping 1.3 -------------- - -* The shell code for searching for the Tcl package at configure time - has been modified. If a tclConfig.sh can be found, the information - it contains is used, otherwise the old searching method is tried. - Let us know if this new scheme causes any problems. - -* Shared library builds may work on HPUX, Rhapsody/MacOS X, and newer - Alpha systems now. - -* The Windows build will now include kvno and gss-sample. - -* The routine krb5_secure_config_files has been disabled. A new - routine, krb5_init_secure_context, has been added in its place. - -* The routine decode_krb5_ticket is now being exported as - krb5_decode_ticket. Any programs that used the old name (which - should be few) should be changed to use the new name; we will - probably eliminate the old name in the future. - -* The CCAPI-based credentials cache code has been changed to store the - local-clock time of issue and expiration rather than the KDC-clock - times. - -* On systems with large numbers of IP addresses, "kinit" should do a - better job of acquiring those addresses to put in the user's - credentials. - -* Several memory leaks in error cases in the gssrpc code have been - fixed. +* The AES cryptosystem has been implemented. However, support in the + Kerberos GSSAPI mechanism has not been written (or even fully + specified), so it's not fully enabled. See the documentation for + details. + +Major changes listed by ticket ID +--------------------------------- + +* [492] PRNG breakage on 64-bit platforms no longer an issue due to + new PRNG implementation. + +* [523] Client library is now compatible with the RC4-based + cryptosystem used by Windows 2000. + +* [709] krb4 long lifetime support has been implemented. + +* [880] krb5_gss_register_acceptor_identity() implemented (is called + gsskrb5_register_acceptor_identity() by Heimdal). + +* [1087] ftpd no longer requires channel bindings, allowing easier use + of ftp from behind a NAT. + +* [1156, 1209] It is now possible to use the system com_err to build + this release. + +* [1174] TCP support added to client library. + +* [1175] TCP support added to the KDC, but is disabled by default. + +* [1176] autoconf-2.5x is now required by the build system. -* A bug with login clobbering some internal static storage on AIX has +* [1184] It is now possible to use the system Berkeley/Sleepycat DB + library to build this release. + +* [1189, 1251] The KfM krb4 library source base has been merged. + +* [1190] The default KDC master key type is now triple-DES. KDCs + being updated may need their config files updated if they are not + already specifying the master key type. + +* [1190] The default ticket lifetime and default maximum renewable + ticket lifetime have been extended to one day and one week, + respectively. + +* [1191] A new script, k5srvutil, may be used to manipulate keytabs in + ways similar to the krb4 ksrvutil utility. + +* [1281] The "fakeka" program, which emulates the AFS kaserver, has + been integrated. Thanks to Ken Hornstein. + +* [1343] The KDC now defaults to not answering krb4 requests. + +* [1344] Addressless tickets are requested by default now. + +* [1372] There is no longer a need to create a special keytab for + kadmind. The legacy administration daemons "kadmind4" and + "v5passwdd" will still require a keytab, though. + +* [1377, 1442, 1443] The Microsoft set-password protocol has been + implemented. Thanks to Paul Nelson. + +* [1385, 1395, 1410] The krb4 protocol vulnerabilities + [MITKRB5-SA-2003-004] have been worked around. Note that this will + disable krb4 cross-realm functionality, as well as krb4 triple-DES + functionality. Please see doc/krb4-xrealm.txt for details of the + patch. + +* [1393] The xdrmem integer overflows [MITKRB5-SA-2003-003] have been fixed. -* Per-library initialization and cleanup functions have been added, - for use in configurations that dynamically load and unload these - libraries. +* [1397] The krb5_principal buffer bounds problems + [MITKRB5-SA-2003-005] have been fixed. Thanks to Nalin Dahyabhai. + +* [1415] Subsession key negotiation has been fixed to allow for + server-selected subsession keys in the future. + +* [1418, 1429, 1446, 1484, 1486, 1487, 1535, 1621] The AES + cryptosystem has been implemented. It is not usable for GSSAPI, + though. + +* [1491] The client-side functionality of the krb524 library has been + moved into the krb5 library. + +* [1550] SRV record support exists for Kerberos v4. + +* [1551] The heuristic for locating the Kerberos v4 KDC by prepending + "kerberos." to the realm name if no config file or DNS information + is available has been removed. + +* [1568, 1067] A krb524 stub library is built on Windows. + +Minor changes listed by ticket ID +--------------------------------- + +* [90] default_principal_flags documented. + +* [175] Docs refer to appropriate example domains/IPs now. + +* [299] kadmin no longer complains about missing kdc.conf parameters + when it really means krb5.conf parameters. + +* [318] Run-time load path for tcl is set now when linking test + programs. + +* [443] --includedir honored now. + +* [479] unused argument in try_krb4() in login.c deleted. + +* [590] The des_read_pw_string() function in libdes425 has been + aligned with the original krb4 and CNS APIs. + +* [608] login.krb5 handles SIGHUP more sanely now and thus avoids + getting the session into a weird state w.r.t. job control. + +* [620] krb4 encrypted rcp should work a little better now. Thanks to + Greg Hudson. + +* [647] libtelnet/kerberos5.c no longer uses internal include files. -* Many compile-time warnings have been fixed. +* [673] Weird echoing of admin password in kadmin client worked around + by not using buffered stdio calls to read passwords. -* The GSS sample programs have been updated to exercise more of the - API. +* [677] The build system has been reworked to allow the user to set + CFLAGS, LDFLAGS, CPPFLAGS, etc. reasonably. -* The telnet server should produce a more meaningful error message if - authentication is required but not provided. +* [680] Related to [673], rewrite krb5_prompter_posix() to no longer + use longjmp(), thus avoiding some bugs relating to non-restoration + of terminal settings. -* Changes have been made to ksu to make it more difficult to use it to - leak information the user does not have access to. +* [697] login.krb5 no longer zeroes out the terminal window size. -* The sample config file information for the CYGNUS.COM realm has been - updated, and the GNU.ORG realm has been added. +* [710] decomp_ticket() in libkrb4 now looks up the local realm name + more correctly. Thanks to Booker Bense. -* A configure-time option has been added to enable a replay cache in - the KDC. We recommend its use when hardware preauthentication is - being used. It is enabled by default, and can be disabled if - desired with the configure-time option --disable-kdc-replay-cache. +* [771] .rconf files are excluded from the release now. -* Some new routines have been added to the library and krb5.h. +* [772] LOG_AUTHPRIV syslog facility is now usable for logging on + systems that support it. -* A new routine has been added to the prompter interface to allow the - application to determine which of the strings prompted for is the - user's password, in case it is needed for other purposes. +* [844] krshd now syslogs using the LOG_AUTH facility. -* The remote kadmin interface has been enhanced to support the - specification of key/salt types for a principal. +* [850] Berekely DB build is better integrated into the krb5 library + build process. -* New keytab entries' key values can now be specified manually with a - new command in the ktutil program. +* [866] lib/krb5/os/localaddr.c and kdc/network.c use a common source + for local address enumeration now. -* A longstanding bug where certain krb4 exchanges using the - compatibility library between systems with different byte orders - would fail half the time has been fixed. +* [882] gss-client now correctly deletes the context on error. -* A source file under the GPL has been replaced with an equivalent - under the BSD license. The file, strftime.c, was part of one of the - OpenVision admin system applications, and was only used on systems - that don't have strftime() in their C libraries. +* [919] kdc/network.c problems relating to SIOCGIFCONF have been + fixed. + +* [922] An overflow in the string-to-time conversion routines has been + fixed. + +* [933] krb524d now handles single-DES session keys other than of type + des-cbc-crc. + +* [935] des-cbc-md4 now included in default enctypes. + +* [939] A minor grammatical error has been fixed in a telnet client + error message. + +* [953] des3 no longer failing on Windows due to SHA1 implementation + problems. + +* [964] kdb_init_hist() no longer fails if master_key_enctype is not + in supported_enctypes. + +* [970] A minor inconsistency in ccache.tex has been fixed. + +* [971] option parsing bugs rendered irrelevant by removal of unused + gss mechanism. + +* [976] make install mentioned in build documentation. + +* [986] Related to [677], problems with the ordering of LDFLAGS + initialization rendered irrelevant by use of native autoconf + idioms. + +* [992] Related to [677], quirks with --with-cc no longer relevant as + AC_PROG_CC is used instead now. + +* [999] The kdc_default_options configuration variable is now honored. + Thanks to Emily Ratliff. + +* [1006] Client library, as well as KDC, now perform reasonable + sorting of ETYPE-INFO preauthentication data. + +* [1055] NULL pointer dereferences in code calling + krb5_change_password() have been fixed. + +* [1063] Initial credentials acquisition failures related to client + host having a large number of local network interfaces should be + fixed now. + +* [1064] Incorrect option parsing in the gssapi library is no longer + relevant due to removal of the "v2" mechanism. + +* [1065, 1225] krb5_get_init_creds_password() should properly warn about + password expiration. + +* [1066] printf() argument mismatches in rpc unit tests fixed. + +* [1085] The krb5.conf manpage has been re-synchronized with other + documentation. + +* [1102] gssapi_generic.h should now work with C++. + +* [1135] The kadm5 ACL system is better documented. + +* [1136] Some documentation for the setup of cross-realm + authentication has been added. + +* [1164] krb5_auth_con_gen_addrs() now properly returns errno instead + of -1 if getpeername() fails. + +* [1173] Address-less forwardable tickets will remain address-less + when forwarded. + +* [1178, 1228, 1244, 1246, 1249] Test suite has been stabilized + somewhat. + +* [1188] As part of the modernization of our usage of autoconf, + AC_CONFIG_FILES is now used instead of passing a list of files to + AC_OUTPUT. + +* [1194] configure will no longer recurse out of the top of the source + tree when attempting to locate the top of the source tree. + +* [1192] Documentation for the krb5 afs functionality of krb524d has + been written. + +* [1195] Example krb5.conf file modified to include all enctypes + supported by the release. + +* [1202] The KDC no longer rejects unrecognized flags. + +* [1203] krb5_get_init_creds_keytab() no longer does a double-free. + +* [1211] The ASN.1 code no longer passes (harmless) uninitialized + values around. + +* [1212] libkadm5 now allows for persistent exclusive database locks. + +* [1217] krb5_read_password() and des_read_password() are now + implemented via krb5_prompter_posix(). + +* [1224] For SAM challenges, omitted optional strings are no longer + encoded as zero-length strings. + +* [1226] Client-side support for SAM hardware-based preauth + implemented. + +* [1229] The keytab search logic no longer fails prematurely if an + incorrect encryption type is found. Thanks to Wyllys Ingersoll. + +* [1232] If the master KDC cannot be resolved, but a slave is + reachable, the client library now returns the real error from the + slave rather than the resolution failure from the master. Thanks to + Ben Cox. + +* [1234] Assigned numbers for SAM preauth have been corrected. + sam-pk-for-sad implementation has been aligned. + +* [1237] Profile-sharing optimizations from KfM have been merged. + +* [1240] Windows calling conventions for krb5int_c_combine_keys() have + been aligned. + +* [1242] Build system incompatibilities with Debian's chimeric + autoconf installation have been worked around. + +* [1256] Incorrect sizes passed to memset() in combine_keys() + operations have been corrected. + +* [1260] Client credential lookup now gets new service tickets in + preference to attempting to use expired ticketes. Thanks to Ben + Cox. + +* [1262, 1572] Sequence numbers are now unsigned; negative sequence + numbers will be accepted for the purposes of backwards + compatibility. + +* [1263] A heuristic for matching the incorrectly encoded sequence + numbers emitted by Heimdal implementations has been written. + +* [1284] kshd accepts connections by IPv6 now. + +* [1292] kvno manpage title fixed. + +* [1293] Source files no longer explicitly attempt to declare errno. + +* [1304] kadmind4 no longer leaves sa_flags uninitialized. + +* [1305] Expired tickets now cause KfM to pop up a password dialog. + +* [1309] krb5_send_tgs() no longer leaks the storage associated with + the TGS-REQ. + +* [1310] kadm5_get_either() no longer leaks regexp library memory. + +* [1311] Output from krb5-config no longer contains spurious uses of + $(PURE). + +* [1324] The KDC no longer logs an inappropriate "no matching key" + error when an encrypted timestamp preauth password is incorrect. + +* [1334] The KDC now returns a clockskew error when the timestamp in + the encrypted timestamp preauth is out of bounds, rather than just + returning a preauthentcation failure. + +* [1342] gawk is no longer required for building kerbsrc.zip for the + Windows build. -* Many bug reports are still outstanding in our database. We are - continuing to work on this backlog. +* [1346] gss_krb5_ccache_name() no longer attempts to return a pointer + to freed memory. +* [1351] The filename globbing vulnerability [CERT VU#258721] in the + ftp client's handling of filenames beginning with "|" or "-" + returned from the "mget" command has been fixed. + +* [1352] GSS_C_PROT_READY_FLAG is no longer asserted inappropriately + during GSSAPI context establishment. + +* [1356] krb5_gss_accept_sec_context() no longer attempts to validate + a null credential if one is passed in. + +* [1362] The "-a user" option to telnetd now does the right thing. + Thanks to Nathan Neulinger. + +* [1363] ksu no longer inappropriately syslogs to stderr. + +* [1357] krb__get_srvtab_name() no longer leaks memory. + +* [1370] GSS_C_NO_CREDENTIAL now accepts any principal in the keytab. + +* [1373] Handling of SAM preauth no longer attempts to stuff a size_t + into an unsigned int. + +* [1387] BIND versions later than 8 now supported. + +* [1392] The getaddrinfo() wrapper should work better on AIX. + +* [1400] If DO_TIME is not set in the auth_context, and no replay + cache is available, no replay cache will be used. + +* [1406, 1108] libdb is no longer installed. If you installed + krb5-1.3-alpha1, you should ensure that no spurious libdb is left in + your install tree. + +* [1412] ETYPE_INFO handling no longer goes into an infinite loop. + +* [1414] libtelnet is now built using the same library build framework + as the rest of the tree. + +* [1417] A minor memory leak in krb5_read_password() has been fixed. + +* [1419] A memory leak in asn1_decode_kdc_req_body() has been fixed. + +* [1435] inet_ntop() is now emulated when needed. + +* [1439] krb5_free_pwd_sequences() now correctly frees the entire + sequence of elements. + +* [1440] errno is no longer explicitly declared. + +* [1441] kadmind should now return useful errors if an unrecognized + version is received in a changepw request. + +* [1454, 1480, 1517, 1525] The etype-info2 preauth type is now + supported. + +* [1459] (KfM/KLL internal) config file resolution can now be + prevented from accessing the user's homedir. + +* [1463] Preauth handling in the KDC has been reorganized. + +* [1470] Double-free in client-side preauth code fixed. + +* [1473] Ticket forwarding when the TGS and the end service have + different enctypes should work somewhat better now. + +* [1474] ASN.1 testsuite memory management has been cleaned up a + little to allow for memory leak checking. + +* [1476] Documentation updated to reflect default krb4 mode. + +* [1482] RFC-1964 OIDs now provided using the suggested symbolic + names. + +* [1483, 1528] KRB5_DEPRECATED is now false by default on all + platforms. + +* [1488] The KDC will now return integrity errors if a decryption + error is responsible for preauthentication failure. + +* [1492] The autom4te.cache directories are now deleted from the + release tarfiles. + +* [1501] Writable keytabs are registered by default. + +* [1515] The check for cross-realm TGTs no longer reads past the end + of an array. + +* [1518] The kdc_default_options option is now actually honored. + +* [1519] The changepw protocol implementation in kadmind now logs + password changes. + +* [1520] Documentation of OS-specific build options has been updated. + +* [1536] A missing prototype for krb5_db_iterate_ext() has been + added. + +* [1537] An incorrect path to kdc.conf show in the kdc.conf manpage + has been fixed. + +* [1540] verify_as_reply() will only check the "renew-till" time + against the "till" time if the RENEWABLE is not set in the request. + +* [1547] gssftpd no longer uses vfork(), as this was causing problems + under RedHat 9. + +* [1549] SRV records with a value of "." are now interpreted as a lack + of support for the protocol. + +* [1553] The undocumented (and confusing!) kdc_supported_enctypes + kdc.conf variable is no longer used. + +* [1560] Some spurious double-colons in password prompts have been + fixed. + +* [1571] The test suite tries a little harder to get a root shell. + +* [1573] The KfM build process now sets localstatedir=/var/db. + +* [1576, 1575] The client library no longer requests RENEWABLE_OK if + the renew lifetime is greater than the ticket lifetime. + +* [1587] A more standard autoconf test to locate the C compiler allows + for gcc to be found by default without additional configuration + arguments. + +* [1593] Replay cache filenames are now escaped with hyphens, not + backslashes. + +* [1598] MacOS 9 support removed from in-tree com_err. + +* [1602] Fixed a memory leak in make_ap_req_v1(). Thanks to Kent Wu. + +* [1604] Fixed a memory leak in krb5_gss_init_sec_context(), and an + uninitialized memory reference in kg_unseal_v1(). Thanks to Kent + Wu. + +* [1607] kerberos-iv SRV records are now documented. + +* [1610] Fixed AES credential delegation under GSSAPI. + +* [1618] ms2mit no longer inserts local addresses into tickets + converted from the MS ccache if they began as addressless tickets. + +* [1619] etype_info parser (once again) accepts extra field emitted by + Heimdal. + +* [1643] Some typos in kdc.conf.M have been fixed. + +* [1648] For consistency, leading spaces before preprocessor + directives in profile.h have been removed. Copyright Notice and Legal Administrivia ---------------------------------------- -Copyright (C) 1985-2000 by the Massachusetts Institute of Technology. +Copyright (C) 1985-2004 by the Massachusetts Institute of Technology. All rights reserved. @@ -459,7 +952,7 @@ Thanks to Doug Engert from ANL for providing many bug fixes, as well as testing to ensure DCE interoperability. Thanks to Ken Hornstein at NRL for providing many bug fixes and -suggestions. +suggestions, and for working on SAM preauthentication. Thanks to Matt Crawford at FNAL for bugfixes and enhancements. @@ -472,11 +965,15 @@ providing patches for numerous buffer overruns. Thanks to Christopher Thompson and Marcus Watts for discovering the ftpd security bug. +Thanks to Paul Nelson of Thursby Software Systems for implementing the +Microsoft set password protocol. + Thanks to the members of the Kerberos V5 development team at MIT, both -past and present: Danilo Almeida, Jay Berkenbilt, Richard Basch, John -Carr, Don Davis, Alexandra Ellwood, Nancy Gilman, Matt Hancher, Sam -Hartman, Paul Hill, Marc Horowitz, Eva Jacobus, Miroslav Jurisic, -Barry Jaspan, Geoffrey King, John Kohl, Peter Litwack, Scott McGuire, -Kevin Mitchell, Cliff Neuman, Paul Park, Ezra Peisach, Chris -Provenzano, Ken Raeburn, Jon Rochlis, Jeff Schiller, Brad Thompson, -Harry Tsai, Ted Ts'o, Marshall Vale, Tom Yu. +past and present: Danilo Almeida, Jeffrey Altman, Jay Berkenbilt, +Richard Basch, Mitch Berger, John Carr, Don Davis, Alexandra Ellwood, +Nancy Gilman, Matt Hancher, Sam Hartman, Paul Hill, Marc Horowitz, Eva +Jacobus, Miroslav Jurisic, Barry Jaspan, Geoffrey King, John Kohl, +Peter Litwack, Scott McGuire, Kevin Mitchell, Cliff Neuman, Paul Park, +Ezra Peisach, Chris Provenzano, Ken Raeburn, Jon Rochlis, Jeff +Schiller, Jen Selby, Brad Thompson, Harry Tsai, Ted Ts'o, Marshall +Vale, Tom Yu. diff --git a/doc/.Sanitize b/doc/.Sanitize deleted file mode 100644 index 89b441370..000000000 --- a/doc/.Sanitize +++ /dev/null @@ -1,46 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -ChangeLog -HOW_TO_BUILD -INCOMPATIBILITY -Makefile -OS-notes -SOURCE-TREE -TREE-GRAPH -api -implement -install.texi -install.ps -kadmin -krb5-protocol -old-V4-docs -texinfo.tex - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/doc/.cvsignore b/doc/.cvsignore deleted file mode 100644 index 5e1510dbe..000000000 --- a/doc/.cvsignore +++ /dev/null @@ -1,16 +0,0 @@ -*.html -*.info -*.info-* -*.log -*.dvi -*.aux -*.toc -*.cp -*.fn -*.vf -*.tp -*.ky -*.pg -*.vr -*.ps -krb5-install diff --git a/doc/ChangeLog b/doc/ChangeLog deleted file mode 100644 index 709c55980..000000000 --- a/doc/ChangeLog +++ /dev/null @@ -1,702 +0,0 @@ -2003-02-04 Sam Hartman - - * krb425.texinfo (Upgrading KDCs): Note that -4 needs to be specified - -2003-01-30 Sam Hartman - - * definitions.texinfo: Remove bogus sample IPs and domains. - -2002-09-20 Ken Raeburn - - * admin.texinfo, dnssrv.texinfo: Documented config file variables - and SRV records to use for Kerberos TCP service, if it's enabled, - which it isn't by default. Removed UDP port 750 from the DNS SRV - recommendations. - -2002-09-20 Jen Selby - - * Makefile: made the list of manpages a variable - * admin.texinfo: took out second inclusion of copyright notice, - changed some section names, updated initial synopsis of file, - added explanation of encryption types and the [login] section of - krb5.conf, added documentation on various tags in the configuration - files, added some more examples, fixed some typos, updated usage - statements for various kadmin and kdb5_util commands, updated the - sample output from the commands, updated the infotex for use with - makeinfo --html, added a section about getting shared-realm keys, - updated the error codes - * build.texinfo: added a section describing the structure of the - source code tree, updated documentation of options to configure - script, added information about defaults for various variable - settings, updated information about shared library support, - added discussion of valid kerberos principals - * definitions.texinfo: added some new default variables, - corrected some pathnames of default values - * dnssrv.texinfo: made the information about default port numbers - reference a variable - * glossary.texinfo: updated definition of principal - * install.texinfo: fixed typos and formatting errors, removed old - sample config files from appendix (samples are in the sections about - the config files), added information about supporting RC4 keys - * kadm5.acl: new file. describes the kadm5.acl file. included by - both admin.texinfo and install.texinfo. text is made up mostly of - text that was split between those two documents. documentation - of backreferences was added - * kdcconf.texinfo: made defaults reference variables - * krb425.texinfo: deleted second inclusion of copyright info, - made defaults reference variable, fixed typos, took out redundant - part about editing inetd.conf and replaced it with reference to - install guide - * krb5conf.texinfo: documented the "final variable" feature, - added mention of the [login] section, - * send-pr.texinfo: minor change in wording for clarity - * user-guide.texinfo: made various minor wording changes, updated - some of the sample output, updated documention of command options - - -2002-09-13 Ken Raeburn - - * build.texinfo (Options to Configure): Update for new options - --with-system-db, DB_HEADER=, DB_LIB=. - -2002-09-03 Ken Raeburn - - * build.texinfo (Options to Configure): Update for new options - --with-system-et, --with-system-ss, SS_DIR=. - -2002-09-02 Ken Raeburn - - * build.texinfo (Options to Configure): Update for new "CC=" style - options replacing "--with-cc=" options. - -2002-07-03 Ezra Peisach - - * user-guide.texinfo: Change `@end rawhtml' to `@end html' Texinfo - 4 is more particular about matching @ifhtml (texinfo 3 did not - check). klist, ftp, and rcp postscript man pages have an - additional page now. - -2002-06-26 Jen Selby - - * Makefile: changed the way html output is generated, made "make all" - remove generated tex files - * admin.texinfo: added sections about encryption types and salts, - updated the configuration file sections, revised the example - configuration files, updated dates on output strings, added an - explanation of destroying a Kerberos database - * build.texinfo: changed the description of the tarball - * definitions.texinfo: added variables for all the default values - so that they can all be updated in one place, changed the release - from 1.2 to 1.3 - * dnstxt.texinfo updated the information - * install.texinfo added more description of the configuration files - and the minimum needed in the files to set up a kerberos realm, - revised the examples of the configuration file sections, took out - old encryption type and salt information - * kdcconf.texinfo: new file, taken from the admin guide and included - in both the admin and install guides, provides descriptions of the - sections in kdc.conf - * krb425.texinfo: moved a texinfo tag so that makeinfo --html would - work - * krb5conf.texinfo: new file, take from the admin guide and included - in both the admin and install guides, provides descriptions of the - sections in krb5.conf - * man2html, man2html.M: new files, a perl program to create html pages - from the output of the man command - * salts.texinfo: new file, a description of the different salt types - that are currently supported - * support-enc.texinfo: new file, a description of the currently - supported encryptions types - * user-guide.texinfo: added a section describing different ticket - flags, added a way to have the man pages in the reference section - accessible in the html version of the documentation - -2002-06-21 Ezra Eeisach - - * implementor.texinfo (IPv6 Support): Update fact that IRIX 6.5.16 - has enough support for configure to believe IPv6 support works, - but the libraries fail to provide a definition of in6addr_any - (although netinet/in.h implies it foes). - -2002-06-20 Sam Hartman - - * implementor.texinfo (Operating System Notes for Shared Libraries): Update why we don't use libtool - (Solaris Shared Library Support): Update - -2002-06-18 Ken Raeburn - - * implementor.texinfo: Don't use @smallbook. - (IPv6 Support): New chapter. - (Socket API): New placeholder chapter. - (Local Addresses, Host Address Lookup): Specify more precisely the - IRIX version we use at MIT. - (Thread Safety): Delete quoted email, since we don't actually have - this API yet. Refer people to the mailing list archives. - (Operating System Notes for Shared Libraries): Add an introduction - mentioning why we can't use libtool. - - * copyright.texinfo: Update copyright year. - -2002-05-30 Jen Selby - - * admin.texinfo, install.texinfo, dnssrv.texinfo, dnstxt.texinfo: - I corrected some minor typos. Moved DNS information to separate - files. Included these files in install guide (where they had - been) and in new sections in the admin guide. - -2002-05-08 Ken Raeburn - - * implementor.texinfo: Formatting updates. Tru64 5.1 SIOCGIFCONF - and getaddrinfo update. Description of fake-addrinfo.h and thread - safety problems. - -2002-03-13 Ken Raeburn - - * implementor.texinfo: Add chapters on local addresses, hostname - address lookups, and thread safety. - -2001-09-25 Ken Raeburn - - * admin.texinfo (realms (kdc.conf)): Add description of - reject_bad_transit realm option. - -2001-06-26 Ezra Peisach - - * user-guide.texinfo, install.texinfo: Cleanup makeinfo warning of - not having `.' or `,' after @xref. - -2001-01-19 Ken Raeburn - - * coding-style: Assume ANSI C '89. Use krb5int_ for internal - names. - -2000-07-12 Tom Yu - - * coding-style: Update after some discussion. Add sections - comparing to BSD KNF and GNU coding standards. - -2000-07-11 Tom Yu - - * coding-style: Some minor tweaks. Require do-while to always be - braced. Note some aspects of function pointer and array pointer - usage. Elaborate on function declaration practices. Add - placeholders for sections on Makefiles and test suites. - -2000-07-10 Tom Yu - - * coding-style: Another pass. Add secion on namespaces. - Elaborate some on null pointers. - -2000-07-10 Tom Yu - - * coding-style: First pass draft of coding standards. - -2000-06-30 Ken Raeburn - - * admin.texinfo (Kerberos V5 Database Library Error Codes): - Replace RCS Id strings with comments indicating that the RCS Id - string of the error table is used. - -2000-06-22 Tom Yu - - * build.texinfo (HPUX): Update note for HPUX compiler flags. - (Shared Library Support): Update shared lib support info. - -2000-06-16 Ken Raeburn - - * admin.texinfo: Update descriptions to indicate full support for - des3. Describe new DNS-related libdefaults tags for krb5.conf. - - * build.texinfo (Options to Configure): Fix @item labels. - - * install.texinfo: Update descriptions to indicate full support - for des3, and describe "v4" salt as being useful only with - des-cbc-crc. - -2000-06-15 Tom Yu - - * admin.texinfo: Note in multiple places that the current default - dump format doesn't include the per-principal policy information, - and some means of working around this problem. - - * install.texinfo (Switching Master and Slave KDCs): Note that - in the process of swapping KDCs, it is necessary to do a ov format - dump in order to preserve per-principal policy information. - -2000-06-13 Tom Yu - - * install.texinfo (Upgrading Existing Kerberos V5 Installations): - Add info describing how to preserve policy information while - upgrading. Also needs to go into other sections, possibly. - -2000-06-13 Ken Raeburn - - * build.texinfo: Enter correct xref info for DNS data - descriptions. Fix up text around some xrefs. - * install.texinfo: Describe SRV and TXT DNS records. Fix up text - around some xrefs. - -2000-06-09 Tom Yu - - * admin.texinfo: Add descriptions of the kadmin {ank,cpw,ktadd} -e - flag. - -2000-06-06 Ken Raeburn - - * install.texinfo: Describe new DNS support, and 3DES upgrade - path. Update "enctypes" config file sample lines. - - * build.texinfo: No kpasswd directory. Describe new configure - options. - - * send-pr.texinfo: Suggest caution regarding tab expansion for - patches. - -2000-06-02 Ken Raeburn - - * definitions.texinfo: Update for 1.2 release. - -2000-05-31 Ken Raeburn - - * krb425.texinfo (libdefaults): Add description of v4_realm. - -1999-09-22 Tom Yu - - * copyright.texinfo: Update copyright again. - -1999-09-17 Tom Yu - - * copyright.texinfo: Update copyright notice somewhat. - - * install.texinfo: Update info on upgrading a KDC for 1.1. - -1999-09-08 Ken Raeburn - - * install.texinfo (Mac OS X Configuration): Revised text from - Alexis, with more explanations of what's going on. - -1999-09-07 Ken Raeburn - - * definitions.texinfo: Update for 1.1 release. - - * admin.texinfo (Adding or Modifying Principals): Mention des3 - enctype for host keys. - - * build.texinfo: Replace "krb5-1.0" with "krb5-@value{RELEASE}" - throughout. - (Shared Library Support): Cut supported-OS list down to Solaris - and Irix for now. - - * install.texinfo: Update EDITION to 1.1. - (MacOS X Configuration): New node, with info from Brad Thompson. - (Encryption Types and Salt Types): Mention des3. - -1999-08-31 Ken Raeburn - - * admin.texinfo (Kadmin Options): Describe -e option. - (The User/Kerberos Interaction): Renamed from User--Kerberos to - avoid an apparent makeinfo 1.68 bug. - (realms (kdc.conf)): Document kdc_supported_enctypes, and mention - how des3 can be used there. Add des-cbc-crc:v4 to both enctype - lists, in the descriptions and in the examples. Delete - encryption_type, which doesn't exist. - (Date Format): Avoid 2-digit years, and add a warning about them. - -Fri Dec 13 15:10:44 1996 Tom Yu - - * admin.texinfo (The User--Kerberos Interaction): The environment - variable is KRB5CCNAME, not KRB5_CCNAME. - (Getting DNS Information Correct): It's Domain Name System, not - Distributed Name Service. - -Thu Dec 12 18:36:20 1996 Tom Yu - - * user-guide.texinfo: Bump edition to 1.0. Nuke gratuitous - vfills. Change @value{PRODUCT} to explicit reference, to avoid - makeinfo bug that introduces a nul character. - - * krb425.texinfo: Bump edition to 1.0. - - * build.texinfo (OS Incompatibilities): Refer to krb5-send-pr - instead of mail to krb5-bugs. - (Options to Configure): Change options to indicate meta-names, - e.g. "--prefix=PREFIX"; also nuke leading slash on some - descriptions of options. - - * admin.texinfo: Add more explicit linebreaks to prevent overruns; - also break up a few long lines in example program output. - -Fri Dec 6 13:58:19 1996 Tom Yu - - * .cvsignore: Ignore by suffix rather than by file. - - * Makefile (admin-guide-info): - (admin-guide-info): Update to reflect new info file name. - - * admin.texinfo: Change info file name to krb5-admin.info for - consistency. - (Administrating Kerberos Database Entries): "-c credentials_cache" - -> "-c ccache" to avoid overrun. - (Privileges): Null instance example is joeuser@REALM, not - joeuser/null@REALM. - - * install.texinfo (Kerberos Realms): SAN_FRANCISCO.FUBAR.ORG -> - HOUSTON.FUBAR.ORG to prevent margin overrun. - (Create a kadmind Keytab): Add explicit linebreak to prevent - margin overrun. - (Overview of This Guide): - (Installing Kerberos V5): Remove references to windows and mac - client machines for now. - - * krb425.texinfo: Use krb425.info instead of - Kerberos-V4-to-V5.info in the interest of shorter filenames. - - * user-guide.texinfo (Introduction): Eliminate "Kerberos V5 is - based on Kerberos V5". - (Ticket Management): Fix ref to "/rsh". - (rsh): Add explicit linebreak to avoid margin overrun. - - * krb425.texinfo (Upgrading KDCs): Use ROOTDIR rather than - INSTALLDIR to get the proper pathname. - - * send-pr.texinfo: Fix some misspellings, also remove references - to things that are only really applicable for Cygnus. - -Wed Dec 4 23:47:28 1996 Tom Yu - - * krb425.texinfo (Upgrading Application Servers): v5srvtab -> - krb5.keytab - -Mon Dec 2 13:00:26 1996 Barry Jaspan - - * build.texinfo (The DejaGnu Tests): info about .k5login for - krb-root tests [krb5-doc/261] - - * install.texinfo (Add Administrators to the Kerberos Database): - note relationship between acl file and admin principals - [krb5-doc/251] - (Edit the Configuration Files): mention the logging stanza here, - too, and tell people to check it when they start the daemons - [krb5-doc/253] - - * build.texinfo (The KADM5 Tests): add section for the kadm5 tests - [krb5-doc/247] - -Fri Nov 29 19:47:38 1996 Tom Yu - - * build.texinfo (Unpacking the Sources): Mention that ./krb5-1.0 - is the default directory that the tarballs will unpack into. - Also, "/u1/krb5" -> "/u1/krb5-1.0". - (osconf.h): Remove reference to DEFAULT_LNAME_FILENAME, as we're - no longer using the aname database code. - (Options to Configure): Add mention of --localstatedir - (Shared Library Support): It's Solaris 2.4/SunOS 5.4, not Solaris - 5.4. - (Solaris 2.X): Shared libs work with gcc. - - * install.texinfo (Mapping Hostnames onto Kerberos Realms): Fix - spacing error. - - * admin.texinfo: Fix up old references to "/krb5". - - * send-pr.texinfo: krb5-send-pr is in PREFIX/sbin, not PREFIX/bin. - - * admin.texinfo: "/lib/krb5kdc" -> "/var/krb5kdc" - - * krb425.texinfo (Upgrading Application Servers): Change flag - "cygnus" to "CYGNUS". - - * install.texinfo (Please Read the Documentation): Change flag - "cygnus" to "CYGNUS". - - * admin.texinfo (domain_realm): Change flag "cygnus" to "CYGNUS". - - * definitions.texinfo: Change /usr/@value{LCPRODUCT} to /usr/local - to sync with default paths. - - * admin.texinfo (domain_realm): Conditionalize "COM" vs "EDU" in - example. - - * install.texinfo (Create Host Keys for the Slave KDCs): Change - -randpass to -randkey. [244] - -Thu Nov 28 18:54:02 1996 Tom Yu - - * krb425.texinfo: Change to use "@chapternewpage odd", also frob - copyright page as per other docs. Also, remove footnote claiming - that "Kerberos V5 is based on the MIT beta7 release". - - * admin.texinfo (capaths): Fix unquoted braces. - (appdefaults): Fix unquoted braces. - -Wed Nov 27 18:27:18 1996 Jeffrey C. G. Bigler - - * Makefile: Added send-pr.texinfo to ADMIN_INCLUDES and - INSTALL_INCLUDES. - - * admin.texinfo: Added chapter on config files. Changed bug - reporting section to include send-pr file. - - * install.texinfo: Changed bug reporting section to include - send-pr file. Added reference to Sysadmin Guide chapter on config - files. - - * send-pr.texinfo: Fixed this up to match our version of - krb5-send-pr. - -Tue Nov 26 18:34:11 1996 Tom Yu - - * install.texinfo: Fix a couple of references to "@value{COMPANY}" - so they don't commit MIT to doing user support; also fixed some - punctuation errors. - -Mon Nov 25 23:39:53 1996 Theodore Y. Ts'o - - * copyright.texinfo: Change lib/kadm to lib/kadm5, and add the - kadmin/passwd to the list of directories containing OV - code. - -Sun Nov 24 23:55:52 1996 Ezra Peisach (epeisach@mit.edu) - - * build.texinfo: Remove --with-kdb-db section as it does not - exist. Add --with-tcl info. - -Tue Nov 19 13:42:00 1996 Barry Jaspan - - * install.texinfo, build.texinfo: misc suggestions from jhawk - [krb5-doc/55] - -Fri Nov 15 17:52:39 1996 Jeff Bigler - - * Makefile (krb425-guide): added section to make krb425 guide. - - * krb425.texinfo: brought in this document from Cygnus. - -Fri Nov 15 00:06:53 1996 Tom Yu - - * user-guide.texinfo: Changes to put copyright page in its own - node in the info file. - - * install.texinfo: Changes to put copyright page in its own node - in the info file. - - * admin.texinfo: Changes to put copyright page in its own node in - the info file, plus more krb5.keytab name updates. - - * install.texinfo (The Keytab File): - (Extract Host Keytabs for the KDCs): - (The Keytab File): - (Some Advice about Secure Hosts): Update filename to krb5.keytab. - (Upgrading the application servers): Add node to explain keytab - rename. - -Wed Nov 13 15:17:22 1996 Barry Jaspan - - * install.texinfo (kdc.conf): remove profile relation from - krb5.conf and kdc.conf [PR 124] - -Mon Nov 11 12:45:39 1996 Barry Jaspan - - * install.texinfo (kdc.conf): remove admin_database_name and - lockfile fields from sample kdc.conf - -Sun Nov 10 21:20:05 1996 Sam Hartman - - * bug-report.texinfo: We have krb5-send-pr now. - - * install.texinfo (Edit the Configuration Files): kdc.conf lives - in var/krb5kdc/kdc.conf - (krb5.conf): No, we will not tell people to log to /dev/ttyp9; - default to /var/log - (Slave KDCs): Avoid over committing MIT to random things that - other vendors might want to do. - (Limit Access to the KDCs): If you are running klogind -c you want -5 not -k - (Some Advice about Secure Hosts): We disable things in /etc/inetd.conf not /etc/services - -Tue Nov 5 16:14:06 1996 Barry Jaspan - - * install.texinfo (Upgrading existing Master and Slave KDCs to the - current release): added section on upgrading to new db format with - dump/load [krb5-doc/119] - -Mon Nov 4 16:50:51 1996 Barry Jaspan - - * admin.texinfo (Adding or Modifying Principals): update kadmin - "default" policy semantics [krb5-doc/84] - - * install.texinfo: various minor comments from jhawk [krb5-doc/55] - -Fri Nov 1 19:05:15 1996 Tom Yu - - * .cvsignore: Ignore the .html files. - - * copyright.texinfo: Add call to "@pagealignmacro" to force a - blank page after copyright spewage. [krb5-doc/54] - - * Makefile: Apply jik's changes for dependencies [krb5-doc/101] - - * install.texinfo (krb5.conf): Fixed extra - closebrace. [krb5-doc/92] - -Fri Oct 18 13:42:49 1996 Barry Jaspan - - * install.texinfo (Create a kadmind Keytab): use kadmin.local - instead of kadmin to perform pre-kadmind setup [krb5-admin/28] - -Tue Sep 10 20:47:41 1996 Theodore Y. Ts'o - - * user-guide.texinfo: The telnet man page only has 9 pages; the - rcp man page only has 1 page. - -Mon Sep 9 19:35:37 1996 Theodore Ts'o - - * build.texinfo: Updated to reflect latest OS inconsistencies; - removed shared library theory section to a new file, - implementor.texinfo, which will have information that only - developers will care about. - -Mon Sep 9 13:25:06 1996 Jeff Bigler - - * texinfo-suppl.tex: extracted @doubleleftarrow{} hack into - separate file so we don't have to ship a modified version of - texinfo.tex. - - * user-guide.texinfo (Reference): changed offset to -700 for - PostScript man pages for full page printing. - - * man2ps: changed scale from 0.7 to 0.85 for full page printing. - Piped csplit output to /dev/null, to make it a bit neater. - -Fri Sep 6 19:59:12 1996 Theodore Y. Ts'o - - * copyright.texinfo: Updated copyright dates and modify copyright - text to have non-commital words about export licenses. - - * admin.texinfo, install.texinfo: Set edition to "b7-1". - - * user-guide.texinfo: Set edition to "b7-1". Fix the hoffset and - voffsets for the included man page poscript files so that - the images are lined up correctly (at least using MIT's - dvips). - - * Makefile (user-guide): Make sure the kpasswd man page's - postscript is built. Add new target "clean-temp-ps" which - cleans up the temporary postscript files. - - * man2ps: Changes to make man2ps more portable. Remove bash - specific constructs, and replace with calls to expr. - Since the arguments to "troff" require groff, just try to - run groff explicitly (someone can always edit the ROFF and - ROFF_OPTIONS at the top of the script). Try to - automatically detect whether csplit or gcsplit should be - used, by grovelling through the user's path. - - * texinfo.tex: Check in version of texinfo.tex that has Jeff's - magic doubleleft arrow hack. - -Fri Sep 6 12:59:43 1996 Jeff Bigler - - * install.texinfo: new name for cyg-install.texinfo - - * install-old.texi: new name for install.texi (so we know what's - what.) - - * Makefile (install-guide): renamed cyg-install.texinfo to - install.texinfo. - - * man2ps: shell script to create postscript include files for - user's guide. - - * man2ps.M: man page for above shell script - - * build.texinfo: this is now included by cyg-install.texinfo - (which should eventually replace install.texi.) - - * definitions.texinfo: added flags "MIT" and "CYGNUS". - - * cyg-install.texinfo: added @ifset and @ifclear sections to - separate MIT-specific and Cygnus-specific sections. - - * admin.texinfo: added @ifset and @ifclear sections as with - cyg-install.texinfo - - * Makefile: rewrote entire contents of file. - -Fri Sep 6 01:22:56 1996 Theodore Y. Ts'o - - * build.texinfo: Remove --enable options which are no longer - valid. Updated reference to dejagnu. - -Thu Apr 18 14:38:42 1996 Theodore Y. Ts'o - - * install.texi (Building using lndir): Minor grammer fix. - -Sun Apr 21 14:01:29 1996 Sam Hartman - - * install.texi (Installing Kerberos Applications): Updated to fix - jhawk's comments to this section. - -Sat Apr 20 03:27:27 1996 Sam Hartman - - * install.texi (Top): Remade master menu. - (Installing Kerberos Applications): New section. - -Fri Apr 19 22:55:36 1996 Sam Hartman - - * install.texi (Shared Library Support): Update to better reflect - reality on AIX. - -Tue Mar 19 10:34:20 1996 Ezra Peisach - - * Makefile (clean): Remove *.info-? now. - - * install.texi: Changes to allow emacs M-X texinfo-format-buffer - to work. (The problem was @item used within @enumerate). - -Fri Mar 8 09:43:13 1996 Ezra Peisach - - * install.texi (The DejaGnu Tests): Describe the DejaGnu tests. - -Mon Oct 30 16:58:54 1995 Ezra Peisach - - * install.texi: Fix all path names, spelling check, convert tabs - to spaces. - -Fri Oct 20 14:06:35 1995 Ezra Peisach - - * install.texi (Shared Library Support): Document shared library - specifics. - -Tue Oct 17 19:23:50 1995 Ezra Peisach - - * .Sanitize (Things-to-keep): Add Makefile - - * Makefile: Simple file to build both dvi and info versions of - install and allow for easy cleaning. - - * install.texi (Options to Configure): Updated to reflect current - major configuration options. - -Wed Oct 11 16:20:58 1995 Ezra Peisach (epeisach@kangaroo.mit.edu) - - * install.texi: Remove config.h descriptions, describe krb5.conf. - -Tue Jul 11 13:07:00 1995 - - * install.texi: BSDI fixes. - -Fri May 5 13:10:38 1995 Theodore Y. Ts'o (tytso@dcl) - - * install.texi: Minor fixups for beta 5 release. Mainly points - that the krb.conf and krb.realms section need to be - updated and should be ignored in favor of the krb5.conf - manual page. - -Fri Apr 28 16:59:41 EDT 1995 Paul Park (pjpark@mit.edu) - Add new kadmin.protocol. - -Wed Feb 22 18:56:06 1995 John Gilmore (gnu at toad.com) - - * install.texi: Minor corrections. Add info about bare source - trees (without configure scripts). - diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 6e26a5edd..000000000 --- a/doc/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -SRCDIR=../src -DVI=texi2dvi -DVIPS=dvips -o "$@" -INFO=makeinfo -HTML=makeinfo --html -RM=rm -f -TAR=tar -chvf -GZIP=gzip -9 -MANPS=./man2ps -MANTXT=nroff -man -MANHTML=./man2html - -ADMIN_INCLUDES=definitions.texinfo copyright.texinfo document-list.texinfo \ - glossary.texinfo support-enc.texinfo salts.texinfo krb5conf.texinfo \ - kdcconf.texinfo dnstxt.texinfo dnssrv.texinfo send-pr.texinfo -ADMIN_DEPS=admin.texinfo $(ADMIN_INCLUDES) - -INSTALL_INCLUDES=definitions.texinfo copyright.texinfo document-list.texinfo \ - dnstxt.texinfo dnssrv.texinfo build.texinfo bug-report.texinfo \ - krb5conf.texinfo kdcconf.texinfo send-pr.texinfo -INSTALL_DEPS=install.texinfo $(INSTALL_INCLUDES) - -MANPAGES=$(SRCDIR)/appl/gssftp/ftp/ftp.M $(SRCDIR)/clients/kdestroy/kdestroy.M $(SRCDIR)/clients/kinit/kinit.M $(SRCDIR)/clients/klist/klist.M $(SRCDIR)/clients/ksu/ksu.M $(SRCDIR)/appl/bsd/rcp.M $(SRCDIR)/appl/bsd/rlogin.M $(SRCDIR)/appl/bsd/rsh.M $(SRCDIR)/appl/telnet/telnet/telnet.1 $(SRCDIR)/kadmin/passwd/kpasswd.M - -USER_GUIDE_INCLUDES=definitions.texinfo copyright.texinfo glossary.texinfo -USER_GUIDE_DEPS=user-guide.texinfo $(USER_GUIDE_INCLUDES) - -KRB425_INCLUDES=definitions.texinfo copyright.texinfo -KRB425_DEPS=krb425.texinfo $(KRB425_INCLUDES) - -.PHONY: all -all:: admin-guide-full install-guide-full user-guide-full krb425-guide-full clean-temp-ps clean-tex - -.PHONY: admin-guide-full -admin-guide-full:: admin-guide admin-guide-info admin-guide-html - -.PHONY: admin-guide -admin-guide:: admin-guide.ps - -admin-guide.ps: $(ADMIN_DEPS) - $(DVI) admin.texinfo - $(DVIPS) admin - -.PHONY: admin-guide-html -admin-guide-html:: admin.html - -admin.html: $(ADMIN_DEPS) - $(HTML) admin.texinfo - -.PHONY: admin-guide-info -admin-guide-info:: krb5-admin.info - -krb5-admin.info: $(ADMIN_DEPS) - $(INFO) admin.texinfo - -.PHONY: install-guide-full -install-guide-full:: install-guide install-guide-info install-guide-html - -.PHONY: install-guide -install-guide:: install-guide.ps - -install-guide.ps: $(INSTALL_DEPS) - $(DVI) install.texinfo - $(DVIPS) install - -.PHONY: install-guide-html -install-guide-html:: install.html - -install.html:: $(INSTALL_DEPS) - $(HTML) install.texinfo - -.PHONY: install-guide-info -install-guide-info:: krb5-install.info - -krb5-install.info: $(INSTALL_DEPS) - $(INFO) install.texinfo - -.PHONY: user-guide-full -user-guide-full:: user-guide user-guide-info user-guide-html - -.PHONY: user-guide -user-guide:: user-guide.ps - -user-guide.ps: $(USER_GUIDE_DEPS) - $(DVI) user-guide.texinfo - $(MANPS) $(MANPAGES) - $(DVIPS) user-guide - -.PHONY: user-guide-info -user-guide-info:: krb5-user.info - -krb5-user.info: $(USER_GUIDE_DEPS) - $(INFO) user-guide.texinfo - -.PHONY: user-guide-html -user-guide-html:: user-guide.html - -user-guide.html: $(USER_GUIDE_DEPS) - $(MANTXT) $(SRCDIR)/appl/gssftp/ftp/ftp.M | $(MANHTML) > ftp.html - $(MANTXT) $(SRCDIR)/clients/kdestroy/kdestroy.M | $(MANHTML) > kdestroy.html - $(MANTXT) $(SRCDIR)/clients/kinit/kinit.M | $(MANHTML) > kinit.html - $(MANTXT) $(SRCDIR)/clients/klist/klist.M | $(MANHTML) > klist.html - $(MANTXT) $(SRCDIR)/clients/ksu/ksu.M | $(MANHTML) > ksu.html - $(MANTXT) $(SRCDIR)/appl/bsd/rcp.M | $(MANHTML) > rcp.html - $(MANTXT) $(SRCDIR)/appl/bsd/rlogin.M | $(MANHTML) > rlogin.html - $(MANTXT) $(SRCDIR)/appl/bsd/rsh.M | $(MANHTML) > rsh.html - $(MANTXT) $(SRCDIR)/appl/telnet/telnet/telnet.1 | $(MANHTML) > telnet.html - $(MANTXT) $(SRCDIR)/kadmin/passwd/kpasswd.M | $(MANHTML) > kpasswd.html - $(HTML) user-guide.texinfo - -.PHONY: krb425-guide-full -krb425-guide-full:: krb425-guide krb425-guide-info krb425-guide-html - -.PHONY: krb425-guide -krb425-guide:: krb425-guide.ps - -krb425-guide.ps: $(KRB425_DEPS) - $(DVI) krb425.texinfo - $(DVIPS) krb425 - -.PHONY: krb425-guide-html -krb425-guide-html:: krb425.html - -krb425.html:: $(KRB425_DEPS) - $(HTML) krb425.texinfo - -.PHONY: krb425-guide-info -krb425-guide-info:: krb425.info - -krb425.info: $(KRB425_DEPS) - $(INFO) krb425.texinfo - -.PHONY: clean -clean:: clean-all - -.PHONY: clean-all -clean-all:: clean-tex clean-backup clean-final clean-tarfiles - -.PHONY: clean-final -clean-final:: - $(RM) *.ps *.info *.info-? *.html - -.PHONY: clean-tex -clean-tex:: - $(RM) *.aux *.cp *.dvi *.fn *.ky *.log *.pg *.toc *.tp *.vr - -.PHONY: clean-backup -clean-backup:: - $(RM) *~ #* - -.PHONY: clean-tarfiles -clean-tarfiles:: - $(RM) *.tar *.tar.gz *.tgz - -.PHONY: clean-temp-ps -clean-temp-ps:: - $(RM) ftp?.ps kinit?.ps klist?.ps kdestroy?.ps ksu?.ps rlogin?.ps \ - rcp?.ps rsh?.ps telnet?.ps kpasswd?.ps - -.PHONY: tgz -tgz:: - $(TAR) krb5-docs.tar admin.texinfo build.texinfo copyright.texinfo definitions.texinfo document-list.texinfo glossary.texinfo install.texinfo texinfo.tex user-guide.texinfo *-guide.ps *.info *.info-? *.html - $(GZIP) krb5-docs.tar - $(MV) krb5-docs.tar.gz krb5-docs.tgz diff --git a/doc/admin.texinfo b/doc/admin.texinfo deleted file mode 100644 index a58cf5675..000000000 --- a/doc/admin.texinfo +++ /dev/null @@ -1,3738 +0,0 @@ -\input texinfo-suppl.tex % contains @doubleleftarrow{} definition - % this line must come *before* \input texinfo -\input texinfo @c -*-texinfo-*- -@c %**start of header -@c guide -@setfilename krb5-admin.info -@settitle Kerberos V5 System Administrator's Guide -@setchapternewpage odd @c chapter begins on next odd page -@c @setchapternewpage on @c chapter begins on next page -@c @smallbook @c Format for 7" X 9.25" paper -@c %**end of header -@paragraphindent 0 -@iftex -@parskip 6pt plus 6pt -@end iftex - -@include definitions.texinfo -@set EDITION 1.0 -@set UPDATED June 16, 2000 - -@finalout @c don't print black warning boxes - -@titlepage -@title @value{PRODUCT} System Administrator's Guide -@subtitle Release: @value{RELEASE} -@subtitle Document Edition: @value{EDITION} -@subtitle Last updated: @value{UPDATED} -@author @value{COMPANY} - -@page -@vskip 0pt plus 1filll - -@end titlepage - -@comment node-name, next, previous, up -@node Top, Copyright, (dir), (dir) - -@ifinfo -This document describes how to administrate a @value{PRODUCT} -installation. -@end ifinfo - -@c The master menu is updated using emacs19's M-x texinfo-all-menus-update -@c function. Don't forget to run M-x texinfo-every-node-update after -@c you add a new section or subsection, or after you've rearranged the -@c order of sections or subsections. Also, don't forget to add an @node -@c comand before each @section or @subsection! All you need to enter -@c is: -@c -@c @node New Section Name -@c @section New Section Name -@c -@c M-x texinfo-every-node-update will take care of calculating the -@c node's forward and back pointers. -@c -@c --------------------------------------------------------------------- - -@menu -* Copyright:: -* Introduction:: -* How Kerberos Works:: -* Configuration Files:: -* Using DNS:: -* Administrating the Kerberos Database:: -* Application Servers:: -* Backups of Secure Hosts:: -* Bug Reporting:: -* Appendix:: -@end menu - -@node Copyright, Introduction, Top, Top -@unnumbered Copyright -@include copyright.texinfo - - -@node Introduction, How Kerberos Works, Copyright, Top -@chapter Introduction - -@menu -* Why Should I use Kerberos?:: -* Documentation for Kerberos V5:: -* Overview of This Guide:: -@end menu - -@node Why Should I use Kerberos?, Documentation for Kerberos V5, Introduction, Introduction -@section Why Should I use Kerberos? - -Since Kerberos negotiates authenticated, and optionally encrypted, -communications between two points anywhere on the internet, it provides -a layer of security that is not dependent on which side of a firewall -either client is on. Since studies have shown that half of the computer -security breaches in industry happen from @i{inside} firewalls, -@value{PRODUCT} from @value{COMPANY} will play a vital role in the -security of your network. - -@node Documentation for Kerberos V5, Overview of This Guide, Why Should I use Kerberos?, Introduction -@section Documentation for @value{PRODUCT} - -@include document-list.texinfo - -@node Overview of This Guide, , Documentation for Kerberos V5, Introduction -@section Overview of This Guide - -The next chapter describes how Kerberos works. - -Chapter three describes administration of the principals in the Kerberos -database. - -Chapter four describes how you can use DNS in configuring your Kerberos realm. - -Chapter five describes administrative programs for manipulating the -Kerberos database as a whole. - -Chapter six describes issues to consider when adding an application -server to the database. - -Chapter seven describes our problem reporting system. - -The appendices include the list of Kerberos error messages, and a -complete list of the time zones understood by @code{kadmin}. - -@node How Kerberos Works, Configuration Files, Introduction, Top -@chapter How Kerberos Works - -This section provides a simplified description of a general user's -interaction with the Kerberos system. This interaction happens -transparently---users don't need to know and probably don't care about -what's going on---but Kerberos administrators might find a schematic -description of the process useful. This description glosses over a lot -of details; for more information, see @i{Kerberos: An Authentication -Service for Open Network Systems}, a paper presented at Winter USENIX -1988, in Dallas, Texas. This paper can be retreived by FTP from -@code{athena-dist.mit.edu}, in the location: -@code{/pub/ATHENA/kerberos/doc/usenix.PS}. - -@menu -* Network Services and Their Client Programs:: -* Kerberos Tickets:: -* The Kerberos Database:: -* Kerberos Realms:: -* The Ticket-Granting Ticket:: -* Network Services and the Master Database:: -* The User/Kerberos Interaction:: -* Definitions:: -@end menu - -@node Network Services and Their Client Programs, Kerberos Tickets, How Kerberos Works, How Kerberos Works -@section Network Services and Their Client Programs - -In an environment that provides network services, you use @dfn{client} -programs to request @dfn{services} from @dfn{server} programs that are -somewhere on the network. Suppose you have logged in to a workstation -and you want to @samp{rlogin} to a typical UNIX host. You use the local -@samp{rlogin} client program to contact the remote machine's -@samp{rlogind} daemon. - -@node Kerberos Tickets, The Kerberos Database, Network Services and Their Client Programs, How Kerberos Works -@section Kerberos Tickets - -Under Kerberos, the @samp{klogind} daemon allows you to login to a -remote machine if you can provide @samp{klogind} a Kerberos ticket -which proves your identity. In addition to the ticket, you must also -have possession of the corresponding ticket session key. The -combination of a ticket and the ticket's session key is known as a credential. - -Typically, a client program automatically obtains credentials -identifying the person using the client program. The credentials are -obtained from a Kerberos server that resides somewhere on the network. -A Kerberos server maintains a database of user, server, and password -information. - -@node The Kerberos Database, Kerberos Realms, Kerberos Tickets, How Kerberos Works -@section The Kerberos Database - -Kerberos will give you credentials only if you have an entry in the -Kerberos server's @dfn{Kerberos database}. Your database entry includes -your Kerberos @dfn{principal} (an identifying string, which is often -just your username), and your Kerberos password. Every Kerberos user -must have an entry in this database. - -@node Kerberos Realms, The Ticket-Granting Ticket, The Kerberos Database, How Kerberos Works -@section Kerberos Realms - -Each administrative domain will have its own Kerberos database, which -contains information about the users and services for that particular -site or administrative domain. This administrative domain is the -@dfn{Kerberos realm}. - -Each Kerberos realm will have at least one Kerberos server, where the -master Kerberos database for that site or administrative domain is -stored. A Kerberos realm may also have one or more @dfn{slave servers}, -which have read-only copies of the Kerberos database that are -periodically propagated from the master server. For more details on how -this is done, see the ``Set Up the Slave KDCs for Database Propagation'' -and ``Propagate the Database to Each Slave KDC'' sections of the -@value{PRODUCT} Installation Guide. - -@node The Ticket-Granting Ticket, Network Services and the Master Database, Kerberos Realms, How Kerberos Works -@section The Ticket-Granting Ticket - -The @samp{kinit} command prompts for your password. If you enter it -successfully, you will obtain a @dfn{ticket-granting ticket} and a -@dfn{ticket session key} which gives you the right to use the ticket. -This combination of the ticket and its associated key is known as your -@dfn{credentials}. As illustrated below, client programs use your -ticket-granting ticket credentials in order to obtain client-specific -credentials as needed. - -Your credentials are stored in a @dfn{credentials cache}, which is often -just a file in @code{/tmp}. The credentials cache is also called the -@dfn{ticket file}, especially in Kerberos V4 documentation. Note, -however, that a credentials cache does not have to be stored in a file. - -@node Network Services and the Master Database, The User/Kerberos Interaction, The Ticket-Granting Ticket, How Kerberos Works -@section Network Services and the Master Database - -The master database also contains entries for all network services that -require Kerberos authentication. Suppose that your site has a machine, -@samp{laughter.@value{PRIMARYDOMAIN}}, that requires Kerberos -authentication from anyone who wants to @samp{rlogin} to it. The host's -Kerberos realm is @samp{@value{PRIMARYREALM}}. - -This service must be registered in the Kerberos database, using the -proper service name, which in this case is the @dfn{principal}: - -@smallexample -host/laughter.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -@end smallexample - -@noindent -The @samp{/} character separates the Kerberos @dfn{primary} (in this -case, @samp{host}) from the @dfn{instance} (in this case, -@samp{laughter.@value{PRIMARYDOMAIN}}); the @samp{@@} character separates -the realm name (in this case, @samp{@value{PRIMARYREALM}}) from the rest -of the principal. The primary, @samp{host}, denotes the name or type of -the service that is being offered: generic host-level access to the -machine. The instance, @samp{laughter.@value{PRIMARYDOMAIN}}, names the -specific machine that is offering this service. There will generally be -many different machines, each offering one particular type of service, -and the instance serves to give each one of these servers a different -Kerberos principal. - -@menu -* The Keytab File:: -@end menu - -@node The Keytab File, , Network Services and the Master Database, Network Services and the Master Database -@subsection The Keytab File - -For each service, there must also be a @dfn{service key} known only by -Kerberos and the service. On the Kerberos server, the service key is -stored in the Kerberos database. - -On the server host, these service keys are stored in @dfn{key tables}, -which are files known as @dfn{keytabs}.@footnote{Keytabs were called -@dfn{srvtabs} in Kerberos V4.} For example, the service keys used by -services that run as root are usually stored in the keytab file -@code{/etc/krb5.keytab}. @b{N.B.:} This service key is the equivalent -of the service's password, and must be kept secure. Data which is meant -to be read only by the service is encrypted using this key. - -@node The User/Kerberos Interaction, Definitions, Network Services and the Master Database, How Kerberos Works -@section The User/Kerberos Interaction - -Suppose that you walk up to a host intending to login to it, and then -@samp{rlogin} to the machine @samp{laughter}. Here's what happens: - -@enumerate -@item -You login to the workstation and use the @samp{kinit} command to get a -ticket-granting ticket. This command prompts you for your Kerberos -password. (On systems running the @value{PRODUCT} @samp{login} program, -this may be done as part of the login process, not requiring the user to -run a separate program.) - -@enumerate A -@item -The @samp{kinit} command sends your request to the Kerberos master -server machine. The server software looks for your principal name's -entry in the Kerberos database. - -@item -If this entry exists, the Kerberos server creates and returns a -ticket-granting ticket and the key which allows you to use it, encrypted -by your password. If @samp{kinit} can decrypt the Kerberos reply using -the password you provide, it stores this ticket in a credentials cache -on your local machine for later use. The name of the credentials cache -can be specified in the @samp{KRB5CCNAME} environment variable. If this -variable is not set, the name of the file will be -@file{/tmp/krb5cc_}, where is your UNIX user-id, represented -in decimal format. -@end enumerate - -@need 1500 -@item -Now you use the @samp{rlogin} client to access the machine -@samp{laughter}. - -@example -host% @b{rlogin laughter} -@end example - -@enumerate A -@item -The @samp{rlogin} client checks your ticket file to see if you have a -ticket for the @samp{host} service for @samp{laughter}. You don't, so -@samp{rlogin} uses the credential cache's ticket-granting ticket to make -a request to the master server's ticket-granting service. - -@item -This ticket-granting service receives the request for a ticket for -@samp{host/laughter.@value{PRIMARYDOMAIN}}, and looks in the master -database for an entry for @samp{host/laughter.@value{PRIMARYDOMAIN}}. -If the entry exists, the ticket-granting service issues you a ticket for -that service. That ticket is also cached in your credentials cache. - -@item -The @samp{rlogin} client now sends that ticket to the @samp{laughter} -@samp{klogind} service program. The service program checks the ticket -by using its own service key. If the ticket is valid, it now knows your -identity. If you are allowed to login to @samp{laughter} (because your -username matches one in /etc/passwd, or your Kerberos principal is in -the appropriate @file{.k5login} file), @code{klogind} will let you -login. -@end enumerate -@end enumerate - -@node Definitions, , The User/Kerberos Interaction, How Kerberos Works -@section Definitions - -Following are definitions of some of the Kerberos terminology. - -@include glossary.texinfo - -@node Configuration Files, Using DNS, How Kerberos Works, Top -@chapter Configuration Files - -@menu -* Supported Encryption Types:: -* Salts:: -* krb5.conf:: -* kdc.conf:: -@end menu - -@node Supported Encryption Types, Salts, Configuration Files, Configuration Files -@section Supported Encryption Types - -Any tag in the configuration files which requires a list of encryption -types can be set to some combination of the following strings. - -@include support-enc.texinfo - -@node Salts, krb5.conf, Supported Encryption Types, Configuration Files -@section Salts - -Your Kerberos key is derived from your password. To ensure that people -who happen to pick the same password do not have the same key, Kerberos -5 incorporates more information into the key using something called a -salt. The supported values for salts are as follows. - -@include salts.texinfo - -@node krb5.conf, kdc.conf, Salts, Configuration Files -@section krb5.conf - -@include krb5conf.texinfo - -@menu -* libdefaults:: -* appdefaults:: -* login:: -* realms (krb5.conf):: -* domain_realm:: -* logging:: -* capaths:: -* Sample krb5.conf File:: -@end menu - -@node libdefaults, appdefaults, krb5.conf, krb5.conf -@subsection [libdefaults] - -The @code{libdefaults} section may contain any of the following -relations: - -@table @b -@itemx default_keytab_name -This relation specifies the default keytab name to be used by -application servers such as telnetd and rlogind. The default is -@value{DefaultDefaultKeytabName}. - -@itemx default_realm -Identifies the default Kerberos realm for the client. Set its value to -your Kerberos realm. If this is not specified and the TXT record -lookup is enabled (see @ref{Using DNS}), then that information will be -used to determine the default realm. If this tag is not set in this -configuration file and there is no DNS information found, then an error -will be returned. - -@itemx default_tgs_enctypes -Identifies the supported list of session key encryption types that -should be returned by the KDC. The list may be delimited with commas -or whitespace. Kerberos supports many different encryption types, and -support for more is planned in the future. (see @ref{Supported Encryption -Types} for a list of the accepted values for this tag). The default -value is @value{DefaultDefaultTgsEnctypes}. - -@itemx default_tkt_enctypes -Identifies the supported list of session key encryption types that -should be requested by the client. The format is the same as for -@emph{default_tgs_enctypes}. The default value for this tag is -@value{DefaultDefaultTktEnctypes}. - -@itemx permitted_enctypes -Identifies all encryption types that are permitted for use in session -key encryption. The default value for this tag is -@value{DefaultPermittedEnctypes}. - -@itemx clockskew -Sets the maximum allowable amount of clockskew in seconds that the -library will tolerate before assuming that a Kerberos message is -invalid. The default value is @value{DefaultClockskew}. - -@itemx kdc_timesync -If this is set to 1 (for true), then client machines will compute the -difference between their time and the time returned by the KDC in the -timestamps in the tickets and use this value to correct for an -inaccurate system clock. This corrective factor is only used by the -Kerberos library. The default is @value{DefaultKDCTimesyncMac} for -Macintosh computers and @value{DefaultKDCTimesync} for all other -platforms. - -@itemx kdc_req_checksum_type -@itemx ap_req_checksum_type -@itemx safe_checksum_type -An integer which specifies the type of checksum to use. Used for -compatability with DCE security servers which do not support the -default @value{DefaultChecksumType} used by this version of Kerberos. -The possible values and their meanings are as follows. - -@comment taken from krb5/src/include/krb5.h[in] -@table @b -@item 1 -CRC32 -@item 2 -RSA MD4 -@item 3 -RSA MD4 DES -@item 4 -DES CBC -@item 7 -RSA MD5 -@item 8 -RSA MD5 DES -@item 9 -NIST SHA -@item 12 -HMAC SHA1 DES3 -@item -138 -Microsoft MD5 HMAC checksum type -@end table - -@comment see lib/krb5/ccache/fcc.h -@itemx ccache_type -Use this parameter on systems which are DCE clients, to specify the -type of cache to be created by kinit, or when forwarded tickets are -received. DCE and Kerberos can share the cache, but some versions of -DCE do not support the default cache as created by this version of -Kerberos. Use a value of 1 on DCE 1.0.3a systems, and a value of 2 on -DCE 1.1 systems. The default value is @value{DefaultCcacheTypeMac} -for Macintosh computers and @value{DefaultCcacheType} for other -platforms. - -@ignore -@itemx tkt_lifetime -The default lifetime of a ticket. The default is -@value{DefaultTktLifetime}. This is currently not supported by the -code. -@end ignore - -@itemx krb4_srvtab -Specifies the location of the Kerberos V4 srvtab file. Default is -@value{DefaultKrb4Srvtab}. - -@itemx krb4_config -Specifies the location of hte Kerberos V4 configuration file. Default -is @value{DefaultKrb4Config}. - -@itemx krb4_realms -Specifies the location of the Kerberos V4 domain/realm translation -file. Default is @value{DefaultKrb4Realms}. - -@itemx dns_lookup_kdc -Indicate whether DNS SRV records should be used to locate the KDCs and -other servers for a realm, if they are not listed in the information for -the realm. (Note that the @samp{admin_server} entry must be in the -file, because the DNS implementation for it is incomplete.) - -Enabling this option does open up a type of denial-of-service attack, if -someone spoofs the DNS records and redirects you to another server. -However, it's no worse than a denial of service, because that fake KDC -will be unable to decode anything you send it (besides the initial -ticket request, which has no encrypted data), and anything the fake KDC -sends will not be trusted without verification using some secret that it -won't know. - -If this option is not specified but @samp{dns_fallback} is, that value -will be used instead. If neither option is specified, the behavior -depends on configure-time options; if none were given, the default is to -enable this option. If the DNS support is not compiled in, this entry -has no effect. - -@itemx dns_lookup_realm -Indicate whether DNS TXT records should be used to determine the -Kerberos realm of a host. - -Enabling this option may permit a redirection attack, where spoofed DNS -replies persuade a client to authenticate to the wrong realm, when -talking to the wrong host (either by spoofing yet more DNS records or by -intercepting the net traffic). Depending on how the client software -manages hostnames, however, it could already be vulnerable to such -attacks. We are looking at possible ways to minimize or eliminate this -exposure. For now, we encourage more adventurous sites to try using -Secure DNS. - -If this option is not specified but @samp{dns_fallback} is, that value -will be used instead. If neither option is specified, the behavior -depends on configure-time options; if none were given, the default is to -disable this option. If the DNS support is not compiled in, this entry -has no effect. - -@itemx dns_fallback -General flag controlling the use of DNS for Kerberos information. If -both of the preceding options are specified, this option has no effect. - -@itemx extra_addresses -This allows a computer to use multiple local addresses, in order to -allow Kerberos to work in a network that uses NATs. The addresses -should be in a comma-separated list. - -@itemx udp_preference_limit -When sending a message to the KDC, the library will try using TCP before -UDP if the size of the message is above @code{udp_preference_list}. -If the message is smaller than @code{udp_preference_list}, then UDP -will be tried before TCP. Regardless of the size, both protocols will -be tried if the first attempt fails. - -@itemx verify_ap_req_nofail -If this flag is set, then an attempt to get initial credentials will -fail if the client machine does not have a keytab. The default for the -flag is @value{DefaultVerifyApReqNofail}. - -@itemx renew_lifetime -The value of this tag is the default renewable lifetime for -initial tickets. The default value for the tag is -@value{DefaultRenewLifetime}. - -@itemx noaddresses -Setting this flag causes the initial Kerberos ticket to be addressless. -The default for the flag is @value{DefaultNoaddresses}. - -@itemx forwardable -If this flag is set, initial tickets by default will be forwardable. -The default value for this flag is @value{DefaultForwardable}. - -@itemx proxiable -If this flag is set, initial tickets by default will be proxiable. -The default value for this flag is @value{DefaultProxiable}. - -@end table - -@node appdefaults, login, libdefaults, krb5.conf -@subsection [appdefaults] - -Each tag in the [appdefaults] section names a Kerberos V5 application -or an option that is used by some Kerberos V5 application[s]. The -value of the tag defines the default behaviors for that application. - -For example: - -@smallexample -@group -[appdefaults] - telnet = @{ - @value{PRIMARYREALM} = @{ - option1 = false - @} - @} - telnet = @{ - option1 = true - option2 = true - @} - @value{PRIMARYREALM} = @{ - option2 = false - @} - option2 = true - -@end group -@end smallexample - -The above four ways of specifying the value of an option are shown -in order of decreasing precedence. In this example, if telnet is -running in the realm @value{SECONDREALM}, it should, by default, have -option1 and option2 set to true. However, a telnet program in the realm -@value{PRIMARYREALM} should have option1 set to false and option2 set -to true. Any other programs in @value{PRIMARYREALM} should have option2 -set to false by default. Any programs running in other realms should -have option2 set to true. - -The list of specifiable options for each application may be found in -that application's man pages. The application defaults specified here -are overridden by those specified in the [realms] section. - -@node login, realms (krb5.conf), appdefaults, krb5.conf -@subsection [login] - -Each tag in the [login] section of the file is an option for -login.krb5. This section may contain any of the following relations: - -@table @b -@itemx krb5_get_tickets -Indicate whether or not to use a user's password to get V5 tickets. -The default value is @value{DefaultKrb5GetTickets}. - -@itemx krb4_get_tickets -Indicate whether or not to user a user's password to get V4 tickets. -The default value is @value{DefaultKrb4GetTickets}. - -@itemx krb4_convert -Indicate whether or not to use the Kerberos conversion daemon to get V4 -tickets. The default value is @value{DefaultKrb4Convert}. If this is -set to false and krb4_get_tickets is true, then login will get the V5 -tickets directly using the Kerberos V4 protocol directly. This does -not currently work with non-MIT-V4 salt types (such as the AFS3 salt -type). Note that if this is set to true and krb524d is not running, -login will hang for approximately a minute under Solaris, due to a -Solaris socket emulation bug. - -@itemx krb_run_aklog -Indicate whether or not to run aklog. The default value is -@value{DefaultKrbRunAklog}. - -@itemx aklog_path -Indicate where to find aklog. The default value is -@value{DefaultAklogPath}. - -@itemx accept_passwd -A true value will cause login not to accept plaintext passwords. The -default value is @value{DefaultAcceptPasswd}. This is not yet -implemented. -@end table - -@node realms (krb5.conf), domain_realm, login, krb5.conf -@subsection [realms] - -Each tag in the [realms] section of the file is the name of a Kerberos -realm. The value of the tag is a subsection with relations that define -the properties of that particular realm. For each realm, the following -tags may be specified in the realm's subsection: - -@table @b -@itemx kdc -The name of a host running a KDC for that realm. An optional port -number (separated from the hostname by a colon) may be included. For -your computer to be able to communicate with the KDC for each realm, -this tag must be given a value in each realm subsection in the -configuration file, or there must be DNS SRV records specifying the -KDCs (see @ref{Using DNS}). - -@itemx admin_server -Identifies the host where the administration server is running. -Typically, this is the master Kerberos server. This tag must be given -a value in order to communicate with the kadmin server for the realm. - -@ignore -this doesn't seem to be used in the code -@itemx application defaults -Application defaults that are specific to a particular realm may be -specified within that realm's tag. Realm-specific application defaults -override the global defaults specified in the [appdefaults] section. -@end ignore - -@itemx default_domain -This tag is used for Kerberos 4 compatibility. Kerberos 4 does not -require the entire hostname of a server to be in its principal like -Kerberos 5 does. This tag provides the domain name needed to produce a -full hostname when translating V4 principal names into V5 principal -names. All servers in this realm are assumed to be in the domain given -as the value of this tag - -@itemx v4_instance_convert -This subsection allows the administrator to configure exceptions to the -default_domain mapping rule. It contains V4 instances (the tag name) -which should be translated to some specific hostname (the tag value) as -the second component in a Kerberos V5 principal name. - -@itemx v4_realm -This relation is used by the krb524 library routines when converting a -V5 principal name to a V4 principal name. It is used when the V4 realm -name and the V5 realm name are not the same, but still share the same -principal names and passwords. The tag value is the Kerberos V4 realm -name. - -@itemx auth_to_local_names -This subsection allows you to set explicit mappings from principal -names to local user names. The tag is the mapping name, and the value -is the corresponding local user name. - -@itemx auth_to_local -This tag allows you to set a general rule for mapping principal names -to local user names. It will be used if there is not an explicit -mapping for the principal name that is being translated. The possible -values are: - -@table @b - -@item DB:@i{filename} -The principal will be looked up in the database @i{filename}. Support -for this is not currently compiled in by default. - -@item RULE:@i{exp} -The local name will be formulated from @i{exp}. - -The format for @i{exp} is -@code{[@i{n}:$@i{d}..@i{string}](@i{regexp})s/@i{pattern}/@i{replacement}/g}. -The integer @i{n} indicates how many components the target principal -should have. If this matches, then a string will be formed by putting -together the components of the principal in the order indicated by each -integer @i{d}, and the arbitrary string @i{string} (i.e. if the -principal was @value{RANDOMUSER}/admin then [2:$2$1foo] would result in -the string "admin@value{RANDOMUSER}foo". If this string matches -@i{regexp}, then the @code{s//[g]} substitution command will be run over the -string. The optional g will cause the substitution to be global over -the string, instead of replacing only the first match in the string. - -@item DEFAULT -The principal name will be used as the local user name. If the -principal has more than one component or is not in the default realm, -this rule is not applicable and the conversion will fail. - -@end table - -For example: - -@smallexample -@group -[realms] - @value{PRIMARYREALM} = @{ - auth_to_local = @{ - RULE:[2:$1](@value{RANDOMUSER})s/^.*$/guest/ - RULE:[2:$1;$2](^.*;admin$)s/;admin$// - RULE:[2:$2](^.*;root)s/^.*$/root/ - DEFAULT - @} - @} -@end group -@end smallexample - -would result in any principal without @code{root} or @code{admin} as -the second component to be translated with the default rule. A -principal with a second component of @code{admin} will become its first -component. @code{root} will be used as the local name for any -principal with a second component of @code{root}. The exception to -these two rules are any principals @value{RANDOMUSER}/*, which will -always get the local name @code{guest}. - -@end table - -@node domain_realm, logging, realms (krb5.conf), krb5.conf -@subsection [domain_realm] - -The [domain_realm] section provides a translation from a domain name or -hostname to a Kerberos realm name. The tag name can be a host name, or -a domain name, where domain names are indicated by a prefix of a period -(@samp{.}). The value of the relation is the Kerberos realm name for -that particular host or domain. Host names and domain names should be -in lower case. - -If no translation entry applies, the host's realm is considered to be -the hostname's domain portion converted to upper case. For example, the -following [domain_realm] section: - -@smallexample -@group -[domain_realm] -@ifset MIT - .mit.edu = ATHENA.MIT.EDU -@end ifset - @value{PRIMARYDOMAIN} = @value{PRIMARYREALM} - crash.@value{PRIMARYDOMAIN} = TEST.@value{PRIMARYREALM} - @value{SECONDDOMAIN} = @value{SECONDREALM} -@end group -@end smallexample - -@noindent -maps crash.@value{PRIMARYDOMAIN} into the TEST.@value{PRIMARYREALM} -realm. All other hosts in the @value{PRIMARYDOMAIN} domain will map by -default to the @value{PRIMARYREALM} realm, and all hosts in the -@value{SECONDDOMAIN} domain will map by default into the -@value{SECONDREALM} realm. Note the entries for the hosts -@value{PRIMARYDOMAIN} and @value{SECONDDOMAIN}. Without these entries, -@ifset CYGNUS -these hosts would be mapped into the Kerberos realms @samp{COM} and -@end ifset -@ifclear CYGNUS -these hosts would be mapped into the Kerberos realms @samp{EDU} and -@end ifclear -@samp{ORG}, respectively. - -@node logging, capaths, domain_realm, krb5.conf -@subsection [logging] -The [logging] section indicates how a particular entity is to perform -its logging. The relations in this section assign one or more values to -the entity name. Currently, the following entities are used: - -@table @b - -@itemx kdc -These entries specify how the KDC is to perform its logging. - -@itemx admin_server -These entries specify how the administrative server -is to perform its logging. - -@itemx default -These entries specify how to perform logging in the -absence of explicit specifications otherwise. -@end table - -Values are of the following forms: - -@table @b -@itemx FILE= - -@itemx FILE: -This value causes the entity's logging messages to go to the specified -file. If the @samp{=} form is used, the file is overwritten. If the -@samp{:} form is used, the file is appended to. - -@itemx STDERR -This value causes the entity's logging messages to go to its standard -error stream. - -@itemx CONSOLE -This value causes the entity's logging messages to go to the console, if -the system supports it. - -@itemx DEVICE= -This causes the entity's logging messages to go to the specified device. - -@itemx SYSLOG[:[:]] -This causes the entity's logging messages to go to the system log. - -The @dfn{severity} argument specifies the default severity of system log -messages. This may be any of the following severities supported by the -@code{syslog(3)} call, minus the LOG_ prefix: LOG_EMERG, LOG_ALERT, -LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, and LOG_DEBUG. -For example, a value of @samp{CRIT} would specify LOG_CRIT severity. - -The facility argument specifies the facility under which the messages -are logged. This may be any of the following facilities supported by -the syslog(3) call minus the LOG_ prefix: LOG_KERN, LOG_USER, LOG_MAIL, -LOG_DAEMON, LOG_AUTH, LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON, and -LOG_LOCAL0 through LOG_LOCAL7. - -If no severity is specified, the default is ERR. If no facility is -specified, the default is AUTH. -@end table - -In the following example, the logging messages from the KDC will go to -the console and to the system log under the facility LOG_DAEMON with -default severity of LOG_INFO; and the logging messages from the -administrative server will be appended to the file /var/adm/kadmin.log -and sent to the device /dev/tty04. - -@smallexample -@group -[logging] - kdc = CONSOLE - kdc = SYSLOG:INFO:DAEMON - admin_server = FILE:/var/adm/kadmin.log - admin_server = DEVICE=/dev/tty04 -@end group -@end smallexample - -@node capaths, Sample krb5.conf File, logging, krb5.conf -@subsection [capaths] - -In order to perform direct (non-hierarchical) cross-realm -authentication, a database is needed to construct the authentication -paths between the realms. This section defines that database. - -A client will use this section to find the authentication path between -its realm and the realm of the server. The server will use this section -to verify the authentication path used by the client, by checking the -transited field of the received ticket. - -There is a tag for each participating realm, and each tag has subtags -for each of the realms. The value of the subtags is an intermediate -realm which may participate in the cross-realm authentication. The -subtags may be repeated if there is more then one intermediate realm. A -value of "." means that the two realms share keys directly, and no -intermediate realms should be allowd to participate. - -There are n**2 possible entries in this table, but only those entries -which will be needed on the client or the server need to be present. -The client needs a tag for its local realm, with subtags for all the -realms of servers it will need to authenticate with. A server needs a -tag for each realm of the clients it will serve. - -For example, ANL.GOV, PNL.GOV, and NERSC.GOV all wish to use the ES.NET -realm as an intermediate realm. ANL has a sub realm of TEST.ANL.GOV -which will authenticate with NERSC.GOV but not PNL.GOV. The [capaths] -section for ANL.GOV systems would look like this: - -@smallexample -@group -[capaths] - ANL.GOV = @{ - TEST.ANL.GOV = . - PNL.GOV = ES.NET - NERSC.GOV = ES.NET - ES.NET = . - @} - TEST.ANL.GOV = @{ - ANL.GOV = . - @} - PNL.GOV = @{ - ANL.GOV = ES.NET - @} - NERSC.GOV = @{ - ANL.GOV = ES.NET - @} - ES.NET = @{ - ANL.GOV = . - @} -@end group -@end smallexample - -The [capaths] section of the configuration file used on NERSC.GOV systems -would look like this: - -@smallexample -@group -[capaths] - NERSC.GOV = @{ - ANL.GOV = ES.NET - TEST.ANL.GOV = ES.NET - TEST.ANL.GOV = ANL.GOV - PNL.GOV = ES.NET - ES.NET = . - @} - ANL.GOV = @{ - NERSC.GOV = ES.NET - @} - PNL.GOV = @{ - NERSC.GOV = ES.NET - @} - ES.NET = @{ - NERSC.GOV = . - @} - TEST.ANL.GOV = @{ - NERSC.GOV = ANL.GOV - NERSC.GOV = ES.NET - @} -@end group -@end smallexample - -In the above examples, the ordering is not important, except when the -same subtag name is used more then once. The client will use this to -determine the path. (It is not important to the server, since the -transited field is not sorted.) - -This feature is not currently supported by DCE. DCE security servers -can be used with Kerberized clients and servers, but versions prior to -DCE 1.1 did not fill in the transited field, and should be used with -caution. - -@node Sample krb5.conf File, , capaths, krb5.conf -@subsection Sample krb5.conf File - -Here is an example of a generic @code{krb5.conf} file: - -@smallexample -@group -[libdefaults] - default_realm = @value{PRIMARYREALM} - default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc - default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc - dns_lookup_kdc = true - dns_lookup_realm = false - -[realms] - @value{PRIMARYREALM} = @{ - kdc = @value{KDCSERVER}.@value{PRIMARYDOMAIN} - kdc = @value{KDCSLAVE1}.@value{PRIMARYDOMAIN} - kdc = @value{KDCSLAVE2}.@value{PRIMARYDOMAIN}:750 - admin_server = @value{KDCSERVER}.@value{PRIMARYDOMAIN} - default_domain = @value{PRIMARYDOMAIN} - @} - @value{SECONDREALM} = @{ - kdc = @value{KDCSERVER}.@value{SECONDDOMAIN} - kdc = @value{KDCSLAVE1}.@value{SECONDDOMAIN} - admin_server = @value{KDCSERVER}.@value{SECONDDOMAIN} - @} - -[domain_realm] -@ifset MIT - .mit.edu = ATHENA.MIT.EDU -@end ifset - @value{PRIMARYDOMAIN} = @value{PRIMARYREALM} - -[capaths] - @value{PRIMARYREALM} = @{ - @value{SECONDREALM} = . - @} - @value{SECONDREALM} = @{ - @value{PRIMARYREALM} = . - @} - -[logging] - kdc = SYSLOG:INFO - admin_server = FILE=/var/kadm5.log - -@end group -@end smallexample - -@iftex -@vfill -@end iftex - -@node kdc.conf, , krb5.conf, Configuration Files -@section kdc.conf - -@include kdcconf.texinfo - -@menu -* kdcdefaults:: -* realms (kdc.conf):: -* Sample kdc.conf File:: -@end menu - -@node kdcdefaults, realms (kdc.conf), kdc.conf, kdc.conf -@subsection [kdcdefaults] - -The following relation is defined in the [kdcdefaults] section: - -@table @b -@itemx kdc_ports -This relation lists the ports on which the Kerberos server should -listen for UDP requests by default. This list is a comma separated -list of integers. -If this relation is not specified, the compiled-in default is -@value{DefaultKdcPorts}, the first being the assigned Kerberos port -and the second which was used by Kerberos V4. - -@itemx kdc_tcp_ports -This relation lists the ports on which the Kerberos server should -listen for TCP connections by default. This list is a comma separated -list of integers. -If this relation is not specified, the compiled-in default is not to -listen for TCP connections at all. - -If you wish to change this (which we do not recommend, because the -current implementation has little protection against denial-of-service -attacks), the standard port number assigned for Kerberos TCP traffic -is port 88. - -@itemx v4_mode -This string specifies how the KDC should respond to Kerberos 4 -packets. The possible values are none, disable, full, and nopreauth. -The default value is @value{DefaultV4Mode}. -@comment these values found in krb5/src/kdc/kerberos_v4.c in v4mode_table -@end table - -@node realms (kdc.conf), Sample kdc.conf File, kdcdefaults, kdc.conf -@subsection [realms] - -Each tag in the [realms] section of the file names a Kerberos realm. -The value of the tag is a subsection where the relations in that -subsection define KDC parameters for that particular realm. - -For each realm, the following tags may be specified in the [realms] -subsection: - -@table @b -@itemx acl_file -(String.) Location of the access control list (acl) file that kadmin -uses to determine which principals are allowed which permissions on the -database. The default is @code{@value{DefaultAclFile}}. - -@itemx admin_keytab -(String.) Location of the keytab file that kadmin uses to authenticate -to the database. The default is -@code{@value{DefaultAdminKeytab}}. - -@itemx database_name -(String.) Location of the Kerberos database for this realm. The -default is @* @code{@value{DefaultDatabaseName}}. - -@itemx default_principal_expiration -(Absolute time string.) Specifies the default expiration date of -principals created in this realm. The default value for this tag is -@value{DefaultDefaultPrincipalExpiration}. - -@itemx default_principal_flags -(Flag string.) Specifies the default attributes of principals created -in this realm. The format for this string is a comma-separated list of -flags, with '+' before each flag that should be enabled and '-' before -each flag that should be disabled. The default is -@value{DefaultDefaultPrincipalFlags}. - -There are a number of possible flags: - -@table @b -@itemx postdateable -Enabling this flag allows the principal to obtain postdateable tickets. - -@itemx forwardable -Enabling this flag allows the principal to obtain forwardable tickets. - -@itemx tgt-based -Enabling this flag allows a principal to obtain tickets based on a -ticket-granting-ticket, rather than repeating the authentication -process that was used to obtain the TGT. - -@itemx renewable -Enabling this flag allows the principal to obtain renewable tickets. - -@itemx proxiable -Enabling this flag allows the principal to obtain proxy tickets. - -@itemx dup-skey -Enabling this flag allows the principal to obtain a session key for -another user, permitting user-to-user authentication for this principal. - -@itemx allow-tickets -Enabling this flag means that the KDC will issue tickets for this -principal. Disabling this flag essentially deactivates the principal -within this realm. - -@itemx preauth -If this flag is enabled on a client principal, then that principal is -required to preauthenticate to the KDC before receiving any tickets. -On a service principal, enabling this flag means that service tickets -for this principal will only be issued to clients with a TGT that has -the preauthenticated ticket set. - -@itemx hwauth -If this flag is enabled, then the principal is required to -preauthenticate using a hardware device before receiving any tickets. - -@itemx pwchange -Enabling this flag forces a password change for this principal. - -@itemx service -Enabling this flag allows the the KDC to issue service tickets for this -principal. - -@itemx pwservice -If this flag is enabled, it marks this principal as a password change -service. This should only be used in special cases, for example, if a -user's password has expired, then the user has to get tickets for that -principal without going through the normal password authentication in -order to be able to change the password. - -@end table - -@itemx dict_file -(String.) Location of the dictionary file containing strings that are -not allowed as passwords. If none is specified or if there is no -policy assigned to the principal, no dictionary checks of passwords -will be performed. - -@itemx kadmind_port -(Port number.) Specifies the port on which the kadmind daemon is to -listen for this realm. The assigned port for kadmind is -@value{DefaultKadmindPort}. - -@itemx kpasswd_port -(Port number.) Specifies the port on which the kpasswd daemon is to -listen for this realm. The default is @value{DefaultKpasswdPort}. - -@itemx key_stash_file -(String.) Specifies the location where the master key has been stored -(via @code{kdb5_util stash}). The default is -@code{@value{DefaultKeyStashFileStub}@i{REALM}}, where @i{REALM} is the -Kerberos realm. - -@itemx kdc_ports -(String.) Specifies the list of ports that the KDC is to listen to -for UDP requests for this realm. By default, the value of kdc_ports -as specified in the [kdcdefaults] section is used. - -@itemx kdc_tcp_ports -(String.) Specifies the list of ports that the KDC is to listen to -for TCP requests for this realm. By default, the value of -kdc_tcp_ports as specified in the [kdcdefaults] section is used. - -@itemx master_key_name -(String.) Specifies the name of the principal associated with the -master key. The default is @value{DefaultMasterKeyName}. - -@itemx master_key_type -(Key type string.) Specifies the master key's key type. The default -value for this is @value{DefaultMasterKeyType}. For a list of all -possible values, see @ref{Supported Encryption Types}. - -@itemx max_life -(Delta time string.) Specifes the maximum time period for which a -ticket may be valid in this realm. The default value is -@value{DefaultMaxLife}. - -@itemx max_renewable_life -(Delta time string.) Specifies the maximum time period during which a -valid ticket may be renewed in this realm. The default value is -@value{DefaultMaxRenewableLife}. - -@itemx supported_enctypes -List of key:salt strings. Specifies the default key/salt combinations of -principals for this realm. Any principals created through @code{kadmin} -will have keys of these types. The default value for this tag is -@value{DefaultSupportedEnctypes}. For lists of possible values, see -@ref{Supported Encryption Types} and @ref{Salts}. - -@itemx kdc_supported_enctypes -Specifies the permitted key/salt combinations of principals for this -realm. The format is the same as @code{supported_enctypes}. - -@itemx reject_bad_transit -A boolean value (@code{true}, @code{false}). If set to @code{true}, the -KDC will check the list of transited realms for cross-realm tickets -against the transit path computed from the realm names and the -@code{capaths} section of its @code{krb5.conf} file; if the path in the -ticket to be issued contains any realms not in the computed path, the -ticket will not be issued, and an error will be returned to the client -instead. If this value is set to @code{false}, such tickets will be -issued anyways, and it will be left up to the application server to -validate the realm transit path. - -If the @code{disable-transited-check} flag is set in the incoming -request, this check is not performed at all. Having the -@code{reject_bad_transit} option will cause such ticket requests to be -rejected always. - -This transit path checking and config file option currently apply only -to TGS requests. - -Earlier versions of the MIT release (before 1.2.3) had bugs in the -application server support such that the server-side checks may not be -performed correctly. We recommend turning this option on, unless you -know that all application servers in this realm have been updated to -fixed versions of the software, and for whatever reason, you don't want -the KDC to do the validation. - -This is a per-realm option so that multiple-realm KDCs may control it -separately for each realm, in case (for example) one realm has had the -software on its application servers updated but another has not. - -This option defaults to @code{true}. - -@end table - -@node Sample kdc.conf File, , realms (kdc.conf), kdc.conf -@subsection Sample kdc.conf File - -Here's an example of a @code{kdc.conf} file: - -@smallexample -@group -[kdcdefaults] - kdc_ports = 88 - -[realms] - @value{PRIMARYREALM} = @{ - kadmind_port = 749 - max_life = 12h 0m 0s - max_renewable_life = 7d 0h 0m 0s - master_key_type = des3-hmac-sha1 - supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal des-cbc-crc:v4 - kdc_supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal des-cbc-crc:v4 - @} - -[logging] - kdc = FILE:@value{ROOTDIR}/var/krb5kdc/kdc.log - admin_server = FILE:@value{ROOTDIR}/var/krb5kdc/kadmin.log - -@end group -@end smallexample - -@node Using DNS, Administrating the Kerberos Database, Configuration Files, Top -@chapter Using DNS - -@menu -* Mapping Hostnames onto Kerberos Realms:: -* Hostnames for KDCs:: -@end menu - -@node Mapping Hostnames onto Kerberos Realms, Hostnames for KDCs, Using DNS, Using DNS -@section Mapping Hostnames onto Kerberos Realms - -@include dnstxt.texinfo - -@node Hostnames for KDCs, , Mapping Hostnames onto Kerberos Realms, Using DNS -@section Hostnames for KDCs - -@include dnssrv.texinfo - -@node Administrating the Kerberos Database, Application Servers, Using DNS, Top -@chapter Administrating the Kerberos Database - -Your Kerberos database contains all of your realm's Kerberos principals, -their passwords, and other administrative information about each -principal. For the most part, you will use the @code{kdb5_util} program -to manipulate the Kerberos database as a whole, and the @code{kadmin} -program to make changes to the entries in the database. (One notable -exception is that users will use the @code{kpasswd} program to change -their own passwords.) The @code{kadmin} program has its own -command-line interface, to which you type the database administrating -commands. - -@code{Kdb5_util} provides a means to create, delete, load, or dump a -Kerberos database. It also includes a command to stash a copy of the -master database key in a file on a KDC, so that the KDC can authenticate -itself to the @code{kadmind} and @code{krb5kdc} daemons at boot time. - -@code{Kadmin} provides for the maintenance of Kerberos principals, KADM5 -policies, and service key tables (keytabs). It exists as both a -Kerberos client, @code{kadmin}, using Kerberos authentication and an -RPC, to operate securely from anywhere on the network, and as a local -client, @code{kadmin.local}, intended to run directly on the KDC without -Kerberos authentication. Other than the fact that the remote client -uses Kerberos to authenticate the person using it, the functionalities -of the two versions are identical. The local version is necessary to -enable you to set up enough of the database to be able to use the remote -version. It replaces the now obsolete @code{kdb5_edit} (except for -database dump and load, which are provided by @code{kdb5_util}). - -The remote version authenticates to the KADM5 server using the service -principal @code{kadmin/admin}. If the credentials cache contains a -ticket for the @code{kadmin/admin} principal, and the @samp{-c ccache} -option is specified, that ticket is used to authenticate to KADM5. -Otherwise, the @samp{-p} and @samp{-k} options are used to specify the -client Kerberos principal name used to authenticate. Once kadmin has -determined the principal name, it requests a @code{kadmin/admin} -Kerberos service ticket from the KDC, and uses that service ticket to -authenticate to KADM5. - -@menu -* Kadmin Options:: -* Date Format:: -* Principals:: -* Policies:: -* Global Operations on the Kerberos Database:: -* Cross-realm Authentication:: -@end menu - -@node Kadmin Options, Date Format, Administrating the Kerberos Database, Administrating the Kerberos Database -@section Kadmin Options - -You can invoke @code{kadmin} or @code{kadmin.local} with any of the -following options: - -@table @b -@item @b{-r} @i{REALM} -Use @i{REALM} as the default Kerberos realm for the database. - -@item @b{-p} @i{principal} -Use the Kerberos principal @i{principal} to authenticate to Kerberos. -If this option is not given, @code{kadmin} will append @code{admin} to -either the primary principal name, the environment variable USER, or to -the username obtained from @code{getpwuid}, in order of preference. - -@item @b{-q} @i{query} -Pass @i{query} directly to @code{kadmin}. This is useful for writing -scripts that pass specific queries to @code{kadmin}. - -@noindent -You can invoke @code{kadmin} with any of the following options: - -@item @b{-k} [@b{-t} @i{keytab}] -Use the keytab @i{keytab} to decrypt the KDC response instead of -prompting for a password on the TTY. In this case, the principal will -be @samp{host/@i{hostname}}. If @b{-t} is not used to specify a keytab, -then the default keytab will be used. - -@item @b{-c} @i{credentials cache} -Use @i{credentials_cache} as the credentials cache. The credentials -cache should contain a service ticket for the @code{kadmin/admin} -service, which can be acquired with the @code{kinit} program. If this -option is not specified, @code{kadmin} requests a new service ticket -from the KDC, and stores it in its own temporary ccache. - -@item @b{-w} @i{password} -Use @i{password} as the password instead of prompting for one on the -TTY. Note: placing the password for a Kerberos principal with -administration access into a shell script can be dangerous if -unauthorized users gain read access to the script. - -@item @b{-s} @i{admin_server[:port]} -Specifies the admin server that kadmin should contact. - -@noindent -You can invoke @code{kadmin.local} with an of the follwing options: - -@item @b{-d_ @i{dbname}} -Specifies the name of the Kerberos database. - -@item @b{-e} @i{"enctypes ..."} -Sets the list of cryptosystem and salt types to be used for any new -keys created. See @ref{Supported Encryption Types} and @ref{Salts} for -available types. - -@item @b{-m} -Do not authenticate using a keytab. This option will cause kadmin to -prompt for the master database password. - -@end table - -@node Date Format, Principals, Kadmin Options, Administrating the Kerberos Database -@section Date Format - -Many of the @code{kadmin} commands take a duration or time as an -argument. The date can appear in a wide variety of formats, such as: - -@smallexample -@group -"15 minutes" -"7 days" -"1 month" -"2 hours" -"400000 seconds" -"next year" -"this Monday" -"next Monday" -yesterday -tomorrow -now -"second Monday" -fortnight -"3/31/1992 10:00:07 PST" -"January 23, 2007 10:05pm" -"22:00 GMT" -@end group -@end smallexample - -Note that if the date specification contains spaces, you must enclose it -in double quotes. Note also that you cannot use a number without a -unit. (I.e., ``"60 seconds"'' is correct, but ``60'' is incorrect.) -All keywords are case-insensitive. The following is a list of all of -the allowable keywords. - -@table @b -@item Months -january, jan, february, feb, march, mar, april, apr, may, june, jun, -july, jul, august, aug, september, sep, sept, october, oct, november, -nov, december, dec - -@item Days -sunday, sun, monday, mon, tuesday, tues, tue, wednesday, wednes, wed, -thursday, thurs, thur, thu, friday, fri, saturday, sat - -@item Units -year, month, fortnight, week, day, hour, minute, min, second, sec - -@item Relative -tomorrow, yesterday, today, now, last, this, next, first, second, -third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, -twelfth, ago - -@item Time Zones -@code{kadmin} recognizes abbreviations for most of the world's time -zones. A complete listing appears in @ref{kadmin Time Zones}. - -@item 12-hour Time Delimiters -am, pm -@end table - -@node Principals, Policies, Date Format, Administrating the Kerberos Database -@section Principals - -Each entry in the Kerberos database contains a Kerberos principal -(@pxref{Definitions}) and the attributes and policies associated with -that principal. - -@menu -* Retrieving Information About a Principal:: -* Privileges:: -* Adding or Modifying Principals:: -* Deleting Principals:: -* Changing Passwords:: -@end menu - -@node Retrieving Information About a Principal, Privileges, Principals, Principals -@subsection Retrieving Information About a Principal - -@menu -* Attributes:: -* Retrieving a List of Principals:: -@end menu - -@node Attributes, Retrieving a List of Principals, Retrieving Information About a Principal, Retrieving Information About a Principal -@subsubsection Attributes - -To retrieve a listing of the attributes and/or policies associated with -a principal, use the @code{kadmin} @code{get_principal} command, which -requires the ``inquire'' administrative privilege. The syntax is: - -@smallexample -@b{get_principal} @i{principal} -@end smallexample - -@noindent -The @code{get_principal} command has the alias @code{getprinc}. - -For example, suppose you wanted to view the attributes of the -principal @* @code{@value{RANDOMUSER1}/root@@@value{PRIMARYREALM}}. - You would type: - -@smallexample -@group -@b{shell%} kadmin -@b{kadmin:} getprinc @value{RANDOMUSER1}/root -@b{Principal: @value{RANDOMUSER1}/root@@@value{PRIMARYREALM} -Expiration date: [never] -Last password change: Mon Jan 31 02:06:40 EDT 2002 -Password Expiration date: [none] -Maximum ticket life: 0 days 10:00:00 -Maximum renewable life: 7 days 00:00:00 -Last modified: Wed Jul 24 14:46:25 EDT 2002 (@value{ADMINUSER}/admin@@@value{PRIMARYREALM}) -Last successful authentication: Mon Jul 29 18:20:17 EDT 2002 -Last failed authentication: Mon Jul 29 18:18:54 EDT 2002 -Failed password attempts: 3 -Number of keys: 2 -Key: vno 2, Triple DES cbc mode with HMAC/sha1, no salt -Key: vno 2, DES cbc mode with CRC-32, no salt -Attributes: DISALLOW_FORWARDABLE, DISALLOW_PROXIABLE -Policy: [none] -kadmin:} -@end group -@end smallexample - -The @code{get_principal} command has a @code{-terse} option, which lists -the fields as a quoted, tab-separated string. For example: - -@smallexample -@group -@b{kadmin:} getprinc -terse @value{RANDOMUSER1}/root -@b{@value{RANDOMUSER1}/root@@@value{PRIMARYREALM} 0 1027458564 -0 36000 (@value{ADMINUSER}/admin@@@value{PRIMARYREALM} -1027536385 18 2 0 [none] 604800 1027980137 -1027980054 3 2 1 2 16 0 1 -2 1 0 -kadmin:} -@end group -@end smallexample - -@node Retrieving a List of Principals, , Attributes, Retrieving Information About a Principal -@subsubsection Retrieving a List of Principals - -To generate a listing of principals, use the @code{kadmin} -@code{list_principals} command, which requires the ``list'' privilege. -The syntax is: - -@smallexample -@b{list_principals} [@i{expression}] -@end smallexample - -@noindent where @i{expression} is a shell-style glob expression that -can contain the characters @samp{*}, @samp{?}, @samp{[}, and @samp{]}. -All policy names matching the expression are displayed. The -@code{list_principals} command has the aliases @code{listprincs}, -@code{get_principals}, and @code{getprincs}. For example: - -@smallexample -@group -@b{kadmin:} listprincs test* -@b{test3@@@value{PRIMARYREALM} -test2@@@value{PRIMARYREALM} -test1@@@value{PRIMARYREALM} -testuser@@@value{PRIMARYREALM} -kadmin:} -@end group -@end smallexample - -@noindent -If no expression is provided, all principals are printed. - -@node Privileges, Adding or Modifying Principals, Retrieving Information About a Principal, Principals -@subsection Privileges - -Administrative privileges for the Kerberos database are stored in the -file @code{kadm5.acl}. - -@include kadm5acl.texinfo - -@node Adding or Modifying Principals, Deleting Principals, Privileges, Principals -@subsection Adding or Modifying Principals - -To add a principal to the database, use the kadmin @code{add_principal} -command, which requires the ``add'' administrative privilege. This -function creates the new principal, prompting twice for a password, and, -if neither the -policy nor -clearpolicy options are specified and the -policy ``default'' exists, assigns it that policy. The syntax is: - -@smallexample -@b{kadmin:} add_principal [@i{options}] @i{principal} -@end smallexample - -To modify attributes of a principal, use the kadmin -@code{modify_principal} command, which requires the ``modify'' -administrative privilege. The syntax is: - -@smallexample -@b{kadmin:} modify_principal [@i{options}] @i{principal} -@end smallexample - -@noindent -@code{add_principal} has the aliases @code{addprinc} and -@code{ank}@footnote{@code{ank} was the short form of the equivalent -command using the deprecated @code{kadmin5} database administrative tool. -It has been kept}. @code{modify_principal} has the alias @code{modprinc}. - -The @code{add_principal} and @code{modify_principal} commands take the -following switches: - -@table @b -@item -expire @i{date} -Sets the expiration date of the principal to @i{date}. - -@item -pwexpire @i{date} -Sets the expiration date of the password to @i{date}. - -@item -maxlife @i{maxlife} -Sets the maximum ticket life of the principal to @i{maxlife}. - -@item -maxrenewlife @i{maxrenewlife} -Sets the maximum renewable life of tickets for the principal to -@i{maxrenewlife}. - -@item -kvno @i{number} -Explicity sets the key version number to @i{number}. @value{COMPANY} -does not recommend doing this unless there is a specific reason. - -@item -policy @i{policy} -Sets the policy used by this principal. (@xref{Policies}.) With -@code{modify_principal}, the current policy assigned to the principal is -set or changed. With @code{add_principal}, if this option is not -supplied, the -clearpolicy is not specified, and the policy ``default'' -exists, that policy is assigned. If a principal is created with no -policy, @code{kadmin} will print a warning message. - -@item -clearpolicy -For @code{modify_principal}, removes the current policy from a -principal. For @code{add_principal}, suppresses the automatic -assignment of the policy ``default''. - -@item @{-|+@}allow_postdated -The ``-allow_postdated'' option prohibits this principal from obtaining -postdated tickets. ``+allow_postdated'' clears this flag. In effect, -``-allow_postdated'' sets the KRB5_KDB_DISALLOW_POSTDATED flag on the -principal in the database. - -@item @{-|+@}allow_forwardable -The ``-allow_forwardable'' option prohibits this principal from -obtaining forwardable tickets. ``+allow_forwardable'' clears this flag. -In effect, ``-allow_forwardable'' sets the KRB5_KDB_DISALLOW_FORWARDABLE -flag on the principal in the database. - -@item @{-|+@}allow_renewable -The ``-allow_renewable'' option prohibits this principal from obtaining -renewable tickets. ``+allow_renewable'' clears this flag. In effect, -``-allow_renewable'' sets the KRB5_KDB_DISALLOW_RENEWABLE flag on the -principal in the database. - -@item @{-|+@}allow_proxiable -The ``-allow_proxiable'' option prohibits this principal from obtaining -proxiable tickets. ``+allow_proxiable'' clears this flag. In effect, -``-allow_proxiable'' sets the @* KRB5_KDB_DISALLOW_PROXIABLE flag. on -the principal in the database. - -@item @{-|+@}allow_dup_skey -The ``-allow_dup_skey'' option disables user-to-user authentication for -this principal by prohibiting this principal from obtaining a session -key for another user. ``+allow_dup_skey'' clears this flag. In effect, -``-allow_dup_skey'' sets the @* KRB5_KDB_DISALLOW_DUP_SKEY flag on the -principal in the database. - -@item @{-|+@}requires_preauth -The ``+requires_preauth'' option requires this principal to -preauthenticate before being allowed to kinit. -requires_preauth clears -this flag. In effect, +requires_preauth sets the -KRB5_KDB_REQUIRES_PRE_AUTH flag on the principal in the database. - -@item @{-|+@}requires_hwauth -The ``+requires_hwauth'' flag requires the principal to preauthenticate -using a hardware device before being allowed to kinit. -``-requires_hwauth'' clears this flag. In effect, ``+requires_hwauth'' -sets the KRB5_KDB_REQUIRES_HW_AUTH flag on the principal in the -database. - -@item @{-|+@}allow_svr -The ``-allow_svr'' flag prohibits the issuance of service tickets for -this principal. ``+allow_svr'' clears this flag. In effect, -``-allow_svr'' sets the @* KRB5_KDB_DISALLOW_SVR flag on the principal -in the database. - -@item @{-|+@}allow_tgs_req -The ``-allow_tgs_req'' option specifies that a Ticket-Granting Service -(TGS) request for a service ticket for this principal is not permitted. -You will probably never need to use this option. ``+allow_tgs_req'' -clears this flag. The default is ``+allow_tgs_req''. In effect, -``-allow_tgs_req'' sets the KRB5_KDB_DISALLOW_TGT_BASED flag on the -principal in the database. - -@item @{-|+@}allow_tix -The ``-allow_tix'' option forbids the issuance of any tickets for this -principal. ``+allow_tix'' clears this flag. The default is -``+allow_tix''. In effect, ``-allow_tix'' sets the @* -KRB5_KDB_DISALLOW_ALL_TIX flag on the principal in the database. - -@item @{-|+@}needchange -The ``+needchange'' option sets a flag in attributes field to force a -password change; ``-needchange'' clears it. The default is -``-needchange''. In effect, ``+needchange'' sets the -KRB5_KDB_REQUIRES_PWCHANGE flag on the principal in the database. - -@item @{-|+@}password_changing_service -The ``+password_changing_service'' option sets a flag in the attributes -field marking this principal as a password change service. (Again, you -will probably never need to use this option.) -``-password_changing_service'' clears the flag. The default is -``-password_changing_service''. In effect, the -``+password_changing_service'' option sets the KRB5_KDB_PWCHANGE_SERVICE -flag on the principal in the database. - -@item -randkey -Sets the key for the principal to a random value (@code{add_principal} -only). @value{COMPANY} recommends using this option for host keys. - -@item -pw @i{password} -Sets the key of the principal to the specified string and does not -prompt for a password (@code{add_principal} only). @value{COMPANY} does -not recommend using this option. - -@item -e @i{enc:salt...} -Uses the specified list of enctype-salttype pairs for setting the key -of the principal. The quotes are necessary if there are multiple -enctype-salttype pairs. This will not function against kadmin daemons -earlier than krb5-1.2. See @ref{Supported Encryption Types} and -@ref{Salts} for available types. -@end table - -If you want to just use the default values, all you need to do is: - -@smallexample -@group -@b{kadmin:} addprinc @value{RANDOMUSER1} -@b{WARNING: no policy specified for "@value{RANDOMUSER1}@@@value{PRIMARYREALM}"; -defaulting to no policy.} -@iftex -@b{Enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type the password.} -@b{Re-enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<= Type the password.} -@b{Re-enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<=Type it again.} -@end ifinfo -@ifhtml -@b{Enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<= Type the password.} -@b{Re-enter password for principal @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<=Type it again.} -@end ifhtml -@b{Principal "@value{RANDOMUSER1}@@@value{PRIMARYREALM}" created. -kadmin:} -@end group -@end smallexample - -If, on the other hand, you want to set up an account that expires on -January 1, 2000, that uses a policy called ``stduser'', with a temporary -password (which you want the user to change immediately), you would type -the following. (Note: each line beginning with @result{} is a -continuation of the previous line.) - -@smallexample -@group - -@b{kadmin:} addprinc @value{RANDOMUSER2} -expire "1/1/2000 12:01am EST" -policy stduser -@result{} +needchange -@iftex -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type the password.} -@b{Re-enter password for principal -@value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type the password.} -@b{Re-enter password for principal -@value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type it again.} -@end ifinfo -@ifhtml -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type the password.} -@b{Re-enter password for principal -@value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type it again.} -@end ifhtml -@b{Principal "@value{RANDOMUSER2}@@@value{PRIMARYREALM}" created. -kadmin:} - -@end group -@end smallexample - -If you will need cross-realm authentication, you need to add principals -for the other realm's TGT to each realm. For example, if you need to -do cross-realm authentication between the realms @value{PRIMARYREALM} -and @value{SECONDREALM}, you would need to add the principals @* -@samp{krbtgt/@value{SECONDREALM}@@@value{PRIMARYREALM}} and -@samp{krbtgt/@value{PRIMARYREALM}@@@value{SECONDREALM}} to both -databases. You need to be sure the passwords and the key version -numbers (kvno) are the same in both databases. This may require -explicitly setting the kvno with the @samp{-kvno} option. See -@ref{Cross-realm Authentication} for more details. - -@node Deleting Principals, Changing Passwords, Adding or Modifying Principals, Principals -@subsection Deleting Principals - -To delete a principal, use the kadmin @code{delete_principal} command, -which requires the ``delete'' administrative privilege. The syntax is: - -@smallexample -@b{delete_principal} [@b{-force}] @i{principal} -@end smallexample - -@noindent @code{delete_principal} has the alias @code{delprinc}. The -@code{-force} option causes @code{delete_principal} not to ask if you're -sure. For example: - -@smallexample -@group -@b{kadmin:} delprinc @value{RANDOMUSER1} -@b{Are you sure you want to delete the principal -"@value{RANDOMUSER1}@@@value{PRIMARYREALM}"? (yes/no):} yes -@b{Principal "@value{RANDOMUSER1}@@@value{PRIMARYREALM}" deleted. -Make sure that you have removed this principal from -all ACLs before reusing. -kadmin:} -@end group -@end smallexample - -@node Changing Passwords, , Deleting Principals, Principals -@subsection Changing Passwords - -To change a principal's password use the kadmin @code{change_password} -command, which requires the ``modify'' administrative privilege (unless -the principal is changing his/her own password). The syntax is: - -@smallexample -@b{change_password} [@i{options}] @i{principal} -@end smallexample - -@noindent The @code{change_password} option has the alias @code{cpw}. -@code{change_password} takes the following options: - -@table @b -@item -randkey -Sets the key of the principal to a random value. - -@item @b{-pw} @i{password} -Sets the password to the string @i{password}. @value{COMPANY} does not -recommend using this option. - -@item @b{-e} @i{"enc:salt..."} -Uses the specified list of enctype-salttype pairs for setting the key -of the principal. The quotes are necessary if there are multiple -enctype-salttype pairs. This will not function against kadmin daemons -earlier than krb5-1.2. See @ref{Supported Encryption Types} and -@ref{Salts} for possible values. - -@item @b{-keepold} -Keeps the previous kvno's keys around. There is no easy way to delete -the old keys, and this flag is usually not necessary except perhaps for -TGS keys. Don't use this flag unless you know what you're doing. - -@end table - -For example: - -@smallexample -@group -@b{kadmin:} cpw @value{RANDOMUSER2} -@iftex -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type the new password.} -@b{Re-enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type the new password.} -@b{Re-enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type it again.} -@end ifinfo -@ifhtml -@b{Enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type the new password.} -@b{Re-enter password for principal @value{RANDOMUSER2}@@@value{PRIMARYREALM}:} @i{<= Type it again.} -@end ifhtml -@b{Password for @value{RANDOMUSER2}@@@value{PRIMARYREALM} changed. -kadmin:} -@end group -@end smallexample - -Note that @code{change_password} will not let you change the password to -one that is in the principal's password history. - -@node Policies, Global Operations on the Kerberos Database, Principals, Administrating the Kerberos Database -@section Policies - -A policy is a set of rules governing passwords. Policies can dictate -minimum and maximum password lifetimes, minimum number of characters and -character classes a password must contain, and the number of old -passwords kept in the database. - -@menu -* Retrieving Policies:: -* Retrieving the List of Policies:: -* Adding or Modifying Policies:: -* Deleting Policies:: -@end menu - -@node Retrieving Policies, Retrieving the List of Policies, Policies, Policies -@subsection Retrieving Policies - -To retrieve a policy, use the kadmin @code{get_policy} command, which -requires the ``inquire'' administrative privilege. The syntax is: - -@smallexample -@b{get_policy} [@b{-terse}] @i{policy} -@end smallexample - -The @code{get_policy} command has the alias @code{getpol}. For example: - -@smallexample -@group -@b{kadmin:} get_policy admin -@b{Policy: admin -Maximum password life: 180 days 00:00:00 -Minimum password life: 00:00:00 -Minimum password length: 6 -Minimum number of password character classes: 2 -Number of old keys kept: 5 -Reference count: 17 -kadmin:} -@end group -@end smallexample - -@noindent The @dfn{reference count} is the number of principals using -that policy. - -The @code{get_policy} command has a @code{-terse} option, which lists -each field as a quoted, tab-separated string. For example: - -@smallexample -@group -@b{kadmin:} get_policy -terse admin -@b{admin 15552000 0 6 2 5 17 -kadmin:} -@end group -@end smallexample - -@node Retrieving the List of Policies, Adding or Modifying Policies, Retrieving Policies, Policies -@subsection Retrieving the List of Policies - -You can retrieve the list of policies with the kadmin -@code{list_policies} command, which requires the ``list'' privilege. The -syntax is: - -@smallexample -@b{list_policies} [@i{expression}] -@end smallexample - -@noindent where @i{expression} is a shell-style glob expression that can -contain the characters *, ?, and []. All policy names matching the -expression are displayed. The @code{list_policies} command has the aliases -@code{listpols}, @code{get_policies}, and @code{getpols}. For example: - -@smallexample -@group -@b{kadmin:} listpols -@b{test-pol -dict-only -once-a-min -test-pol-nopw} - -@b{kadmin:} listpols t* -@b{test-pol -test-pol-nopw -kadmin:} -@end group -@end smallexample - -@node Adding or Modifying Policies, Deleting Policies, Retrieving the List of Policies, Policies -@subsection Adding or Modifying Policies - -To add a new policy, use the kadmin @code{add_policy} command, which -requires the ``add'' administrative privilege. The syntax is: - -@smallexample -@b{add_policy} [@i{options}] @i{policy_name} -@end smallexample - -To modify attributes of a principal, use the kadmin @code{modify_policy} -command, which requires the ``modify'' administrative privilege. The -syntax is: - -@smallexample -@b{modify_policy} [@i{options}] @i{policy_name} -@end smallexample - -@noindent @code{add_policy} has the alias @code{addpol}. -@code{modify_poilcy} has the alias @code{modpol}. - -The @code{add_policy} and @code{modify_policy} commands take the -following switches: - -@table @b -@item -maxlife @i{time} -Sets the maximum lifetime of a password to @i{time}. - -@item -minlife @i{time} -Sets the minimum lifetime of a password to @i{time}. - -@item -minlength @i{length} -Sets the minimum length of a password to @i{length} characters. - -@item -minclasses @i{number} -Requires at least @i{number} of character classes in a password. - -@item -history @i{number} -Sets the number of past keys kept for a principal to @i{number}. -@end table - -@c **** An example here would be nice. **** - -@node Deleting Policies, , Adding or Modifying Policies, Policies -@subsection Deleting Policies - -To delete a policy, use the @code{kadmin} @code{delete_policy} command, -which requires the ``delete'' administrative privilege. The syntax is: - -@smallexample -@b{delete_policy [-force]} @i{policy_name} -@end smallexample - -@noindent The @code{delete_policy} command has the alias @code{delpol}. -It prompts for confirmation before deletion. -For example: - -@smallexample -@group -@b{kadmin:} delete_policy guests -@b{Are you sure you want to delete the policy "guests"? -(yes/no):} yes -@b{kadmin:} -@end group -@end smallexample - -Note that you must cancel the policy from all principals before deleting -it. The @code{delete_policy} command will fail if it is in use by any -principals. - -@node Global Operations on the Kerberos Database, Cross-realm Authentication, Policies, Administrating the Kerberos Database -@section Global Operations on the Kerberos Database - -@menu -* Dumping a Kerberos Database to a File:: -* Restoring a Kerberos Database from a Dump File:: -* Creating a Stash File:: -* Creating and Destroying a Kerberos Database:: -@end menu - -The @code{kdb5_util} command is the primary tool for administrating the -Kerberos database. The syntax is: - -@smallexample -@b{kdb5_util} @i{command} [@i{kdb5_util_options}] [@i{command_options}] -@end smallexample - -The @code{kdb5_util} command takes the following options, which override -the defaults specified in the configuration files: - -@table @b -@itemx -r @i{realm} -specifies the the Kerberos realm of the database. - -@itemx -d @i{database_name} -specifies the name under which the principal database is stored. - -@itemx -k @i{master_key_type} -specifies the key type of the master key in the database. - -@itemx -M @i{master_key_name} -specifies the principal name of the master key in the database. - -@itemx -m -indicates that the master database password should be read from the TTY -rather than fetched from a file on disk. - -@itemx -sf @i{stash_file} -specifies the stash file of the master database password - -@itemx -P @i{password} -specifies the master database password. @value{COMPANY} does not -recommend using this option. - -@end table - -@node Dumping a Kerberos Database to a File, Restoring a Kerberos Database from a Dump File, Global Operations on the Kerberos Database, Global Operations on the Kerberos Database -@subsection Dumping a Kerberos Database to a File - -To dump a Kerberos database into a file, use the @code{kdb5_util} -@code{dump} command on one of the KDCs. The syntax is: - -@smallexample -@b{kdb5_util dump} [@b{-old}] [@b{-b6}] [@b{-b7}] [@b{-ov}] -[@b{-verbose}] [-mkey_convert] [-new_mkey_file] [@i{filename} -[@i{principals...}]] -@end smallexample - -The @code{kdb5_util dump} command takes the following options: - -@table @b -@itemx -old -causes the dump to be in the Kerberos 5 Beta 5 and earlier dump format -(``kdb5_edit load_dump version 2.0''). -@itemx -b6 -causes the dump to be in the Kerberos 5 Beta 6 format (``kdb5_edit -load_dump version 3.0''). -@itemx -b7 -causes the dump to be in the Kerberos 5 Beta 7 format (``kdbt_edit -load_dump version 4''). -@itemx -ov -causes the dump to be in ovsec_adm_export format. Currently, the only -way to preserve per-principal policy information is to use this in -conjunction with a normal dump. -@itemx -verbose -causes the name of each principal and policy to be printed as it is -dumped. -@itemx -mkey_convert -prompts for a new master password, and then dumps the database with -all keys reencrypted in this new master key -@itemx -new_mkey_file -reads a new key from the default keytab and then dumps the database -with all keys reencrypted in this new master key -@end table - -For example: - -@smallexample -@group -@b{shell%} kdb5_util dump dumpfile -@b{shell%} -@end group -@end smallexample - -@smallexample -@group -@b{shell%} kbd5_util dump -verbose dumpfile -@b{kadmin/admin@@@value{PRIMARYREALM} -krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM} -kadmin/history@@@value{PRIMARYREALM} -K/M@@@value{PRIMARYREALM} -kadmin/changepw@@@value{PRIMARYREALM} -shell%} -@end group -@end smallexample - -@noindent -If you specify which principals to dump, you must use the full -principal, as in the following example. (The line beginning with -@result{} is a continuation of the previous line.): - -@smallexample -@group -@b{shell%} kdb5_util dump -verbose dumpfile K/M@@@value{PRIMARYREALM} -@result{} kadmin/admin@@@value{PRIMARYREALM} -@b{kadmin/admin@@@value{PRIMARYREALM} -K/M@@@value{PRIMARYREALM} -shell%} -@end group -@end smallexample - -@noindent -Otherwise, the principals will not match those in the database and will -not be dumped: - -@smallexample -@group -@b{shell%} kdb5_util dump -verbose dumpfile K/M kadmin/admin -@b{shell%} -@end group -@end smallexample - -@noindent -If you do not specify a dump file, @code{kdb5_util} will dump the -database to the standard output. - -There is currently a bug where the default dump format omits the -per-principal policy information. In order to dump all the data -contained in the Kerberos database, you must perform a normal dump (with -no option flags) and an additional dump using the ``-ov'' flag to a -different file. - -@node Restoring a Kerberos Database from a Dump File, Creating a Stash File, Dumping a Kerberos Database to a File, Global Operations on the Kerberos Database -@subsection Restoring a Kerberos Database from a Dump File - -To restore a Kerberos database dump from a file, use the -@code{kdb5_util} @code{load} command on one of the KDCs. The syntax -is: - -@smallexample -@b{kdb5_util load} [@b{-old}] [@b{-b6}] [@b{-b7}] [@b{-ov}] [@b{-verbose}] -[@b{-update}] [@b{-hash}] @i{dumpfilename} @i{dbname} [@i{admin_dbname}] -@end smallexample - -The @code{kdb5_util load} command takes the following options: - -@table @b -@itemx -old -requires the dump to be in the Kerberos 5 Beta 5 and earlier dump format -(``kdb5_edit load_dump version 2.0''). -@itemx -b6 -requires the dump to be in the Kerberos 5 Beta 6 format (``kdb5_edit -load_dump version 3.0''). -@itemx -b7 -requires the dump to be in the Kerberos 5 Beta 7 format (``kdb5_edit -load_dump version 4''). -@itemx -ov -requires the dump to be in ovsec_adm_export format. -@itemx -verbose -causes the name of each principal and policy to be printed as it is -loaded. -@itemx -update -causes records from the dump file to be updated in or added to the -existing database. This is useful in conjunction with an -ovsec_adm_export format dump if you want to preserve per-principal -policy information, since the current default format does not contain -this data. -@itemx -hash -causes the database to be stored as a hash rather than a binary tree. -@end table - -For example: - -@smallexample -@group -@b{shell%} kdb5_util load dumpfile principal -@b{shell%} -@end group -@end smallexample - -@smallexample -@group -@b{shell%} kdb5_util load -update dumpfile principal -@b{shell%} -@end group -@end smallexample - -@noindent -If the database file exists, and the @b{-update} flag was not given, -@code{kdb5_util} will overwrite the existing database. - -@node Creating a Stash File, Creating and Destroying a Kerberos Database, Restoring a Kerberos Database from a Dump File, Global Operations on the Kerberos Database -@subsection Creating a Stash File - -A stash file allows a KDC to authenticate itself to the database -utilities, such as @code{kadmin}, @code{kadmind}, @code{krb5kdc}, and -@code{kdb5_util}. - -To create a stash file, use the @code{kdb5_util} @code{stash} command. -The syntax is: - -@smallexample -@b{kdb5_util stash} [@b{-f} @i{keyfile}] -@end smallexample - -For example: - -@smallexample -@group -@b{shell%} kdb5_util stash -@b{kdb5_util: Cannot find/read stored master key while reading master key -kdb5_util: Warning: proceeding without master key} -@iftex -@b{Enter KDC database master key:} @i{@doubleleftarrow{} Type the KDC database master password.} -@end iftex -@ifinfo -@b{Enter KDC database master key:} @i{<= Type the KDC database master password.} -@end ifinfo -@ifhtml -@b{Enter KDC database master key:} @i{<= Type the KDC database master password.} -@end ifhtml -@b{shell%} -@end group -@end smallexample - -@noindent -If you do not specify a stash file, @code{kdb5_util} will stash the key -in the file specified in your @code{kdc.conf} file. - -@node Creating and Destroying a Kerberos Database, , Creating a Stash File, Global Operations on the Kerberos Database -@subsection Creating and Destroying a Kerberos Database - -If you need to create a new Kerberos database, use the @code{kdb5_util} -@code{create} command. The syntax is: - -@smallexample -@b{kdb5_util create} [@b{-s}] -@end smallexample - -If you specify the @samp{-s} option, @code{kdb5_util} will stash a copy -of the master key in a stash file. (@xref{Creating a Stash File}.) For -example: - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kdb5_util -r @value{PRIMARYREALM} create -s -@b{kdb5_util: No such file or directory while setting active database to -@result{} '@value{ROOTDIR}/var/krb5kdc/principal' -Initializing database '@value{ROOTDIR}/var/krb5kdc/principal' for -@result{} realm '@value{PRIMARYREALM}', -master key name 'K/M@@@value{PRIMARYREALM}' -You will be prompted for the database Master Password. -It is important that you NOT FORGET this password.} -@iftex -@b{Enter KDC database master key:} @i{@doubleleftarrow{} Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter KDC database master key:} @i{<= Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{<= Type it again.} -@end ifinfo -@ifhtml -@b{Enter KDC database master key:} @i{<= Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{<= Type it again.} -@end ifhtml -@b{shell%} -@end group -@end smallexample - -If you need to destroy the current Kerberos database, use the -@code{kdb5_util} @code{destroy} command. The syntax is: - -@smallexample -@b{kdb5_util destroy} [@b{-f}] -@end smallexample - -The @code{destroy} command destroys the database, first overwriting the -disk sectors and then unlinking the files. If you specify the -@samp{-f} option, @code{kdb5_util} will not prompt you for a -confirmation before destroying the database. - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kdb5_util -r @value{PRIMARYREALM} destroy -@iftex -@b{kdb5_util: Deleting KDC database stored in @value{DefaultDatabaseName}, are you sure -(type yes to confirm)?} @i{@doubleleftarrow{}yes} -@end iftex -@ifinfo -@b{kdb5_util: Deleting KDC database stored in @value{DefaultDatabaseName}, are you sure -(type yes to confirm)?} @i{<== yes} -@end ifinfo -@ifhtml -@b{kdb5_util: Deleting KDC database stored in @value{DefaultDatabaseName}, are you sure -(type yes to confirm)?} @i{<== yes} -@end ifhtml -@b{OK, deleting database '@value{DefaultDatabaseName}'...} - -@b{shell%} -@end group -@end smallexample - -@ignore -@c @node The KDC Logs, , Creating and Destroying a Kerberos Database, Administrating the Kerberos Database -@c @section The KDC Logs - -This will have to wait until the next release. *sigh* -@end ignore - -@node Cross-realm Authentication, , Global Operations on the Kerberos Database, Administrating the Kerberos Database -@section Cross-realm Authentication - -In order for a KDC in one realm to authenticate Kerberos users in a -different realm, it must share a key with the KDC in the other realm. -In both databases, there must be krbtgt service principals for realms. -These principals should all have the same passwords, key version -numbers, and encryption types. For example, if the administrators of -@value{PRIMARYREALM} and @value{SECONDREALM} wanted to authenticate -across the realms, they would run the following commands on the KDCs in -@i{both} realms: - -@smallexample -@group -@b{shell%:} kadmin.local -e "des3-hmac-sha1:normal des-cbc-crc:v4" -@b{kadmin:} add_princ -requires_preauth krbtgt/@value{PRIMARYREALM}@@@value{SECONDREALM} -@b{Enter password for principal krbtgt/@value{PRIMARYREALM}@@@value{SECONDREALM}:} -@b{Re-enter password for principal krbtgt/@value{PRIMARYREALM}@@@value{SECONDREALM}:} -@b{kadmin:} add_princ -requires_preauth krbtgt/@value{SECONDREALM}@@@value{PRIMARYREALM} -@b{Enter password for principal krbtgt/@value{SECONDREALM}@@@value{PRIMARYREALM}:} -@b{Enter password for principal krbtgt/@value{SECONDREALM}@@@value{PRIMARYREALML}:} -@b{kadmin:} -@end group -@end smallexample - -Even if most principals in a realm are generally created with the -requires_preauth flag enabled, this flag is not desirable on -cross-realm authentication keys because doing so makes it impossible to -disable preauthentication on a service-by-service basis. Disabling it -as in the example above is recommended. - -It is also very important that these principals have good passwords. -@value{COMPANY} recommends that TGT principal passwords be at least 26 -characters of random ASCII text. - -@node Application Servers, Backups of Secure Hosts, Administrating the Kerberos Database, Top -@chapter Application Servers - -If you need to install the @value{PRODUCT} programs on an application -server, please refer to the @value{PRODUCT} Installation Guide. Once -you have installed the software, you need to add that host to the -Kerberos database (@pxref{Adding or Modifying Principals}), and generate -a @dfn{keytab} for that host, that contains the host's key. You also -need to make sure the host's clock is within your maximum clock skew of -the KDCs. - -@menu -* Keytabs:: -* Clock Skew:: -* Getting DNS Information Correct:: -* Configuring Your Firewall to Work With Kerberos V5:: -@end menu - -@node Keytabs, Clock Skew, Application Servers, Application Servers -@section Keytabs - -A @dfn{keytab} is a host's copy of its own keylist, which is analogous -to a user's password. An application server that needs to authenticate -itself to the KDC has to have a keytab that contains its own principal -and key. Just as it is important for users to protect their passwords, -it is equally important for hosts to protect their keytabs. You should -always store keytab files on local disk, and make them readable only by -root, and you should never send a keytab file over a network in the -clear. Ideally, you should run the @code{kadmin} command to extract a -keytab on the host on which the keytab is to reside. - -@menu -* Adding Principals to Keytabs:: -* Removing Principals from Keytabs:: -@end menu - -@node Adding Principals to Keytabs, Removing Principals from Keytabs, Keytabs, Keytabs -@subsection Adding Principals to Keytabs - -To generate a keytab, or to add a principal to an existing keytab, use -the @code{ktadd} command from @code{kadmin}, which requires the -``inquire'' administrative privilege. (If you use the @b{-glob} -@i{princ_exp} option, it also requires the ``list'' administrative -privilege.) The syntax is: - -@smallexample -@b{ktadd} [@b{-k[eytab]} @i{keytab}] [@b{-q}] [@b{-e} -@i{key:salt_list}] [@i{principal} | @b{-glob} @i{princ_exp}] -[@i{@dots{}}] -@end smallexample - -The @code{ktadd} command takes the following switches: - -@table @b -@item -k[eytab] @i{keytab} -use @i{keytab} as the keytab file. Otherwise, @code{ktadd} will use the -default keytab file (@code{@value{DefaultDefaultKeytabName}}). - -@item @b{-e} @i{"enc:salt..."} -Uses the specified list of enctype-salttype pairs for setting the key -of the principal. The quotes are necessary if there are multiple -enctype-salttype pairs. This will not function against kadmin daemons -earlier than krb5-1.2. See @ref{Supported Encryption Types} and -@ref{Salts} for all possible values. - -@item -q -run in quiet mode. This causes @code{ktadd} to display less verbose -information. - -@item @i{principal} | -glob @i{principal expression} -add @i{principal}, or all principals matching @i{principal expression} -to the keytab. The rules for @i{principal expression} are the same as -for the kadmin @code{list_principals} (@pxref{Retrieving a List of -Principals}) command. -@end table - -Here is a sample session, using configuration files that enable only -@samp{des-cbc-crc} encryption. (The line beginning with @result{} is a -continuation of the previous line.) - -@smallexample -@group -@b{kadmin:} ktadd host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -@b{kadmin: Entry for principal host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} with - kvno 2, encryption type DES-CBC-CRC added to keytab - WRFILE:/etc/krb5.keytab. -kadmin:} -@end group -@end smallexample - -@smallexample -@group -@b{kadmin:} ktadd -k @value{ROOTDIR}/var/krb5kdc/kadmind.keytab -@result{} kadmin/admin kadmin/changepw -@b{kadmin: Entry for principal kadmin/admin@@@value{PRIMARYREALM} with - kvno 3, encryption type DES-CBC-CRC added to keytab - WRFILE:@value{ROOTDIR}/var/krb5kdc/kadmind.keytab. -kadmin:} -@end group -@end smallexample - -@node Removing Principals from Keytabs, , Adding Principals to Keytabs, Keytabs -@subsection Removing Principals from Keytabs - -To remove a principal from an existing keytab, use the kadmin -@code{ktremove} command. The syntax is: - -@smallexample -@b{ktremove} [@b{-k[eytab]} @i{keytab}] [@b{-q}] @i{principal} [@i{kvno} | @b{all} | @b{old}] -@end smallexample - -The @code{ktremove} command takes the following switches: - -@table @b -@item -k[eytab] @i{keytab} -use @i{keytab} as the keytab file. Otherwise, @code{ktremove} will use -the default keytab file (@code{/etc/krb5.keytab}). - -@item -q -run in quiet mode. This causes @code{ktremove} to display less verbose -information. - -@item @i{principal} -the principal to remove from the keytab. (Required.) - -@item @i{kvno} -remove all entries for the specified principal whose Key Version Numbers -match @i{kvno}. - -@item all -remove all entries for the specified principal - -@item old -remove all entries for the specified principal except those with the -highest kvno. -@end table - -For example: - -@smallexample -@group -@b{kadmin:} ktremove -k @value{ROOTDIR}/var/krb5kdc/kadmind.keytab kadmin/admin -@b{kadmin: Entry for principal kadmin/admin with kvno 3 removed - from keytab WRFILE:@value{ROOTDIR}/var/krb5kdc/kadmind.keytab. -kadmin:} -@end group -@end smallexample - -@node Clock Skew, Getting DNS Information Correct, Keytabs, Application Servers -@section Clock Skew - -In order to prevent intruders from resetting their system clocks in -order to continue to use expired tickets, @value{PRODUCT} is set up to -reject ticket requests from any host whose clock is not within the -specified maximum clock skew of the KDC (as specified in the -@code{kdc.conf} file). Similarly, hosts are configured to reject -responses from any KDC whose clock is not within the specified maximum -clock skew of the host (as specified in the @code{krb5.conf} file). The -default value for maximum clock skew is @value{DefaultClockskew}. - -@value{COMPANY} suggests that you add a line to client machines' -@code{/etc/rc} files to synchronize the machine's clock to your KDC at -boot time. On UNIX hosts, assuming you had a kdc called -@code{@value{KDCSERVER}} in your realm, this would be: - -@smallexample -gettime -s @value{KDCSERVER} -@end smallexample - -If the host is not likely to be rebooted frequently, you may also want -to set up a cron job that adjusts the time on a regular basis. - -@node Getting DNS Information Correct, Configuring Your Firewall to Work With Kerberos V5, Clock Skew, Application Servers -@section Getting DNS Information Correct - -Several aspects of Kerberos rely on name service. In order for Kerberos -to provide its high level of security, it is less forgiving of name -service problems than some other parts of your network. It is important -that your Domain Name System (DNS) entries and your hosts have the -correct information. - -Each host's canonical name must be the fully-qualified host name -(including the domain), and each host's IP address must reverse-resolve -to the canonical name. - -Other than the @code{localhost} entry, make all entries in each -machine's @code{/etc/hosts} file in the following form: - -@smallexample -IP address fully-qualified hostname aliases -@end smallexample - -Here is a sample @code{/etc/hosts} file: - -@smallexample -@group -# this is a comment -127.0.0.1 localhost localhost@@@value{PRIMARYDOMAIN} -@value{RANDOMHOST1IP} @value{RANDOMHOST1}.@value{PRIMARYDOMAIN} trillium wake-robin -@end group -@end smallexample - -Additionally, on Solaris machines, you need to be sure the ``hosts'' -entry in the file @* @code{/etc/nsswitch.conf} includes the source -``dns'' as well as ``file''. - -Finally, each host's keytab file must include a host/key pair for the -host's canonical name. You can list the keys in a keytab file by -issuing the command @code{klist -k}. For example: - -@smallexample -@group -viola# klist -k -Keytab name: /etc/krb5.keytab -KVNO Principal ----- ------------------------------------------------------------ - 1 host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -@end group -@end smallexample - -If you telnet to the host with a fresh credentials cache (ticket file), -and then @code{klist}, the host's service principal should be -@i{host/fully-qualified-hostname@@REALM_NAME}. - -@node Configuring Your Firewall to Work With Kerberos V5, , Getting DNS Information Correct, Application Servers -@section Configuring Your Firewall to Work With @value{PRODUCT} - -If you need off-site users to be able to get Kerberos tickets in your -realm, they must be able to get to your KDC. This requires either that -you have a slave KDC outside your firewall, or you configure your -firewall to allow UDP requests into at least one of your KDCs, on -whichever port the KDC is running. (The default is port -@value{DefaultPort}; other ports may be specified in the KDC's kdc.conf -file.) Similarly, if you need off-site users to be able to change -their passwords in your realm, they must be able to get to your -Kerberos admin server. The default port for the admin server is -@value{DefaultKadmindPort}. - -If your on-site users inside your firewall will need to get to KDCs in -other realms, you will also need to configure your firewall to allow -outgoing TCP and UDP requests to port @value{DefaultPort}. -Additionally, if they will need to get to any Kerberos V4 KDCs, you may -also need to allow TCP and UDP requests to port -@value{DefaultSecondPort}. If your on-site users inside your firewall -will need to get to Kerberos admin servers in other realms, you will -also need to allow outgoing TCP and UDP requests to port -@value{DefaultKadmindPort}. - -If any of your KDCs are outside your firewall, you will need to allow -@code{kprop} requests to get through to the remote KDC. @code{Kprop} -uses the krb5_prop service on port @value{DefaultKrbPropPort} (tcp). - -If you need your off-site users to have access to machines inside your -firewall, you need to allow TCP connections from their off-site hosts on -the appropriate ports for the programs they will be using. The -following lines from @code{/etc/services} show the default port numbers -for the @value{PRODUCT} programs: - -@smallexample -@group -ftp @value{DefaultFTPPort}/tcp # Kerberos ftp and telnet use the -telnet @value{DefaultTelnetPort}/tcp # default ports -kerberos @value{DefaultPort}/udp kdc # Kerberos V5 KDC -kerberos @value{DefaultPort}/tcp kdc # Kerberos V5 KDC -klogin @value{DefaultKloginPort}/tcp # Kerberos authenticated rlogin -kshell @value{DefaultKshellPort}/tcp cmd # and remote shell -kerberos-adm @value{DefaultKadmindPort}/tcp # Kerberos 5 admin/changepw -kerberos-adm @value{DefaultKadmindPort}/udp # Kerberos 5 admin/changepw -krb5_prop @value{DefaultKrbPropPort}/tcp # Kerberos slave propagation -@c kpop 1109/tcp # Pop with Kerberos -eklogin @value{DefaultEkloginPort}/tcp # Kerberos auth. & encrypted rlogin -krb524 @value{DefaultKrb524Port}/tcp # Kerberos 5 to 4 ticket translator -@end group -@end smallexample - -By default, @value{PRODUCT} @code{telnet} and @code{ftp} use the same -ports as the standard @code{telnet} and @code{ftp} programs, so if you -already allow telnet and ftp connections through your firewall, the -@value{PRODUCT} versions will get through as well. If you do not -already allow telnet and ftp connections through your firewall, but need -your users to be able to use @value{PRODUCT} telnet and ftp, you can -either allow ftp and telnet connections on the standard ports, or switch -these programs to non-default port numbers and allow ftp and telnet -connections on those ports to get through. - -@value{PRODUCT} @code{rlogin} uses the @code{klogin} service, which by -default uses port @value{DefaultKloginPort}. Encrypted @value{PRODUCT} -rlogin uses the @code{eklogin} service, which by default uses port -@value{DefaultEkloginPort}. - -@value{PRODUCT} @code{rsh} uses the @code{kshell} service, which by -default uses port @value{DefaultKshellPort}. However, the server must -be able to make a TCP connection from the kshell port to an arbitrary -port on the client, so if your users are to be able to use @code{rsh} -from outside your firewall, the server they connect to must be able to -send outgoing packets to arbitrary port numbers. Similarly, if your -users need to run @code{rsh} from inside your firewall to hosts outside -your firewall, the outside server needs to be able to connect to an -arbitrary port on the machine inside your firewall. Because -@value{PRODUCT} @code{rcp} uses @code{rsh}, the same issues apply. If -you need to use @code{rsh} (or @code{rcp}) through your firewall and -are concerned with the security implications of allowing connections to -arbitrary ports, @value{COMPANY} suggests that you have rules that -specifically name these applications and, if possible, list the allowed -hosts. - -The book @cite{UNIX System Security}, by David Curry, is a good -starting point for learning to configure firewalls. - -@ignore -@c @node Enabling Users to Connect from Off-Site, , Configuring Your Firewall to Work With @value{PRODUCT}, Application Servers -@c @section Enabling Users to Connect from Off-Site - -This will have to wait until the next release. *sigh* -@end ignore - -@node Backups of Secure Hosts, Bug Reporting, Application Servers, Top -@chapter Backups of Secure Hosts - -When you back up a secure host, you should exclude the host's keytab -file from the backup. If someone obtained a copy of the keytab from a -backup, that person could make any host masquerade as the host whose -keytab was compromised. This could be particularly dangerous if the -compromised keytab was from one of your KDCs. If the machine has a disk -crash and the keytab file is lost, it is easy to generate another keytab -file. (@xref{Adding Principals to Keytabs}.) If you are unable to -exclude particular files from backups, you should ensure that the -backups are kept as secure as the host's root password. - -@menu -* Backing Up the Kerberos Database:: -@end menu - -@node Backing Up the Kerberos Database, , Backups of Secure Hosts, Backups of Secure Hosts -@section Backing Up the Kerberos Database - -As with any file, it is possible that your Kerberos database could -become corrupted. If this happens on one of the slave KDCs, you might -never notice, since the next automatic propagation of the database would -install a fresh copy. However, if it happens to the master KDC, the -corrupted database would be propagated to all of the slaves during the -next propagation. For this reason, @value{COMPANY} recommends that you -back up your Kerberos database regularly. Because the master KDC is -continuously dumping the database to a file in order to propagate it to -the slave KDCs, it is a simple matter to have a cron job periodically -copy the dump file to a secure machine elsewhere on your network. (Of -course, it is important to make the host where these backups are stored -as secure as your KDCs, and to encrypt its transmission across your -network.) Then if your database becomes corrupted, you can load the -most recent dump onto the master KDC. (@xref{Restoring a Kerberos -Database from a Dump File}.) - -@node Bug Reporting, Appendix, Backups of Secure Hosts, Top -@chapter Bug Reporting - -@include send-pr.texinfo - -@node Appendix, , Bug Reporting, Top -@appendix Appendix - -@menu -* Errors:: -* kadmin Time Zones:: -@end menu - -@node Errors, kadmin Time Zones, Appendix, Appendix -@appendixsec Kerberos Error Messages - -@menu -* Kerberos V5 Library Error Codes:: -* Kerberos V5 Database Library Error Codes:: -* Kerberos V5 Magic Numbers Error Codes:: -* ASN.1 Error Codes:: -* GSSAPI Error Codes:: -@end menu - -@node Kerberos V5 Library Error Codes, Kerberos V5 Database Library Error Codes, Errors, Errors -@appendixsubsec Kerberos V5 Library Error Codes - -This is the Kerberos v5 library error code table. Protocol error codes -are @* ERROR_TABLE_BASE_krb5 + the protocol error code number; other -error codes start at ERROR_TABLE_BASE_krb5 + 128. - -@c error table numbering starts at 0 -@enumerate 0 -@item -KRB5KDC_ERR_NONE: No error -@item -KRB5KDC_ERR_NAME_EXP: Client's entry in database has expired -@item -KRB5KDC_ERR_SERVICE_EXP: Server's entry in database has expired -@item -KRB5KDC_ERR_BAD_PVNO: Requested protocol version not supported -@item -KRB5KDC_ERR_C_OLD_MAST_KVNO: Client's key is encrypted in an old master -key -@item -KRB5KDC_ERR_S_OLD_MAST_KVNO: Server's key is encrypted in an old master -key -@item -KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: Client not found in Kerberos database -@item -KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: Server not found in Kerberos database -@item -KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE: Principal has multiple entries in -Kerberos database -@item -KRB5KDC_ERR_NULL_KEY: Client or server has a null key -@item -KRB5KDC_ERR_CANNOT_POSTDATE: Ticket is ineligible for postdating -@item -KRB5KDC_ERR_NEVER_VALID: Requested effective lifetime is negative or -too short -@item -KRB5KDC_ERR_POLICY: KDC policy rejects request -@item -KRB5KDC_ERR_BADOPTION: KDC can't fulfill requested option -@item -KRB5KDC_ERR_ETYPE_NOSUPP: KDC has no support for encryption type -@item -KRB5KDC_ERR_SUMTYPE_NOSUPP: KDC has no support for checksum type -@item -KRB5KDC_ERR_PADATA_TYPE_NOSUPP: KDC has no support for padata type -@item -KRB5KDC_ERR_TRTYPE_NOSUPP: KDC has no support for transited type -@item -KRB5KDC_ERR_CLIENT_REVOKED: Clients credentials have been revoked -@item -KRB5KDC_ERR_SERVICE_REVOKED: Credentials for server have been revoked -@item -KRB5KDC_ERR_TGT_REVOKED: TGT has been revoked -@item -KRB5KDC_ERR_CLIENT_NOTYET: Client not yet valid - try again later -@item -KRB5KDC_ERR_SERVICE_NOTYET: Server not yet valid - try again later -@item -KRB5KDC_ERR_KEY_EXP: Password has expired -@item -KRB5KDC_ERR_PREAUTH_FAILED: Preauthentication failed -@item -KRB5KDC_ERR_PREAUTH_REQUIRED: Additional pre-auth@-en@-ti@-ca@-tion required -@item -KRB5KDC_ERR_SERVER_NOMATCH: Requested server and ticket don't match -@item -KRB5PLACEHOLD_27: KRB5 error code 27 -@item -KRB5PLACEHOLD_28: KRB5 error code 28 -@item -KRB5PLACEHOLD_29: KRB5 error code 29 -@item -KRB5PLACEHOLD_30: KRB5 error code 30 -@item -KRB5KRB_AP_ERR_BAD_INTEGRITY: Decrypt integrity check failed -@item -KRB5KRB_AP_ERR_TKT_EXPIRED: Ticket expired -@item -KRB5KRB_AP_ERR_TKT_NYV: Ticket not yet valid -@item -KRB5KRB_AP_ERR_REPEAT: Request is a replay -@item -KRB5KRB_AP_ERR_NOT_US: The ticket isn't for us -@item -KRB5KRB_AP_ERR_BADMATCH: Ticket/authenticator don't match -@item -KRB5KRB_AP_ERR_SKEW: Clock skew too great -@item -KRB5KRB_AP_ERR_BADADDR: Incorrect net address -@item -KRB5KRB_AP_ERR_BADVERSION: Protocol version mismatch -@item -KRB5KRB_AP_ERR_MSG_TYPE: Invalid message type -@item -KRB5KRB_AP_ERR_MODIFIED: Message stream modified -@item -KRB5KRB_AP_ERR_BADORDER: Message out of order -@item -KRB5KRB_AP_ERR_ILL_CR_TKT: Illegal cross-realm ticket -@item -KRB5KRB_AP_ERR_BADKEYVER: Key version is not available -@item -KRB5KRB_AP_ERR_NOKEY: Service key not available -@item -KRB5KRB_AP_ERR_MUT_FAIL: Mutual authentication failed -@item -KRB5KRB_AP_ERR_BADDIRECTION: Incorrect message direction -@item -KRB5KRB_AP_ERR_METHOD: Alternative authentication method required -@item -KRB5KRB_AP_ERR_BADSEQ: Incorrect sequence number in message -@item -KRB5KRB_AP_ERR_INAPP_CKSUM: Inappropriate type of checksum in message -@item -KRB5KRB_AP_PATH_NOT_ACCEPTED: Policy rejects transited path -@item -KRB5KRB_ERR_RESPONSE_TOO_BIG: Response too big for UDP, retry with TCP -@item -KRB5PLACEHOLD_53: KRB5 error code 53 -@item -KRB5PLACEHOLD_54: KRB5 error code 54 -@item -KRB5PLACEHOLD_55: KRB5 error code 55 -@item -KRB5PLACEHOLD_56: KRB5 error code 56 -@item -KRB5PLACEHOLD_57: KRB5 error code 57 -@item -KRB5PLACEHOLD_58: KRB5 error code 58 -@item -KRB5PLACEHOLD_59: KRB5 error code 59 -@item -KRB5KRB_ERR_GENERIC: Generic error (see e-text) -@item -KRB5KRB_ERR_FIELD_TOOLONG: Field is too long for this implementation -@item -KRB5PLACEHOLD_62: KRB5 error code 62 -@item -KRB5PLACEHOLD_63: KRB5 error code 63 -@item -KRB5PLACEHOLD_64: KRB5 error code 64 -@item -KRB5PLACEHOLD_65: KRB5 error code 65 -@item -KRB5PLACEHOLD_66: KRB5 error code 66 -@item -KRB5PLACEHOLD_67: KRB5 error code 67 -@item -KRB5PLACEHOLD_68: KRB5 error code 68 -@item -KRB5PLACEHOLD_69: KRB5 error code 69 -@item -KRB5PLACEHOLD_70: KRB5 error code 70 -@item -KRB5PLACEHOLD_71: KRB5 error code 71 -@item -KRB5PLACEHOLD_72: KRB5 error code 72 -@item -KRB5PLACEHOLD_73: KRB5 error code 73 -@item -KRB5PLACEHOLD_74: KRB5 error code 74 -@item -KRB5PLACEHOLD_75: KRB5 error code 75 -@item -KRB5PLACEHOLD_76: KRB5 error code 76 -@item -KRB5PLACEHOLD_77: KRB5 error code 77 -@item -KRB5PLACEHOLD_78: KRB5 error code 78 -@item -KRB5PLACEHOLD_79: KRB5 error code 79 -@item -KRB5PLACEHOLD_80: KRB5 error code 80 -@item -KRB5PLACEHOLD_81: KRB5 error code 81 -@item -KRB5PLACEHOLD_82: KRB5 error code 82 -@item -KRB5PLACEHOLD_83: KRB5 error code 83 -@item -KRB5PLACEHOLD_84: KRB5 error code 84 -@item -KRB5PLACEHOLD_85: KRB5 error code 85 -@item -KRB5PLACEHOLD_86: KRB5 error code 86 -@item -KRB5PLACEHOLD_87: KRB5 error code 87 -@item -KRB5PLACEHOLD_88: KRB5 error code 88 -@item -KRB5PLACEHOLD_89: KRB5 error code 89 -@item -KRB5PLACEHOLD_90: KRB5 error code 90 -@item -KRB5PLACEHOLD_91: KRB5 error code 91 -@item -KRB5PLACEHOLD_92: KRB5 error code 92 -@item -KRB5PLACEHOLD_93: KRB5 error code 93 -@item -KRB5PLACEHOLD_94: KRB5 error code 94 -@item -KRB5PLACEHOLD_95: KRB5 error code 95 -@item -KRB5PLACEHOLD_96: KRB5 error code 96 -@item -KRB5PLACEHOLD_97: KRB5 error code 97 -@item -KRB5PLACEHOLD_98: KRB5 error code 98 -@item -KRB5PLACEHOLD_99: KRB5 error code 99 -@item -KRB5PLACEHOLD_100: KRB5 error code 100 -@item -KRB5PLACEHOLD_101: KRB5 error code 101 -@item -KRB5PLACEHOLD_102: KRB5 error code 102 -@item -KRB5PLACEHOLD_103: KRB5 error code 103 -@item -KRB5PLACEHOLD_104: KRB5 error code 104 -@item -KRB5PLACEHOLD_105: KRB5 error code 105 -@item -KRB5PLACEHOLD_106: KRB5 error code 106 -@item -KRB5PLACEHOLD_107: KRB5 error code 107 -@item -KRB5PLACEHOLD_108: KRB5 error code 108 -@item -KRB5PLACEHOLD_109: KRB5 error code 109 -@item -KRB5PLACEHOLD_110: KRB5 error code 110 -@item -KRB5PLACEHOLD_111: KRB5 error code 111 -@item -KRB5PLACEHOLD_112: KRB5 error code 112 -@item -KRB5PLACEHOLD_113: KRB5 error code 113 -@item -KRB5PLACEHOLD_114: KRB5 error code 114 -@item -KRB5PLACEHOLD_115: KRB5 error code 115 -@item -KRB5PLACEHOLD_116: KRB5 error code 116 -@item -KRB5PLACEHOLD_117: KRB5 error code 117 -@item -KRB5PLACEHOLD_118: KRB5 error code 118 -@item -KRB5PLACEHOLD_119: KRB5 error code 119 -@item -KRB5PLACEHOLD_120: KRB5 error code 120 -@item -KRB5PLACEHOLD_121: KRB5 error code 121 -@item -KRB5PLACEHOLD_122: KRB5 error code 122 -@item -KRB5PLACEHOLD_123: KRB5 error code 123 -@item -KRB5PLACEHOLD_124: KRB5 error code 124 -@item -KRB5PLACEHOLD_125: KRB5 error code 125 -@item -KRB5PLACEHOLD_126: KRB5 error code 126 -@item -KRB5PLACEHOLD_127: KRB5 error code 127 -@item -KRB5_ERR_RCSID: (RCS Id string for the krb5 error table) -@item -KRB5_LIBOS_BADLOCKFLAG: Invalid flag for file lock mode -@item -KRB5_LIBOS_CANTREADPWD: Cannot read password -@item -KRB5_LIBOS_BADPWDMATCH: Password mismatch -@item -KRB5_LIBOS_PWDINTR: Password read interrupted -@item -KRB5_PARSE_ILLCHAR: Illegal character in component name -@item -KRB5_PARSE_MALFORMED: Malformed representation of principal -@item -KRB5_CONFIG_CANTOPEN: Can't open/find Kerberos configuration file -@item -KRB5_CONFIG_BADFORMAT: Improper format of Kerberos configuration file -@item -KRB5_CONFIG_NOTENUFSPACE: Insufficient space to return complete -information -@item -KRB5_BADMSGTYPE: Invalid message type specified for encoding -@item -KRB5_CC_BADNAME: Credential cache name malformed -@item -KRB5_CC_UNKNOWN_TYPE: Unknown credential cache type -@item -KRB5_CC_NOTFOUND: Matching credential not found -@item -KRB5_CC_END: End of credential cache reached -@item -KRB5_NO_TKT_SUPPLIED: Request did not supply a ticket -@item -KRB5KRB_AP_WRONG_PRINC: Wrong principal in request -@item -KRB5KRB_AP_ERR_TKT_INVALID: Ticket has invalid flag set -@item -KRB5_PRINC_NOMATCH: Requested principal and ticket don't match -@item -KRB5_KDCREP_MODIFIED: KDC reply did not match expectations -@item -KRB5_KDCREP_SKEW: Clock skew too great in KDC reply -@item -KRB5_IN_TKT_REALM_MISMATCH: Client/server realm mismatch in initial -ticket request -@item -KRB5_PROG_ETYPE_NOSUPP: Program lacks support for encryption type -@item -KRB5_PROG_KEYTYPE_NOSUPP: Program lacks support for key type -@item -KRB5_WRONG_ETYPE: Requested encryption type not used in message -@item -KRB5_PROG_SUMTYPE_NOSUPP: Program lacks support for checksum type -@item -KRB5_REALM_UNKNOWN: Cannot find KDC for requested realm -@item -KRB5_SERVICE_UNKNOWN: Kerberos service unknown -@item -KRB5_KDC_UNREACH: Cannot contact any KDC for requested realm -@item -KRB5_NO_LOCALNAME: No local name found for principal name -@item -KRB5_MUTUAL_FAILED: Mutual authentication failed -@item -KRB5_RC_TYPE_EXISTS: Replay cache type is already registered -@item -KRB5_RC_MALLOC: No more memory to allocate (in replay cache code) -@item -KRB5_RC_TYPE_NOTFOUND: Replay cache type is unknown -@item -KRB5_RC_UNKNOWN: Generic unknown RC error -@item -KRB5_RC_REPLAY: Message is a replay -@item -KRB5_RC_IO: Replay I/O operation failed XXX -@item -KRB5_RC_NOIO: Replay cache type does not support non-volatile storage -@item -KRB5_RC_PARSE: Replay cache name parse/format error -@item -KRB5_RC_IO_EOF: End-of-file on replay cache I/O -@item -KRB5_RC_IO_MALLOC: No more memory to allocate (in replay cache I/O -code) -@item -KRB5_RC_IO_PERM: Permission denied in replay cache code -@item -KRB5_RC_IO_IO: I/O error in replay cache i/o code -@item -KRB5_RC_IO_UNKNOWN: Generic unknown RC/IO error -@item -KRB5_RC_IO_SPACE: Insufficient system space to store replay information -@item -KRB5_TRANS_CANTOPEN: Can't open/find realm translation file -@item -KRB5_TRANS_BADFORMAT: Improper format of realm translation file -@item -KRB5_LNAME_CANTOPEN: Can't open/find lname translation database -@item -KRB5_LNAME_NOTRANS: No translation available for requested principal -@item -KRB5_LNAME_BADFORMAT: Improper format of translation database entry -@item -KRB5_CRYPTO_INTERNAL: Cryptosystem internal error -@item -KRB5_KT_BADNAME: Key table name malformed -@item -KRB5_KT_UNKNOWN_TYPE: Unknown Key table type -@item -KRB5_KT_NOTFOUND: Key table entry not found -@item -KRB5_KT_END: End of key table reached -@item -KRB5_KT_NOWRITE: Cannot write to specified key table -@item -KRB5_KT_IOERR: Error writing to key table -@item -KRB5_NO_TKT_IN_RLM: Cannot find ticket for requested realm -@item -KRB5DES_BAD_KEYPAR: DES key has bad parity -@item -KRB5DES_WEAK_KEY: DES key is a weak key -@item -KRB5_BAD_ENCTYPE: Bad encryption type -@item -KRB5_BAD_KEYSIZE: Key size is incompatible with encryption type -@item -KRB5_BAD_MSIZE: Message size is incompatible with encryption type -@item -KRB5_CC_TYPE_EXISTS: Credentials cache type is already registered. -@item -KRB5_KT_TYPE_EXISTS: Key table type is already registered. -@item -KRB5_CC_IO: Credentials cache I/O operation failed XXX -@item -KRB5_FCC_PERM: Credentials cache file permissions incorrect -@item -KRB5_FCC_NOFILE: No credentials cache found -@item -KRB5_FCC_INTERNAL: Internal credentials cache error -@item -KRB5_CC_WRITE: Error writing to credentials cache -@item -KRB5_CC_NOMEM: No more memory to allocate (in credentials cache code) -@item -KRB5_CC_FORMAT: Bad format in credentials cache -@item -KRB5_INVALID_FLAGS: Invalid KDC option combination (library internal -error) [for dual tgt library calls] -@item -KRB5_NO_2ND_TKT: Request missing second ticket [for dual tgt library -calls] -@item -KRB5_NOCREDS_SUPPLIED: No credentials supplied to library routine -@item -KRB5_SENDAUTH_BADAUTHVERS: Bad sendauth version was sent -@item -KRB5_SENDAUTH_BADAPPLVERS: Bad application version was sent (via -sendauth) -@item -KRB5_SENDAUTH_BADRESPONSE: Bad response (during sendauth exchange) -@item -KRB5_SENDAUTH_REJECTED: Server rejected authentication (during sendauth -exchange) -@item -KRB5_PREAUTH_BAD_TYPE: Unsupported preauthentication type -@item -KRB5_PREAUTH_NO_KEY: Required preauthentication key not supplied -@item -KRB5_PREAUTH_FAILED: Generic preauthentication failure -@item -KRB5_RCACHE_BADVNO: Unsupported replay cache format version number -@item -KRB5_CCACHE_BADVNO: Unsupported credentials cache format version number -@item -KRB5_KEYTAB_BADVNO: Unsupported key table format version number -@item -KRB5_PROG_ATYPE_NOSUPP: Program lacks support for address type -@item -KRB5_RC_REQUIRED: Message replay detection requires rcache parameter -@item -KRB5_ERR_BAD_HOSTNAME: Hostname cannot be canonicalized -@item -KRB5_ERR_HOST_REALM_UNKNOWN: Cannot determine realm for host -@item -KRB5_SNAME_UNSUPP_NAMETYPE: Conversion to service principal undefined -for name type -@item -KRB5KRB_AP_ERR_V4_REPLY: Initial Ticket response appears to be Version -4 error -@item -KRB5_REALM_CANT_RESOLVE: Cannot resolve KDC for requested realm -@item -KRB5_TKT_NOT_FORWARDABLE: Requesting ticket can't get forwardable -tickets -@item -KRB5_FWD_BAD_PRINCIPAL: Bad principal name while trying to forward -credentials -@item -KRB5_GET_IN_TKT_LOOP: Looping detected inside krb5_get_in_tkt -@item -KRB5_CONFIG_NODEFREALM: Configuration file does not specify default realm -@item -KRB5_SAM_UNSUPPORTED: Bad SAM flags in obtain_sam_padata -@item -KRB5_KT_NAME_TOOLONG: Keytab name too long -@item -KRB5_KT_KVNONOTFOUND: Key version number for principal in key table is incorrect -@item -KRB5_APPL_EXPIRED: This application has expired -@item -KRB5_LIB_EXPIRED: This Krb5 library has expired -@item -KRB5_CHPW_PWDNULL: New password cannot be zero length -@item -KRB5_CHPW_FAIL: Password change failed -@item -KRB5_KT_FORMAT: Bad format in keytab -@item -KRB5_NOPERM_ETYPE: Encryption type not permitted -@item -KRB5_CONFIG_ETYPE_NOSUPP: No supported encryption types (config file error?) -@item -KRB5_OBSOLETE_FN: Program called an obsolete, deleted function -@item -KRB5_EAI_FAIL: unknown getaddrinfo failure -@item -KRB5_EAI_NODATA: no data available for host/domain name -@item -KRB5_EAI_NONAME: host/domain name not found -@item -KRB5_EAI_SERVICE: service name unknown -@item -KRB5_ERR_NUMERIC_REALM: Cannot determine realm for numeric host address -@end enumerate - -@node Kerberos V5 Database Library Error Codes, Kerberos V5 Magic Numbers Error Codes, Kerberos V5 Library Error Codes, Errors -@appendixsubsec Kerberos V5 Database Library Error Codes - -This is the Kerberos v5 database library error code table. - -@c error table numbering starts at 0 -@enumerate 0 -@item -KRB5_KDB_RCSID: (RCS Id string for the kdb error table) -@item -KRB5_KDB_INUSE: Entry already exists in database -@item -KRB5_KDB_UK_SERROR: Database store error -@item -KRB5_KDB_UK_RERROR: Database read error -@item -KRB5_KDB_UNAUTH: Insufficient access to perform requested operation -@item -KRB5_KDB_NOENTRY: No such entry in the database -@item -KRB5_KDB_ILL_WILDCARD: Illegal use of wildcard -@item -KRB5_KDB_DB_INUSE: Database is locked or in use--try again later -@item -KRB5_KDB_DB_CHANGED: Database was modified during read -@item -KRB5_KDB_TRUNCATED_RECORD: Database record is incomplete or corrupted -@item -KRB5_KDB_RECURSIVELOCK: Attempt to lock database twice -@item -KRB5_KDB_NOTLOCKED: Attempt to unlock database when not locked -@item -KRB5_KDB_BADLOCKMODE: Invalid kdb lock mode -@item -KRB5_KDB_DBNOTINITED: Database has not been initialized -@item -KRB5_KDB_DBINITED: Database has already been initialized -@item -KRB5_KDB_ILLDIRECTION: Bad direction for converting keys -@item -KRB5_KDB_NOMASTERKEY: Cannot find master key record in database -@item -KRB5_KDB_BADMASTERKEY: Master key does not match database -@item -KRB5_KDB_INVALIDKEYSIZE: Key size in database is invalid -@item -KRB5_KDB_CANTREAD_STORED: Cannot find/read stored master key -@item -KRB5_KDB_BADSTORED_MKEY: Stored master key is corrupted -@item -KRB5_KDB_CANTLOCK_DB: Insufficient access to lock database -@item -KRB5_KDB_DB_CORRUPT: Database format error -@item -KRB5_KDB_BAD_VERSION: Unsupported version in database entry -@item -KRB5_KDB_BAD_SALTTYPE: Unsupported salt type -@item -KRB5_KDB_BAD_ENCTYPE: Unsupported encryption type -@item -KRB5_KDB_BAD_CREATEFLAGS: Bad database creation flags -@item -KRB5_KDB_NO_PERMITTED_KEY: No matching key in entry having a permitted enc type -@item -KRB5_KDB_NO_MATCHING_KEY: No matching key in entry -@end enumerate - -@node Kerberos V5 Magic Numbers Error Codes, ASN.1 Error Codes, Kerberos V5 Database Library Error Codes, Errors -@appendixsubsec Kerberos V5 Magic Numbers Error Codes - -This is the Kerberos v5 magic numbers error code table. - -@c error table numbering starts at 0 -@enumerate 0 -@item -KV5M_NONE: Kerberos V5 magic number table -@item -KV5M_PRINCIPAL: Bad magic number for krb5_principal structure -@item -KV5M_DATA: Bad magic number for krb5_data structure -@item -KV5M_KEYBLOCK: Bad magic number for krb5_keyblock structure -@item -KV5M_CHECKSUM: Bad magic number for krb5_checksum structure -@item -KV5M_ENCRYPT_BLOCK: Bad magic number for krb5_encrypt_block structure -@item -KV5M_ENC_DATA: Bad magic number for krb5_enc_data structure -@item -KV5M_CRYPTOSYSTEM_ENTRY: Bad magic number for krb5_cryp@-to@-sys@-tem_entry -structure -@item -KV5M_CS_TABLE_ENTRY: Bad magic number for krb5_cs_table_entry structure -@item -KV5M_CHECKSUM_ENTRY: Bad magic number for krb5_check@-sum_en@-try structure -@item -KV5M_AUTHDATA: Bad magic number for krb5_authdata structure -@item -KV5M_TRANSITED: Bad magic number for krb5_transited structure -@item -KV5M_ENC_TKT_PART: Bad magic number for krb5_enc_tkt_part structure -@item -KV5M_TICKET: Bad magic number for krb5_ticket structure -@item -KV5M_AUTHENTICATOR: Bad magic number for krb5_authenticator structure -@item -KV5M_TKT_AUTHENT: Bad magic number for krb5_tkt_authent structure -@item -KV5M_CREDS: Bad magic number for krb5_creds structure -@item -KV5M_LAST_REQ_ENTRY: Bad magic number for krb5_last_req_entry structure -@item -KV5M_PA_DATA: Bad magic number for krb5_pa_data structure -@item -KV5M_KDC_REQ: Bad magic number for krb5_kdc_req structure -@item -KV5M_ENC_KDC_REP_PART: Bad magic number for @* -krb5_enc_kdc_rep_part structure -@item -KV5M_KDC_REP: Bad magic number for krb5_kdc_rep structure -@item -KV5M_ERROR: Bad magic number for krb5_error structure -@item -KV5M_AP_REQ: Bad magic number for krb5_ap_req structure -@item -KV5M_AP_REP: Bad magic number for krb5_ap_rep structure -@item -KV5M_AP_REP_ENC_PART: Bad magic number for @* -krb5_ap_rep_enc_part structure -@item -KV5M_RESPONSE: Bad magic number for krb5_response structure -@item -KV5M_SAFE: Bad magic number for krb5_safe structure -@item -KV5M_PRIV: Bad magic number for krb5_priv structure -@item -KV5M_PRIV_ENC_PART: Bad magic number for krb5_priv_enc_part structure -@item -KV5M_CRED: Bad magic number for krb5_cred structure -@item -KV5M_CRED_INFO: Bad magic number for krb5_cred_info structure -@item -KV5M_CRED_ENC_PART: Bad magic number for krb5_cred_enc_part structure -@item -KV5M_PWD_DATA: Bad magic number for krb5_pwd_data structure -@item -KV5M_ADDRESS: Bad magic number for krb5_address structure -@item -KV5M_KEYTAB_ENTRY: Bad magic number for krb5_keytab_entry structure -@item -KV5M_CONTEXT: Bad magic number for krb5_context structure -@item -KV5M_OS_CONTEXT: Bad magic number for krb5_os_context structure -@item -KV5M_ALT_METHOD: Bad magic number for krb5_alt_method structure -@item -KV5M_ETYPE_INFO_ENTRY: Bad magic number for @* -krb5_etype_info_entry structure -@item -KV5M_DB_CONTEXT: Bad magic number for krb5_db_context structure -@item -KV5M_AUTH_CONTEXT: Bad magic number for krb5_auth_context structure -@item -KV5M_KEYTAB: Bad magic number for krb5_keytab structure -@item -KV5M_RCACHE: Bad magic number for krb5_rcache structure -@item -KV5M_CCACHE: Bad magic number for krb5_ccache structure -@item -KV5M_PREAUTH_OPS: Bad magic number for krb5_preauth_ops -@item -KV5M_SAM_CHALLENGE: Bad magic number for krb5_sam_challenge -@item -KV5M_SAM_KEY: Bad magic number for krb5_sam_key -@item -KV5M_ENC_SAM_RESPONSE_ENC: Bad magic number for @* -krb5_enc_sam_response_enc -@item -KV5M_SAM_RESPONSE: Bad magic number for krb5_sam_response -@item -KV5M_PREDICTED_SAM_RESPONSE: Bad magic number for -krb5_predicted_sam_response -@item -KV5M_PASSWD_PHRASE_ELEMENT: Bad magic number for passwd_phrase_element -@item -KV5M_GSS_OID: Bad magic number for GSSAPI OID -@item -KV5M_GSS_QUEUE: Bad magic number for GSSAPI QUEUE -@end enumerate - -@node ASN.1 Error Codes, GSSAPI Error Codes, Kerberos V5 Magic Numbers Error Codes, Errors -@appendixsubsec ASN.1 Error Codes - -@c error table numbering starts at 0 -@enumerate 0 -@item -ASN1_BAD_TIMEFORMAT: ASN.1 failed call to system time library -@item -ASN1_MISSING_FIELD: ASN.1 structure is missing a required field -@item -ASN1_MISPLACED_FIELD: ASN.1 unexpected field number -@item -ASN1_TYPE_MISMATCH: ASN.1 type numbers are inconsistent -@item -ASN1_OVERFLOW: ASN.1 value too large -@item -ASN1_OVERRUN: ASN.1 encoding ended unexpectedly -@item -ASN1_BAD_ID: ASN.1 identifier doesn't match expected value -@item -ASN1_BAD_LENGTH: ASN.1 length doesn't match expected value -@item -ASN1_BAD_FORMAT: ASN.1 badly-formatted encoding -@item -ASN1_PARSE_ERROR: ASN.1 parse error -@item -ASN1_BAD_GMTIME: ASN.1 bad return from gmtime -@item -ASN1_MISMATCH_INDEF: ASN.1 non-constructed indefinite encoding -@item -ASN1_MISSING_EOC: ASN.1 missing expected EOC -@end enumerate - -@node GSSAPI Error Codes, , ASN.1 Error Codes, Errors -@appendixsubsec GSSAPI Error Codes - -Generic GSSAPI Errors: - -@c error table numbering starts at 0 -@enumerate 0 -@item -G_BAD_SERVICE_NAME: No @ in SERVICE-NAME name string -@item -G_BAD_STRING_UID: STRING-UID-NAME contains nondigits -@item -G_NOUSER: UID does not resolve to username -@item -G_VALIDATE_FAILED: Validation error -@item -G_BUFFER_ALLOC: Couldn't allocate gss_buffer_t data -@item -G_BAD_MSG_CTX: Message context invalid -@item -G_WRONG_SIZE: Buffer is the wrong size -@item -G_BAD_USAGE: Credential usage type is unknown -@item -G_UNKNOWN_QOP: Unknown quality of protection specified -@item -G_BAD_HOSTNAME: Hostname in SERVICE-NAME string could not be -canonicalized -@item -G_WRONG_MECH: Mechanism is incorrect -@item -G_BAD_TOK_HEADER: Token header is malformed or corrupt -@item -G_BAD_DIRECTION: Packet was replayed in wrong direction -@item -G_TOK_TRUNC: Token is missing data -@item -G_REFLECT: Token was reflected -@item -G_WRONG_TOKID: Received token ID does not match expected token ID -@end enumerate - -Kerberos 5 GSSAPI Errors: - -@c error table numbering starts at 0 -@enumerate 0 -@item -KG_CCACHE_NOMATCH: Principal in credential cache does not match desired -name -@item -KG_KEYTAB_NOMATCH: No principal in keytab matches desired name -@item -KG_TGT_MISSING: Credential cache has no TGT -@item -KG_NO_SUBKEY: Authenticator has no subkey -@item -KG_CONTEXT_ESTABLISHED: Context is already fully established -@item -KG_BAD_SIGN_TYPE: Unknown signature type in token -@item -KG_BAD_LENGTH: Invalid field length in token -@item -KG_CTX_INCOMPLETE: Attempt to use incomplete security context -@item -KG_CONTEXT: Bad magic number for krb5_gss_ctx_id_t -@item -KG_CRED: Bad magic number for krb5_gss_cred_id_t -@item -KG_ENC_DESC: Bad magic number for krb5_gss_enc_desc -@item -KG_BAD_SEQ: Sequence number in token is corrupt -@item -KG_EMPTY_CCACHE: Credential cache is empty -@item -KG_NO_CTYPES: Acceptor and Initiator share no checksum types -@end enumerate - -@node kadmin Time Zones, , Errors, Appendix -@appendixsec kadmin Time Zones - -This is a complete listing of the time zones recognized by the -@code{kadmin} command. - -@table @b -@itemx gmt -Greenwich Mean Time -@itemx ut, utc -Universal Time (Coordinated). -@itemx wet -Western European Time. (Same as GMT.) -@itemx bst -British Summer Time. (1 hour ahead of GMT.) -@itemx wat -West Africa Time. (1 hour behind GMT.) -@itemx at -Azores Time. (2 hours behind GMT.) -@itemx bst -Brazil Standard Time. (3 hours behind GMT.) Note that the abbreviation -BST also stands for British Summer Time. -@itemx gst -Greenland Standard Time. (3 hours behind GMT.) Note that the -abbreviation GST also stands for Guam Standard Time. -@itemx nft -Newfoundland Time. (3.5 hours behind GMT.) -@itemx nst -Newfoundland Standard Time. (3.5 hours behind GMT.) -@itemx ndt -Newfoundland Daylight Time. (2.5 hours behind GMT.) -@itemx ast -Atlantic Standard Time. (4 hours behind GMT.) -@itemx adt -Atlantic Daylight Time. (3 hours behind GMT.) -@itemx est -Eastern Standard Time. (5 hours behind GMT.) -@itemx edt -Eastern Daylight Time. (4 hours behind GMT.) -@itemx cst -Central Standard Time. (6 hours behind GMT.) -@itemx cdt -Central Daylight Time. (5 hours behind GMT.) -@itemx mst -Mountain Standard Time. (7 hours behind GMT.) -@itemx mdt -Mountain Daylight Time. (6 hours behind GMT.) -@itemx pst -Pacific Standard Time. (8 hours behind GMT.) -@itemx pdt -Pacific Daylight Time. (7 hours behind GMT.) -@itemx yst -Yukon Standard Time. (9 hours behind GMT.) -@itemx ydt -Yukon Daylight Time. (8 hours behind GMT.) -@itemx hst -Hawaii Standard Time. (10 hours behind GMT.) -@itemx hdt -Hawaii Daylight Time. (9 hours behind GMT.) -@itemx cat -Central Alaska Time. (10 hours behind GMT.) -@itemx ahst -Alaska-Hawaii Standard Time. (10 hours behind GMT.) -@itemx nt -Nome Time. (11 hours behind GMT.) -@itemx idlw -International Date Line West Time. (12 hours behind GMT.) -@itemx cet -Central European Time. (1 hour ahead of GMT.) -@itemx met -Middle European Time. (1 hour ahead of GMT.) -@itemx mewt -Middle European Winter Time. (1 hour ahead of GMT.) -@itemx mest -Middle European Summer Time. (2 hours ahead of GMT.) -@itemx swt -Swedish Winter Time. (1 hour ahead of GMT.) -@itemx sst -Swedish Summer Time. (1 hours ahead of GMT.) -@itemx fwt -French Winter Time. (1 hour ahead of GMT.) -@itemx fst -French Summer Time. (2 hours ahead of GMT.) -@itemx eet -Eastern Europe Time; Russia Zone 1. (2 hours ahead of GMT.) -@itemx bt -Baghdad Time; Russia Zone 2. (3 hours ahead of GMT.) -@itemx it -Iran Time. (3.5 hours ahead of GMT.) -@itemx zp4 -Russia Zone 3. (4 hours ahead of GMT.) -@itemx zp5 -Russia Zone 4. (5 hours ahead of GMT.) -@itemx ist -Indian Standard Time. (5.5 hours ahead of GMT.) -@itemx zp6 -Russia Zone 5. (6 hours ahead of GMT.) -@itemx nst -North Sumatra Time. (6.5 hours ahead of GMT.) Note that the -abbreviation NST is also used for Newfoundland Stanard Time. -@itemx sst -South Sumatra Time; Russia Zone 6. (7 hours ahead of GMT.) Note that -SST is also Swedish Summer Time. -@itemx wast -West Australian Standard Time. (7 hours ahead of GMT.) -@itemx wadt -West Australian Daylight Time. (8 hours ahead of GMT.) -@itemx jt -Java Time. (7.5 hours ahead of GMT.) -@itemx cct -China Coast Time; Russia Zone 7. (8 hours ahead of GMT.) -@itemx jst -Japan Standard time; Russia Zone 8. (9 hours ahead of GMT.) -@itemx kst -Korean Standard Time. (9 hours ahead of GMT.) -@itemx cast -Central Australian Standard Time. (9.5 hours ahead of GMT.) -@itemx cadt -Central Australian Daylight Time. (10.5 hours ahead of GMT.) -@itemx east -Eastern Australian Standard Time. (10 hours ahead of GMT.) -@itemx eadt -Eastern Australian Daylight Time. (11 hours ahead of GMT.) -@itemx gst -Guam Standard Time; Russia Zone 9. (10 hours ahead of GMT.) -@itemx kdt -Korean Daylight Time. (10 hours ahead of GMT.) -@itemx nzt -New Zealand Time. (12 hours ahead of GMT.) -@itemx nzst -New Zealand Standard Time. (12 hours ahead of GMT.) -@itemx nzdt -New Zealand Daylight Time. (13 hours ahead of GMT.) -@itemx idle -International Date Line East. (12 hours ahead of GMT.) -@end table - -@contents -@bye - diff --git a/doc/api/.Sanitize b/doc/api/.Sanitize deleted file mode 100644 index e778459b9..000000000 --- a/doc/api/.Sanitize +++ /dev/null @@ -1,48 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -ChangeLog -Makefile -ccache.tex -changebar.sty -errors.tex -fancyheadings.sty -fixunder.sty -free.tex -functions.sty -intro.tex -keytab.tex -krb5.tex -libdes.tex -libos.tex -library.tex -rcache.tex -tables.tex - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/doc/api/.cvsignore b/doc/api/.cvsignore deleted file mode 100644 index 8625a6f31..000000000 --- a/doc/api/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -library.ps -library.ind -library.log -library.idx -library.aux -library.toc -lib1.stamp -library.dvi -libdes.dvi -libdes.ps diff --git a/doc/api/ChangeLog b/doc/api/ChangeLog deleted file mode 100644 index 3728895f4..000000000 --- a/doc/api/ChangeLog +++ /dev/null @@ -1,184 +0,0 @@ -2002-01-15 Sam Hartman - - * krb5.tex (subsubsection{Principal access functions}): krb5_princ_realm returns a pointer. - - -2001-11-06 Ken Raeburn - - * Makefile (clean): Delete *.ilg. - -2001-06-22 Ken Raeburn - - * ccache.tex (krb5_cc_default): Fix "equivalent to" example code. - Patch from Michael Gerdts . - -2001-06-19 Mitchell Berger - - * krb5.tex: Silly typo fixed. - -Wed Oct 18 09:55:25 2000 Ezra Peisach - - * library.tex: Update to latex2e. Include krb5idx.sty. - - * Makefile (lib1.stamp): Use makeindex to generate index instead - of an antiquated texindex program - which is not the same texindex - as in the texinfo package. - - * krb5idx.sty: Style for generating indexes. Provides definitions - for use with krb5.ist. - - * krb5.ist: makeindex macros. Based on gind.ist. - -2000-10-17 Ezra Peisach - - * krb5.tex: krb5_unparse_name_ext(), krb5_build_principal(), - krb5_build_principal_va, krb5_build_printicpal_ext() use unsigned - ints. - - * libos.tex: krb5_read_password() takes an unsigned int * as the - final argument. - - * keytab.tex: krb5_kt_get_name() takes an unsigned int. - -2000-10-16 Ezra Peisach - - * krb5.tex (krb5_init_context): Parameter is output only. - -2000-06-22 Ken Raeburn - - * Makefile (lib1.stamp): Use texindex instead of index. - -1999-08-30 Ken Raeburn - - * libdes.tex: Don't use ncs style; it's availability is dependent - on the local TeX installation. - -1999-01-20 Theodore Ts'o - - * krb5.tex (krb5_mk_safe): Fix reference to a non-existent flag. - (KRB5_AUTH_CONTEXT_DO_TIME_NOTIME should have been - KRB5_AUTH_CONTEXT_DO_TIME). [krb5-doc/528] - -Thu Jun 6 15:50:39 1996 Theodore Y. Ts'o - - * krb5.tex: Update function prototype for krb5_encrypt_tkt_part - -Mon Sep 4 21:13:36 1995 Ezra Peisach - - * libos.tex: Update krb5_lock_file and krb5_unlock_file no longer - take FILE *. - -Sun Jun 11 09:17:10 1995 Ezra Peisach - - * krb5.tex: Update krb5_auth_context usage. - -Sat May 13 17:40:32 1995 Ezra Peisach - - * ccache.tex: Add krb5_get_notification_message. - - * krb5.tex: Add krb5_get_cred_via_tkt. - -Sun May 7 13:56:43 1995 Ezra Peisach - - * krb5.tex (subsubsection{The krb5_auth_context}): Some function - names were misformed. - - * errors.tex (subsection{error_table kv5m}): Reformatting nits. - - * tables.tex: Formatting fixes. - -Thu May 4 14:29:45 1995 Ezra Peisach - - * krb5.tex: Reorganized into subsubsections. Added principal - access macros. - - * libos.tex: Added missing functions (os_context) and reorganized - into subsubsections. - -Wed May 3 01:22:11 1995 Ezra Peisach - - * krb5.tex: Added auth_context routines. - - * free.tex: Add krb5_xfree and krb5_free_data. - - * rcache.tex: Add krb5_rc_get_type, krb5_rc_resolve_type. - - * krb5.tex: API changes finished. - -Tue May 2 15:26:11 1995 Ezra Peisach (epeisach@kangaroo.mit.edu) - - * ccache.tex: krb5_cc_gen_new instead of krb5_cc_generate_new. - -Sun Apr 30 15:37:31 1995 Ezra Peisach - - * errors.tex: Formatting fixes - - * intro.tex: Formatting fixes - - * Makefile: Add free.tex to list. - - * rcache.tex: Update to current API specs. - - * ccache.tex: Update to current API specs. - - * keytab.tex: Update to current API specs. - - * free.tex: Finished first version. - -Tue Apr 18 10:42:03 1995 Ezra Peisach - - * intro.tex: spell checked - -Tue Apr 11 14:21:21 1995 Ezra Peisach (epeisach@kangaroo.mit.edu) - - * Makefile Cleaned up two pass processing through latex of library - document. - -Tue Apr 4 15:22:11 1995 Ezra Peisach - - * errors.tex Added missing entries in existing tables. Removed - isode table. Added asn.1 table and magic number table. - -Tue Feb 07 18:31:58 1995 Chris Provenzano (proven@mit.edu) - - * krb5.tex Documented API changes to krb5_get_in_tkt*() routines - and added krb5_get_in_tkt_with_keytab(). The explanation of - each of these routines still needs appropriate changes. - -Thu Feb 02 22:59:41 1995 Chris Provenzano (proven@mit.edu) - - * krb5.tex Documented change of krb5_enctype to krb5_enctypes - to krb5_send_tgs(). - - * krb5.tex Documented added krb5_keytype arg to (*keyproc)() arg - for krb5_rd_req(), krb5_rd_req_decoded(), and krb5_recvauth(). - -Fri Jan 27 22:15:23 1995 Chris Provenzano (proven@mit.edu) - - * keytab.tex Documented added krb5_keytab argunment to - krb5_kt_read_service_key() and krb5_kt_get_entry(). - -Mon Nov 21 14:17:50 1994 Theodore Y. Ts'o (tytso@dcl) - - * library.tex (internalfunc): Define \internalfunc, which prints a - disclaimer in front of "internal functions". We should - move them somewhere else, but for now, let's start marking - those functions which we believe are internal. - - * krb5.tex: Documented changed interfaces to krb5_encode_kdc_rep - and krb5_encrypt_tkt_part. Document krb5_encode_kdc_rep, - krb5_decode_kdc_rep, krb5_encrypt_tkt_part, - krb5_decrypt_tkt_part, and krb5_send_tgs as all internal - functions. - -Thu Oct 13 13:14:48 1994 Theodore Y. Ts'o (tytso@dcl) - - * krb5.tex: Fixed typo; extra space in \funcname{ krb5_recvauth}. - -Wed Oct 12 02:03:37 1994 Theodore Y. Ts'o (tytso@dcl) - - * Makefile: Added better dependencies to do two-pass latex runs - automatically. Make "make clean" clean up the tex temp - files. - - diff --git a/doc/api/Makefile b/doc/api/Makefile deleted file mode 100644 index 72ad368e5..000000000 --- a/doc/api/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -.SUFFIXES: .tex .dvi .ps - -SHELL=/bin/sh - -STYLES=changebar.sty fixunder.sty functions.sty krb5idx.sty -LIBTEX= library.tex intro.tex tables.tex errors.tex krb5.tex ccache.tex \ - rcache.tex keytab.tex libos.tex free.tex - -DESTEX= libdes.tex - -all: library.ps libdes.ps - - -libdes.dvi: $(DESTEX) $(STYLES) - -library.ps: library.dvi - -clean: - rm -f *.toc *.log *.idx *.ind *.aux *.ilg lib1.stamp - -really-clean: clean - rm -f *.dvi *.ps - - -library.dvi: lib1.stamp $(LIBTEX) $(STYLES) - latex library - -lib1.stamp: $(LIBTEX) $(STYLES) - touch library.ind - latex library - makeindex -s krb5.ist library.idx - date > lib1.stamp - -.tex.dvi: - latex $* - - -.dvi.ps: - dvips $*.dvi -o - diff --git a/doc/api/ccache.tex b/doc/api/ccache.tex deleted file mode 100644 index d6e24e834..000000000 --- a/doc/api/ccache.tex +++ /dev/null @@ -1,239 +0,0 @@ -The credentials cache functions (some of which are macros which call to -specific types of credentials caches) deal with storing credentials -(tickets, session keys, and other identifying information) in a -semi-permanent store for later use by different programs. - -\begin{funcdecl}{krb5_cc_resolve}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{char *}{string_name} -\funcout -\funcarg{krb5_ccache *}{id} -\end{funcdecl} - -Fills in \funcparam{id} with a ccache identifier which corresponds to -the name in \funcparam{string_name}. - -Requires that \funcparam{string_name} be of the form ``type:residual'' and -``type'' is a type known to the library. - -\begin{funcdecl}{krb5_cc_gen_new}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_cc_ops *}{ops} -\funcout -\funcarg{krb5_ccache *}{id} -\end{funcdecl} - - -Fills in \funcparam{id} with a unique ccache identifier of a type defined by -\funcparam{ops}. The cache is left unopened. - -\begin{funcdecl}{krb5_cc_register}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_cc_ops *}{ops} -\funcarg{krb5_boolean}{override} -\end{funcdecl} - -Adds a new cache type identified and implemented by \funcparam{ops} to -the set recognized by \funcname{krb5_cc_resolve}. -If \funcparam{override} is FALSE, a ticket cache type named -\funcparam{ops{\ptsto}prefix} must not be known. - -\begin{funcdecl}{krb5_cc_get_name}{char *}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{id} -\end{funcdecl} - -Returns the name of the ccache denoted by \funcparam{id}. - -\begin{funcdecl}{krb5_cc_default_name}{char *}{\funcinout} -\funcarg{krb5_context}{context} -\end{funcdecl} - -Returns the name of the default credentials cache; this may be equivalent to -\funcnamenoparens{getenv}({\tt "KRB5CCACHE"}) with an appropriate fallback. - -\begin{funcdecl}{krb5_cc_default}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_ccache *}{ccache} -\end{funcdecl} - -Equivalent to -\funcnamenoparens{krb5_cc_resolve}(\funcparam{context}, -\funcname{krb5_cc_default_name}, -\funcparam{ccache}). - -\begin{funcdecl}{krb5_cc_initialize}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\funcin -\funcarg{krb5_principal}{primary_principal} -\end{funcdecl} - -Creates/refreshes a credentials cache identified by \funcparam{id} with -primary principal set to \funcparam{primary_principal}. -If the credentials cache already exists, its contents are destroyed. - -Errors: permission errors, system errors. - -Modifies: cache identified by \funcparam{id}. - -\begin{funcdecl}{krb5_cc_destroy}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\end{funcdecl} - -Destroys the credentials cache identified by \funcparam{id}, invalidates -\funcparam{id}, and releases any other resources acquired during use of -the credentials cache. Requires that \funcparam{id} identifies a valid -credentials cache. After return, \funcparam{id} must not be used unless -it is first reinitialized using \funcname{krb5_cc_resolve} or -\funcname{krb5_cc_gen_new}. - -Errors: permission errors. - -\begin{funcdecl}{krb5_cc_close}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\end{funcdecl} - -Closes the credentials cache \funcparam{id}, invalidates -\funcparam{id}, and releases \funcparam{id} and any other resources -acquired during use of the credentials cache. Requires that -\funcparam{id} identifies a valid credentials cache. After return, -\funcparam{id} must not be used unless it is first reinitialized using -\funcname{krb5_cc_resolve} or \funcname{krb5_cc_gen_new}. - - -\begin{funcdecl}{krb5_cc_store_cred}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{id} -\funcarg{krb5_creds *}{creds} -\end{funcdecl} - -Stores \funcparam{creds} in the cache \funcparam{id}, tagged with -\funcparam{creds{\ptsto}client}. -Requires that \funcparam{id} identifies a valid credentials cache. - -Errors: permission errors, storage failure errors. - -\begin{funcdecl}{krb5_cc_retrieve_cred}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{id} -\funcarg{krb5_flags}{whichfields} -\funcarg{krb5_creds *}{mcreds} -\funcout -\funcarg{krb5_creds *}{creds} -\end{funcdecl} - -Searches the cache \funcparam{id} for credentials matching -\funcparam{mcreds}. The fields which are to be matched are specified by -set bits in \funcparam{whichfields}, and always include the principal -name \funcparam{mcreds{\ptsto}server}. -Requires that \funcparam{id} identifies a valid credentials cache. - -If at least one match is found, one of the matching credentials is -returned in \funcparam{*creds}. The credentials should be freed using -\funcname{krb5_free_credentials}. - -Errors: error code if no matches found. - -\begin{funcdecl}{krb5_cc_get_principal}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{id} -\funcarg{krb5_principal *}{principal} -\end{funcdecl} - -Retrieves the primary principal of the credentials cache (as -set by the \funcname{krb5_cc_initialize} request) -The primary principal is filled into \funcparam{*principal}; the caller -should release this memory by calling \funcname{krb5_free_principal} on -\funcparam{*principal} when finished. - -Requires that \funcparam{id} identifies a valid credentials cache. - -\begin{funcdecl}{krb5_cc_start_seq_get}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\funcout -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Prepares to sequentially read every set of cached credentials. -\funcparam{cursor} is filled in with a cursor to be used in calls to -\funcname{krb5_cc_next_cred}. - -\begin{funcdecl}{krb5_cc_next_cred}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\funcout -\funcarg{krb5_creds *}{creds} -\funcinout -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Fetches the next entry from \funcparam{id}, returning its values in -\funcparam{*creds}, and updates \funcparam{*cursor} for the next request. -Requires that \funcparam{id} identifies a valid credentials cache and -\funcparam{*cursor} be a cursor returned by -\funcname{krb5_cc_start_seq_get} or a subsequent call to -\funcname{krb5_cc_next_cred}. - -Errors: error code if no more cache entries. - -\begin{funcdecl}{krb5_cc_end_seq_get}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Finishes sequential processing mode and invalidates \funcparam{*cursor}. -\funcparam{*cursor} must never be re-used after this call. - -Requires that \funcparam{id} identifies a valid credentials cache and -\funcparam{*cursor} be a cursor returned by -\funcname{krb5_cc_start_seq_get} or a subsequent call to -\funcname{krb5_cc_next_cred}. - -Errors: may return error code if \funcparam{*cursor} is invalid. - - -\begin{funcdecl}{krb5_cc_remove_cred}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{id} -\funcarg{krb5_flags}{which} -\funcarg{krb5_creds *}{cred} -\end{funcdecl} - -Removes any credentials from \funcparam{id} which match the principal -name {cred{\ptsto}server} and the fields in \funcparam{cred} masked by -\funcparam{which}. -Requires that \funcparam{id} identifies a valid credentials cache. - -Errors: returns error code if nothing matches; returns error code if -couldn't delete. - -\begin{funcdecl}{krb5_cc_set_flags}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ccache}{id} -\funcin -\funcarg{krb5_flags}{flags} -\end{funcdecl} - -Sets the flags on the cache \funcparam{id} to \funcparam{flags}. Useful -flags are defined in {\tt }. - -\begin{funcdecl}{krb5_get_notification_message}{unsigned int}{\funcvoid} -\end{funcdecl} - -Intended for use by Windows. Will register a unique message type using -\funcname{RegisterWindowMessage} which will be notified whenever the -cache changes. This will allow all processes to recheck their caches. diff --git a/doc/api/changebar.sty b/doc/api/changebar.sty deleted file mode 100644 index 61b7383f9..000000000 --- a/doc/api/changebar.sty +++ /dev/null @@ -1,155 +0,0 @@ -% Change bar document-style option for LaTeX. -% -% Copyright (C) 1990 by David B. Johnson. - -% These macros draw a solid bar down the right margin of the output, -% covering a range of the input file that has been declared to be changed. -% -% The beginning and end of a change bar in the text are marked with -% \chgbarbegin and \chgbarend, respectively. For example, -% -% Here is some sample text \chgbarbegin that was -% changed\chgbarend{} and some that wasn't changed. -% -% The change bar is drawn continuously between the line of output -% containing the \chgbarbegin and the line of output containing the -% \chgbarend. These lines can end up on separate pages, and the -% division at page boundaries is handled automatically. - -% Two dimensions control the size and placement of the change bars: -% \chgbarwidth The width of a change bar -% \chgbarsep The distance between the text and the change bar - -% Warning: it does not appear to be possible to do this completely -% correctly, due to the time at which the verticle glue on a page is -% finally set, and the way that page breaks are decided. With -% \raggedbottom, this normally works fine. It hasn't been tested with -% \flushbottom, but will probably behave worse. In strange rare -% situations, a change bar might be drawn from the first line of a page -% up off the top of a page; this can usually be fixed by slightly moving -% the \chngbarend around, or by breaking a single change bar range -% into two ranges. - -\newdimen\chgbarwidth \newdimen\chgbarsep -\chgbarwidth 4pt -\chgbarsep .25in - -\def\chgbarbegin{\ifhmode\@chgbar{-2}\else\@chgbar{-3}\fi} -\def\chgbarend{\@chgbar{-4}\relax} - -\marginparpush 0pt - -% The remainder of this is hacked up based on the LaTeX 2.09 latex.tex. - -% copied from \marginpar -\def\@chgbar#1{\ifhmode \@bsphack\@floatpenalty -\@Mii\else - \@floatpenalty-\@Miii\fi\ifinner - \@parmoderr\@floatpenalty\z@ - \else\@next\@currbox\@freelist{\global - \count\@currbox#1}{\@floatpenalty\z@ \@fltovf - \def\@currbox{\@tempboxa}}\fi - \setbox\@tempboxa\vbox - \bgroup\end@float\@esphack} - -\newdimen\@chgbarbegin -\newif\if@inchgbar \@inchgbarfalse - -\def\@addmarginpar{% -\ifnum\count\@currbox = -2 % change bar begin from hmode - \global\@chgbarbegin\@pageht \global\advance\@chgbarbegin -\baselineskip - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -3 % change bar begin not from hmode - \global\@chgbarbegin\@pageht - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -4 % change bar end - \if@inchgbar\else\@latexbug\fi - \@tempdima\@pageht \advance\@tempdima -\@chgbarbegin - \nointerlineskip - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi -\hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@ -}} -\hss} - \nointerlineskip - \global\@inchgbarfalse - \@cons\@freelist\@currbox -\else - \@next\@marbox\@currlist{\@cons\@freelist\@marbox - \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi - \@tempdima\@mparbottom \advance\@tempdima -\@pageht - \advance\@tempdima\ht\@marbox \ifdim\@tempdima >\z@ - \@warning{Marginpar on page \thepage\space moved}\else\@tempdima\z@ \fi - \global\@mparbottom\@pageht \global\advance\@mparbottom\@tempdima - \global\advance\@mparbottom\dp\@marbox - \global\advance\@mparbottom\marginparpush - \advance\@tempdima -\ht\@marbox - \global\ht\@marbox\z@ \global\dp\@marbox\z@ - \vskip -\@pagedp \vskip\@tempdima\nointerlineskip - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\marginparsep - \else \hskip -\marginparsep \hskip -\marginparwidth \fi - \box\@marbox \hss} - \vskip -\@tempdima - \nointerlineskip - \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp} -\fi\fi\fi} - -\def\@makecol{\setbox\@outputbox\box\@cclv - \if@inchgbar - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \@tempdima\ht\@outputbox \advance\@tempdima -\@chgbarbegin - \advance\@tempdima -\baselineskip - \setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox \nointerlineskip \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi - \hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@}}\hss}} - \global\@chgbarbegin 0pt -\fi - \ifvoid\footins\else\setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox\vskip\skip\footins\footnoterule\unvbox\footins}\fi - \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats - \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth - \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox - \vskip-\dimen128\@textbottom} - \global\maxdepth\@maxdepth} - -\newenvironment{changebar}{\chgbarbegin}{\chgbarend} diff --git a/doc/api/errors.tex b/doc/api/errors.tex deleted file mode 100644 index ad90cac53..000000000 --- a/doc/api/errors.tex +++ /dev/null @@ -1,310 +0,0 @@ -\subsection{error_table krb5} - -% $Source$ -% $Author$ - -The Kerberos v5 library error code table follows. -Protocol error codes are ERROR_TABLE_BASE_krb5 + the protocol error -code number. Other error codes start at ERROR_TABLE_BASE_krb5 + 128. - -\begin{small} -\begin{tabular}{ll} -{\sc krb5kdc_err_none }& No error \\ -{\sc krb5kdc_err_name_exp }& Client's entry in database has expired \\ -{\sc krb5kdc_err_service_exp }& Server's entry in database has expired \\ -{\sc krb5kdc_err_bad_pvno }& Requested protocol version not supported \\ -{\sc krb5kdc_err_c_old_mast_kvno }& \parbox[t]{2in}{Client's key is encrypted in an old master key} \\ -{\sc krb5kdc_err_s_old_mast_kvno }& \parbox[t]{2in}{Server's key is encrypted in an old master key} \\ -{\sc krb5kdc_err_c_principal_unknown }& Client not found in Kerberos database \\ -{\sc krb5kdc_err_s_principal_unknown }& Server not found in Kerberos database \\ -{\sc krb5kdc_err_principal_not_unique }&\parbox[t]{2in}{\raggedright{Principal has multiple entries in Kerberos database}} \\ -{\sc krb5kdc_err_null_key }& Client or server has a null key \\ -{\sc krb5kdc_err_cannot_postdate }& Ticket is ineligible for postdating \\ -{\sc krb5kdc_err_never_valid }& \parbox[t]{2in}{Requested effective lifetime is negative or too short} \\ -{\sc krb5kdc_err_policy }& KDC policy rejects request \\ -{\sc krb5kdc_err_badoption }& KDC can't fulfill requested option \\ -{\sc krb5kdc_err_etype_nosupp }& KDC has no support for encryption type \\ -{\sc krb5kdc_err_sumtype_nosupp }& KDC has no support for checksum type \\ -{\sc krb5kdc_err_padata_type_nosupp }& KDC has no support for padata type \\ -{\sc krb5kdc_err_trtype_nosupp }& KDC has no support for transited type \\ -{\sc krb5kdc_err_client_revoked }& Clients credentials have been revoked \\ -{\sc krb5kdc_err_service_revoked }& Credentials for server have been revoked \\ -{\sc krb5kdc_err_tgt_revoked }& TGT has been revoked \\ -{\sc krb5kdc_err_client_notyet }& Client not yet valid - try again later \\ -{\sc krb5kdc_err_service_notyet }& Server not yet valid - try again later \\ -{\sc krb5kdc_err_key_exp }& Password has expired \\ -{\sc krb5kdc_preauth_failed }& Preauthentication failed \\ -{\sc krb5kdc_err_preauth_require }& Additional pre-authentication required \\ -{\sc krb5kdc_err_server_nomatch }& Requested server and ticket don't match \\ -\multicolumn{2}{c}{error codes 27-30 are currently placeholders}\\ - -\end{tabular} - -\begin{tabular}{ll} -{\sc krb5krb_ap_err_bad_integrity }& Decrypt integrity check failed \\ -{\sc krb5krb_ap_err_tkt_expired }& Ticket expired \\ -{\sc krb5krb_ap_err_tkt_nyv }& Ticket not yet valid \\ -{\sc krb5krb_ap_err_repeat }& Request is a replay \\ -{\sc krb5krb_ap_err_not_us }& The ticket isn't for us \\ -{\sc krb5krb_ap_err_badmatch }& Ticket/authenticator don't match \\ -{\sc krb5krb_ap_err_skew }& Clock skew too great \\ -{\sc krb5krb_ap_err_badaddr }& Incorrect net address \\ -{\sc krb5krb_ap_err_badversion }& Protocol version mismatch \\ -{\sc krb5krb_ap_err_msg_type }& Invalid message type \\ -{\sc krb5krb_ap_err_modified }& Message stream modified \\ -{\sc krb5krb_ap_err_badorder }& Message out of order \\ -{\sc krb5placehold_43 }& KRB5 error code 43 \\ -{\sc krb5krb_ap_err_badkeyver }& Key version is not available \\ -{\sc krb5krb_ap_err_nokey }& Service key not available \\ -{\sc krb5krb_ap_err_mut_fail }& Mutual authentication failed \\ -{\sc krb5krb_ap_err_baddirection }& Incorrect message direction \\ -{\sc krb5krb_ap_err_method }& Alternative authentication method required \\ -{\sc krb5krb_ap_err_badseq }& Incorrect sequence number in message \\ -{\sc krb5krb_ap_err_inapp_cksum }& Inappropriate type of checksum in message \\ -\multicolumn{2}{c}{error codes 51-59 are currently placeholders} \\ - -{\sc krb5krb_err_generic }& Generic error (see e-text) \\ -{\sc krb5krb_err_field_toolong }& Field is too long for this implementation \\ -\multicolumn{2}{c}{error codes 62-127 are currently placeholders} \\ -\end{tabular} - -\begin{tabular}{ll} -{\sc krb5_libos_badlockflag }& Invalid flag for file lock mode \\ -{\sc krb5_libos_cantreadpwd }& Cannot read password \\ -{\sc krb5_libos_badpwdmatch }& Password mismatch \\ -{\sc krb5_libos_pwdintr }& Password read interrupted \\ -{\sc krb5_parse_illchar }& Illegal character in component name \\ -{\sc krb5_parse_malformed }& Malformed representation of principal \\ -{\sc krb5_config_cantopen }& Can't open/find configuration file \\ -{\sc krb5_config_badformat }& Improper format of configuration file \\ -{\sc krb5_config_notenufspace }& Insufficient space to return complete information \\ -{\sc krb5_badmsgtype }& Invalid message type specified for encoding \\ -{\sc krb5_cc_badname }& Credential cache name malformed \\ -{\sc krb5_cc_unknown_type }& Unknown credential cache type \\ -{\sc krb5_cc_notfound }& Matching credential not found \\ -{\sc krb5_cc_end }& End of credential cache reached \\ -{\sc krb5_no_tkt_supplied }& Request did not supply a ticket \\ -{\sc krb5krb_ap_wrong_princ }& Wrong principal in request \\ -{\sc krb5krb_ap_err_tkt_invalid }& Ticket has invalid flag set \\ -{\sc krb5_princ_nomatch }& Requested principal and ticket don't match \\ -{\sc krb5_kdcrep_modified }& KDC reply did not match expectations \\ -{\sc krb5_kdcrep_skew }& Clock skew too great in KDC reply \\ -{\sc krb5_in_tkt_realm_mismatch }&\parbox[t]{2.5 in}{Client/server realm -mismatch in initial ticket requst}\\ - -{\sc krb5_prog_etype_nosupp }& Program lacks support for encryption type \\ -{\sc krb5_prog_keytype_nosupp }& Program lacks support for key type \\ -{\sc krb5_wrong_etype }& Requested encryption type not used in message \\ -{\sc krb5_prog_sumtype_nosupp }& Program lacks support for checksum type \\ -{\sc krb5_realm_unknown }& Cannot find KDC for requested realm \\ -{\sc krb5_service_unknown }& Kerberos service unknown \\ -{\sc krb5_kdc_unreach }& Cannot contact any KDC for requested realm \\ -{\sc krb5_no_localname }& No local name found for principal name \\ - -%\multicolumn{1}{c}{some of these should be combined/supplanted by system codes} \\ -\end{tabular} - -\begin{tabular}{ll} -{\sc krb5_rc_type_exists }& Replay cache type is already registered \\ -{\sc krb5_rc_malloc }& No more memory to allocate (in replay cache code) \\ -{\sc krb5_rc_type_notfound }& Replay cache type is unknown \\ -{\sc krb5_rc_unknown }& Generic unknown RC error \\ -{\sc krb5_rc_replay }& Message is a replay \\ -{\sc krb5_rc_io }& Replay I/O operation failed XXX \\ -{\sc krb5_rc_noio }& \parbox[t]{3in}{Replay cache type does not support non-volatile storage} \\ -{\sc krb5_rc_parse }& Replay cache name parse/format error \\ -{\sc krb5_rc_io_eof }& End-of-file on replay cache I/O \\ -{\sc krb5_rc_io_malloc }& \parbox[t]{3in}{No more memory to allocate (in replay cache I/O code)}\\ -{\sc krb5_rc_io_perm }& Permission denied in replay cache code \\ -{\sc krb5_rc_io_io }& I/O error in replay cache i/o code \\ -{\sc krb5_rc_io_unknown }& Generic unknown RC/IO error \\ -{\sc krb5_rc_io_space }& Insufficient system space to store replay information \\ -{\sc krb5_trans_cantopen }& Can't open/find realm translation file \\ -{\sc krb5_trans_badformat }& Improper format of realm translation file \\ -{\sc krb5_lname_cantopen }& Can't open/find lname translation database \\ -{\sc krb5_lname_notrans }& No translation available for requested principal \\ -{\sc krb5_lname_badformat }& Improper format of translation database entry \\ -{\sc krb5_crypto_internal }& Cryptosystem internal error \\ -{\sc krb5_kt_badname }& Key table name malformed \\ -{\sc krb5_kt_unknown_type }& Unknown Key table type \\ -{\sc krb5_kt_notfound }& Key table entry not found \\ -{\sc krb5_kt_end }& End of key table reached \\ -{\sc krb5_kt_nowrite }& Cannot write to specified key table \\ -{\sc krb5_kt_ioerr }& Error writing to key table \\ -{\sc krb5_no_tkt_in_rlm }& Cannot find ticket for requested realm \\ -{\sc krb5des_bad_keypar }& DES key has bad parity \\ -{\sc krb5des_weak_key }& DES key is a weak key \\ -{\sc krb5_bad_keytype }& Keytype is incompatible with encryption type \\ -{\sc krb5_bad_keysize }& Key size is incompatible with encryption type \\ -{\sc krb5_bad_msize }& Message size is incompatible with encryption type \\ -{\sc krb5_cc_type_exists }& Credentials cache type is already registered. \\ -{\sc krb5_kt_type_exists }& Key table type is already registered. \\ -{\sc krb5_cc_io }& Credentials cache I/O operation failed XXX \\ -{\sc krb5_fcc_perm }& Credentials cache file permissions incorrect \\ -{\sc krb5_fcc_nofile }& No credentials cache file found \\ -{\sc krb5_fcc_internal }& Internal file credentials cache error \\ -{\sc krb5_cc_nomem }& \parbox[t]{3in}{No more memory to allocate (in credentials cache code)}\\ -\end{tabular} - -\begin{tabular}{ll} -\multicolumn{2}{c}{errors for dual TGT library calls} \\ - -{\sc krb5_invalid_flags }& Invalid KDC option combination (library internal error) \\ -{\sc krb5_no_2nd_tkt }& Request missing second ticket \\ -{\sc krb5_nocreds_supplied }& No credentials supplied to library routine \\ - -\end{tabular} - -\begin{tabular}{ll} -\multicolumn{2}{c}{errors for sendauth and recvauth} \\ - -{\sc krb5_sendauth_badauthvers }& Bad sendauth version was sent \\ -{\sc krb5_sendauth_badapplvers }& Bad application version was sent (via sendauth) \\ -{\sc krb5_sendauth_badresponse }& Bad response (during sendauth exchange) \\ -{\sc krb5_sendauth_rejected }& Server rejected authentication\\ -& \ (during sendauth exchange) \\ -{\sc krb5_sendauth_mutual_failed }& Mutual authentication failed\\&\ (during sendauth exchange) \\ - -\end{tabular} - -\begin{tabular}{ll} -\multicolumn{2}{c}{errors for preauthentication} \\ - -{\sc krb5_preauth_bad_type }& Unsupported preauthentication type \\ -{\sc krb5_preauth_no_key }& Required preauthentication key not supplied \\ -{\sc krb5_preauth_failed }& Generic preauthentication failure \\ - -\end{tabular} - -\begin{tabular}{ll} -\multicolumn{2}{c}{version number errors} \\ - -{\sc krb5_rcache_badvno }& Unsupported replay cache format version number \\ -{\sc krb5_ccache_badvno }& Unsupported credentials cache format version number \\ -{\sc krb5_keytab_badvno }& Unsupported key table format version number \\ - -\end{tabular} - -\begin{tabular}{ll} -\multicolumn{2}{c}{other errors} \\ - -{\sc krb5_prog_atype_nosupp }& Program lacks support for address type \\ -{\sc krb5_rc_required }& Message replay detection requires\\&\ rcache parameter \\ -{\sc krb5_err_bad_hostname }& Hostname cannot be canonicalized \\ -{\sc krb5_err_host_realm_unknown }& Cannot determine realm for host \\ -{\sc krb5_sname_unsupp_nametype }& Conversion to service principal undefined\\&\ for name type \\ -{\sc krb5krb_ap_err_v4_reply }& Initial Ticket Response appears to be\\ -&\ Version 4 error \\ -{\sc krb5_realm_cant_resolve }& Cannot resolve KDC for requested realm \\ -{\sc krb5_tkt_not_forwardable }& Requesting ticket can't get forwardable tickets \\ -\end{tabular} -\end{small} - -\subsection{error_table kdb5} - -% $Source$ -% $Author$ - -The Kerberos v5 database library error code table - -\begin{small} -\begin{tabular}{ll} -\multicolumn{2}{c}{From the server side routines} \\ -{\sc krb5_kdb_inuse }& Entry already exists in database\\ -{\sc krb5_kdb_uk_serror }& Database store error\\ -{\sc krb5_kdb_uk_rerror }& Database read error\\ -{\sc krb5_kdb_unauth }& Insufficient access to perform requested operation\\ -{\sc krb5_kdb_noentry }& No such entry in the database\\ -{\sc krb5_kdb_ill_wildcard }& Illegal use of wildcard\\ -{\sc krb5_kdb_db_inuse }& Database is locked or in use--try again later\\ -{\sc krb5_kdb_db_changed }& Database was modified during read\\ -{\sc krb5_kdb_truncated_record }& Database record is incomplete or corrupted\\ -{\sc krb5_kdb_recursivelock }& Attempt to lock database twice\\ -{\sc krb5_kdb_notlocked }& Attempt to unlock database when not locked\\ -{\sc krb5_kdb_badlockmode }& Invalid kdb lock mode\\ -{\sc krb5_kdb_dbnotinited }& Database has not been initialized\\ -{\sc krb5_kdb_dbinited }& Database has already been initialized\\ -{\sc krb5_kdb_illdirection }& Bad direction for converting keys\\ -{\sc krb5_kdb_nomasterkey }& Cannot find master key record in database\\ -{\sc krb5_kdb_badmasterkey }& Master key does not match database\\ -{\sc krb5_kdb_invalidkeysize }& Key size in database is invalid\\ -{\sc krb5_kdb_cantread_stored }& Cannot find/read stored master key\\ -{\sc krb5_kdb_badstored_mkey }& Stored master key is corrupted\\ -{\sc krb5_kdb_cantlock_db }& Insufficient access to lock database \\ -{\sc krb5_kdb_db_corrupt }& Database format error\\ -{\sc krb5_kdb_bad_version }& Unsupported version in database entry \\ -\end{tabular} -\end{small} - -% $Source$ -% $Author$ - -\subsection{error_table kv5m} - -The Kerberos v5 magic numbers errorcode table follows. These are used -for the magic numbers found in data structures. - -\begin{small} -\begin{tabular}{ll} -{\sc kv5m_none }& Kerberos V5 magic number table \\ -{\sc kv5m_principal }& Bad magic number for krb5_principal structure \\ -{\sc kv5m_data }& Bad magic number for krb5_data structure \\ -{\sc kv5m_keyblock }& Bad magic number for krb5_keyblock structure \\ -{\sc kv5m_checksum }& Bad magic number for krb5_checksum structure \\ -{\sc kv5m_encrypt_block }& Bad magic number for krb5_encrypt_block structure \\ -{\sc kv5m_enc_data }& Bad magic number for krb5_enc_data structure \\ -{\sc kv5m_cryptosystem_entry }& Bad magic number for krb5_cryptosystem_entry\\&\ structure \\ -{\sc kv5m_cs_table_entry }& Bad magic number for krb5_cs_table_entry structure \\ -{\sc kv5m_checksum_entry }& Bad magic number for krb5_checksum_entry structure \\ - -{\sc kv5m_authdata }& Bad magic number for krb5_authdata structure \\ -{\sc kv5m_transited }& Bad magic number for krb5_transited structure \\ -{\sc kv5m_enc_tkt_parT }& Bad magic number for krb5_enc_tkt_part structure \\ -{\sc kv5m_ticket }& Bad magic number for krb5_ticket structure \\ -{\sc kv5m_authenticator }& Bad magic number for krb5_authenticator structure \\ -{\sc kv5m_tkt_authent }& Bad magic number for krb5_tkt_authent structure \\ -{\sc kv5m_creds }& Bad magic number for krb5_creds structure \\ -{\sc kv5m_last_req_entry }& Bad magic number for krb5_last_req_entry structure \\ -{\sc kv5m_pa_data }& Bad magic number for krb5_pa_data structure \\ -{\sc kv5m_kdc_req }& Bad magic number for krb5_kdc_req structure \\ -{\sc kv5m_enc_kdc_rep_part }& Bad magic number for krb5_enc_kdc_rep_part structure \\ -{\sc kv5m_kdc_rep }& Bad magic number for krb5_kdc_rep structure \\ -{\sc kv5m_error }& Bad magic number for krb5_error structure \\ -{\sc kv5m_ap_req }& Bad magic number for krb5_ap_req structure \\ -{\sc kv5m_ap_rep }& Bad magic number for krb5_ap_rep structure \\ -{\sc kv5m_ap_rep_enc_part }& Bad magic number for krb5_ap_rep_enc_part structure \\ -{\sc kv5m_response }& Bad magic number for krb5_response structure \\ -{\sc kv5m_safe }& Bad magic number for krb5_safe structure \\ -{\sc kv5m_priv }& Bad magic number for krb5_priv structure \\ -{\sc kv5m_priv_enc_part }& Bad magic number for krb5_priv_enc_part structure \\ -{\sc kv5m_cred }& Bad magic number for krb5_cred structure \\ -{\sc kv5m_cred_info }& Bad magic number for krb5_cred_info structure \\ -{\sc kv5m_cred_enc_part }& Bad magic number for krb5_cred_enc_part structure \\ -{\sc kv5m_pwd_data }& Bad magic number for krb5_pwd_data structure \\ -{\sc kv5m_address }& Bad magic number for krb5_address structure \\ -{\sc kv5m_keytab_entry }& Bad magic number for krb5_keytab_entry structure \\ -{\sc kv5m_context }& Bad magic number for krb5_context structure \\ -{\sc kv5m_os_context }& Bad magic number for krb5_os_context structure \\ - -\end{tabular} -\end{small} - -\subsection{error_table asn1} - -The Kerberos v5/ASN.1 error table mappings - -\begin{small} -\begin{tabular}{ll} -{\sc asn1_bad_timeformat }& ASN.1 failed call to system time library \\ -{\sc asn1_missing_field }& ASN.1 structure is missing a required field \\ -{\sc asn1_misplaced_field }& ASN.1 unexpected field number \\ -{\sc asn1_type_mismatch }& ASN.1 type numbers are inconsistent \\ -{\sc asn1_overflow }& ASN.1 value too large \\ -{\sc asn1_overrun }& ASN.1 encoding ended unexpectedly \\ -{\sc asn1_bad_id }& ASN.1 identifier doesn't match expected value \\ -{\sc asn1_bad_length }& ASN.1 length doesn't match expected value \\ -{\sc asn1_bad_format }& ASN.1 badly-formatted encoding \\ -{\sc asn1_parse_error }& ASN.1 parse error \\ -\end{tabular} -\end{small} - diff --git a/doc/api/fancyheadings.sty b/doc/api/fancyheadings.sty deleted file mode 100644 index a71de0fb5..000000000 --- a/doc/api/fancyheadings.sty +++ /dev/null @@ -1,233 +0,0 @@ -% fancyheadings.sty version 1.0 -% Fancy headers and footers. -% Piet van Oostrum, Dept of Computer Science, University of Utrecht -% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands -% Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!hp4nl!ruuinf!piet) -% March, 1989. - -% Here is a documentstylestyle option that allows you to customize your -% page headers and footers in an easy way. It combines features that were -% separately available in other pagestyles, without introducing much -% complexity. You can define: -% - three-part headers and footers -% - rules in header and footer -% - headers and footers wider than \textwidth -% - multiline headers and footers -% - separate headers and footers for even and odd pages -% - separate headers and footers for chapter pages -% -% To use this pagestyle, you must include the ``fancyheadings'' style -% option in your \documentstyle, and issue the \pagestyle{fancy} command. -% The \pagestyle{fancy} command should be issued after any changes made to -% \textwidth. -% -% The page layout will be as follows: -% -% LHEAD CHEAD RHEAD -% ----------------------------------- (rule) -% -% page body -% -% -% ----------------------------------- (rule) -% LFOOT CFOOT RFOOT -% -% The L-fields will be leftadjusted, the C-fields centered and the -% R-fields rightadjusted. -% Each of the six fields and the two rules can be defined separately. -% -% Simple use: -% -% The header and footer fields can be defined by commands \lhead{LHEAD} -% and so on for the other fields. If the field depends on something in the -% document (e.g. section titles) you must in general use the \markboth and -% \markright commands, otherwise a title may end on the wrong page. You -% can do this e.g. by redefining the commands \chaptermark, \sectionmark -% and so on (see example below). The defaults for these marks are as in -% the standard pagestyles. The marks can be put into a header or footer -% field by referencing \leftmark and \rightmark. -% -% Rules in header and footer -% -% The thickness of the rules below the header and above the footer can be -% changed by redefining the length parameters \headrulewidth (default -% 0.4pt) and \footrulewidth (default 0). These may be redefined by the -% \setlength command. A thickness of 0pt makes the rule invisible. -% If you want to make more complicated changes, you have to redefine the -% commands \headrule and/or \footrule. -% -% Headers and footers wider than \textwidth -% -% The headers and footers are set in a box of width \headwidth. The -% default for this is the value of \textwidth. You can make it wider (or -% smaller) by redefining \headwidth with the \setlength or \addtolength -% command. The headers and footers will stick out the page on the same -% side as the marginal notes. For example to include the marginal notes, -% add both \marginparsep and \marginparwidth to \headwidth (see also the -% example below). -% -% Multiline headers and footers -% -% Each of the six fields is set in an appropriate parbox, so you can put a -% multiline part in it with the \\ command. It is also possible to put -% extra space in it with the \vspace command. Note that if you do this you -% will probably have to increase the \headheight or \footskip lengths. -% -% Separate headers and footers for even and odd pages -% -% If you want the headers and footers to be different on even- and -% odd-numbered pages in the ``twoside'' style, the field-defining macros -% can be given an optional argument, to be used on the even-numbered -% pages, like \lhead[EVEN-LHEAD]{ODD-RHEAD}. -% -% Separate headers and footers for chapter pages -% -% LaTeX gives a \thispagestyle{plain} command for the first page of the -% document, the first page of each chapter and a couple of other pages. It -% might be incompatible with your pagestyle. In this case you can use a -% slightly different version of the pagestyle, called \pagestyle{fancyplain}. -% This pagestyle redefines the pagestyle ``plain'' to also use pagestyle -% ``fancy'' with the following modifications: -% - the thicknesses of the rules is defined by \plainheadrulewidth and -% \plainfootrulewidth (both default 0). -% - the 6 fields may be defined separately for the plain pages by -% giving them the value \fancyplain{PLAIN-VALUE}{NORMAL-VALUE}. This -% construct may be used in both the optional argument and the normal -% argument. Thus \lhead[\fancyplain{F1}{F2}]{\fancyplain{F3}{F4}} -% specifies the LHEAD value in a two-sided document: -% F1 on an even-numbered ``plain'' page -% F2 on an even-numbered normal page -% F3 on an odd-numbered ``plain'' page -% F4 on an odd-numbered normal page. -% -% Defaults: -% -% \headrulewidth 0.4pt -% \footrulewidth 0pt -% \plainheadrulewidth 0pt -% \plainfootrulewidth 0pt -% -% \lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}} -% % i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages -% \chead{} -% \rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}} -% % i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages -% \lfoot{} -% \cfoot{\rm\thepage} % page number -% \rfoot{} -% -% Examples: -% -% To put two lines containing the section title and the subsection title -% in the righthandside corner, use: -% -% \documentstyle[fancyheadings]{article} -% \pagestyle{fancy} -% \renewcommand{\sectionmark}[1]{\markboth{#1}{}} -% \renewcommand{\subsectionmark}[1]{\markright{#1}} -% \rfoot{\leftmark\\\rightmark} -% -% The following definitions give an approximation of the style used in the -% LaTeX book: -% -% \documentstyle[fancyheadings]{book} -% \pagestyle{fancyplain} -% \addtolength{\headwidth}{\marginparsep} -% \addtolength{\headwidth}{\marginparwidth} -% \renewcommand{\chaptermark}[1]{\markboth{#1}{#1}} % remember chapter title -% \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} -% % section number and title -% \lhead[\fancyplain{}{\bf\thepage}]{\fancyplain{}{\bf\rightmark}} -% \rhead[\fancyplain{}{\bf\leftmark}]{\fancyplain{}{\bf\thepage}} -% \cfoot{} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\lhead{\@ifnextchar[{\@xlhead}{\@ylhead}} -\def\@xlhead[#1]#2{\gdef\@elhead{#1}\gdef\@olhead{#2}} -\def\@ylhead#1{\gdef\@elhead{#1}\gdef\@olhead{#1}} - -\def\chead{\@ifnextchar[{\@xchead}{\@ychead}} -\def\@xchead[#1]#2{\gdef\@echead{#1}\gdef\@ochead{#2}} -\def\@ychead#1{\gdef\@echead{#1}\gdef\@ochead{#1}} - -\def\rhead{\@ifnextchar[{\@xrhead}{\@yrhead}} -\def\@xrhead[#1]#2{\gdef\@erhead{#1}\gdef\@orhead{#2}} -\def\@yrhead#1{\gdef\@erhead{#1}\gdef\@orhead{#1}} - -\def\lfoot{\@ifnextchar[{\@xlfoot}{\@ylfoot}} -\def\@xlfoot[#1]#2{\gdef\@elfoot{#1}\gdef\@olfoot{#2}} -\def\@ylfoot#1{\gdef\@elfoot{#1}\gdef\@olfoot{#1}} - -\def\cfoot{\@ifnextchar[{\@xcfoot}{\@ycfoot}} -\def\@xcfoot[#1]#2{\gdef\@ecfoot{#1}\gdef\@ocfoot{#2}} -\def\@ycfoot#1{\gdef\@ecfoot{#1}\gdef\@ocfoot{#1}} - -\def\rfoot{\@ifnextchar[{\@xrfoot}{\@yrfoot}} -\def\@xrfoot[#1]#2{\gdef\@erfoot{#1}\gdef\@orfoot{#2}} -\def\@yrfoot#1{\gdef\@erfoot{#1}\gdef\@orfoot{#1}} - -\newdimen\headrulewidth -\newdimen\footrulewidth -\newdimen\plainheadrulewidth -\newdimen\plainfootrulewidth -\newdimen\headwidth -\newif\if@fancyplain \@fancyplainfalse -\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi} - -% Initialization of the head and foot text. - -\headrulewidth 0.4pt -\footrulewidth\z@ -\plainheadrulewidth\z@ -\plainfootrulewidth\z@ - -\lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}} -% i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages -\chead{} -\rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}} -% i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages -\lfoot{} -\cfoot{\rm\thepage} % page number -\rfoot{} - -% Put together a header or footer given the left, center and -% right text, fillers at left and right and a rule. -% The \lap commands put the text into an hbox of zero size, -% so overlapping text does not generate an errormessage. - -\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\hbox -{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[b]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5} - - -\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\footrule -\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[t]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5} - -\def\headrule{{\if@fancyplain\headrulewidth\plainheadrulewidth\fi -\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}} - -\def\footrule{{\if@fancyplain\footrulewidth\plainfootrulewidth\fi -\vskip-0.3\normalbaselineskip\vskip-\footrulewidth -\hrule\@width\headwidth\@height\footrulewidth\vskip0.3\normalbaselineskip}} - -\def\ps@fancy{ -\let\@mkboth\markboth -\@ifundefined{chapter}{\def\sectionmark##1{\markboth -{\uppercase{\ifnum \c@secnumdepth>\z@ - \thesection\hskip 1em\relax \fi ##1}}{}} -\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne - \thesubsection\hskip 1em\relax \fi ##1}}} -{\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth>\m@ne - \@chapapp\ \thechapter. \ \fi ##1}}{}} -\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@ - \thesection. \ \fi ##1}}}} -\def\@oddhead{\@fancyhead\relax\@olhead\@ochead\@orhead\hss} -\def\@oddfoot{\@fancyfoot\relax\@olfoot\@ocfoot\@orfoot\hss} -\def\@evenhead{\@fancyhead\hss\@elhead\@echead\@erhead\relax} -\def\@evenfoot{\@fancyfoot\hss\@elfoot\@ecfoot\@erfoot\relax} -\headwidth\textwidth} -\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy} -\def\ps@plain@fancy{\@fancyplaintrue\ps@fancy} diff --git a/doc/api/fixunder.sty b/doc/api/fixunder.sty deleted file mode 100644 index b7ae58dbf..000000000 --- a/doc/api/fixunder.sty +++ /dev/null @@ -1,48 +0,0 @@ -% fixunder.sty, 31 May 1990, John T. Kohl -% -% The contents of this file are in the public domain. -% -% -% play games with _ to make it active and to provide a reasonable _ -% character (from \tt in most cases), and a discretionary word-break point. - -% -% Some \makeunder... macros for convenience in setting catcodes. -% -\def\makeunderactive{\catcode`\_=\active\relax} -\def\makeunderother{\catcode`\_=12\relax} -\def\makeunderletter{\catcode`\_=11\relax} -\def\makeundernormal{\catcode`\_=8\relax} -\makeunderother -\def\cctwlunder{_} - -% -% The hair here is to allow things like \index to work reasonably with -% the new definition of underscore when the argument to index is part of -% a macro replacement and as such gets tokenized before \index is -% evaluated. -% [in the normal case at top-level, \index{foo_bar} works since \index -% does some hair to make _ into a reasonable character code, and \index -% does NOT use a macro expansion. If you have something like -% \def\foo#1#2{\index{#1} bar #2} -% then \foo{baz_quux}{frobnitz} will result in baz_quux getting -% tokenized BEFORE \foo is expanded, so that the catcode hair in \index -% is to no avail.] -% -% \underrealfalse declares that you want to replace with the \tt _; -% \underrealtrue declares that you want to replace with \char95 (ASCII _). -% -% for things like \index which write things out to files, set -% \underrealfalse before evaluating the \index macro, and what actually -% gets written to the file is an _, rather than something like -% {\leavemode \kern... } (the typical definition of \_). -% -% the above example would then be -% \def\foo#1#2{\underrealfalse\index{#1}\underrealtrue bar #2} -% - -\newif\ifunderreal -\underrealfalse -\makeunderactive -\def_{\ifunderreal\cctwlunder\else\leavevmode {\tt \cctwlunder}\discretionary{}{}{}\fi} -\let\_=_ diff --git a/doc/api/free.tex b/doc/api/free.tex deleted file mode 100644 index 02733b702..000000000 --- a/doc/api/free.tex +++ /dev/null @@ -1,266 +0,0 @@ -The free functions deal with deallocation of memory that has been -allocated by various routines. It is recommended that the developer use -these routines as they will know about the contents of the structures. - -\begin{funcdecl}{krb5_xfree}{void}{\funcinout} -\funcarg{void *}{ptr} -\end{funcdecl} - -Frees the pointer \funcarg{ptr}. This is a wrapper macro to -\funcname{free} that is designed to keep lint ``happy.'' - -\begin{funcdecl}{krb5_free_data}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_data *}{val} -\end{funcdecl} - -Frees the data structure \funcparam{val}, including the pointer -\funcparam{val} which has been allocate by any of numerous routines. - - -\begin{funcdecl}{krb5_free_princial}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_principal}{val} -\end{funcdecl} - -Frees the pwd_data \funcparam{val} that has been allocated from -\funcname{krb5_copy_principal}. - -\begin{funcdecl}{krb5_free_authenticator}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_authenticator *}{val} -\end{funcdecl} - -Frees the authenticator \funcparam{val}, including the pointer -\funcparam{val}. - -\begin{funcdecl}{krb5_free_authenticator_contents}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_authenticator *}{val} -\end{funcdecl} - -Frees the authenticator contents of \funcparam{val}. The pointer -\funcparam{val} is not freed. - - -\begin{funcdecl}{krb5_free_addresses}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_address **}{val} -\end{funcdecl} - -Frees the series of addresses \funcparam{*val} that have been allocated from -\funcname{krb5_copy_addresses}. - -\begin{funcdecl}{krb5_free_address}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_address *}{val} -\end{funcdecl} - -Frees the address \funcparam{val}. - -\begin{funcdecl}{krb5_free_authdata}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_authdata **}{val} -\end{funcdecl} - -Frees the authdata structure pointed to by \funcparam{val} that has been -allocated from -\funcname{krb5_copy_authdata}. - -\begin{funcdecl}{krb5_free_enc_tkt_part}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_enc_tkt_part *}{val} -\end{funcdecl} - -Frees \funcparam{val} that has been allocated from -\funcname{krb5_enc_tkt_part} and \funcname{krb5_decrypt_tkt_part}. - -\begin{funcdecl}{krb5_free_ticket}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ticket *}{val} -\end{funcdecl} - -Frees the ticket \funcparam{val} that has been allocated from -\funcname{krb5_copy_ticket} and other routines. - -\begin{funcdecl}{krb5_free_tickets}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ticket **}{val} -\end{funcdecl} - -Frees the tickets pointed to by \funcparam{val}. - -\begin{funcdecl}{krb5_free_kdc_req}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_kdc_req *}{val} -\end{funcdecl} - -Frees the kdc_req \funcparam{val} and all substructures. The pointer -\funcparam{val} is freed as well. - -\begin{funcdecl}{krb5_free_kdc_rep}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_kdc_rep *}{val} -\end{funcdecl} - -Frees the kdc_rep \funcparam{val} that has been allocated from -\funcname{krb5_get_in_tkt}. - -\begin{funcdecl}{krb5_free_kdc_rep_part}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_enc_kdc_rep_part *}{val} -\end{funcdecl} - -Frees the kdc_rep_part \funcparam{val}. - -\begin{funcdecl}{krb5_free_error}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_error *}{val} -\end{funcdecl} - -Frees the error \funcparam{val} that has been allocated from -\funcname{krb5_read_error} or \funcname{krb5_sendauth}. - -\begin{funcdecl}{krb5_free_ap_req}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ap_req *}{val} -\end{funcdecl} - -Frees the ap_req \funcparam{val}. - -\begin{funcdecl}{krb5_free_ap_rep}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ap_rep *}{val} -\end{funcdecl} - -Frees the ap_rep \funcparam{val}. - -\begin{funcdecl}{krb5_free_safe}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_safe *}{val} -\end{funcdecl} - -Frees the safe application data \funcparam{val} that is allocated with -\funcparam{decode_krb5_safe}. - - -\begin{funcdecl}{krb5_free_priv}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_priv *}{val} -\end{funcdecl} - -Frees the private data \funcparam{val} that has been allocated from -\funcname{decode_krb5_priv}. - -\begin{funcdecl}{krb5_free_priv_enc_part}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_priv_enc_part *}{val} -\end{funcdecl} - -Frees the private encoded part \funcparam{val} that has been allocated from -\funcname{decode_krb5_enc_priv_part}. - -\begin{funcdecl}{krb5_free_cred}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_cred *}{val} -\end{funcdecl} - -Frees the credential \funcparam{val}. - -\begin{funcdecl}{krb5_free_creds}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_creds *}{val} -\end{funcdecl} - -Calls \funcname{krb5_free_cred_contents} with \funcparam{val} as the -argument. \funcparam{val} is freed as well. - -\begin{funcdecl}{krb5_free_cred_contents}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_creds *}{val} -\end{funcdecl} - -The function zeros out the session key stored in the credential and then -frees the credentials structures. The argument \funcparam{val} is -{\bf not} freed. - - -\begin{funcdecl}{krb5_free_cred_enc_part}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_cred_enc_part *}{val} -\end{funcdecl} - -Frees the addresses and ticket_info elements of -\funcparam{val}. \funcparam{val} is {\bf not} freed by this routine. - -\begin{funcdecl}{krb5_free_checksum}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_checksum *}{val} -\end{funcdecl} - -The checksum and the pointer \funcparam{val} are both freed. - -\begin{funcdecl}{krb5_free_keyblock}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keyblock *}{val} -\end{funcdecl} - -The keyblock contents of \funcparam{val} are zeroed and the memory -freed. The pointer \funcparam{val} is freed as well. - -\begin{funcdecl}{krb5_free_pa_data}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_pa_data **}{val} -\end{funcdecl} - -Frees the contents of \funcparam{*val}. \funcparam{val} is freed as -well. - -\begin{funcdecl}{krb5_free_ap_rep_enc_part}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_ap_rep_enc_part *}{val} -\end{funcdecl} - -Frees the subkey keyblock (if set) as well as \funcparam{val} that has -been allocated from \funcname{krb5_rd_rep} or \funcname{krb5_send_auth}. - -\begin{funcdecl}{krb5_free_tkt_authent}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_tkt_authent *}{val} -\end{funcdecl} - -Frees the ticket and authenticator portions of \funcparam{val}. The -pointer \funcparam{val} is freed as well. - -\begin{funcdecl}{krb5_free_pwd_data}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{passwd_pwd_data *}{val} -\end{funcdecl} - -Frees the pwd_data \funcparam{val} that has been allocated from -\funcname{decode_krb5_pwd_data}. - -\begin{funcdecl}{krb5_free_pwd_sequences}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{passwd_phrase_element **}{val} -\end{funcdecl} - -Frees the passwd_phrase_element \funcparam{val}. This is usually called -from \funcname{krb5_free_pwd_data}. - -\begin{funcdecl}{krb5_free_realm_tree}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_principal *}{realms} -\end{funcdecl} - -Frees the realms tree \funcparam{realms} returned by -\funcname{krb5_walk_realm_tree}. - -\begin{funcdecl}{krb5_free_tgt_creds}{void}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_creds **}{tgts} -\end{funcdecl} - -Frees the TGT credentials \funcparam{tgts} returned by -\funcname{krb5_get_cred_from_kdc}. - diff --git a/doc/api/functions.sty b/doc/api/functions.sty deleted file mode 100644 index a3165f811..000000000 --- a/doc/api/functions.sty +++ /dev/null @@ -1,70 +0,0 @@ -% -% definitions related to function declarations/displays -% -\ifx\undefined\@psfonts -\def\argfont{\tt} -\else -\font\argfont = pcrb -\hyphenchar\argfont = -1 -\fi -\let\funcfont=\bf -\newcount\argc@ount -%\setlength{\marginparsep}{0.05in} -%\setlength{\marginparwidth}{1.45in} -% -% This function fixes up the function name to be displayed in the -% margin so that the krb5_, if any, is stripped. -% -% Note: this is a hack; what's really happening is that name beginning with -% krb5 will have its first five characters stripped from it. -% This means that 'Krb5abc' will get rewritten to be 'bc'. -% Unfortunately, we can't do better because of the underscore -% hacks that are going on elsewhere. -% -% WARNING: This is ugly; don't look at it too soon after lunch! -% [tytso:19900920.2231EDT] -\newif\if@krbfunc -\def\endkrb{} -\def\fix@parname#1{\expandafter\parse@krb#1\endkrb% -\endkrb\endkrb\endkrb\endkrb}% In case the argument is less -% than five letters, we don't want to -% lose on the argument parsing. -\def\parse@krb#1#2#3#4#5#6\endkrb{\@krbfuncfalse% -\if#1k\if#2r\if#3b\if#45\@krbfunctrue\fi\fi\fi\fi% -\if@krbfunc#6\else#1#2#3#4#5#6\fi} -% -% funcdecl is used as \begin{funcdecl}{funcname}{return type}{firstline} -% -% see fixunder.sty for comments on why the \underrealtrue & \underrealfalse -% stuff is here. -\newenvironment{funcdecl}[3]{\underrealtrue\index{#1}\underrealfalse% -\medbreak -\gdef\funcn@me{#1} -\argc@ount=0\noindent% -%the \mbox{} is to prevent the line/paragraph breaking from eating the -%fill space. -\marginpar[{{\sloppy \hfil\fix@parname{\funcn@me}\hfill\mbox{}}}]% -{{\sloppy \hfill\fix@parname{\funcn@me}\hfil\mbox{}}}% -\vbox\bgroup\begin{minipage}[t]{\textwidth}\begin{tabbing} -#2 \\ -{\bf #1}(\= \+ #3% -}{) -\end{tabbing}\vfil\end{minipage}\egroup\par\nopagebreak -} -\newcommand{\docomm@}{\ifnum\argc@ount >0, \\\fi} -\newcommand{\funcvoid}{\argc@ount=0} -\newcommand{\funcin}{\docomm@\argc@ount=0{\sl /* IN */}\\} -\newcommand{\funcinout}{\docomm@\argc@ount=0{\sl /* IN/OUT */}\\} -\newcommand{\funcout}{\docomm@\argc@ount=0{\sl /* OUT */}\\} -\newcommand{\funcarg}[2]{\docomm@#1 {\argfont #2}\advance\argc@ount by1} -\newcommand{\funcparam}[1]{{\argfont #1}} -\newcommand{\funcfuncarg}[2]{\docomm@#1 {\argfont #2}(\= \+ \argc@ount=0} -\newcommand{\funcendfuncarg}{), \- \\ \argc@ount=0} -\newcommand{\libname}[1]{{\argfont #1}} -\newcommand{\globalname}[1]{{\argfont #1}} -\newcommand{\ptsto}{->\discretionary{}{}{}} -\newcommand{\datatype}[1]{{\bf #1}} -\newcommand{\filename}[1]{{\sl #1\/}} - -\newcommand{\funcname}[1]{\underrealtrue\index{#1}\underrealfalse{\funcfont #1}()} -\newcommand{\funcnamenoparens}[1]{\underrealtrue\index{#1}\underrealfalse{\funcfont #1}} diff --git a/doc/api/intro.tex b/doc/api/intro.tex deleted file mode 100644 index 370775b02..000000000 --- a/doc/api/intro.tex +++ /dev/null @@ -1,299 +0,0 @@ - This document describes the routines that make up the Kerberos -V5 application programming interface. It is geared towards -programmers who already have a basic familiarity with Kerberos and are -in the process of including Kerberos authentication as part of -applications being developed. - - The function descriptions included are up to date, even if the -description of the functions may be hard to understand for the novice -Kerberos programmer. - -\subsection{Acknowledgments} - - -The Kerberos model is based in part on Needham and Schroeder's trusted -third-party authentication protocol and on modifications suggested by -Denning and Sacco. The original design and implementation of Kerberos -Versions 1 through 4 was the work of Steve Miller of Digital Equipment -Corporation and Clifford Neuman (now at the Information Sciences -Institute of the University of Southern California), along with Jerome -Saltzer, Technical Director of Project Athena, and Jeffrey Schiller, -MIT Campus Network Manager. Many other members of Project Athena have -also contributed to the work on Kerberos. Version 4 is publicly -available, and has seen wide use across the Internet. - -Version 5 (described in this document) has evolved from Version 4 based -on new requirements and desires for features not available in Version 4. - -%nlg- a bunch more probably needs to be added here to credit all -%those that have contributed to V5 -nlg - -\subsection{Kerberos Basics} - -Kerberos performs authentication as a trusted third-party -authentication service by using conventional (shared secret -key\footnote{ {\em Secret} and {\em private} are often used -interchangeably in the literature. In our usage, it takes two (or -more) to share a secret, thus a shared DES key is a {\em secret} key. -Something is only private when no one but its owner knows it. Thus, -in public key cryptosystems, one has a public and a {\em private} key. -}) cryptography. Kerberos provides a means of verifying the -identities of principals, without relying on authentication by the -host operating system, without basing trust on host addresses, without -requiring physical security of all the hosts on the network, and under -the assumption that packets traveling along the network can be read, -modified, and inserted at will. - -When integrating Kerberos into an application it is important to -review how and when Kerberos functions are used to ensure that the -application's design does not compromise the authentication. For -instance, an application which uses Kerberos' functions only upon the -{\em initiation} of a stream-based network connection, and assumes the -absence of any active attackers who might be able to ``hijack'' the -stream connection. - -%{\Huge nlg- It would be nice to include more examples here of common -%mistakes one can make in designing kerberized systems -nlg} - -The Kerberos protocol code libraries, whose API is described in this -document, can be used to provide encryption to any application. In -order to add authentication to its transactions, a typical network -application adds one or two calls to the Kerberos library, which -results in the transmission of the necessary messages to achieve -authentication. - -The two methods for obtaining credentials, the initial ticket exchange -and the ticket granting ticket exchange, use slightly different -protocols and require different API routines. The basic difference an -API programmer will see is that the initial request does not require a -ticket granting ticket (TGT) but does require the client's secret key -because the reply is sent back encrypted in the client's secret key. -Usually this request is for a TGT and TGT based exchanges are used -from then on. In a TGT exchange the TGT is sent as part of the -request for tickets and the reply is encrypted in the session key from -the TGT. For example, once a user's password is used to obtain a TGT, -it is not required for subsequent TGT exchanges. - -The reply consists of a ticket and a session key, encrypted either in -the user's secret key (i.e., password), or the TGT session key. The -combination of a ticket and a session key is known as a set of {\em -credentials}.\footnote{In Kerberos V4, the ``ticket file'' was a bit of -a misnomer, since it contained both tickets and their associated session -keys. In Kerberos V5, the ``ticket file'' has been renamed to be the -{\em credentials cache}.} An application client can use these -credentials to authenticate to the application server by sending the -ticket and an {\em authenticator} to the server. The authenticator is -encrypted in the session key of the ticket, and contains the name of the -client, the name of the server, the time the authenticator was created. - -In order to verify the authentication, the application server decrypts -the ticket using its service key, which is only known by the application -server and the Kerberos server. Inside the ticket, the Kerberos server -had placed the name of the client, the name of the server, a DES key -associated with this ticket, and some additional information. The -application server then uses the ticket session key to decrypt the -authenticator, and verifies that the information in the authenticator -matches the information in the ticket, and that the timestamp in the -authenticator is recent (to prevent reply attacks). Since the session -key was generated randomly by the Kerberos server, and delivered only -encrypted in the service key, and in a key known only by the user, the -application server can be confident that user is really who he or she -claims to be, by virtue of the fact that the user was able to encrypt -the authenticator in the correct key. - -To provide detection of both replay -attacks and message stream modification attacks, the integrity of all -the messages exchanged between principals can also be -guar\-an\-teed\footnote{Using -\funcname{krb5_mk_safe} and \funcname{krb5_rd_safe} to create and -verify KRB5_SAFE messages} by generating and transmitting a -collision-proof checksum\footnote{aka cryptographic checksum, -elsewhere this is called a hash or digest function} of the client's -message, keyed with the session key. Privacy and integrity of the -messages exchanged between principals can be secured\footnote{Using -\funcname{krb5_mk_priv} and \funcname{krb5_rd_priv} to create and -verify KRB5_PRIV messages} by encrypting the data to be passed using -the session key. - -\subsubsection{The purpose of Realms} - -The Kerberos protocol is designed to operate across organizational -boundaries. Each organization wishing to run a Kerberos -server establishes its own {\em realm}. The name of the realm in which a -client is registered is part of the client's name, and can be used by the -end-service to decide whether to honor a request. - -By establishing {\em inter-realm} keys, the administrators of two -realms can allow a client authenticated in the local realm to use its -credentials remotely. The exchange of inter-realm keys (a separate -key may be used for each direction) registers the ticket-granting -service of each realm as a principal in the other realm. A client is -then able to obtain a ticket-granting ticket for the remote realm's -ticket-granting service from its local realm. When that -ticket-granting ticket is used, the remote ticket-granting service -uses the inter-realm key (which usually differs from its own normal -TGS key) to decrypt the ticket-granting ticket, and is thus certain -that it was issued by the client's own TGS. Tickets issued by the -remote ticket-granting service will indicate to the end-service that -the client was authenticated from another realm. - - -This method can be repeated to authenticate throughout an organization -across multiple realms. To build a valid authentication -path\footnote{An {\em authentication path} is the sequence of -intermediate realms that are transited in communicating from one realm -to another.} to a distant realm, the local realm must share an -inter-realm key with an intermediate realm which -communicates\footnote{A realm is said to {\em communicate} with -another realm if the two realms share an inter-realm key} with either -the distant remote realm or yet another intermediate realm. - -Realms are typically organized hierarchically. Each realm shares a -key with its parent and a different key with each child. If an -inter-realm key is not directly shared by two realms, the hierarchical -organization allows an authentication path to be easily constructed. -If a hierarchical organization is not used, it may be necessary to -consult some database in order to construct an authentication path -between realms. - -Although realms are typically hierarchical, intermediate realms may be -bypassed to achieve cross-realm authentication through alternate -authentication paths\footnote{These might be established to make communication -between two realms more efficient}. It is important for the -end-service to know which realms were transited when deciding how much -faith to place in the authentication process. To facilitate this -decision, a field in each ticket contains the names of the realms that -were involved in authenticating the client. - -\subsubsection{Fundamental assumptions about the environment} - -Kerberos has certain limitations that should be kept in mind when -designing security measures: - -\begin{itemize} -\item -Kerberos does not address ``Denial of service'' attacks. There are -places in these protocols where an intruder can prevent an application -from participating in the proper authentication steps. Detection and -solution of such attacks (some of which can appear to be not-uncommon -``normal'' failure modes for the system) is usually best left to -the human administrators and users. - -\item -Principals must keep their secret keys secret. If an intruder somehow -steals a principal's key, it will be able to masquerade as that -principal or impersonate any server to the legitimate principal. - -\item -``Password guessing'' attacks are not solved by Kerberos. If a user -chooses a poor password, it is possible for an attacker to -successfully mount an offline dictionary attack by repeatedly -attempting to decrypt, with successive entries from a dictionary, -messages obtained which are encrypted under a key derived from the -user's password. - -\end{itemize} - -\subsection{Glossary of terms} - -Below is a list of terms used throughout this document. - -\begin{description} -\item [Authentication] -Verifying the claimed identity of a principal. - -\item [Authentication header] -A record containing a Ticket and an Authenticator to be presented to a -server as part of the authentication process. - -\item [Authentication path] -A sequence of intermediate realms transited in the authentication -process when communicating from one realm to another. - -\item [Authenticator] -A record containing information that can be shown to -have been recently generated using the session key known only by the -client and server. - -\item [Authorization] -The process of determining whether a client may use a -service, which objects the client is allowed to access, and the -type of access allowed for each. - -\item [Ciphertext] -The output of an encryption function. Encryption transforms plaintext -into ciphertext. - -\item [Client] -A process that makes use of a network service on behalf of a -user. Note that in some cases a {\em Server} may itself be a client of -some other server (e.g. a print server may be a client of a file server). - -\item [Credentials] -A ticket plus the secret session key necessary to -successfully use that ticket in an authentication exchange. - -\item [KDC] -Key Distribution Center, a network service that supplies -tickets and temporary session keys; or an -instance of that service or the host on which it runs. -The KDC services both initial ticket and ticket-granting ticket -requests. -The initial ticket portion is sometimes referred to as the -Authentication Server (or service). -The ticket-granting ticket portion is sometimes referred to as the -ticket-granting server (or service). - -\item [Kerberos] -Aside from the 3-headed dog guarding Hades, the name given -to Project Athena's authentication service, the protocol used by that -service, or the code used to implement the authentication service. - -\item [Plaintext] -The input to an encryption function or the output of a decryption -function. Decryption transforms ciphertext into plaintext. - -\item [Principal] -A uniquely named client or server instance that participates in -a network communication. - -\item [Principal identifier] -The name used to uniquely identify each different -principal. - -\item [Seal] -To encipher a record containing several fields in such a way -that the fields cannot be individually replaced without either -knowledge of the encryption key or leaving evidence of tampering. - -\item [Secret key] -An encryption key shared by a principal and the KDC, -distributed outside the bounds of the system, with a long lifetime. -In the case of a human user's principal, the secret key is derived from a -password. - -\item [Server] -A particular Principal which provides a resource to network clients. - -\item [Service] -A resource provided to network clients; often provided by more than one -server (for example, remote file service). - -\item [Session key] -A temporary encryption key used between two principals, -with a lifetime limited to the duration of a single login -{\em session}. - -\item [Sub-session key] -A temporary encryption key used between two -principals, selected and exchanged by the principals using the session -key, and with a lifetime limited to the duration of a single -association. - -\item [Ticket] -A record that helps a client authenticate itself to a server; it contains -the client's identity, a session key, a timestamp, and other -information, all sealed using the server's secret key. It only serves to -authenticate a client when presented along with a fresh Authenticator. - -\end{description} diff --git a/doc/api/keytab.tex b/doc/api/keytab.tex deleted file mode 100644 index 63e27e538..000000000 --- a/doc/api/keytab.tex +++ /dev/null @@ -1,221 +0,0 @@ -The key table functions deal with storing and retrieving service keys -for use by unattended services which participate in authentication exchanges. - -Keytab routines are all be atomic. Every routine that acquires -a non-sharable resource releases it before it returns. - -All keytab types support multiple concurrent sequential scans. - -The order of values returned from \funcname{krb5_kt_next_entry} is -unspecified. - -Although the ``right thing'' should happen if the program aborts -abnormally, a close routine, \funcname{krb5_kt_free_entry}, is provided -for freeing resources, etc. People should use the close routine when -they are finished. - -\begin{funcdecl}{krb5_kt_register}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_kt_ops *}{ops} -\end{funcdecl} - - -Adds a new ticket cache type to the set recognized by -\funcname{krb5_kt_resolve}. -Requires that a keytab type named \funcparam{ops{\ptsto}prefix} is not -yet known. - -An error is returned if \funcparam{ops{\ptsto}prefix} is already known. - -\begin{funcdecl}{krb5_kt_resolve}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const char *}{string_name} -\funcout -\funcarg{krb5_keytab *}{id} -\end{funcdecl} - -Fills in \funcparam{*id} with a handle identifying the keytab with name -``string_name''. The keytab is not opened. -Requires that \funcparam{string_name} be of the form ``type:residual'' and -``type'' is a type known to the library. - -Errors: badly formatted name. - -\begin{funcdecl}{krb5_kt_default_name}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{char *}{name} -\funcarg{int}{namesize} -\end{funcdecl} - -\funcparam{name} is filled in with the first \funcparam{namesize} bytes of -the name of the default keytab. -If the name is shorter than \funcparam{namesize}, then the remainder of -\funcparam{name} will be zeroed. - - -\begin{funcdecl}{krb5_kt_default}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_keytab *}{id} -\end{funcdecl} - -Fills in \funcparam{id} with a handle identifying the default keytab. - -\begin{funcdecl}{krb5_kt_read_service_key}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_pointer}{keyprocarg} -\funcarg{krb5_principal}{principal} -\funcarg{krb5_kvno}{vno} -\funcarg{krb5_keytype}{keytype} -\funcout -\funcarg{krb5_keyblock **}{key} -\end{funcdecl} - -If \funcname{keyprocarg} is not NULL, it is taken to be a -\datatype{char *} denoting the name of a keytab. Otherwise, the default -keytab will be used. -The keytab is opened and searched for the entry identified by -\funcparam{principal}, \funcparam{keytype}, and \funcparam{vno}, -returning the resulting key -in \funcparam{*key} or returning an error code if it is not found. - -\funcname{krb5_free_keyblock} should be called on \funcparam{*key} when -the caller is finished with the key. - -Returns an error code if the entry is not found. - -\begin{funcdecl}{krb5_kt_add_entry}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_keytab}{id} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Calls the keytab-specific add routine \funcname{krb5_kt_add_internal} -with the same function arguments. If this routine is not available, -then KRB5_KT_NOWRITE is returned. - -\begin{funcdecl}{krb5_kt_remove_entry}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_keytab}{id} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Calls the keytab-specific remove routine -\funcname{krb5_kt_remove_internal} with the same function arguments. -If this routine is not available, then KRB5_KT_NOWRITE is returned. - -\begin{funcdecl}{krb5_kt_get_name}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{char *}{name} -\funcin -\funcarg{unsigned int}{namesize} -\end{funcdecl} - -\funcarg{name} is filled in with the first \funcparam{namesize} bytes of -the name of the keytab identified by \funcname{id}. -If the name is shorter than \funcparam{namesize}, then \funcarg{name} -will be null-terminated. - -\begin{funcdecl}{krb5_kt_close}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\end{funcdecl} - -Closes the keytab identified by \funcparam{id} and invalidates -\funcparam{id}, and releases any other resources acquired during use of -the key table. - -Requires that \funcparam{id} identifies a keytab. - -\begin{funcdecl}{krb5_kt_get_entry}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\funcin -\funcarg{krb5_principal}{principal} -\funcarg{krb5_kvno}{vno} -\funcarg{krb5_keytype}{keytype} -\funcout -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -\begin{sloppypar} -Searches the keytab identified by \funcparam{id} for an entry whose -principal matches \funcparam{principal}, whose keytype matches -\funcparam{keytype}, and -whose key version number matches \funcparam{vno}. If \funcparam{vno} is -zero, the first entry whose principal matches is returned. -\end{sloppypar} - -Returns an error code if no suitable entry is found. If an entry is -found, the entry is returned in \funcparam{*entry}; its contents should -be deallocated by calling \funcname{krb5_kt_free_entry} when no longer -needed. - -\begin{funcdecl}{krb5_kt_free_entry}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Releases all storage allocated for \funcparam{entry}, which must point -to a structure previously filled in by \funcname{krb5_kt_get_entry} or -\funcname{krb5_kt_next_entry}. - -\begin{funcdecl}{krb5_kt_start_seq_get}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{krb5_kt_cursor *}{cursor} -\end{funcdecl} - -Prepares to read sequentially every key in the keytab identified by -\funcparam{id}. -\funcparam{cursor} is filled in with a cursor to be used in calls to -\funcname{krb5_kt_next_entry}. - -\begin{funcdecl}{krb5_kt_next_entry}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{krb5_keytab_entry *}{entry} -\funcinout -\funcarg{krb5_kt_cursor *}{cursor} -\end{funcdecl} - -Fetches the ``next'' entry in the keytab, returning it in -\funcparam{*entry}, and updates \funcparam{*cursor} for the next -request. If the keytab changes during the sequential get, an error is -guaranteed. \funcparam{*entry} should be freed after use by calling -\funcname{krb5_kt_free_entry}. - -Requires that \funcparam{id} identifies a valid keytab. and -\funcparam{*cursor} be a cursor returned by -\funcname{krb5_kt_start_seq_get} or a subsequent call to -\funcname{krb5_kt_next_entry}. - -Errors: error code if no more cache entries or if the keytab changes. - -\begin{funcdecl}{krb5_kt_end_seq_get}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_keytab}{id} -\funcarg{krb5_kt_cursor *}{cursor} -\end{funcdecl} - -Finishes sequential processing mode and invalidates \funcparam{cursor}, -which must never be re-used after this call. - -Requires that \funcparam{id} identifies a valid keytab and -\funcparam{*cursor} be a cursor returned by -\funcname{krb5_kt_start_seq_get} or a subsequent call to -\funcname{krb5_kt_next_entry}. - -May return error code if \funcparam{cursor} is invalid. - - diff --git a/doc/api/krb5.ist b/doc/api/krb5.ist deleted file mode 100644 index 36e9adb2b..000000000 --- a/doc/api/krb5.ist +++ /dev/null @@ -1,26 +0,0 @@ -%% -%% This is based on the gind.ist -%% -actual '=' -quote '!' -level '>' -preamble -"\n \\begin{theindex} \n" -postamble -"\n\n \\end{theindex}\n" -item_x1 "\\efill \n \\subitem " -item_x2 "\\efill \n \\subsubitem " -delim_0 "\\pfill " -delim_1 "\\pfill " -delim_2 "\\pfill " -% The next lines will produce some warnings when -% running Makeindex as they try to cover two different -% versions of the program: -lethead_prefix "{\\bfseries\\hfil " -lethead_suffix "\\hfil}\\nopagebreak\n" -lethead_flag 1 -heading_prefix "{\\bfseries\\hfil " -heading_suffix "\\hfil}\\nopagebreak\n" -headings_flag 1 -%% -%% diff --git a/doc/api/krb5.tex b/doc/api/krb5.tex deleted file mode 100644 index 1574f169b..000000000 --- a/doc/api/krb5.tex +++ /dev/null @@ -1,1810 +0,0 @@ -The main functions deal with the nitty-gritty details: verifying -tickets, creating authenticators, and the like. - -\subsubsection{The krb5_context} -The \datatype{krb5_context} is designed to represent the per process -state. When the library is made thread-safe, the context will represent -the per-thread state. Global parameters which are ``context'' specific -are stored in this structure, including default realm, default -encryption type, default configuration files and the like. Functions -exist to provide full access to the data structures stored in the -context and should not be accessed directly by developers. - -\begin{funcdecl}{krb5_init_context}{krb5_error_code}{\funcout} -\funcarg{krb5_context *}{context} -\end{funcdecl} - -Initializes the context \funcparam{*context} for the -application. Currently the context contains the encryption types, a -pointer to operating specific data and the default realm. In the future, -the context may be also contain thread specific data. The data in the -context should be freed with \funcname{krb5_free_context}. - -Returns system errors. - -\begin{funcdecl}{krb5_free_context}{void}{\funcinout} -\funcarg{krb5_context}{context} -\end{funcdecl} - -Frees the context returned by \funcname{krb5_init_context}. Internally -calls \funcname{krb5_os_free_context}. - -\begin{funcdecl}{krb5_set_default_in_tkt_etypes}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_enctype *}{etypes} -\end{funcdecl} - -Sets the desired default encryption type \funcparam{etypes} for the context -if valid. - -Returns {\sc enomem}, {\sc krb5_prog_etype_nosupp}. - -\begin{funcdecl}{krb5_get_default_in_tkt_etypes}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_enctype **}{etypes} -\end{funcdecl} - -Retrieves the default encryption types from the context and stores them -in \funcarg{etypes} which should be freed by the caller. - -Returns {\sc enomem}. - -\subsubsection{The krb5_auth_context} - -While the \datatype{krb5_context} represents a per-process or per-thread -context, the \datatype{krb5_auth_context} represents a per-connection -context are are used by the various functions involved directly in -client/server authentication. Some of the data stored in this context -include keyblocks, addresses, sequence numbers, authenticators, checksum -type, and replay cache pointer. - -\begin{funcdecl}{krb5_auth_con_init}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_auth_context *}{auth_context} -\end{funcdecl} - -The auth_context may be described as a per connection context. This -context contains all data pertinent to the the various authentication -routines. This function initializes the auth_context. - -The default flags for the context are set to enable the use of the replay cache -(KRB5_AUTH_CONTEXT_DO_TIME) but no sequence numbers. The function -\funcname{krb5_auth_con_setflags} allows the flags to be changed. - -The default checksum type is set to CKSUMTYPE_RSA_MD4_DES. This may be -changed with \funcname{krb5_auth_con_setcksumtype}. - -The auth_context structure should be freed with -\funcname{krb5_auth_con_free}. - -\begin{funcdecl}{krb5_auth_con_free}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\end{funcdecl} - -Frees the auth_context \funcparam{auth_context} returned by -\funcname{krb5_auth_con_init}. - -% perhaps some comment about which substructures are freed and which are not? - -\begin{funcdecl}{krb5_auth_con_setflags}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_int32}{flags} -\end{funcdecl} - -Sets the flags of \funcparam{auth_context} to funcparam{flags}. Valid -flags are: - -\begin{tabular}{ll} -\multicolumn{1}{c}{Symbol} & Meaning \\ -KRB5_AUTH_CONTEXT_DO_TIME & Use timestamps \\ -KRB5_AUTH_CONTEXT_RET_TIME & Save timestamps\\ &\ to output structure\\ -KRB5_AUTH_CONTEXT_DO_SEQUENCE & Use sequence numbers \\ -KRB5_AUTH_CONTEXT_RET_SEQUENCE & Copy sequence numbers \\ &\ to output structure\\ -\end{tabular} - - -\begin{funcdecl}{krb5_auth_con_getflags}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_int32 *}{flags} -\end{funcdecl} - -Retrievs the flags of \funcparam{auth_context}. - -\begin{funcdecl}{krb5_auth_con_setaddrs}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_address *}{local_addr} -\funcarg{krb5_address *}{remote_addr} -\end{funcdecl} - -Copies the \funcparam{local_addr} and \funcparam{remote_addr} into the -\funcparam{auth_context}. If either address is NULL, the previous -address remains in place. - -\begin{funcdecl}{krb5_auth_con_getaddrs}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_address **}{local_addr} -\funcarg{krb5_address **}{remote_addr} -\end{funcdecl} - -Retrieves \funcparam{local_addr} and \funcparam{remote_addr} from the -\funcparam{auth_context}. If \funcparam{local_addr} or -\funcparam{remote_addr} is not NULL, the memory is first freed with -\funcname{krb5_free_address} and then newly allocated. It is the callers -responsibility to free the returned addresses in this way. - - -\begin{funcdecl}{krb5_auth_con_setports}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_address *}{local_port} -\funcarg{krb5_address *}{remote_port} -\end{funcdecl} - -Copies the \funcparam{local_port} and \funcparam{remote_port} addresses -into the \funcparam{auth_context}. If either address is NULL, the previous -address remains in place. These addresses are set by -\funcname{krb5_auth_con_genaddrs}. - -\begin{funcdecl}{krb5_auth_con_setuserkey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_keyblock *}{keyblock} -\end{funcdecl} - -This function overloads the keyblock field. It is only useful prior to a -\funcname{krb5_rd_req_decode} call for user to user authentication where -the server has the key and needs to use it to decrypt the incoming -request. Once decrypted this key is no longer necessary and is then -overwritten with the session key sent by the client. - -\begin{funcdecl}{krb5_auth_con_getkey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_keyblock **}{keyblock} -\end{funcdecl} - -Retrieves the keyblock stored in \funcparam{auth_context}. The memory -allocated in this function should be freed with a call to -\funcname{krb5_free_keyblock}. - -\begin{funcdecl}{krb5_auth_con_getlocalsubkey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_keyblock **}{keyblock} -\end{funcdecl} - -Retrieves the local_subkey keyblock stored in -\funcparam{auth_context}. The memory allocated in this function should -be freed with a call to \funcname{krb5_free_keyblock}. - -\begin{funcdecl}{krb5_auth_con_getremotesubkey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_keyblock **}{keyblock} -\end{funcdecl} - -Retrieves the remote_subkey keyblock stored in -\funcparam{auth_context}. The memory allocated in this function should -be freed with a call to \funcname{krb5_free_keyblock}. - - -\begin{funcdecl}{krb5_auth_setcksumtype}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_cksumtype}{cksumtype} -\end{funcdecl} - -Sets the checksum type used by the other functions in the library. - -\begin{funcdecl}{krb5_auth_getlocalseqnumber}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_int32 *}{seqnumber} -\end{funcdecl} - -Retrieves the local sequence number that was used during authentication -and stores it in \funcparam{seqnumber}. - -\begin{funcdecl}{krb5_auth_getremoteseqnumber}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_int32 *}{seqnumber} -\end{funcdecl} - -Retrieves the remote sequence number that was used during authentication -and stores it in \funcparam{seqnumber}. - -\begin{funcdecl}{krb5_auth_getauthenticator}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_authenticator **}{authenticator} -\end{funcdecl} - -Retrieves the authenticator that was used during mutual -authentication. It is the callers responsibility to free the memory -allocated to \funcparam{authenticator} by calling -\funcname{krb5_free_authenticator}. - -\begin{funcdecl}{krb5_auth_con_initivector}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\end{funcdecl} - -Allocates memory for and zeros the initial vector in the -\funcparam{auth_context} keyblock. - -\begin{funcdecl}{krb5_auth_con_setivector}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{krb5_pointer}{ivector} -\end{funcdecl} - -Sets the i_vector portion of \funcparam{auth_context} to -\funcparam{ivector}. - -\begin{funcdecl}{krb5_auth_con_setrcache}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{krb5_rcache}{rcache} -\end{funcdecl} - -Sets the replay cache that is used by the authentication routines to \funcparam{rcache}. - -%% -%% The following prototypes exist, but there is no code at this time -%% krb5_auth_con_getcksumtype, krb5_auth_con_getivector, -%% krb5_auth_con_getrcache. -- Ezra - -\subsubsection{Principal access functions} - -Principals define a uniquely named client or server instance that -participates in a network communication. The following functions allow -one to create, modify and access portions of the -\datatype{krb5_principal}. - -Other functions found in orther portions of the manual include -\funcname{krb5_sname_to_principal}, \funcname{krb5_free_principal}, - -While it is possible to directly access the data structure in the -structure, it is recommended that the functions be used. - -\begin{funcdecl}{krb5_parse_name}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const char *}{name} -\funcout -\funcarg{krb5_principal *}{principal} -\end{funcdecl} - -Converts a single-string representation \funcparam{name} of the -principal name to the multi-part principal format used in the protocols. - -A single-string representation of a Kerberos name consists of one or -more principal name components, separated by slashes, optionally -followed by the ``@'' character and a realm name. If the realm name -is not specified, the local realm is used. - -The slash and ``@'' characters may be quoted (i.e., included as part -of a component rather than as a component separator or realm prefix) -by preceding them with a backslash (``$\backslash$'') character. -Similarly, newline, tab, backspace, and null characters may be -included in a component by using $\backslash{}n$, $\backslash{}t$, -$\backslash{}b$ or $\backslash{}0$, respectively. - -The realm in a Kerberos name may not contain the slash, colon or null -characters. - -\funcparam{*principal} will point to allocated storage which should be freed by -the caller (using \funcname{krb5_free_principal}) after use. - -\funcname{krb5_parse_name} returns KRB5_PARSE_MALFORMED if the string is - badly formatted, or ENOMEM if space for the return value can't be -allocated. - -\begin{funcdecl}{krb5_unparse_name}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_const_principal}{principal} -\funcout -\funcarg{char **}{name} -\end{funcdecl} - -Converts the multi-part principal name \funcparam{principal} from the -format used in the protocols to a single-string representation of the -name. The resulting single-string representation will use the format -and quoting conventions described for \funcname{krb5_parse_name} -above. - -\funcparam{*name} points to allocated storage and should be freed by the caller -when finished. - -\funcname{krb5_unparse_name} returns {\sc KRB_PARSE_MALFORMED} if the principal -does not contain at least 2 components, and system errors ({\sc ENOMEM} if -unable to allocate memory). - -\begin{funcdecl}{krb5_unparse_name_ext}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_const_principal}{principal} -\funcinout -\funcarg{char **}{name} -\funcarg{unsigned int *}{size} -\end{funcdecl} - -\funcname{krb5_unparse_name_ext} is designed for applications which -must unparse a large number of principals, and are concerned about the -speed impact of needing to do a lot of memory allocations and -deallocations. It functions similarly to \funcname{krb5_unparse_name} -except if \funcparam{*name} is non-null, in which case, it is assumed -to contain an allocated buffer of size \funcparam{*size} and this -buffer will be resized with \funcname{realloc} to hold the unparsed -name. Note that in this case, -\funcparam{size} must not be null. - -If \funcparam{size} is non-null (whether or not \funcparam{*name} is -null when the function is called), it will be filled in with the size -of the unparsed name upon successful return. - -\begin{funcdecl}{krb5_princ_realm}{krb5_data *}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\end{funcdecl} - -A macro which returns the realm of \funcparam{principal}. - -\begin{funcdecl}{krb5_princ_set_realm}{void}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\funcparam{krb5_data *}{realm} -\end{funcdecl} - -A macro which returns sets the realm of \funcparam{principal} to -\funcparam{realm}. - -\begin{funcdecl}{krb5_princ_set_realm_data}{void}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\funcparam{char *}{data} -\end{funcdecl} - -\internalfunc - -A macro which returns sets the data portion of the realm of -\funcparam{principal} to \funcparam{data}. - -\begin{funcdecl}{krb5_princ_set_realm_length}{void}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\funcparam{int}{length} -\end{funcdecl} - -\internalfunc - -A macro which returns sets the length \funcparam{principal} to -\funcparam{length}. - -\begin{funcdecl}{krb5_princ_size}{void}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\end{funcdecl} - -\internalfunc - -A macro which gives the number of elements in the principal. -May also be used on the left size of an assignment. - -\begin{funcdecl}{krb5_princ_type}{void}{\funcinout} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\end{funcdecl} - -\internalfunc - -A macro which gives the type of the principal. -May also be used on the left size of an assignment. - -\begin{funcdecl}{krb5_princ_data}{} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\end{funcdecl} - -\internalfunc - -A macro which gives the pointer to data portion of the principal. -May also be used on the left size of an assignment. - - -\begin{funcdecl}{krb5_princ_component}{} -\funcparam{krb5_context}{context} -\funcparam{krb5_principal}{principal} -\funcparam{int}{i} -\end{funcdecl} - -\internalfunc - -A macro which gives the pointer to ith element of the principal. -May also be used on the left size of an assignment. - -\begin{funcdecl}{krb5_build_principal}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_principal *}{princ} -\funcin -\funcarg{unsigned int}{rlen} -\funcarg{const char *}{realm} -\funcarg{char}{*s1, *s2, ..., 0} -\end{funcdecl} -\begin{funcdecl}{krb5_build_principal_va}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_principal *}{princ} -\funcin -\funcarg{unsigned int}{rlen} -\funcarg{const char *}{realm} -\funcarg{va_list}{ap} -\end{funcdecl} - -\begin{sloppypar} -\funcname{krb5_build_principal} and -\funcname{krb5_build_principal_va} -perform the same function; the former takes variadic arguments, while -the latter takes a pre-computed varargs pointer. -\end{sloppypar} - -Both functions take a realm name \funcparam{realm}, realm name length -\funcparam{rlen}, and a list of null-terminated strings, and fill in a -pointer to a principal structure \funcparam{princ}, making it point to a -structure representing the named principal. -The last string must be followed in the argument list by a null pointer. - - -\begin{funcdecl}{krb5_build_principal_ext}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_principal *}{princ} -\funcin -\funcarg{unsigned int}{rlen} -\funcarg{const char *}{realm} -\funcarg{}{int len1, char *s1, int len2, char *s2, ..., 0} -\end{funcdecl} - -\funcname{krb5_build_principal_ext} is similar to -\funcname{krb5_build_principal} but it takes its components as a list of -(length, contents) pairs rather than a list of null-terminated strings. -A length of zero indicates the end of the list. - -\begin{funcdecl}{krb5_copy_principal}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_const_principal}{inprinc} -\funcout -\funcarg{krb5_principal *}{outprinc} -\end{funcdecl} - -Copy a principal structure, filling in \funcparam{*outprinc} to point to -the newly allocated copy, which should be freed with -\funcname{krb5_free_principal}. - -\begin{funcdecl}{krb5_principal_compare}{krb5_boolean}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_const_principal}{princ1} -\funcarg{krb5_const_principal}{princ2} -\end{funcdecl} - -If the two principals are the same, return TRUE, else return FALSE. - -\begin{funcdecl}{krb5_realm_compare}{krb5_boolean}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_const_principal}{princ1} -\funcarg{krb5_const_principal}{princ2} -\end{funcdecl} - -If the realms of the two principals are the same, return TRUE, else -return FALSE. - - -\begin{funcdecl}{krb5_425_conv_principal}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const char *}{name} -\funcarg{const char *}{instance} -\funcarg{const char *}{realm} -\funcout -\funcarg{krb5_principal *}{princ} -\end{funcdecl} - -Build a principal \funcparam{princ} from a V4 specification made up of -\funcparam{name}.\funcparam{instance}@\funcparam{realm}. The routine is -site-customized to convert the V4 naming scheme to a V5 one. For -instance, the V4 ``rcmd'' is changed to ``host''. - -The returned principal should be freed with -\funcname{krb5_free_principal}. - -\subsubsection{The application functions} - -\begin{funcdecl}{krb5_encode_kdc_rep}{krb5_error_code}{\funcin} -\funcarg{const krb5_msgtype}{type} -\funcarg{const krb5_enc_kdc_rep_part *}{encpart} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{const krb5_keyblock *}{client_key} -\funcinout -\funcarg{krb5_kdc_rep *}{dec_rep} -\funcout -\funcarg{krb5_data **}{enc_rep} -\end{funcdecl} - -\internalfunc - -Takes KDC rep parts in \funcparam{*rep} and \funcparam{*encpart}, and -formats it into \funcparam{*enc_rep}, using message type -\funcparam{type} and encryption key \funcparam{client_key} and -encryption block \funcparam{eblock}. - -\funcparam{enc_rep{\ptsto}data} will point to allocated storage upon -non-error return; the caller should free it when finished. - -Returns system errors. - -\begin{funcdecl}{krb5_decode_kdc_rep}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_data *}{enc_rep} -\funcarg{const krb5_keyblock *}{key} -\funcarg{const krb5_enctype}{etype} -\funcout -\funcarg{krb5_kdc_rep **}{dec_rep} -\end{funcdecl} - -\internalfunc - -Takes a KDC_REP message and decrypts encrypted part using -\funcparam{etype} and \funcparam{*key}, putting result in \funcparam{*dec_rep}. -The pointers in \funcparam{dec_rep} -are all set to allocated storage which should be freed by the caller -when finished with the response (by using \funcname{krb5_free_kdc_rep}). - - -If the response isn't a KDC_REP (tgs or as), it returns an error from -the decoding routines. - -Returns errors from encryption routines, system errors. - -\begin{funcdecl}{krb5_kdc_rep_decrypt_proc}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{key} -\funcarg{krb5_const_pointer}{decryptarg} -\funcinout -\funcarg{krb5_kdc_rep *}{dec_rep} -\end{funcdecl} - -Decrypt the encrypted portion of \funcparam{dec_rep}, using the -encryption key \funcparam{key}. The parameter \funcparam{decryptarg} is -ignored. - -The result is in allocated storage pointed to by -\funcparam{dec_rep{\ptsto}enc_part2}, unless some error occurs. - -This function is suitable for use as the \funcparam{decrypt_proc} -argument to \funcname{krb5_get_in_tkt}. - -\begin{funcdecl}{krb5_encrypt_tkt_part}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{srv_key} -\funcinout -\funcarg{krb5_ticket *}{dec_ticket} -\end{funcdecl} - -\internalfunc - -\begin{sloppypar} -Encrypts the unecrypted part of the ticket found in -\funcparam{dec_ticket{\ptsto}enc_part2} using -\funcparam{srv_key}, and places result in -\funcparam{dec_ticket{\ptsto}enc_part}. -The \funcparam{dec_ticket{\ptsto}enc_part} will be allocated by this -function. -\end{sloppypar} - -Returns errors from encryption routines, system errors - -\funcparam{enc_part{\ptsto}data} is allocated and filled in with -encrypted stuff. - -\begin{funcdecl}{krb5_decrypt_tkt_part}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{srv_key} -\funcinout -\funcarg{krb5_ticket *}{dec_ticket} -\end{funcdecl} - -\internalfunc - -Takes encrypted \funcparam{dec_ticket{\ptsto}enc_part}, decrypts with -\funcparam{dec_ticket{\ptsto}etype} -using \funcparam{srv_key}, and places result in -\funcparam{dec_ticket{\ptsto}enc_part2}. The storage of -\funcparam{dec_ticket{\ptsto}enc_part2} will be allocated before return. - -Returns errors from encryption routines, system errors - -\begin{funcdecl}{krb5_send_tgs}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{kdcoptions} -\funcarg{const krb5_ticket_times *}{timestruct} -\funcarg{const krb5_enctype *}{etypes} -\funcarg{const krb5_cksumtype}{sumtype} -\funcarg{krb5_const_principal}{sname} -\funcarg{krb5_address * const *}{addrs} -\funcarg{krb5_authdata * const *}{authorization_data} -\funcarg{krb5_pa_data * const *}{padata} -\funcarg{const krb5_data *}{second_ticket} -\funcinout -\funcarg{krb5_creds *}{in_cred} -\funcout -\funcarg{krb5_response *}{rep} -\end{funcdecl} - -\internalfunc - -Sends a request to the TGS and waits for a response. -\funcparam{kdcoptions} is used for the options in the KRB_TGS_REQ. -\funcparam{timestruct} values are used for from, till, and rtime in the -KRB_TGS_REQ. -\funcparam{etypes} is a list of etypes used in the KRB_TGS_REQ. -\funcparam{sumtype} is used for the checksum in the AP_REQ in the KRB_TGS_REQ. -\funcparam{sname} is used for sname in the KRB_TGS_REQ. -\funcparam{addrs}, if non-NULL, is used for addresses in the KRB_TGS_REQ. -\funcparam{authorization_data}, if non-NULL, is used for -\funcparam{authorization_data} in the KRB_TGS_REQ. -\funcparam{padata}, if non-NULL, is combined with any other supplied -pre-authentication data for the KRB_TGS_REQ. -\funcparam{second_ticket}, if required by options, is used for the 2nd -ticket in the KRB_TGS_REQ. -\funcparam{in_cred} is used for the ticket and session key in the KRB_AP_REQ header in the KRB_TGS_REQ. - -The KDC realm is extracted from \funcparam{in_cred{\ptsto}server}'s realm. - -The response is placed into \funcparam{*rep}. -\funcparam{rep{\ptsto}response.data} is set to point at allocated storage -which should be freed by the caller when finished. - -Returns system errors. - -\begin{funcdecl}{krb5_get_cred_from_kdc}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_ccache}{ccache} -\funcarg{krb5_creds *}{in_cred} -\funcout -\funcarg{krb5_cred **}{out_cred} -\funcarg{krb5_creds ***}{tgts} -\end{funcdecl} - - -Retrieve credentials for principal \funcparam{in_cred{\ptsto}client}, -server \funcparam{creds{\ptsto}server}, possibly -\funcparam{creds{\ptsto}second_ticket} if needed by the ticket flags. - -\funcparam{ccache} is used to fetch initial TGT's to start the authentication -path to the server. - -Credentials are requested from the KDC for the server's realm. Any -TGT credentials obtained in the process of contacting the KDC are -returned in an array of credentials; \funcparam{tgts} is filled in to -point to an array of pointers to credential structures (if no TGT's were -used, the pointer is zeroed). TGT's may be returned even if no useful -end ticket was obtained. - -The returned credentials are NOT cached. - -If credentials are obtained, \funcparam{creds} is filled in with the results; -\funcparam{creds{\ptsto}ticket} and -\funcparam{creds{\ptsto}keyblock{\ptsto}key} are set to allocated storage, -which should be freed by the caller when finished. - -Returns errors, system errors. - -\begin{funcdecl}{krb5_get_cred_via_tkt}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_creds *}{tkt} -\funcarg{const krb5_flags}{kdcoptions} -\funcarg{krb5_address *const *}{address} -\funcarg{krb5_creds *}{in_cred} -\funcout -\funcarg{krb5_creds **}{out_cred} -\end{funcdecl} - -Takes a ticket \funcparam{tkt} and a target credential -\funcparam{in_cred}, attempts to fetch a TGS from the KDC. Upon -success the resulting is stored in \funcparam{out_cred}. The memory -allocated in \funcparam{out_cred} should be freed by the called when -finished by using \funcname{krb5_free_creds}. - -\funcparam{kdcoptions} refers to the options as listed in Table -\ref{KDCOptions}. The optional \funcparam{address} is used for addressed -in the KRB_TGS_REQ (see \funcname{krb5_send_tgs}). - -Returns errors, system errors. - - -\begin{funcdecl}{krb5_get_credentials}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{options} -\funcarg{krb5_ccache}{ccache} -\funcarg{krb5_creds *}{in_creds} -\funcout -\funcarg{krb5_creds *}{out_creds} -\end{funcdecl} - -This routine attempts to use the credentials cache \funcparam{ccache} or a TGS -exchange to get an additional ticket for the client identified by -\funcparam{in_creds{\ptsto}client}, with following information: -\begin{itemize} -\item {\bf The server} identified by \funcparam{in_creds{\ptsto}server} -\item {\bf The options} in \funcparam{options}. -Valid choices are KRB5_GC_USER_USER and KRB5_GC_GC_CACHED -\item {\bf The expiration date} specified in -\funcparam{in_creds{\ptsto}times.endtime} -\item {\bf The session key type} specified in -\funcparam{in_creds{\ptsto}keyblock.keytype} if it is non-zero. -\end{itemize} - -If \funcparam{options} specifies KRB5_GC_CACHED, -then \funcname{krb5_get_credentials} will only search the credentials cache -for a ticket. - -If \funcparam{options} specifies KRB5_GC_USER_USER, then -\funcname{krb5_get_credentials} will get credentials for a user to user -authentication. In a user to user authentication, the secret key for -the server -is the session key from the server's ticket-granting-ticket -(TGT). The TGT is passed from the server to the client over the -network --- this is safe since the TGT is encrypted in a key -known only by the Kerberos server --- and the client must pass -this TGT to \funcname{krb5_get_credentials} in -\funcparam{in_creds{\ptsto}second_ticket}. The Kerberos server will use -this TGT to construct a user to user ticket which can be verified by -the server by using the session key from its TGT. - -The effective {\bf expiration date} is the minimum of the following: -\begin{itemize} -\item The expiration date as specified in -\funcparam{in_creds{\ptsto}times.endtime} -\item The requested start time plus the maximum lifetime of the -server as specified by the server's entry in the -Kerberos database. -\item The requested start time plus the maximum lifetime of tickets -allowed in the local site, as specified by the KDC. -This is currently a compile-time option, -KRB5_KDB_MAX_LIFE in config.h, and is by default 1 day. -\end{itemize} - -If any special authorization data needs to be included in the ticket, ---- for example, restrictions on how the ticket can be used --- -they should be specified in \funcparam{in_creds{\ptsto}authdata}. If there -is no special authorization data to be passed, -\funcparam{in_creds{\ptsto}authdata} should be NULL. - -Any returned ticket and intermediate ticket-granting tickets are -stored in \funcparam{ccache}. - -Returns errors from encryption routines, system errors. - -\begin{funcdecl}{krb5_get_in_tkt}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{options} -\funcarg{krb5_address * const *}{addrs} -\funcarg{const krb5_enctype *}{etypes} -\funcarg{const krb5_preauthtype *}{ptypes} -\funcfuncarg{krb5_error_code}{(*key_proc)} - \funcarg{krb5_context}{context} - \funcarg{const krb5_keytype}{type} - \funcarg{krb5_data *}{salt} - \funcarg{krb5_const_pointer}{keyseed} - \funcarg{krb5_keyblock **}{key} -\funcendfuncarg -\funcarg{krb5_const_pointer}{keyseed} -\funcfuncarg{krb5_error_code}{(*decrypt_proc)} - \funcarg{krb5_context}{context} - \funcarg{const krb5_keyblock *}{key} - \funcarg{krb5_const_pointer}{decryptarg} - \funcarg{krb5_kdc_rep *}{dec_rep} -\funcendfuncarg -\funcarg{krb5_const_pointer}{decryptarg} -\funcinout -\funcarg{krb5_creds *}{creds} -\funcarg{krb5_ccache}{ccache} -\funcarg{krb5_kdc_rep **}{ret_as_reply} -\end{funcdecl} - -This all-purpose initial ticket routine, usually called via -\funcname{krb5_get_in_tkt_with_skey} or -\funcname{krb5_get_in_tkt_with_password} or -\funcname{krb5_get_in_tkt_with_keytab}. - - -Attempts to get an initial ticket for \funcparam{creds{\ptsto}client} -to use server \funcparam{creds{\ptsto}server}, using the following: -the realm from \funcparam{creds{\ptsto}client}; the options in -\funcparam{options} (listed in Table \ref{KDCOptions}); -and \funcparam{ptypes}, the preauthentication -method (valid preauthentication methods are listed in Table -\ref{padata-types}). -\funcname{krb5_get_in_tkt} requests encryption type -\funcparam{etypes} (valid encryption types are ETYPE_DES_CBC_CRC and -ETYPE_RAW_DES_CBC), -using \funcparam{creds{\ptsto}times.starttime}, -\funcparam{creds{\ptsto}times.endtime}, -\funcparam{creds{\ptsto}times.renew_till} -as from, till, and rtime. \funcparam{creds{\ptsto}times.renew_till} is -ignored unless the RENEWABLE option is requested. - -\funcparam{key_proc} is called, with \funcparam{context}, \funcparam{keytype}, -\funcparam{keyseed} and\funcparam{padata} as arguments, to fill in \funcparam{key} to be used for -decryption. The valid key types for \funcparam{keytype} are -KEYTYPE_NULL,\footnote{See RFC section 6.3.1} and -KEYTYPE_DES.\footnote{See RFC section 6.3.4} However, KEYTYPE_DES is -the only key type supported by MIT kerberos. -The content of \funcparam{keyseed} -depends on the \funcparam{key_proc} being used. %nlg - need a ref here -The \funcparam{padata} passed -to \funcparam{key_proc} is the preauthentication data returned by the -KDC as part of the reply to the initial ticket request. It may -contain an element of type KRB5_PADATA_PW_SALT, which -\funcparam{key_proc} should use to determine what salt to use when -generating the key. \funcparam{key_proc} should fill in -\funcparam{key} with a key for the client, or return an error code. - -\funcparam{decrypt_proc} is called to perform the decryption of the -response (the encrypted part is in -\funcparam{dec_rep{\ptsto}enc_part}; the decrypted part should be -allocated and filled into -\funcparam{dec_rep{\ptsto}enc_part2}. -\funcparam{decryptarg} is passed on to \funcparam{decrypt_proc}, and -its content depends on the \funcparam{decrypt_proc} being used. - -If \funcparam{addrs} is non-NULL, it is used for the addresses -requested. If it is null, the system standard addresses are used. - -If \funcparam{ret_as_reply} is non-NULL, it is filled in with a -pointer to a structure containing the reply packet from the KDC. Some -programs may find it useful to have direct access to this information. -For example, it can be used to obtain the pre-authentication data -passed back from the KDC. The caller is responsible for freeing this -structure by using \funcname{krb5_free_kdc_rep}. - -If \funcparam{etypes} is non-NULL, the it is used as for the list of -valid encyrption types. Otherwise, the context default is used (as -returned by \funcname{krb5_get_default_in_tkt_etypes}. - -A succesful call will place the ticket in the credentials cache -\funcparam{ccache} and fill in \funcparam{creds} with the ticket -information used/returned. - -Returns system errors, preauthentication errors, encryption errors. - -% XXX Right now, uses creds->addresses before it's copied into from -% the reply -- it's passed to krb5_obtain_padata. I think that's -% wrong, and it should be using either addrs or the result of -% krb5_os_localaddr instead. If I'm wrong, then this spec has to be -% updated to document that creds->addresses is used. On the other -% hand, if I'm right, then the bug in get_in_tkt needs to be fixed. -% See ov-cambridge PR 1525. - -\begin{funcdecl}{krb5_get_in_tkt_with_password}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{options} -\funcarg{krb5_address * const *}{addrs} -\funcarg{const krb5_enctype *}{etypes} -\funcarg{const krb5_preauthtype *}{pre_auth_types} -\funcarg{const char *}{password} -\funcarg{krb5_ccache}{ccache} -\funcinout -\funcarg{krb5_creds *}{creds} -\funcarg{krb5_kdc_rep **}{ret_as_reply} -\end{funcdecl} - -Attempts to get an initial ticket using the null-terminated string -\funcparam{password}. If \funcparam{password} is NULL, the password -is read from the terminal using as a prompt the globalname -\globalname{krb5_default_pwd_prompt1}. - -The password is converted into a key using the appropriate -string-to-key conversion function for the specified -\funcparam{keytype}, and using any salt data returned by the KDC in -response to the authentication request. - -See \funcname{krb5_get_in_tkt} for documentation of the -\funcparam{options}, \funcparam{addrs}, \funcparam{pre_auth_type}, -\funcparam{etype}, \funcparam{keytype}, \funcparam{ccache}, -\funcparam{creds} and \funcparam{ret_as_reply} arguments. - -Returns system errors, preauthentication errors, encryption errors. - -\begin{funcdecl}{krb5_get_in_tkt_with_keytab}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{options} -\funcarg{krb5_address * const *}{addrs} -\funcarg{const krb5_enctype *}{etypes} -\funcarg{const krb5_preauthtype *}{pre_auth_types} -\funcarg{const krb5_keytab *}{keytab} -\funcarg{krb5_ccache}{ccache} -\funcinout -\funcarg{krb5_creds *}{creds} -\funcarg{krb5_kdc_rep **}{ret_as_reply} -\end{funcdecl} - -Attempts to get an initial ticket using \funcparam{keytab}. If -\funcparam{keytab} is NULL, the default keytab is used -(e.g., \filename{/etc/v5srvtab}). - -See \funcname{krb5_get_in_tkt} for documentation of the -\funcparam{options}, \funcparam{addrs}, \funcparam{pre_auth_type}, -\funcparam{etype}, \funcparam{ccache}, \funcparam{creds} and -\funcparam{ret_as_reply} arguments. - -Returns system errors, preauthentication errors, encryption errors. - -\begin{funcdecl}{krb5_get_in_tkt_with_skey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_flags}{options} -\funcarg{krb5_address * const *}{addrs} -\funcarg{const krb5_enctype *}{etypes} -\funcarg{const krb5_preauthtype *}{pre_auth_types} -\funcarg{const krb5_keyblock *}{key} -\funcarg{krb5_ccache}{ccache} -\funcinout -\funcarg{krb5_creds *}{creds} -\funcarg{krb5_kdc_rep **}{ret_as_reply} -\end{funcdecl} - -Attempts to get an initial ticket using \funcparam{key}. If -\funcparam{key} is NULL, an appropriate key is retrieved from the -system key store (e.g., \filename{/etc/v5srvtab}). - -See \funcname{krb5_get_in_tkt} for documentation of the -\funcparam{options}, \funcparam{addrs}, \funcparam{pre_auth_type}, -\funcparam{etype}, \funcparam{ccache}, \funcparam{creds} and -\funcparam{ret_as_reply} arguments. - -Returns system errors, preauthentication errors, encryption errors. - -\begin{funcdecl}{krb5_mk_req}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{const krb5_flags}{ap_req_options} -\funcarg{char *}{service} -\funcarg{char *}{hostname} -\funcarg{krb5_data *}{in_data} -\funcinout -\funcarg{krb5_ccache}{ccache} -\funcout -\funcarg{krb5_data *}{outbuf} -\end{funcdecl} - -Formats a KRB_AP_REQ message into \funcparam{outbuf}. - -The server to receive the message is specified by -\funcparam{hostname}. The principal of the server to receive the message -is specified by \funcparam{hostname} and \funcparam{service}. -If credentials are not present in the credentials cache -\funcparam{ccache} for this server, the TGS request with default -parameters is used in an attempt to obtain such credentials, and they -are stored in \funcparam{ccache}. - -\funcparam{ap_req_options} specifies the KRB_AP_REQ options desired. -Valid options are: - -\begin{tabular}{ll} -AP_OPTS_USE_SESSION_KEY&\\ -AP_OPTS_MUTUAL_REQUIRED&\\ -\end{tabular} -\label{ap-req-options} - -The checksum method to be used is as specified in \funcparam{auth_context}. - -% XXX Not sure if it's legal in the protocol for no checksum to be -% included, or if so, how the server reacts to a request with no -% checksum. - -\funcparam{outbuf} should point to an existing \datatype{krb5_data} -structure. \funcparam{outbuf{\ptsto}length} and -\funcparam{outbuf{\ptsto}data} will be filled in on success, and the latter -should be freed by the caller when it is no longer needed; if an error -is returned, however, no storage is allocated and {\tt -outbuf{\ptsto}data} does not need to be freed. - -Returns system errors, error getting credentials for -\funcparam{server}. - -\begin{funcdecl}{krb5_mk_req_extended}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{const krb5_flags}{ap_req_options} -\funcarg{krb5_data *}{in_data} -\funcarg{krb5_creds *}{in_creds} -\funcout -\funcarg{krb5_data *}{outbuf} -\end{funcdecl} - -Formats a KRB_AP_REQ message into \funcparam{outbuf}, with more complete -options than \funcname{krb5_mk_req}. - -\funcparam{outbuf}, \funcparam{ap_req_options}, \funcparam{auth_context}, -and \funcparam{ccache} are used in the same fashion as for -\funcname{krb5_mk_req}. - -\funcparam{in_creds} is used to supply the credentials (ticket and session -key) needed to form the request. - -If \funcparam{in_creds{\ptsto}ticket} has no data (length == 0), then an -error is returned. - -During this call, the structure elements in \funcparam{in_creds} may be -freed and reallocated. Hence all of the structure elements which are -pointers should point to allocated memory, and there should be no other -pointers aliased to the same memory, since it may be deallocated during -this procedure call. - - -If \funcparam{ap_req_options} specifies AP_OPTS_USE_SUBKEY, then a -subkey will be generated if need be by \funcname{krb5_generate_subkey}. - -A copy of the authenticator will be stored in the -\funcparam{auth_context}, with the principal and checksum fields nulled -out, unless an error is returned. (This is to prevent pointer sharing -problems; the caller shouldn't need these fields anyway, since the -caller supplied them.) - -Returns system errors, errors contacting the KDC, KDC errors getting -a new ticket for the authenticator. - -\begin{funcdecl}{krb5_generate_subkey}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{key} -\funcout -\funcarg{krb5_keyblock **}{subkey} -\end{funcdecl} - -Generates a pseudo-random sub-session key using the encryption system's -random key functions, based on the input \funcparam{key}. - -\funcparam{subkey} is filled in to point to the generated subkey, unless -an error is returned. The returned key (i.e., \funcparam{*subkey}) is -allocated and should be freed by the caller with -\funcname{krb5_free_keyblock} when it is no longer needed. - -\begin{funcdecl}{krb5_rd_req}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{const krb5_data *}{inbuf} -\funcarg{krb5_const_principal}{server} -\funcarg{krb5_keytab}{keytab} -\funcinout -\funcarg{krb5_flags *}{ap_req_options} -\funcout -\funcarg{krb5_ticket **}{ticket} -\end{funcdecl} - -Parses a KRB_AP_REQ message, returning its contents. Upon successful -return, if \funcparam{ticket} is non-NULL, \funcparam{*ticket} will be -modified to point to allocated storage containing the ticket -information. The caller is responsible for deallocating this space by -using \funcname{krb5_free_ticket}. - -\funcparam{inbuf} should contain the KRB_AP_REQ message to be parsed. - -If \funcparam{auth_context} is NULL, one will be generated and freed -internally by the function. - -\funcparam{server} specifies the expected server's name for the ticket. -If \funcparam{server} is NULL, then any server name will be accepted if -the appropriate key can be found, and the caller should verify that the -server principal matches some trust criterion. - -If \funcparam{server} is not NULL, and a replay detaction cache has not been -established with the \funcparam{auth_context}, one will be generated. - -\funcparam{keytab} specifies a keytab containing generate a decryption key. If -NULL, \funcparam{krb5_kt_default} will be used to find the default -keytab and the key taken from there\footnote{i.e., srvtab file in -Kerberos V4 parlance}. - - -If a keyblock is present in the \funcparam{auth_context}, it will be -used to decrypt the ticket request and the keyblock freed with -\funcname{krb5_free_keyblock}. This is useful for user to user -authentication. If no keyblock is specified, the \funcparam{keytab} is -consulted for an entry matching the requested keytype, server and -version number and used instead. - -The authentcator in the request is decrypted and stored in the -\funcparam{auth_context}. The client specified in the decrypted -authenticator is compared to the client specified in the decoded ticket -to ensure that the compare. - -If the remote_addr portion of the \funcparam{auth_context} is set, -then this routine checks if the request came from the right client. - -\funcparam{sender_addr} specifies the address(es) expected to be present -in the ticket. - -The replay cache is checked to see if the ticket and authenticator have -been seen and if so, returns an error. If not, the ticket and -authenticator are entered into the cache. - -Various other checks are made of the decoded data, including, -cross-realm policy, clockskew and ticket validation times. - -The keyblock, subkey, and sequence number of the request are all stored -in the \funcparam{auth_context} for future use. - -If the request has the AP_OPTS_MUTUAL_REQUIRED bit set, the local -sequence number, which is stored in the auth_context, is XORed with the -remote sequence number in the request. - -If \funcparam{ap_req_options} is non-NULL, it will be set to contain the -application request flags. - -Returns system errors, encryption errors, replay errors. - -\begin{funcdecl}{krb5_rd_req_decoded}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{const krb5_ap_req *}{req} -\funcarg{krb5_const_principal}{server} -\funcinout -\funcarg{krb5_keytab}{keytab} -\funcout -\funcarg{krb5_ticket **}{ticket} -\end{funcdecl} - -Essentially the same as \funcname{krb5_rd_req}, but uses a decoded AP_REQ -as the input rather than an encoded input. - -\begin{funcdecl}{krb5_mk_rep}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcout -\funcarg{krb5_data *}{outbuf} -\end{funcdecl} - -Formats and encrypts an AP_REP message, including in it the data in the -authentp portion of \funcparam{auth_context}, encrypted using the -keyblock portion of \funcparam{auth_context}. - -When successful, \funcparam{outbuf{\ptsto}length} and -\funcparam{outbuf{\ptsto}data} are filled in with the length of the -AP_REQ message and allocated data holding it. -\funcparam{outbuf{\ptsto}data} should be freed by the -caller when it is no longer needed. - -If the flags in \funcparam{auth_context} indicate that a sequence number -should be used (either {\sc KRB5_AUTH_CONTEXT_DO_SEQUENCE} or -{\sc KRB5_AUTH_CONTEXT_RET_SEQUENCE}) and the local sequqnce number in the -\funcparam{auth_context} is 0, a new number will be generated with -\funcname{krb5_generate_seq_number}. - -Returns system errors. - -\begin{funcdecl}{krb5_rd_rep}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{const krb5_data *}{inbuf} -\funcout -\funcarg{krb5_ap_rep_enc_part **}{repl} -\end{funcdecl} - -Parses and decrypts an AP_REP message from \funcparam{*inbuf}, filling in -\funcparam{*repl} with a pointer to allocated storage containing the -values from the message. The caller is responsible for freeing this -structure with \funcname{krb5_free_ap_rep_enc_part}. - -The keyblock stored in \funcparam{auth_context} is used to decrypt the -message after establishing any key pre-processing with -\funcname{krb5_process_key}. - -Returns system errors, encryption errors, replay errors. - -\begin{funcdecl}{krb5_mk_error}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_error *}{dec_err} -\funcout -\funcarg{krb5_data *}{enc_err} -\end{funcdecl} - -Formats the error structure \funcparam{*dec_err} into an error buffer -\funcparam{*enc_err}. - -The error buffer storage (\funcparam{enc_err{\ptsto}data}) is -allocated, and should be freed by the caller when finished. - -Returns system errors. - -\begin{funcdecl}{krb5_rd_error}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_data *}{enc_errbuf} -\funcout -\funcarg{krb5_error **}{dec_error} -\end{funcdecl} - -Parses an error protocol message from \funcparam{enc_errbuf} and fills in -\funcparam{*dec_error} with a pointer to allocated storage containing -the error message. The caller is reponsible for freeing this structure by -using \funcname{krb5_free_error}. - -Returns system errors. - -\begin{funcdecl}{krb5_generate_seq_number}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{key} -\funcout -\funcarg{krb5_int32 *}{seqno} -\end{funcdecl} - -Generates a pseudo-random sequence number suitable for use as an initial -sequence number for the KRB_SAFE and KRB_PRIV message processing -routines. - -\funcparam{key} parameterizes the choice of the random sequence number, -which is filled into \funcparam{*seqno} upon return. - -\begin{funcdecl}{krb5_sendauth}{krb5_error_code} -\funcinout -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{krb5_pointer}{fd} -\funcarg{char *}{appl_version} -\funcarg{krb5_principal}{client} -\funcarg{krb5_principal}{server} -\funcarg{krb5_flags}{ap_req_options} -\funcarg{krb5_data *}{in_data} -\funcarg{krb5_creds *}{in_creds} -\funcinout -\funcarg{krb5_ccache}{ccache} -\funcout -\funcarg{krb5_error **}{error} -\funcarg{krb5_ap_rep_enc_part **}{rep_result} -\funcarg{krb5_creds **}{out_creds} -\end{funcdecl} - -\funcname{krb5_sendauth} provides a convenient means for client and -server programs to send authenticated messages to one another through -network connections. \funcname{krb5_sendauth} sends an authenticated -ticket from the client program to the server program using the network -connection specified by \funcparam{fd}. In the MIT Unix implementation, -\funcparam{fd} should be a pointer to a file descriptor describing the -network socket. This can be changed in other implementations, however, -if the routines \funcname{krb5_read_message}, -\funcname{krb5_write_message}, \funcname{krb5_net_read}, and -\funcname{krb5_net_write} are changed. - -The paramter \funcparam{appl_version} is a string describing the -application protocol version which the client is expecting to use for -this exchange. If the server is using a different application protocol, -an error will be returned. - -The parameters \funcparam{client} and \funcparam{server} specify the -kerberos principals for the client and the server. They are -ignored if \funcparam{in_creds} is non-null. Otherwise, -\funcparam{server} must be non-null, but \funcparam{client} may be -null, in which case the client principal used is the one in the -credential cache's default principal. - -The \funcparam{ap_req_options} parameters specifies the options which -should be passed to \funcname{krb5_mk_req}. Valid options are listed -in Table \ref{ap-req-options}. If \funcparam{ap_req_options} -specifies MUTUAL_REQUIRED, then \funcname{krb5_sendauth} will perform -a mutual authentication exchange, and if \funcparam{rep_result} is -non-null, it will be filled in with the result of the mutual -authentication exchange; the caller should free -\funcparam{*rep_result} with -\funcname{krb5_free_ap_rep_enc_part} when done with it. - -If \funcparam{in_creds} is non-null, then -\funcparam{in_creds{\ptsto}client} and -\funcparam{in_creds{\ptsto}server} must be filled in, and either -the other structure fields should be filled in with valid credentials, -or \funcparam{in_creds{\ptsto}ticket.length} should be zero. If -\funcparam{in_creds{\ptsto}ticket.length} is non-zero, then -\funcparam{in_creds} will be used as-is as the credentials to send to -the server, and \funcparam{ccache} is ignored; otherwise, -\funcparam{ccache} is used as described below, and \funcparam{out_creds} -, if not NULL, is filled in with the retrieved credentials. - -\funcname{ccache} specifies the credential cache to use when one is -needed (i.e., when \funcname{in_creds} is null or -\funcparam{in_creds{\ptsto}ticket.length} is zero). When a credential -cache is not needed, \funcname{ccache} is ignored. When a credential -cache is needed and \funcname{ccache} is null, the default credential -cache is used. Note that if the credential cache is needed and does -not contain the needed credentials, they will be retrieved from the -KDC and stored in the credential cache. - -If mutual authentication is used and \funcparam{rep_result} is non-null, -the sequence number for the server is available to the caller in -\funcparam{*rep_result->seq_number}. (If mutual authentication is not -used, there is no way to negotiate a sequence number for the server.) - -If an error occurs during the authenticated ticket exchange and -\funcparam{error} is non-null, the error packet (if any) that was sent -from the server will be placed in it. This error should be freed with -\funcname{krb5_free_error}. - -\begin{funcdecl}{krb5_recvauth}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context *}{auth_context} -\funcin -\funcarg{krb5_pointer}{fd} -\funcarg{char *}{appl_version} -\funcarg{krb5_principal}{server} -\funcarg{char *}{rc_type} -\funcarg{krb5_int32}{flags} -\funcarg{krb5_keytab}{keytab} -\funcout -\funcarg{krb5_ticket **}{ticket} -\end{funcdecl} - -\funcname{krb5_recvauth} provides a convenient means for client and -server programs to send authenticated messages to one another through -network connections. \funcname{krb5_sendauth} is the matching routine -to \funcname{krb5_recvauth} for the server. \funcname{krb5_recvauth} -will engage in an authentication dialogue with the -client program running \funcname{krb5_sendauth} to authenticate the -client to the server. In addition, if requested by the client, -\funcname{krb5_recvauth} will provide mutual authentication to -prove to the client that the server represented by -\funcname{krb5_recvauth} is legitimate. - -\funcparam{fd} is a pointer to the network connection. As in -\funcname{krb5_sendauth}, in the MIT Unix implementation -\funcparam{fd} is a pointer to a file descriptor. - -The parameter \funcparam{appl_version} is a string describing the -application protocol version which the server is expecting to use for -this exchange. If the client is using a different application protocol, -an error will be returned and the authentication exchange will be -aborted. - -If \funcparam{server} is non-null, then \funcname{krb5_recvauth} -verifies that the server principal requested by the client matches -\funcparam{server}. If not, an error will be returned and the -authentication exchange will be aborted. - -The parameters \funcparam{server}, \funcparam{auth_context}, -and \funcparam{keytab} are used by \funcname{krb5_rd_req} to obtain the -server's private key. - -If \funcparam{server} is non-null, the princicpal component of it is -ysed to determine the replay cache to use. Otherwise, -\funcname{krb5_recvauth} will use a default replay cache. - -The \funcparam{flags} argument allows the caller to modify the behavior of -\funcname{krb5_recvauth}. For non-library callers, \funcparam{flags} -should be 0. - -% XXX Note that if the bug I submitted entitled ``"flags" argument -% should not have been added to krb5_recvauth'' (OpenVision Cambridge -% bug number 1585) causes code changes, this will have to be updated. - -\funcparam{ticket} is optional and is only filled in if non-null. It is -filled with the data from the ticket sent by the client, and should be -freed with -\funcname{krb5_free_ticket} when it is no longer needed. - -\begin{funcdecl}{krb5_mk_safe}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{const krb5_data *}{userdata} -\funcout -\funcarg{krb5_data *}{outbuf} -\funcinout -\funcarg{krb5_replay_data *}{outdata} -\end{funcdecl} - -Formats a KRB_SAFE message into \funcparam{outbuf}. - -\funcparam{userdata} is formatted as the user data in the message. -Portions of \funcparam{auth_context} specify the checksum type; the -keyblockm which might be used to seed the checksum; -full addresses (host and port) for the sender and receiver. -The \funcparam{local_addr} portion of \funcparam{*auth_context} -is used to form the addresses usedin the KRB_SAFE message. The \funcparam{remote_addr} is optional; if the -receiver's address is not known, it may be replaced by NULL. -\funcparam{local_addr}, however, is mandatory. - -The \funcparam{auth_context} flags select whether sequence numbers or -timestamps should be used to identify the message. Valid flags are -listed below. - -\begin{tabular}{ll} -\multicolumn{1}{c}{Symbol} & Meaning \\ -KRB5_AUTH_CONTEXT_DO_TIME & Use timestamps\\ - &\ and replay cache\\ -KRB5_AUTH_CONTEXT_RET_TIME & Copy timestamp \\ - &\ to \funcparam{*outdata} \\ -KRB5_AUTH_CONTEXT_DO_SEQUENCE & Use sequence numbers \\ -KRB5_AUTH_CONTEXT_RET_SEQUENCE & Copy sequence numbers\\ - &\ to \funcparam{*outdata} \\ -\end{tabular} - -If timestamps are to be used (i.e., if KRB5_AUTH_CONTEXT_DO_TIME is -set), an entry describing the message will be entered in the replay -cache so that the caller may detect if this message is sent -back to him by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, -the \funcparam{auth_context} replay cache is not used. - -If sequence numbers are to be used (i.e., if either -KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENEC is -set), then \funcparam{auth_context} local sequence number will be -placed in the protected message as its sequence number. - -The \funcparam{outbuf} buffer storage (i.e., -\funcparam{outbuf{\ptsto}data}) is allocated, and should be freed by -the caller when finished. - -Returns system errors, encryption errors. - -\begin{funcdecl}{krb5_rd_safe}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{const krb5_data *}{inbuf} -\funcout -\funcarg{krb5_data *}{outbuf} -\funcinout -\funcarg{krb5_replay_data *}{outdata} -\end{funcdecl} - -Parses a KRB_SAFE message from \funcparam{inbuf}, placing the -data in \funcparam{*outbuf} after verifying its integrity. - -The keyblock used for verifying the integrity of the message is taken -from the \funcparam{auth_context} local_subkey, remote_subkey, or -keyblock. The keyblock is chosen in the above order by the first one -which is not NULL. - -The remote_addr and localaddr portions of the \funcparam{*auth_context} -specify the full addresses (host and port) of the sender and receiver, -and must be of type \datatype{ADDRTYPE_ADDRPORT}. - - -The \funcparam{remote_addr} parameter is mandatory; it -specifies the address of the sender. If the address of the sender in -the message does not match \funcparam{remote_addr}, the error -KRB5KRB_AP_ERR_BADADDR will be returned. - -If \funcparam{local_addr} is non-NULL, then the address of the receiver -in the message much match it. If it is null, the receiver address in -the message will be checked against the list of local addresses as -returned by \funcname{krb5_os_localaddr}. If the check fails, -KRB5KRB_AP_ERR_BADARRD is returned. - -The \funcparam{outbuf} buffer storage (i.e., -\funcparam{outbuf{\ptsto}data} is allocated storage which the caller -should free when it is no longer needed. - -If auth_context_flags portion of \funcparam{auth_context} indicates -that sequence numbers are to be used (i.e., if KRB5_AUTH_CONTEXT_DOSEQUENCE is -set in it), The \funcparam{remote_seq_number} portion of -\funcparam{auth_context} is compared to the sequence number for the -message, and KRB5_KRB_AP_ERR_BADORDER is returned if it does not match. -Otherwise, the sequence number is not used. - - -If timestamps are to be used (i.e., if KRB5_AUTH_CONTEXT_DO_TIME is set -in the \funcparam{auth_context}), then two additional checks are performed: -\begin{itemize} -\item The timestamp in the message must be within the permitted clock - skew (which is usually five minutes), or KRB5KRB_AP_ERR_SKEW - is returned. -\item The message must not be a replayed message, according to - \funcparam{rcache}. -\end{itemize} - -Returns system errors, integrity errors. - -\begin{funcdecl}{krb5_mk_priv}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{const krb5_data *}{userdata} -\funcout -\funcarg{krb5_data *}{outbuf} -\funcarg{krb5_replay_data *}{outdata} -\end{funcdecl} - -Formats a KRB_PRIV message into \funcparam{outbuf}. Behaves similarly -to \funcname{krb5_mk_safe}, but the message is encrypted and -integrity-protected rather than just integrity-protected. - -\funcparam{inbuf}, \funcparam{auth_context}, -\funcparam{outdata} and -\funcparam{outbuf} function as in \funcname{krb5_mk_safe}. - -As in \funcname{krb5_mk_safe}, the remote_addr and remote_port part of -the \funcparam{auth_context} is optional; if the receiver's address is -not known, it may be replaced by NULL. The local_addr, however, is -mandatory. - -The encryption type is taken from the \funcparam{auth_context} keyblock -portion. If i_vector portion of the \funcparam{auth_context} -is non-null, it is used as an initialization vector for the encryption -(if the chosen encryption type supports initialization vectors) -and its contents are replaced with the last block of encrypted data -upon return. - -The flags from the \funcparam{auth_context} selects whether sequence numbers or timestamps -should be used to identify the message. Valid flags are listed below. - -\begin{tabular}{ll} -\multicolumn{1}{c}{Symbol} & Meaning \\ -KRB5_AUTH_CONTEXT_DO_TIME& Use timestamps in replay cache\\ -KRB5_AUTH_CONTEXT_RET_TIME& Use timestamps in output data\\ -KRB5_AUTH_CONTEXT_DO_SEQUENCE& Use sequence numbers\\ - &\ in replay cache\\ -KRB5_AUTH_CONTEXT_RET_SEQUENCE& Use sequence numbers\\ - &\ in replay cache and output data \\ -\end{tabular} - -Returns system errors, encryption errors. - -\begin{funcdecl}{krb5_rd_priv}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_auth_context}{auth_context} -\funcin -\funcarg{const krb5_data *}{inbuf} -\funcout -\funcarg{krb5_data *}{outbuf} -\funcarg{krb5_data *}{outdata} -\end{funcdecl} - -Parses a KRB_PRIV message from \funcparam{inbuf}, placing the data in -\funcparam{*outbuf} after decrypting it. Behaves similarly to -\funcname{krb5_rd_safe}, but the message is decrypted rather than -integrity-checked. - -\funcparam{inbuf}, \funcparam{auth_context}, -\funcparam{outdata} and \funcparam{outbuf} -function as in \funcname{krb5_rd_safe}. - - -The remote_addr part of the \funcparam{auth_context} as set by -\funcname{krb5_auth_con_setaddrs} is mandatory; it -specifies the address of the sender. If the address of the sender in -the message does not match the remote_addr, the error -KRB5KRB_AP_ERR_BADADDR will be returned. - -If local_addr portion of the auth_context is non-NULL, then the address -of the receiver in the message much match it. If it is null, the -receiver address in the message will be checked against the list of -local addresses as returned by \funcname{krb5_os_localaddr}. - -The \funcparam{keyblock} portion of \funcparam{auth_context} specifies -the key to be used for decryption of the message. If the -\funcparam{i_vector} element, is non-null, it is used as an -initialization vector for the decryption (if the encryption type of the -message supports initialization vectors) and its contents are replaced -with the last block of encrypted data in the message. - -The \funcparam{auth_context} flags specify whether timestamps -(KRB5_AUTH_CONTEXT_DO_TIME) and sequence numbers -(KRB5_AUTH_CONTEXT_DO_SEQUENCE) are to be used. - -Returns system errors, integrity errors. - -\subsubsection{Miscellaneous main functions} - -\begin{funcdecl}{krb5_address_search}{krb5_boolean}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_address *}{addr} -\funcarg{krb5_address * const *}{addrlist} -\end{funcdecl} - -If \funcparam{addr} is listed in \funcparam{addrlist}, or -\funcparam{addrlist} is null, return TRUE. If not listed, return FALSE. - -\begin{funcdecl}{krb5_address_compare}{krb5_boolean}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_address *}{addr1} -\funcarg{const krb5_address *}{addr2} -\end{funcdecl} - -If the two addresses are the same, return TRUE, else return FALSE. - -\begin{funcdecl}{krb5_fulladdr_order}{int}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_fulladdr *}{addr1} -\funcarg{const krb5_fulladdr *}{addr2} -\end{funcdecl} - -Return an ordering on the two full addresses: 0 if the same, -$< 0$ if first is less than 2nd, $> 0$ if first is greater than 2nd. - -\begin{funcdecl}{krb5_address_order}{int}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_address *}{addr1} -\funcarg{const krb5_address *}{addr2} -\end{funcdecl} - -Return an ordering on the two addresses: 0 if the same, -$< 0$ if first is less than 2nd, $> 0$ if first is greater than 2nd. - -\begin{funcdecl}{krb5_copy_addresses}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_address * const *}{inaddr} -\funcout -\funcarg{krb5_address ***}{outaddr} -\end{funcdecl} - -Copy addresses in \funcparam{inaddr} to \funcparam{*outaddr} which is -allocated memory and should be freed with \funcname{krb5_free_addresses}. - -\begin{funcdecl}{krb5_copy_authdata}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_authdata * const *}{inauthdat} -\funcout -\funcarg{krb5_authdata ***}{outauthdat} -\end{funcdecl} - -Copy an authdata structure, filling in \funcparam{*outauthdat} to point to the -newly allocated copy, which should be freed with -\funcname{krb5_free_authdata}. - -\begin{funcdecl}{krb5_copy_authenticator}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_authenticator *}{authfrom} -\funcout -\funcarg{krb5_authenticator **}{authto} -\end{funcdecl} - -Copy an authenticator structure, filling in \funcparam{*outauthdat} to -point to the newly allocated copy, which should be freed with -\funcname{krb5_free_authenticator}. - -\begin{funcdecl}{krb5_copy_keyblock}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{from} -\funcout -\funcarg{krb5_keyblock **}{to} -\end{funcdecl} - -Copy a keyblock, filling in \funcparam{*to} to point to the newly -allocated copy, which should be freed with -\funcname{krb5_free_keyblock}. - -\begin{funcdecl}{krb5_copy_keyblock_contents}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_keyblock *}{from} -\funcout -\funcarg{krb5_keyblock *}{to} -\end{funcdecl} - -Copy keyblock contents from \funcparam{from} to \funcparam{to}, including -allocated storage. The allocated storage in \funcparam{to} should be -freed by using {\bf free}(\funcparam{to->contents}). - -\begin{funcdecl}{krb5_copy_checksum}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_checksum *}{ckfrom} -\funcout -\funcarg{krb5_checksum **}{ckto} -\end{funcdecl} - -Copy a checksum structure, filling in \funcparam{*ckto} to point to -the newly allocated copy, which should be freed with -\funcname{krb5_free_checksum}. - -\begin{funcdecl}{krb5_copy_creds}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_creds *}{incred} -\funcout -\funcarg{krb5_creds **}{outcred} -\end{funcdecl} - -Copy a credentials structure, filling in \funcparam{*outcred} to point -to the newly allocated copy, which should be freed with -\funcname{krb5_free_creds}. - -\begin{funcdecl}{krb5_copy_data}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_data *}{indata} -\funcout -\funcarg{krb5_data **}{outdata} -\end{funcdecl} - -Copy a data structure, filling in \funcparam{*outdata} to point to the -newly allocated copy, which should be freed with \funcname{krb5_free_data}. - -\begin{funcdecl}{krb5_copy_ticket}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_ticket *}{from} -\funcout -\funcarg{krb5_ticket **}{pto} -\end{funcdecl} - -Copy a ticket structure, filling in \funcparam{*pto} to point to -the newly allocated copy, which should be freed with -\funcname{krb5_free_ticket}. - - -\begin{funcdecl}{krb5_get_server_rcache}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const krb5_data *}{piece} -\funcout -\funcarg{krb5_rcache *}{ret_rcache} -\end{funcdecl} - -Generate a replay cache name, allocate space for its handle, and open -it. \funcparam{piece} is used to distinguish this replay cache from -others currently in use on the system. Typically, \funcparam{piece} -is the first component of the principal name for the client or server -which is calling \funcname{krb5_get_server_rcache}. - -Upon successful return, \funcparam{ret_rcache} is filled in to contain a -handle to an open rcache, which should be closed with -\funcname{krb5_rc_close}. - - diff --git a/doc/api/krb5idx.sty b/doc/api/krb5idx.sty deleted file mode 100644 index 729ed9779..000000000 --- a/doc/api/krb5idx.sty +++ /dev/null @@ -1,10 +0,0 @@ -\usepackage{makeidx} - -% The following defintions are for our indexing scheme. Stolen from -% doc.sty. -\def\dotfill{\leaders\hbox to.6em{\hss .\hss}\hskip\z@ plus 1fill}% -\def\dotfil{\leaders\hbox to.6em{\hss .\hss}\hfil}% -\def\efill{\hfill\nopagebreak}% -\def\pfill{\unskip~\dotfill\penalty500\strut\nobreak - \dotfil~\ignorespaces}% -%% diff --git a/doc/api/libdes.tex b/doc/api/libdes.tex deleted file mode 100644 index 71e75c59b..000000000 --- a/doc/api/libdes.tex +++ /dev/null @@ -1,38 +0,0 @@ -\documentstyle[fixunder,functions,twoside]{article} -\setlength{\oddsidemargin}{0.25in} -\setlength{\evensidemargin}{-0.25in} -\setlength{\topmargin}{-.5in} -\setlength{\textheight}{9in} -\setlength{\parskip}{.1in} -\setlength{\parindent}{2em} -\setlength{\textwidth}{6.25in} - -\pagestyle{headings} -\begin{document} -\begin{center} -{\Huge Kerberos V5 Data Encryption Standard library} \\ -{\Large DRAFT} -\end{center} -\section{DES functions} -The DES functions conform to the encryption interface required by the -Kerberos version 5 library, and provide an encryption mechanism based on -the DES Cipher-block chaining mode (CBC), with the addition of a -cyclical redundancy check (CRC-32) for integrity checking upon -decryption. - -The functions have the same signatures as those described by the main -library document; the names are: -{\obeylines -\funcname{mit_des_encrypt_func} -\funcname{mit_des_decrypt_func} -\funcname{mit_des_process_key} -\funcname{mit_des_finish_key} -\funcname{mit_des_string_to_key} -\funcname{mit_des_init_random_key} -\funcname{mit_des_finish_random_key} -\funcname{mit_des_random_key} -} -The \datatype{krb5_cryptosystem_entry} for this cryptosystem is -\globalname{mit_des_cryptosystem_entry}. - -\end{document} diff --git a/doc/api/libos.tex b/doc/api/libos.tex deleted file mode 100644 index 447044fec..000000000 --- a/doc/api/libos.tex +++ /dev/null @@ -1,486 +0,0 @@ -The operating-system specific functions provide an interface between the -other parts of the \libname{libkrb5.a} libraries and the operating system. - -Beware! Any of the functions below are allowed to be implemented as -macros. Prototypes for functions can be found in {\tt -}; other definitions (including macros, if used) are -in {\tt }. - -The following global symbols are provided in \libname{libos.a}. If you -wish to substitute for any of them, you must substitute for all of them -(they are all declared and initialized in the same object file): -\begin{description} -% These come from src/lib/osconfig.c -\item[extern char *\globalname{krb5_defkeyname}:] default name of key -table file -\item[extern char *\globalname{krb5_lname_file}:] name of aname/lname -translation database -\item[extern int \globalname{krb5_max_dgram_size}:] maximum allowable -datagram size -\item[extern int \globalname{krb5_max_skdc_timeout}:] maximum -per-message KDC reply timeout -\item[extern int \globalname{krb5_skdc_timeout_shift}:] shift factor -(bits) to exponentially back-off the KDC timeouts -\item[extern int \globalname{krb5_skdc_timeout_1}:] initial KDC timeout -\item[extern char *\globalname{krb5_kdc_udp_portname}:] name of KDC UDP port -\item[extern char *\globalname{krb5_default_pwd_prompt1}:] first prompt -for password reading. -\item[extern char *\globalname{krb5_default_pwd_prompt2}:] second prompt - -\end{description} - -\subsubsection{Operating specific context} -The \datatype{krb5_context} has space for operating system specific -data. These functions are called from \funcname{krb5_init_context} and -\funcname{krb5_free_context}, but are included here for completeness. - -\begin{funcdecl}{krb5_os_init_context}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\end{funcdecl} - -\internalfunc - -Initializes \funcparam{context{\ptsto}os_context} and establishes the -location of the initial configuration files. - -\begin{funcdecl}{krb5_os_free_context}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\end{funcdecl} - -\internalfunc - -Frees the operating system specific portion of \funcparam{context}. - -\subsubsection{Configuration based functions} -These functions allow access to configuration specific information. In -some cases, the configuration may be overriden by program control. - - -\begin{funcdecl}{krb5_set_config_files}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const char **}{filenames} -\end{funcdecl} - -Sets the list of configuration files to be examined in determining -machine defaults. \funcparam{filenames} is an array of files to check in -order. The array must have a NULL entry as the last element. - -Returns system errors. - -\begin{funcdecl}{krb5_get_krbhst}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const krb5_data *}{realm} -\funcout -\funcarg{char ***}{hostlist} -\end{funcdecl} - -Figures out the Kerberos server names for the given \funcparam{realm}, -filling in \funcparam{hostlist} with a null terminated array of -pointers to hostnames. - -If \funcparam{realm} is unknown, the filled-in pointer is set to NULL. - -The pointer array and strings pointed to are all in allocated storage, -and should be freed by the caller when finished. - -Returns system errors. - -\begin{funcdecl}{krb5_free_krbhst}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{char * const *}{hostlist} -\end{funcdecl} - -Frees the storage taken by a host list returned by \funcname{krb5_get_krbhst}. - -\begin{funcdecl}{krb5_get_default_realm}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcout -\funcarg{char **}{lrealm} -\end{funcdecl} - -Retrieves the default realm to be used if no user-specified realm is -available (e.g. to interpret a user-typed principal name with the -realm omitted for convenience), filling in \funcparam{lrealm} with a -pointer to the default realm in allocated storage. - -It is the caller's responsibility for freeing the allocated storage -pointed to be \funcparam{lream} when it is finished with it. - -Returns system errors. - -\begin{funcdecl}{krb5_set_default_realm}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{char *}{realm} -\end{funcdecl} - -Sets the default realm to be used if no user-specified realm is -available (e.g. to interpret a user-typed principal name with the -realm omitted for convenience). (c.f. krb5_get_default_realm) - -If \funcparam{realm} is NULL, then the operating system default value -will used. - -Returns system errors. - -\begin{funcdecl}{krb5_get_host_realm}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const char *}{host} -\funcout -\funcarg{char ***}{realmlist} -\end{funcdecl} - -Figures out the Kerberos realm names for \funcparam{host}, filling in -\funcparam{realmlist} with a -pointer to an argv[] style list of names, terminated with a null pointer. - -If \funcparam{host} is NULL, the local host's realms are determined. - -If there are no known realms for the host, the filled-in pointer is set -to NULL. - -The pointer array and strings pointed to are all in allocated storage, -and should be freed by the caller when finished. - -Returns system errors. - -\begin{funcdecl}{krb5_free_host_realm}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{char * const *}{realmlist} -\end{funcdecl} - -Frees the storage taken by a \funcparam{realmlist} returned by -\funcname{krb5_get_local_realm}. - -\begin{funcdecl}{krb5_get_realm_domain}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{const char *}{realm} -\funcout -\funcarg{char **}{domain} -\end{funcdecl} - -Determines the proper name of a realm. This is mainly so that a krb4 -principal can be converted properly into a krb5 one. If -\funcparam{realm} is null, the function will assume the default realm of -the host. The returned \funcparam{*domain} is allocated and must be -freed by the caller. - -\subsubsection{Disk based functions} -These functions all relate to disk based I/O. - -\begin{funcdecl}{krb5_lock_file}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{in}{fd} -\funcarg{int}{mode} -\end{funcdecl} - -Attempts to lock the file in the given \funcparam{mode}; returns 0 for a -successful lock, or an error code otherwise. - -The caller should arrange for the file referred by \funcparam{fd} to be -opened in such a way as to allow the required lock. - -Modes are given in {\tt } - -\begin{funcdecl}{krb5_unlock_file}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{int}{fd} -\end{funcdecl} - -Attempts to (completely) unlock the file. Returns 0 if successful, -or an error code otherwise. - - -\begin{funcdecl}{krb5_create_secure_file}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const char *}{pathname} -\end{funcdecl} - -Creates a file named pathname which can only be read by the current -user. - -\begin{funcdecl}{krb5_sync_disk_file}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{FILE *}{fp} -\end{funcdecl} - -Assures that the changes made to the file pointed to by the file -handle -fp are forced out to disk. - -\subsubsection{Network based routines} - -These routines send and receive network data the specifics -of addresses and families on a given operating system. - -\begin{funcdecl}{krb5_os_localaddr}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_address ***}{addr} -\end{funcdecl} - -Return all the protocol addresses of this host. - -Compile-time configuration flags will indicate which protocol family -addresses might be returned. -\funcparam{*addr} is filled in to point to an array of address pointers, -terminated by a null pointer. All the storage pointed to is allocated -and should be freed by the caller with \funcname{krb5_free_address} -when no longer needed. - -\begin{funcdecl}{krb5_gen_portaddr}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const krb5_address *}{adr} -\funcarg{krb5_const_pointer}{ptr} -\funcout -\funcarg{krb5_address **}{outaddr} -\end{funcdecl} - -Given an address \funcparam{adr} and an additional address-type specific -portion pointed to by -\funcparam{port} this routine -combines them into a freshly-allocated -\datatype{krb5_address} with type \datatype{ADDRTYPE_ADDRPORT} and fills in -\funcparam{*outaddr} to point to this address. For IP addresses, -\funcparam{ptr} should point to a network-byte-order TCP or UDP port -number. Upon success, \funcparam{*outaddr} will point to an allocated -address which should be freed with \funcname{krb5_free_address}. - - -\begin{funcdecl}{krb5_sendto_kdc}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const krb5_data *}{send} -\funcarg{const krb5_data *}{realm} -\funcout -\funcarg{krb5_data *}{receive} -\end{funcdecl} - -Send the message \funcparam{send} to a KDC for realm \funcparam{realm} and -return the response (if any) in \funcparam{receive}. - -If the message is sent and a response is received, 0 is returned, -otherwise an error code is returned. - -The storage for \funcparam{receive} is allocated and should be freed by -the caller when finished. - - -\begin{funcdecl}{krb5_net_read}{int}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{int}{fd} -\funcout -\funcarg{char *}{buf} -\funcin -\funcarg{int}{len} -\end{funcdecl} - -Like read(2), but guarantees that it reads as much as was requested -or returns -1 and sets errno. - -(make sure your sender will send all the stuff you are looking for!) -Only useful on stream sockets and pipes. - -\begin{funcdecl}{krb5_net_write}{int}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{int}{fd} -\funcarg{const char *}{buf} -\funcarg{int}{len} -\end{funcdecl} - -Like write(2), but guarantees that it writes as much as was requested -or returns -1 and sets errno. - -Only useful on stream sockets and pipes. - -\begin{funcdecl}{krb5_write_message}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_pointer}{fd} -\funcarg{krb5_data *}{data} -\end{funcdecl} - - -\funcname{krb5_write_message} writes data to the network as a message, -using the network connection pointed to by \funcparam{fd}. - -\begin{funcdecl}{krb5_read_message}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_pointer}{fd} -\funcout -\funcarg{krb5_data *}{data} -\end{funcdecl} - -Reads data from the network as a message, using the network connection -pointed to by fd. - -\subsubsection{Operating specific access functions} -These functions are involved with access control decisions and policies. - -\begin{funcdecl}{krb5_aname_to_localname}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_const_principal}{aname} -\funcarg{int}{lnsize} -\funcout -\funcarg{char *}{lname} -\end{funcdecl} - -Converts a principal name \funcparam{aname} to a local name suitable for use by -programs wishing a translation to an environment-specific name (e.g. -user account name). - -\funcparam{lnsize} specifies the maximum length name that is to be filled into -\funcparam{lname}. -The translation will be null terminated in all non-error returns. - -Returns system errors. - -\begin{funcdecl}{krb5_kuserok}{krb5_boolean}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_principal}{principal} -\funcarg{const char *}{luser} -\end{funcdecl} - -Given a Kerberos principal \funcparam{principal}, and a local username -\funcparam{luser}, -determine whether user is authorized to login to the account \funcparam{luser}. -Returns TRUE if authorized, FALSE if not authorized. - -\begin{funcdecl}{krb5_sname_to_principal}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const char *}{hostname} -\funcarg{const char *}{sname} -\funcarg{krb5_int32}{type} -\funcout -\funcarg{krb5_principal *}{ret_princ} -\end{funcdecl} - -Given a hostname \funcparam{hostname} and a generic service name -\funcparam{sname}, this function generates a full principal name to be -used when authenticating with the named service on the host. The full -prinicpal name is returned in \funcparam{ret_princ}. - -The realm of the -principal is determined internally by calling \funcname{krb5_get_host_realm}. - -The \funcparam{type} argument controls how -\funcname{krb5_sname_to_principal} generates the principal name, -\funcparam{ret_princ}, for the named service, \funcparam{sname}. -Currently, two values are supported: KRB5_NT_SRV_HOST, and -KRB5_NT_UNKNOWN. - -If \funcparam{type} is set to -KRB5_NT_SRV_HOST, the hostname will be -canonicalized, i.e. a fully qualified lowercase hostname using -the primary name and the domain name, before \funcparam{ret_princ} is -generated in the form -"sname/hostname@LOCAL.REALM." Most applications should use -KRB5_NT_SRV_HOST. - -However, if \funcparam{type} is set to KRB5_NT_UNKNOWN, -while the generated principal name will have the form -"sname/hostname@LOCAL.REALM" the hostname will not be canonicalized -first. It will appear exactly as it was passed in \funcparam{hostname}. - -The caller should release \funcparam{ret_princ}'s storage by calling -\funcname{krb5_free_principal} when it is finished with the principal. - - - -\subsubsection{Miscellaneous operating specific functions} -These functions handle the other operating specific functions that do -not fall into any other major class. - -\begin{funcdecl}{krb5_timeofday}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_context}{context} -\funcarg{krb5_int32 *}{timeret} -\end{funcdecl} - -Retrieves the system time of day, in seconds since the local system's -epoch. -[The ASN.1 encoding routines must convert this to the standard ASN.1 -encoding as needed] - -\begin{funcdecl}{krb5_us_timeofday}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcout -\funcarg{krb5_int32 *}{seconds} -\funcarg{krb5_int32 *}{microseconds} -\end{funcdecl} - -Retrieves the system time of day, in seconds since the local system's -epoch. -[The ASN.1 encoding routines must convert this to the standard ASN.1 -encoding as needed] - -{\raggedright The seconds portion is returned in \funcparam{*seconds}, the -microseconds portion in \funcparam{*microseconds}.} - -\begin{funcdecl}{krb5_read_password}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const char *}{prompt} -\funcarg{const char *}{prompt2} -\funcout -\funcarg{char *}{return_pwd} -\funcinout -\funcarg{unsigned int *}{size_return} -\end{funcdecl} - -Read a password from the keyboard. The first \funcparam{*size_return} -bytes of the password entered are returned in \funcparam{return_pwd}. -If fewer than \funcparam{*size_return} bytes are typed as a password, -the remainder of \funcparam{return_pwd} is zeroed. Upon success, the -total number of bytes filled in is stored in \funcparam{*size_return}. - -\funcparam{prompt} is used as the prompt for the first reading of a password. -It is printed to the terminal, and then a password is read from the -keyboard. No newline or spaces are emitted between the prompt and the -cursor, unless the newline/space is included in the prompt. - -If \funcparam{prompt2} is a null pointer, then the password is read -once. If \funcparam{prompt2} is set, then it is used as a prompt to -read another password in the same manner as described for -\funcparam{prompt}. After the second password is read, the two -passwords are compared, and an error is returned if they are not -identical. - -Echoing is turned off when the password is read. - -If there is an error in reading or verifying the password, an error code -is returned; else zero is returned. - - -\begin{funcdecl}{krb5_random_confounder}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{int}{size} -\funcout -\funcarg{krb5_pointer}{fillin} -\end{funcdecl} - -Given a length and a pointer, fills in the area pointed to by -\funcparam{fillin} with \funcparam{size} random octets suitable for use -in a confounder. - -\begin{funcdecl}{krb5_gen_replay_name}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{const krb5_address *}{inaddr} -\funcarg{const char *}{uniq} -\funcout -\funcarg{char **}{string} -\end{funcdecl} - -Given a \datatype{krb5_address} with type \datatype{ADDRTYPE_ADDRPORT} -in \funcparam{inaddr}, this function unpacks its component address and -additional type, and uses them along with \funcparam{uniq} to allocate a -fresh string to represent the address and additional information. The -string is suitable for use as a replay cache tag. This string is -allocated and should be freed with \funcname{free} when the caller has -finished using it. When using IP addresses, the components in -\funcparam{inaddr{\ptsto}contents} must be of type -\datatype{ADDRTYPE_INET} and \datatype{ADDRTYPE_PORT}. - -% XXX Note that if the bug I sent in entitled ``krb5_gen_replay_name -% outputs char * when krb5_get_server_rcache expects krb5_data'' -% (OpenVision Cambridge bug number 1582) causes the code of this -% function to change, the documentation above will have to be updated. diff --git a/doc/api/library.tex b/doc/api/library.tex deleted file mode 100644 index cdfceb42c..000000000 --- a/doc/api/library.tex +++ /dev/null @@ -1,114 +0,0 @@ -\documentclass[twoside]{article} -\usepackage{fixunder,functions,changebar,fancyheadings} -\usepackage{krb5idx} -%\usepackage{hyperref} - -%\hypersetup{letterpaper, -% bookmarks=true, -%pdfpagemode=UseOutlines, -%} - -% -%\setlength{\oddsidemargin}{1in} -%\setlength{\evensidemargin}{1.00in} -%\setlength{\textwidth}{6.5in} -\setlength{\oddsidemargin}{0in} -\setlength{\evensidemargin}{1.50in} -\setlength{\textwidth}{5.25in} -\setlength{\marginparsep}{0.0in} -\setlength{\marginparwidth}{1.95 in} -\setlength{\topmargin}{-.5in} -\setlength{\textheight}{9in} -\setlength{\parskip}{.1in} -\setlength{\parindent}{2em} -\setlength{\footrulewidth}{0.4pt} -\setlength{\plainfootrulewidth}{0.4pt} -\setlength{\plainheadrulewidth}{0.4pt} -\makeindex -\newif\ifdraft -\draftfalse -% -% Far, far too inconvenient... it's still very draft-like anyway.... -% [tytso:19900921.0018EDT] -% -%\typein{Draft flag? (type \noexpand\draftfalse if not draft...)} -\ifdraft -\pagestyle{fancyplain} -\addtolength{\headwidth}{\marginparsep} -\addtolength{\headwidth}{\marginparwidth} -\makeatletter -\renewcommand{\sectionmark}[1]{\markboth {\uppercase{\ifnum \c@secnumdepth >\z@ - \thesection\hskip 1em\relax \fi #1}}{}}% -\renewcommand{\subsectionmark}[1]{\markright {\ifnum \c@secnumdepth >\@ne - \thesubsection\hskip 1em\relax \fi #1}} -\makeatother -\lhead[\thepage]{\fancyplain{}{\sl\rightmark}} -\rhead[\fancyplain{}{\sl\rightmark}]{\thepage} -\lfoot[]{{\bf DRAFT---DO NOT REDISTRIBUTE}} -\rfoot[{\bf DRAFT---DO NOT REDISTRIBUTE}]{} -\cfoot{\thepage} -\else\pagestyle{headings}\fi - -\def\internalfunc{NOTE: This is an internal function, which is not -necessarily intended for use by application programs. Its interface may -change at any time.\par} - -%nlg- time to make this a real document - -\title{\Huge Kerberos V5 application programming library} -\date{\ifdraft \\ {\Large DRAFT---}\fi\today} -\author{MIT Information Systems} - -\begin{document} -\maketitle -\tableofcontents - -%\thispagestyle{empty} -%\begin{center} -%{\Huge Kerberos V5 application programming library} -%\ifdraft \\ {\Large DRAFT---\today}\fi -%\end{center} - -\section{Introduction} -\input{intro.tex} - -\section{Useful KDC parameters to know about} -\input{tables.tex} - -\section{Error tables} -\input{errors.tex} - -%\addtolength{\oddsidemargin}{-1in} -%\addtolength{\evensidemargin}{1.00in} -%\addtolength{\textwidth}{-1.75in} -\newpage - -\section{libkrb5.a functions} -This section describes the functions provided in the \libname{libkrb5.a} -library. The library is built from several pieces, mostly for convenience in -programming, maintenance, and porting. - -\ifdraft\sloppy\fi - -\subsection{Main functions} -\input{krb5.tex} - -\subsection{Credentials cache functions} -\input{ccache.tex} - -\subsection{Replay cache functions} -\input{rcache.tex} - -\subsection{Key table functions} -\input{keytab.tex} - -\subsection{Free functions} -\input{free.tex} - -\subsection{Operating-system specific functions} -\input{libos.tex} - -\appendix -\cleardoublepage -\printindex -\end{document} diff --git a/doc/api/rcache.tex b/doc/api/rcache.tex deleted file mode 100644 index 28bad36ab..000000000 --- a/doc/api/rcache.tex +++ /dev/null @@ -1,207 +0,0 @@ -The replay cache functions deal with verifying that AP_REQ's do not -contain duplicate authenticators; the storage must be non-volatile for -the site-determined validity period of authenticators. - -Each replay cache has a string ``name'' associated with it. The use of -this name is dependent on the underlying caching strategy (for -file-based things, it would be a cache file name). The -caching strategy uses non-volatile storage so that replay -integrity can be maintained across system failures. - -\begin{funcdecl}{krb5_auth_to_rep}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcin -\funcarg{krb5_tkt_authent *}{auth} -\funcout -\funcarg{krb5_donot_replay *}{rep} -\end{funcdecl} -Extract the relevant parts of \funcparam{auth} and fill them into the -structure pointed to by \funcparam{rep}. \funcparam{rep{\ptsto}client} -and \funcparam{rep{\ptsto}server} are set to allocated storage and -should be freed when \funcparam{*rep} is no longer needed. - -\begin{funcdecl}{krb5_rc_resolve_full}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache *}{id} -\funcin -\funcarg{char *}{string_name} -\end{funcdecl} - -\begin{sloppypar} -\funcparam{id} is filled in to identify a replay cache which -corresponds to the name in \funcparam{string_name}. The cache is not opened. -Requires that \funcparam{string_name} be of the form ``type:residual'' -and that ``type'' is a type known to the library. -\end{sloppypar} - -Before the cache can be used \funcname{krb5_rc_initialize} or -\funcname{krb5_rc_recover} must be called. - -Errors: error if cannot resolve name. - - -\begin{funcdecl}{krb5_rc_resolve_type}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache *}{id} -\funcin -\funcarg{char *}{type} -\end{funcdecl} - -\internalfunc - -Looks up \funcparam{type} in the list of knows cache types and if found -attaches the operations to \funcparam{*id} which must be previously -allocated. - -If \funcparam{type} is not found, {\sc krb5_rc_type_notfound} is returned. - -\begin{funcdecl}{krb5_rc_register_type}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rc_ops *}{ops} -\end{funcdecl} -Adds a new replay cache type implemented and identified by -\funcparam{ops} to the set recognized by -\funcname{krb5_rc_resolve}. This function requires that a ticket -cache of the type named in -\funcparam{ops{\ptsto}prefix} has not been previously registered. - - -\begin{funcdecl}{krb5_rc_default_name}{char *}{\funcin} -\funcarg{krb5_context}{context} -\end{funcdecl} - -\begin{sloppypar} -Returns the name of the default replay cache; this may be equivalent to -\funcnamenoparens{getenv}({\tt "KRB5RCACHE"}) with an appropriate fallback. -\end{sloppypar} - -\begin{funcdecl}{krb5_rc_default_type}{char *}{\funcin} -\funcarg{krb5_context}{context} -\end{funcdecl} - -Returns the type of the default replay cache. - -\begin{funcdecl}{krb5_rc_default}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache *}{id} -\end{funcdecl} - -This function returns an unopened replay cache of the default type and -default name (as would be returned by \funcname{krb5_rc_default_type} -and \funcname{krb5_rc_default_name}). Before the cache can be used -\funcname{krb5_rc_initialize} or \funcname{krb5_rc_recover} must be -called. - - -\begin{funcdecl}{krb5_rc_initialize}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\funcarg{krb5_deltat}{auth_lifespan} -\end{funcdecl} - -Creates/refreshes the replay cache identified by \funcparam{id} and sets its -authenticator lifespan to \funcparam{auth_lifespan}. If the -replay cache already exists, its contents are destroyed. - -Errors: permission errors, system errors - -\begin{funcdecl}{krb5_rc_recover}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} -Attempts to recover the replay cache \funcparam{id}, (presumably after a -system crash or server restart). - -Errors: error indicating that no cache was found to recover - -\begin{funcdecl}{krb5_rc_destroy}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Destroys the replay cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -Errors: permission errors. - -\begin{funcdecl}{krb5_rc_close}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Closes the replay cache \funcparam{id}, invalidates \funcparam{id}, -and releases any other resources acquired during use of the replay cache. -Requires that \funcparam{id} identifies a valid replay cache. - -Errors: permission errors - -\begin{funcdecl}{krb5_rc_store}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\funcarg{krb5_donot_replay *}{rep} -\end{funcdecl} -Stores \funcparam{rep} in the replay cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -Returns KRB5KRB_AP_ERR_REPEAT if \funcparam{rep} is already in the -cache. May also return permission errors, storage failure errors. - -\begin{funcdecl}{krb5_rc_expunge}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} -Removes all expired replay information (i.e. those entries which are -older than then authenticator lifespan of the cache) from the cache -\funcparam{id}. Requires that \funcparam{id} identifies a valid replay -cache. - -Errors: permission errors. - -\begin{funcdecl}{krb5_rc_get_lifespan}{krb5_error_code}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\funcout -\funcarg{krb5_deltat *}{auth_lifespan} -\end{funcdecl} -Fills in \funcparam{auth_lifespan} with the lifespan of -the cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -\begin{funcdecl}{krb5_rc_resolve}{krb5_error_code}{\funcinout} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\funcin -\funcarg{char *}{name} -\end{funcdecl} - -Initializes private data attached to \funcparam{id}. This function MUST -be called before the other per-replay cache functions. - -Requires that \funcparam{id} points to allocated space, with an -initialized \funcparam{id{\ptsto}ops} field. - -Since \funcname{krb5_rc_resolve} allocates memory, -\funcname{krb5_rc_close} must be called to free the allocated memory, -even if neither \funcname{krb5_rc_initialize} or -\funcname{krb5_rc_recover} were successfully called by the application. - -Returns: allocation errors. - - -\begin{funcdecl}{krb5_rc_get_name}{char *}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Returns the name (excluding the type) of the rcache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -\begin{funcdecl}{krb5_rc_get_type}{char *}{\funcin} -\funcarg{krb5_context}{context} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Returns the type (excluding the name) of the rcache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - - diff --git a/doc/api/tables.tex b/doc/api/tables.tex deleted file mode 100644 index b272a07b9..000000000 --- a/doc/api/tables.tex +++ /dev/null @@ -1,79 +0,0 @@ -The following is a list of options which can be passed to the Kerberos -server (also known as the Key Distribution Center or KDC). These -options affect what sort of tickets the KDC will return to the -application program. The KDC options can be passed to -\funcname{krb5_get_in_tkt}, \funcname{krb5_get_in_tkt_with_password}, -\funcname{krb5_get_in_tkt_with_skey}, and \funcname{krb5_send_tgs}. - - -\begin{center} -\begin{tabular}{llc} -\multicolumn{1}{c}{Symbol}&\multicolumn{1}{c}{RFC}& Valid for \\ -&\multicolumn{1}{c}{section}&get_in_tkt? \\ \hline -KDC_OPT_FORWARDABLE & 2.6 & yes \\ -KDC_OPT_FORWARDED & 2.6 & \\ -KDC_OPT_PROXIABLE & 2.5 & yes \\ -KDC_OPT_PROXY & 2.5 & \\ -KDC_OPT_ALLOW_POSTDATE & 2.4 & yes \\ -KDC_OPT_POSTDATED & 2.4 & yes \\ -KDC_OPT_RENEWABLE & 2.3 & yes \\ -KDC_OPT_RENEWABLE_OK & 2.7 & yes \\ -KDC_OPT_ENC_TKT_IN_SKEY & 2.7 & \\ -KDC_OPT_RENEW & 2.3 & \\ -KDC_OPT_VALIDATE & 2.2 & \\ -\end{tabular} -\end{center} -\label{KDCOptions} - -The following is a list of preauthentication methods which are supported -by Kerberos. Most preauthentication methods are used by -\funcname{krb5_get_in_tkt}, \funcname{krb5_get_in_tkt_with_password}, and -\funcname{krb5_get_in_tkt_with_skey}; at some sites, the Kerberos server can be -configured so that during the initial ticket transation, it will only -return encrypted tickets after the user has proven his or her identity -using a supported preauthentication mechanism. This is done to make -certain password guessing attacks more difficult to carry out. - - - -\begin{center} -\begin{tabular}{lcc} -\multicolumn{1}{c}{Symbol}&In & Valid for \\ -&RFC?&get_in_tkt? \\ \hline -KRB5_PADATA_NONE & yes & yes \\ -KRB5_PADATA_AP_REQ & yes & \\ -KRB5_PADATA_TGS_REQ & yes & \\ -KRB5_PADATA_PW_SALT & yes & \\ -KRB5_PADATA_ENC_TIMESTAMP & yes & yes \\ -KRB5_PADATA_ENC_SECURID & & yes \\ -\end{tabular} -\end{center} -\label{padata-types} - -KRB5_PADATA_TGS_REQ is rarely used by a programmer; it is used to pass -the ticket granting ticket to the Ticket Granting Service (TGS) during a -TGS transaction (as opposed to an initial ticket transaction). - -KRB5_PW_SALT is not really a preauthentication method at all. It is -passed back from the Kerberos server to application program, and it -contains a hint to the proper password salting algorithm which should be -used during the initial ticket exchange. - -%The encription type can also be specified in -%\funcname{krb5_get_in_tkt}, however normally only one keytype is used -%in any one database. -% -%\begin{center} -%\begin{tabular}{llc} -%\multicolumn{1}{c}{Symbol}&\multicolumn{1}{c}{RFC}& Supported? \\ -%& \multicolumn{1}{c}{section} & \\ \hline -%ETYPE_NULL & 6.3.1 & \\ -%ETYPE_DES_CBC_CRC & 6.3.2 & yes \\ -%ETYPE_DES_CBC_MD4 & 6.3.3 & \\ -%ETYPE_DES_CBC_MD5 & 6.3.4 & \\ -%ETYPE_RAW_DES_CBC & & yes \\ -%\end{tabular} -%\end{center} -%\label{etypes} - - diff --git a/doc/bug-report.texinfo b/doc/bug-report.texinfo deleted file mode 100644 index 9a1767d56..000000000 --- a/doc/bug-report.texinfo +++ /dev/null @@ -1,10 +0,0 @@ -In any complex software, there will be bugs. Please send bug reports or -other problems you may uncover using the @code{krb5-send-pr} program -installed with the distribution. In case @code{krb5-send-pr} fails to -work, send bug reports to @samp{krb5-bugs@@mit.edu}. Please mention -which version of the Kerberos V5 distribution you are using, and whether -you have made any private changes. Bug reports that include proposed -fixes are especially welcome. If you do include fixes, please send them -using either context diffs or unified diffs (using @samp{diff -c} or -@samp{diff -u}, respectively). - diff --git a/doc/build.texinfo b/doc/build.texinfo deleted file mode 100644 index 1f0ef9687..000000000 --- a/doc/build.texinfo +++ /dev/null @@ -1,926 +0,0 @@ -@value{PRODUCT} uses a configuration system built using the Free -Software Foundation's @samp{autoconf} program. This system makes -Kerberos V5 much simpler to build and reduces the amount of effort -required in porting Kerberos V5 to a new platform. - -@menu -* Organization of the Source Directory:: Description of the source tree. -* Build Requirements:: How much disk space, etc. you need to - build Kerberos. -* Unpacking the Sources:: Preparing the source tree. -* Doing the Build:: Compiling Kerberos. -* Testing the Build:: Making sure Kerberos built correctly. -* Options to Configure:: Command-line options to Configure -* osconf.h:: Header file-specific configurations -* Shared Library Support:: Building Shared Libraries for Kerberos V5 -* OS Incompatibilities:: Special cases to watch for. -* Using Autoconf:: Modifying Kerberos V5's - configuration scripts. -@end menu - -@node Organization of the Source Directory, Build Requirements, Building Kerberos V5, Building Kerberos V5 -@section Build Requirements - -Below is a brief overview of the organization of the complete source -directory. More detailed descriptions follow. - -@table @b -@itemx appl -applications with @value{PRODUCT} extensions -@itemx clients -@value{PRODUCT} user programs -@itemx gen-manpages -manpages for @value{PRODUCT} and the @value{PRODUCT} login program -@itemx include -include files -@itemx kadmin -administrative interface to the Kerberos master database -@itemx kdc -the @value{PRODUCT} Authentication Service and Key Distribution Center -@itemx krb524 -utilities for converting between Kerberos 4 and Kerberos 5 -@itemx lib -libraries for use with/by @value{PRODUCT} -@itemx mac -source code for building @value{PRODUCT} on MacOS -@itemx prototype -templates for source code files -@itemx slave -utilities for propagating the database to slave KDCs -@itemx tests -test suite -@itemx util -various utilities for building/configuring the code, sending bug reports, etc. -@itemx windows -source code for building @value{PRODUCT} on Windows (see windows/README) -@end table - -@menu -* The appl Directory:: -* The clients Directory:: -* The gen-manpages Directory:: -* The include Directory:: -* The kadmin Directory:: -* The kdc Directory:: -* The krb524 Directory:: -* The lib Directory:: -* The prototype Directory:: -* The slave Directory:: -* The util Directory:: -@end menu - -@node The appl Directory, The clients Directory, Organization of the Source Directory, Organization of the Source Directory -@subsection The appl Directory - -The Kerberos release provides certain UNIX utilities, modified to use -Kerberos authentication. In the @i{appl/bsd} directory are the -Berkeley utilities @i{login}, @i{rlogin}, @i{rsh}, and @i{rcp}, as well as -the associated daemons @i{kshd} and @i{klogind}. The @i{login} program -obtains ticket-granting tickets for users upon login; the other utilities -provide authenticated Unix network services. - -The @i{appl} directory also contains Kerberized telnet and ftp programs, -as well as sample Kerberos application client and server programs. - -@node The clients Directory, The gen-manpages Directory, The appl Directory, Organization of the Source Directory -@subsection The clients Directory - -This directory contains the code for several user-oriented programs. - -@table @b -@itemx kdestroy -This program destroys the user's active Kerberos authorization tickets. -@value{COMPANY} recommends that users @code{kdestroy} before logging out. - -@itemx kinit -This program prompts users for their Kerberos principal name and password, -and attempts to get an initial ticket-granting-ticket for that principal. - -@itemx klist -This program lists the Kerberos principal and Kerberos tickets held in -a credentials cache, or the keys held in a keytab file. - -@itemx kpasswd -This program changes a user's Kerberos password. - -@itemx ksu -This program is a Kerberized verions of the @code{su} program that is -meant to securely change the real and effective user ID to that of the -target user and to create a new security context. - -@itemx kvno -This program acquires a service ticket for the specified Kerberos -principals and prints out the key version numbers of each. -@end table - -@node The gen-manpages Directory, The include Directory, The clients Directory, Organization of the Source Directory -@subsection The gen-manpages Directory - -There are two manual pages in this directory. One is an introduction -to the Kerberos system. The other describes the @code{.k5login} file -which allows users to give access with their UID to other users -authenticated by the Kerberos system. - -@node The include Directory, The kadmin Directory, The gen-manpages Directory, Organization of the Source Directory -@subsection The include Directory - -This directory contains the @i{include} files needed to build the -Kerberos system. - -@node The kadmin Directory, The kdc Directory, The include Directory, Organization of the Source Directory -@subsection The kadmin Directory - -In this directory is the code for the utilities @code{kadmin}, -@code{kadmin.local}, @code{kdb5_util}, and @code{ktutil}. -@code{ktutil} is the Kerberos keytab file maintenance utility from -which a Kerberos administrator can read, write, or edit entries in a -Kerberos V5 keytab or Kerberos V4 srvtab. @code{kadmin} and -@code{kadmin.local} are command-line interfaces to the Kerberos V5 KADM5 -administration system. @code{kadmin.local} runs on the master KDC and -does not use Kerberos to authenticate to the database, while -@code{kadmin} uses Kerberos authentication and an encrypted RPC. The -two provide identical functionalities, which allow administrators to -modify the database of Kerberos principals. @code{kdb5_util} allows -administrators to perform low-level maintenance procedures on Kerberos -and the KADM5 database. With this utility, databases can be created, -destroyed, or dumped to and loaded from ASCII files. It can also be -used to create master key stash files. - -@node The kdc Directory, The krb524 Directory, The kadmin Directory, Organization of the Source Directory -@subsection The kdc Directory - -This directory contains the code for the @code{krb5kdc} daemon, the -Kerberos Authentication Service and Key Distribution Center. - -@node The krb524 Directory, The lib Directory, The kdc Directory, Organization of the Source Directory -@subsection The krb524 Directory - -This directory contains the code for @code{krb524}, a service that -converts Kerberos V5 credentials into Kerberos V4 credentials suitable -for use with applications that for whatever reason do not use V5 -directly. - -@node The lib Directory, The prototype Directory, The krb524 Directory, Organization of the Source Directory -@subsection The lib Directory - -The @i{lib} directory contain 10 subdirectories as well as some -definition and glue files. The @i{crypto} subdirectory contains the -Kerberos V5 encryption library. The @i{des425} subdirectory exports -the Kerberos V4 encryption API, and translates these functions into -calls to the Kerberos V5 encryption API. The @i{gssapi} library -contains the Generic Security Services API, which is a library of -commands to be used in secure client-server communication. The -@i{kadm5} directory contains the libraries for the KADM5 administration -utilities. The Kerberos 5 database libraries are contained in -@i{kdb}. The directories @i{krb4} and @i{krb5} contain the Kerberos 4 -and Kerberos 5 APIs, respectively. The @i{rpc} directory contains the -API for the Kerberos Remote Procedure Call protocol. - -@node The prototype Directory, The slave Directory, The lib Directory, Organization of the Source Directory -@subsection The prototype Directory - -This directory contains several template files. The @code{prototype.h} -and @code{prototype.c} files contain the MIT copyright message and a -placeholder for the title and description of the file. -@code{prototype.h} also has a short template for writing @code{ifdef} -and @code{ifndef} preprocessor statements. The @code{getopt.c} file -provides a template for writing code that will parse the options with -which a program was called. - -@node The slave Directory, The util Directory, The prototype Directory, Organization of the Source Directory -@subsection The slave Directory - -This directory contains code which allows for the propagation of the -Kerberos principal database from the master KDC to slave KDCs over an -encrypted, secure channel. @code{kprop} is the program which actually -propagates the database dump file. @code{kpropd} is the Kerberos V5 -slave KDC update server which accepts connections from the @code{kprop} -program. @code{kslave_update} is a script that takes the name of a -slave server, and propagates the database to that server if the -database has been modified since the last dump or if the database has -been dumped since the last propagation. - -@node The util Directory, , The slave Directory, Organization of the Source Directory -@subsection The util Directory - -This directory contains several utility programs and libraries. The -programs used to configure and build the code, such as @code{autoconf}, -@code{lndir}, @code{kbuild}, @code{reconf}, and @code{makedepend}, -are in this directory. The @i{profile} directory contains most of the -functions which parse the Kerberos configuration files (@code{krb5.conf} -and @code{kdc.conf}). Also in this directory are the Kerberos error table -library and utilities (@i{et}), the Sub-system library and utilities -(@i{ss}), database utilities (@i{db2}), pseudo-terminal utilities -(@i{pty}), and bug-reporting program @code{send-pr}. - -@node Build Requirements, Unpacking the Sources, Organization of the Source Directory, Building Kerberos V5 -@section Organization of the Source Directory - -In order to build Kerberos V5, you will need approximately 60-70 -megabytes of disk space. The exact amount will vary depending on the -platform and whether the distribution is compiled with debugging symbol -tables or not. - -If you wish to keep a separate @dfn{build tree}, which contains the compiled -@file{*.o} file and executables, separate from your source tree, you -will need a @samp{make} program which supports @samp{VPATH}, or -you will need to use a tool such as @samp{lndir} to produce a symbolic -link tree for your build tree. - -@node Unpacking the Sources, Doing the Build, Build Requirements, Building Kerberos V5 -@section Unpacking the Sources - -The first step in each of these build procedures is to unpack the -source distribution. The Kerberos V5 distribution comes in a tar file, -generally named @file{krb5-@value{RELEASE}.tar}, which contains a -compressed tar file consisting of the sources for all of Kerberos -(generally @file{krb5-@value{RELEASE}.tar.gz}) and a PGP signature for -this source tree (generally @file{krb5-@value{RELEASE}.tar.gz.asc}). -@value{COMPANY} highly recommends that you verify the integrity of the -source code using this signature. - -Unpack the compressed tar file in some directory, such as -@file{/u1/krb5-@value{RELEASE}}. (In the rest of this document, we -will assume that you have chosen to unpack the Kerberos V5 source -distribution in this directory. Note that the tarfiles will by default -all unpack into the @file{./krb5-@value{RELEASE}} directory, so that if -your current directory is @file{/u1} when you unpack the tarfiles, you -will get @file{/u1/krb5-@value{RELEASE}/src}, etc.) - - -@node Doing the Build, Testing the Build, Unpacking the Sources, Building Kerberos V5 -@section Doing the Build - -You have a number of different options in how to build Kerberos. If you -only need to build Kerberos for one platform, using a single directory -tree which contains both the source files and the object files is the -simplest. However, if you need to maintain Kerberos for a large number -of platforms, you will probably want to use separate build trees for -each platform. We recommend that you look at @ref{OS -Incompatibilities}, for notes that we have on particular operating -systems. - -@menu -* Building Within a Single Tree:: -* Building with Separate Build Directories:: -* Building using lndir:: -@end menu - -@node Building Within a Single Tree, Building with Separate Build Directories, Doing the Build, Doing the Build -@subsection Building Within a Single Tree - -If you don't want separate build trees for each architecture, then -use the following abbreviated procedure. - -@enumerate -@item - @code{cd /u1/krb5-@value{RELEASE}/src} -@item - @code{./configure} -@item - @code{make} -@end enumerate - -That's it! - -@node Building with Separate Build Directories, Building using lndir, Building Within a Single Tree, Doing the Build -@subsection Building with Separate Build Directories - -If you wish to keep separate build directories for each platform, you -can do so using the following procedure. (Note, this requires that your -@samp{make} program support @samp{VPATH}. GNU's make will provide this -functionality, for example.) If your @samp{make} program does not -support this, see the next section. - -For example, if you wish to create a build directory for @code{pmax} binaries -you might use the following procedure: - -@enumerate -@item -@code{mkdir /u1/krb5-@value{RELEASE}/pmax} -@item - @code{cd /u1/krb5-@value{RELEASE}/pmax} -@item - @code{../src/configure} -@item - @code{make} -@end enumerate - -@node Building using lndir, , Building with Separate Build Directories, Doing the Build -@subsection Building Using @samp{lndir} - -If you wish to keep separate build directories for each platform, and -you do not have access to a @samp{make} program which supports @samp{VPATH}, -all is not lost. You can use the @samp{lndir} program to create -symbolic link trees in your build directory. - -For example, if you wish to create a build directory for solaris binaries -you might use the following procedure: - -@enumerate -@item - @code{mkdir /u1/krb5-@value{RELEASE}/solaris} -@item - @code{cd /u1/krb5-@value{RELEASE}/solaris} -@item - @code{/u1/krb5-@value{RELEASE}/src/util/lndir `pwd`/../src} -@item - @code{./configure} -@item - @code{make} -@end enumerate - -You must give an absolute pathname to @samp{lndir} because it has a bug that -makes it fail for relative pathnames. Note that this version differs -from the latest version as distributed and installed by the XConsortium -with X11R6. Either version should be acceptable. - -@node Testing the Build, Options to Configure, Doing the Build, Building Kerberos V5 -@section Testing the Build - -The Kerberos V5 distribution comes with built-in regression tests. To -run them, simply type the following command while in the top-level build -directory (i.e., the directory where you sent typed @samp{make} to start -building Kerberos; see @ref{Doing the Build}.): - -@example -% make check -@end example - -@menu -* The DejaGnu Tests:: -* The KADM5 Tests:: -@end menu - -@node The DejaGnu Tests, The KADM5 Tests, Testing the Build, Testing the Build -@subsection The DejaGnu Tests - -Some of the built-in regression tests are setup to use the DejaGnu -framework for running tests. These tests tend to be more comprehensive -than the normal built-in tests as they setup test servers and test -client/server activities. - -DejaGnu may be found wherever GNU software is archived. - -Most of the tests are setup to run as a non-privledged user. For some -of the krb-root tests to work properly, either (a) the user running the -tests must not have a .k5login file in the home directory or (b) the -.k5login file must contain an entry for @code{@@KRBTEST.COM}. -There are two series of tests (@samp{rlogind} and @samp{telnetd}) which -require the ability to @samp{rlogin} as root to the local -machine. Admittedly, this does require the use of a @file{.rhosts} file -or some authenticated means. @footnote{If you are fortunate enough to -have a previous version of Kerberos V5 or V4 installed, and the Kerberos -rlogin is first in your path, you can setup @file{.k5login} or -@file{.klogin} respectively to allow you access.} - -If you cannot obtain root access to your machine, all the other tests -will still run. Note however, with DejaGnu 1.2, the "untested testcases" -will cause the testsuite to exit with a non-zero exit status which -@samp{make} will consider a failure of the testing process. Do not worry -about this, as these tests are the last run when @samp{make check} is -executed from the top level of the build tree. This problem does not -exist with DejaGnu 1.3. - -@node The KADM5 Tests, , The DejaGnu Tests, Testing the Build -@subsection The KADM5 Tests - -Regression tests for the KADM5 system, including the GSS-RPC, KADM5 -client and server libraries, and kpasswd, are also included in this -release. Each set of KADM5 tests is contained in a sub-directory called -@code{unit-test} directly below the system being tested. For example, -lib/rpc/unit-test contains the tests for GSS-RPC. The tests are all -based on DejaGnu (but they are not actually called part of "The DejaGnu -tests," whose naming predates the inclusion of the KADM5 system). In -addition, they require the Tool Command Language (TCL) header files and -libraries to be available during compilation and some of the tests also -require Perl in order to operate. If all of these resources are not -available during configuration, the KADM5 tests will not run. The TCL -installation directory can be specified with the @code{--with-tcl} -configure option. (See @xref{Options to Configure}.) The runtest and -perl programs must be in the current execution path. - -If you install DejaGnu, TCL, or Perl after configuring and building -Kerberos and then want to run the KADM5 tests, you will need to -re-configure the tree and run @code{make} at the top level again to make -sure all the proper programs are built. To save time, you actually only -need to reconfigure and build in the directories src/kadmin/testing, -src/lib/rpc, src/lib/kadm5. - -@node Options to Configure, osconf.h, Testing the Build, Building Kerberos V5 -@section Options to Configure - -There are a number of options to @samp{configure} which you can use to -control how the Kerberos distribution is built. The following table -lists the most commonly used options to Kerberos V5's @samp{configure} -program. - -@table @code - -@item --help - -Provides help to configure. This will list the set of commonly used -options for building Kerberos. - -@item --prefix=PREFIX - -By default, Kerberos will install the package's files rooted at -`/usr/local' as in `/usr/local/bin', `/usr/local/sbin', etc. If you -desire a different location, use this option. - -@item --exec-prefix=EXECPREFIX - -This option allows one to separate the architecture independent programs -from the configuration files and manual pages. - -@item --localstatedir=LOCALSTATEDIR - -This option sets the directory for locally modifiable single-machine -data. In Kerberos, this mostly is useful for setting a location for the -KDC data files, as they will be installed in -@code{LOCALSTATEDIR/krb5kdc}, which is by default -@code{PREFIX/var/krb5kdc}. - -@item CC=COMPILER - -Use @code{COMPILER} as the C compiler. - -@item CFLAGS=FLAGS - -Use @code{FLAGS} as the default set of C compiler flags. - -Note that if you use the native Ultrix compiler on a -DECstation you are likely to lose if you pass no flags to cc; md4.c -takes an estimated 3,469 billion years to compile if you provide neither -the @samp{-g} flag nor the @samp{-O} flag to @samp{cc}. - -@item CPPFLAGS=CPPOPTS - -Use @code{CPPOPTS} as the default set of C preprocessor flags. The most -common use of this option is to select certain @code{#define}'s for use -with the operating system's include files. - -@item LD=LINKER - -Use @code{LINKER} as the default loader if it should be different from C -compiler as specified above. - -@item LDFLAGS=LDOPTS - -This option allows one to specify optional arguments to be passed to the -linker. This might be used to specify optional library paths. - -@item --with-krb4 - -This option enables Kerberos V4 backwards compatibility using the -builtin Kerberos V4 library. - -@item --with-krb4=KRB4DIR - -This option enables Kerberos V4 backwards compatibility using a -pre-existing Kerberos V4 installation. The directory specified by -@code{KRB4DIR} specifies where the V4 header files should be found -(@file{KRB4DIR/include}) as well as where the V4 Kerberos library should -be found (@file{KRB4DIR/lib}). - -@item --without-krb4 - -Disables Kerberos V4 backwards compatibility. This prevents Kerberos V4 -clients from using the V5 services including the KDC. This would be -useful if you know you will never install or need to interact with V4 -clients. - -@item --with-netlib[=libs] - -Allows for suppression of or replacement of network libraries. By -default, Kerberos V5 configuration will look for @code{-lnsl} and -@code{-lsocket}. If your operating system has a broken resolver library -(see @ref{Solaris versions 2.0 through 2.3}) or fails to pass the tests in -@file{src/tests/resolv} you will need to use this option. - -@item --with-tcl=TCLPATH - -Some of the unit-tests in the build tree rely upon using a program in -Tcl. The directory specified by @code{TCLPATH} specifies where the Tcl -header file (@file{TCLPATH/include/tcl.h} as well as where the Tcl -library should be found (@file{TCLPATH/lib}). - -@item --enable-shared - -This option will turn on the building and use of shared library objects -in the Kerberos build. This option is only supported on certain -platforms. - -@item --enable-dns -@item --enable-dns-for-kdc -@item --enable-dns-for-realm - -Enable the use of DNS to look up a host's Kerberos realm, or a realm's -KDCs, if the information is not provided in krb5.conf. See @ref{Hostnames -for the Master and Slave KDCs} for information about using DNS to -locate the KDCs, and @ref{Mapping Hostnames onto Kerberos Realms} for -information about using DNS to determine the default realm. By default, -DNS lookups are enabled for the former but not for the latter. - -@item --enable-kdc-replay-cache - -Enable a cache in the KDC to detect retransmitted messages, and resend -the previous responses to them. This protects against certain types of -attempts to extract information from the KDC through some of the -hardware preauthentication systems. - -@item --with-system-et - -Use an installed version of the error-table support software, the -@samp{compile_et} program, the @file{com_err.h} header file and the -@file{com_err} library. If these are not in the default locations, -you may wish to specify @code{CPPFLAGS=-I/some/dir} and -@code{LDFLAGS=-L/some/other/dir} options at configuration time as -well. - -If this option is not given, a version supplied with the Kerberos -sources will be built and installed along with the rest of the -Kerberos tree, for Kerberos applications to link against. - -@item --with-system-ss - -Use an installed version of the subsystem command-line interface -software, the @samp{mk_cmds} program, the @file{ss/ss.h} header file -and the @file{ss} library. If these are not in the default locations, -you may wish to specify @code{CPPFLAGS=-I/some/dir} and -@code{LDFLAGS=-L/some/other/dir} options at configuration time as -well. See also the @samp{SS_LIB} option. - -If this option is not given, the @file{ss} library supplied with the -Kerberos sources will be compiled and linked into those programs that -need it; it will not be installed separately. - -@item SS_LIB=libs... - -If @samp{-lss} is not the correct way to link in your installed -@file{ss} library, for example if additional support libraries are -needed, specify the correct link options here. Some variants of this -library are around which allow for Emacs-like line editing, but -different versions require different support libraries to be -explicitly specified. - -This option is ignored if @samp{--with-system-ss} is not specified. - -@item --with-system-db - -Use an installed version of the Berkeley DB package, which must -provide an API compatible with version 1.85. - -If this option is not given, a version supplied with the Kerberos -sources will be built and installed. (We are not updating this -version at this time because of licensing issues with newer versions -that we haven't investigated sufficiently yet.) - -@item DB_HEADER=headername.h - -If @samp{db.h} is not the correct header file to include to compile -against the Berkeley DB 1.85 API, specify the correct header file name -with this option. For example, @samp{DB_HEADER=db3/db_185.h}. - -@item DB_LIB=libs... - -If @samp{-ldb} is not the correct library specification for the -Berkeley DB library version to be used, override it with this option. -For example, @samp{DB_LIB=-ldb-3.3}. - -@end table - -For example, in order to configure Kerberos on a Solaris machine using -the @samp{suncc} compiler with the optimizer turned on, run the configure -script with the following options: - -@example -% ./configure CC=suncc CFLAGS=-O -@end example - -For a slightly more complicated example, consider a system where -several packages to be used by Kerberos are installed in -@samp{/usr/foobar}, including Berkeley DB 3.3, and an @samp{ss} -library that needs to link against the @samp{curses} library. The -configuration of Kerberos might be done thus: - -@example -% ./configure CPPFLAGS=-I/usr/foobar/include LDFLAGS=-L/usr/foobar/lib \ - --with-system-et --with-system-ss --with-system-db \ - SS_LIB='-lss -lcurses' \ - DB_HEADER=db3/db_185.h DB_LIB=-ldb-3.3 -@end example - -In previous releases, @code{--with-} options were used to specify the -compiler and linker and their options. - -@node osconf.h, Shared Library Support, Options to Configure, Building Kerberos V5 -@section @file{osconf.h} - -There is one configuration file which you may wish to edit to control -various compile-time parameters in the Kerberos distribution: -@file{include/krb5/stock/osconf.h}. The list that follows is by no means -complete, just some of the more interesting variables. - -Please note: The former configuration file @file{config.h} no longer -exists as its functionality has been merged into the auto-configuration -process. @xref{Options to Configure}. - - -@table @code - -@item DEFAULT_PROFILE_PATH - -The pathname to the file which contains the profiles for the known realms, -their KDCs, etc. The default value is @value{DefaultDefaultProfilePath}. - -The profile file format is no longer the same format as Kerberos V4's -@file{krb.conf} file. - -@item DEFAULT_KEYTAB_NAME - -The type and pathname to the default server keytab file (the -equivalent of Kerberos V4's @file{/etc/srvtab}). The default is -@value{DefaultDefaultKeytabName}. - -@item DEFAULT_KDC_ENCTYPE - -The default encryption type for the KDC. The default value is -@value{DefaultMasterKeyType}. - -@item KDCRCACHE - -The name of the replay cache used by the KDC. The default value is -@value{DefaultKDCRCache}. - -@item RCTMPDIR - -The directory which stores replay caches. The default is to try -@value{DefaultRCTmpDirs}. - -@item DEFAULT_KDB_FILE - -The location of the default database. The default value is -@value{DefaultDatabaseName}. - -@end table - -@node Shared Library Support, OS Incompatibilities, osconf.h, Building Kerberos V5 -@section Shared Library Support - -Shared library support is provided for a few operating systems. There -are restrictions as to which compiler to use when using shared -libraries. In all cases, executables linked with the shared libraries in -this build process will have built in the location of the libraries, -therefore obliterating the need for special LD_LIBRARY_PATH, et al environment -variables when using the programs. Except where noted, multiple versions -of the libraries may be installed on the same system and continue to -work. - -Currently the supported platforms are Solaris 2.6-2.9 (aka SunOS -5.6-5.9), Irix 6.5, Redhat Linux, MacOS 8-10, and Microsoft Windows -(using DLLs). - -Shared library support has been tested on the following platforms but -not exhaustively (they have been built but not necessarily tested in an -installed state): Tru64 (aka Alpha OSF/1 or Digital Unix) 4.0, and -HP/UX 10.20. - -Platforms for which there is shared library support but not significant -testing include FreeBSD, OpenBSD, AIX (4.3.3), Linux, NetBSD 1.4.x -(i386), and SunOS 4.x. - -To enable shared libraries on the above platforms, run the configure -script with the option @samp{--enable-shared}. - -@ifset notdef - -XXX What does this mean? - -One special note is that if the Kerberos V4 compatibility is compiled -in, you @b{must not} specify an alternate Kerberos V4 library from the -one in the tree or you will be missing references. - -@end ifset - -@node OS Incompatibilities, Using Autoconf, Shared Library Support, Building Kerberos V5 -@section Operating System Incompatibilities - -This section details operating system incompatibilities with Kerberos V5 -which have been reported to the developers at MIT. If you find -additional incompatibilities, and/or discover work arounds to such -problems, please send a report via the @code{krb5-send-pr} program. -Thanks! - -@menu -* AIX:: -* Alpha OSF/1 V1.3:: -* Alpha OSF/1 (Digital Unix) V2.0++:: -* BSDI:: -* HPUX:: -* Solaris versions 2.0 through 2.3:: -* Solaris 2.X:: -* SGI Irix 5.X:: -* Ultrix 4.2/3:: -@end menu - -@node AIX, Alpha OSF/1 V1.3, OS Incompatibilities, OS Incompatibilities -@subsection AIX - -The AIX 3.2.5 linker dumps core trying to build a shared -@samp{libkrb5.a} produced with the GNU C compiler. The native AIX -compiler works fine. This problem is fixed using the AIX 4.1 linker. - -@node Alpha OSF/1 V1.3, Alpha OSF/1 (Digital Unix) V2.0++, AIX, OS Incompatibilities -@subsection Alpha OSF/1 V1.3 - -Using the native compiler, compiling with the @samp{-O} compiler flag -causes the @code{asn.1} library to be compiled incorrectly. - -Using GCC version 2.6.3 or later instead of the native compiler will also work -fine, both with or without optimization. - -@node Alpha OSF/1 (Digital Unix) V2.0++, BSDI, Alpha OSF/1 V1.3, OS Incompatibilities -@subsection Alpha OSF/1 V2.0++ - -There used to be a bug when using the native compiler in compiling -@file{md4.c} when compiled without either the @samp{-O} or @samp{-g} -compiler options. We have changed the code and there is no problem -under V2.1, but we do not have access to V2.0 to test and see if the -problem would exist there. (We welcome feedback on this issue). There -was never a problem in using GCC version 2.6.3. - -In version 3.2 and beyond of the operating system, we have not seen any -problems with the native compiler. - -@c @node Alpha Tru64 UNIX 5.0 -@c @subsection Alpha Tru64 UNIX 5.0 -@c ... login.krb5 problems - -@node BSDI, HPUX, Alpha OSF/1 (Digital Unix) V2.0++, OS Incompatibilities -@subsection BSDI - -BSDI versions 1.0 and 1.1 reportedly has a bad @samp{sed} which causes -it to go into an infinite loop during the build. The work around is -to use a @samp{sed} from somewhere else, such as GNU. (This may be -true for some versions of other systems derived from BSD 4.4, such as -NetBSD and FreeBSD.) - -@node HPUX, Solaris versions 2.0 through 2.3, BSDI, OS Incompatibilities -@subsection HPUX - -The native (bundled) compiler for HPUX currently will not work, because -it is not a full ANSI C compiler. The optional compiler (c89) should -work as long as you give it the @samp{-D_HPUX_SOURCE} flag -(i.e. @samp{./configure --with-cc='c89 -D_HPUX_SOURCE'}). This has only -been tested recently for HPUX 10.20. - -@node Solaris versions 2.0 through 2.3, Solaris 2.X, HPUX, OS Incompatibilities -@subsection Solaris versions 2.0 through 2.3 - -The @code{gethostbyname()} routine is broken; it does not return a fully -qualified domain name, even if you are using the Domain Name Service -routines. Since Kerberos V5 uses the fully qualified domain name as the -second component of a service principal (i.e, -@samp{host/tsx-11.mit.edu@@ATHENA.MIT.EDU}), this causes problems for servers -who try to figure out their own fully qualified domain name. - -Workarounds: - -@enumerate - -@item - Supply your own resolver library. (such as bind-4.9.3pl1 available -from ftp.vix.com) - -@item - Upgrade to Solaris 2.4 - -@item - Make sure your /etc/nsswitch.conf has `files' before `dns' like: - -@example -hosts: files dns -@end example - -and then in /etc/hosts, make sure there is a line with your -workstation's IP address and hostname, with the fully qualified domain -name first. Example: - -@example -18.172.1.4 dcl.mit.edu dcl -@end example - -Note that making this change may cause other programs in your -environment to break or behave differently. - -@end enumerate - -@node Solaris 2.X, SGI Irix 5.X, Solaris versions 2.0 through 2.3, OS Incompatibilities -@subsection Solaris 2.X - -You @b{must} compile Kerberos V5 without the UCB compatibility -libraries. This means that @file{/usr/ucblib} must not be in the -LD_LIBRARY_PATH environment variable when you compile it. Alternatively -you can use the @code{-i} option to @samp{cc}, by using the specifying -@code{--with-ccopts=-i} option to @samp{configure}. - -@node SGI Irix 5.X, Ultrix 4.2/3, Solaris 2.X, OS Incompatibilities -@subsection SGI Irix 5.X - -If you are building in a tree separate from the source tree, the vendors -version of make does not work properly with regards to -@samp{VPATH}. It also has problems with standard inference rules in 5.2 -(not tested yet in 5.3) so one needs to use GNU's make. - -Under 5.2, there is a bug in the optional System V @code{-lsocket} -library in which the routine @code{gethostbyname()} is broken. The -system supplied version in @code{-lc} appears to work though so one may -simply specify @code{--with-netlib} option to @samp{configure}. - -In 5.3, @code{gethostbyname()} is no longer present in @code{-lsocket} and -is no longer an issue. - -@node Ultrix 4.2/3, , SGI Irix 5.X, OS Incompatibilities -@subsection Ultrix 4.2/3 - -The DEC MIPS platform currently will not support the native compiler, -since the Ultrix compiler is not a full ANSI C compiler. You should use -GCC instead. - -@ifset notdef - -On the DEC MIPS platform, using the native compiler, @file{md4.c} and -@file{md5.c} can not be compiled with the optimizer set at level 1. -That is, you must specify either @samp{--with-ccopts=-O} and -@samp{--with-ccopts=-g} to configure. If you don't specify either, the -compile will never complete. - -The optimizer isn't hung; it just takes an exponentially long time. -Compiling 6 out of the 48 algorithmic steps takes 3 seconds; compiling 7 -steps takes 9 seconds; compiling 8 steps takes 27 seconds, and so on. -Calculations estimate it will finish in approximately 3,469 billion -years.... - -Using GCC instead of the native compiler will also work fine, both with -or without optimization. - -@end ifset - -@node Using Autoconf, , OS Incompatibilities, Building Kerberos V5 -@section Using @samp{Autoconf} - -(If you are not a developer, you can skip this section.) - -In most of the Kerberos V5 source directories, there is a -@file{configure} script which automatically determines the compilation -environment and creates the proper Makefiles for a particular -platform. These @file{configure} files are generated using -@samp{autoconf}, which can be found in the @file{src/util/autoconf} -directory in the distribution. - -Normal users will not need to worry about running @samp{autoconf}; the -distribution comes with the @file{configure} files already prebuilt. -Developers who wish to modify the @file{configure.in} files should see -@ref{Top, , Overview, autoconf, The Autoconf Manual}. - -Note that in order to run @samp{autoconf}, you must have GNU @samp{m4} -in your path. Before you use the @samp{autoconf} in the Kerberos V5 -source tree, you may also need to run @samp{configure}, and then run -@samp{make} in the @file{src/util/autoconf} directory in order to -properly set up @samp{autoconf}. - -One tool which is provided for the convenience of developers can be -found in @file{src/util/reconf}. This program should be run while the -current directory is the top source directory. It will automatically -rebuild any @file{configure} files which need rebuilding. If you know -that you have made a change that will require that all the -@file{configure} files need to be rebuilt from scratch, specify the -@code{--force} option: - -@example -% cd /u1/krb5-@value{RELEASE}/src -% ./util/reconf --force -@end example - -The developmental sources are a raw source tree (before it's been packaged -for public release), without the pre-built @file{configure} files. -In order to build from such a source tree, you must do: - -@example -% cd krb5/util/autoconf -% ./configure -% make -% cd ../.. -% util/reconf -@end example - -Then follow the instructions for building packaged source trees (above). -To install the binaries into a binary tree, do: - -@example -% cd /u1/krb5-@value{RELEASE}/src -% make all -% make install DESTDIR=somewhere-else -@end example - diff --git a/doc/coding-style b/doc/coding-style deleted file mode 100644 index 524c8a61e..000000000 --- a/doc/coding-style +++ /dev/null @@ -1,563 +0,0 @@ -WRITING C CODE -============== - -The code in the krb5 source tree largely follows BSD KNF -(/usr/share/misc/style on NetBSD) except that it uses a four column -basic offset. The style described here is a synthesis of BSD KNF and -the GNU coding standards for the C language. The formatting described -in the "Formatting Your Source Code" section of the GNU coding -standards is mostly what we want, except we use BSD brace style and -BSD-ish conventions for the spacing around operators. - -Formatting style for C code ---------------------------- - -In general, use a four column basic offset, tab stops at eight -columns. Indents should be tabified, i.e. continuous tabs followed by -spaces if necessary if the indent isn't a multiple of eight columns. -The "bsd" style in emacs cc-mode mostly does the right thing. You can -use "M-x c-set-style" "bsd" to get this. Alternatively, you can use -the "krb5" style that is included here. - -Labels, including case labels, are outdented by four columns. -Continuations of statements are indented by an additional four -columns. When continuing expressions this way, split the expression -so that the newline goes before a binary operator rather than after -it. - -Continuations of argument lists or parenthesized expressions should -line up with the column after the opening parenthesis. Note that this -may create width problems if you call a fuction deep in a bunch of -nested control flow statements. Regardless, any expression split -between lines should stil be split so that the newline goes before a -binary operator rather than after it. - -The maximum width should be 79 columns. If you need more than this, -consider rewriting the code so that it fits in 79 columns, since -control flow that is nested deeply enough to require excessive width -is also likely to be difficult to understand if not broken up. -Exceptions may be made for long strings, though ANSI C string -concatenation should work around that as well. - -Function names for definitions should start on column zero, on the -line following their return type name, e.g. - - char * - foo(int a) - { - /* ... */ - } - -[just pretend that's really at column zero] - -The opening brace of a function definition should also be on column -zero. - -Braces that open substatements, such as those following "if", "else", -"while", "for", "do", and "switch", should be on the same line as the -begining of the statement. This is sometimes called "hanging" braces. -The corresponding closing brace should be at the same indentation -level as the beginning of the statement. - -The "while" keyword in a do-while construct should sit on the same -line as the closing brace of the substatement following "do": - - do { - foo(); - } while (0); - -If there is an "if" statement immediately following an "else" keyword, -it should go on the same line immediately after the "else": - - if (x) { - foo(); - } else if (y) { - bar(); - } - -Comments to the right of code start in column 32. Comments not to the -right of code are indented at the prevailing indent for the -surrounding code. Make the comments complete sentences. If you need -more than one line, make them into block comments, like this: - - /* - * This is a block comment. It should consist of complete - * sentences. - * - * Paragraphs should be separated by blank lines so that emacs - * fill commands will work properly. - */ - -Really important single-line comments should also be done in block -form: - - /* - * This is a really important one-line comment. - */ - -In order to get the start and end delimiters for block comments to -stay when you use emacs to fill paragraphs in the comments, set both -the c-hanging-comment-starter-p and the c-hanging-comment-ender-p -variables to nil. This will be done by the tentative "krb5" style for -the emacs cc-mode. - -Spaces go after keywords, but not after function names. Do not, -however, put a space after sizeof. Don't put a space after a cast -operator, either. Spaces also do not go before parentheses that are -argument lists for function calls even if the function call is through -a pointer. Spaces go after commas in argument lists, as well as -commas that are comma operators. Spaces also go between parts in a -for loop, except for "forever" type loops. Use for statements rather -than while statements to create forever loops. - - if (x) { - p = calloc(1024, sizeof(int)); - } - cp = (*elem->fp)(1024); - for (i = 0; i < 10; i++); - for (;;) { - /* ... */ - } - -Binary operators get spaces, unary ones do not. Prefix and postfix -operators also do not get spaces. The structure member operators "." -and "->" count as postfix operators syntactically, not as binary -operators. - - x = --a + b / c - d++; - y = p->z.v[x]; - -Put spaces around the "?" and ":" in a conditional expression. - - x = y ? f() : g(); - -In general, do not parenthesize the argument of "return". - -Coding practices for C ----------------------- - -Assume, for most purposes, working ANSI/ISO C ('89, not '99) support, -both for internal use and for applications compiling against Kerberos -header files and libraries. Some exceptions are noted below. - -Do not use assignments as truth values. Rather than this: - - /* bad style */ - if ((retval = krb5_foo())) - /* ... */; - -do this: - - /* better style */ - retval = krb5_foo(); - if (retval) - /* ... */; - -This makes the code easier to read, and also makes it easier to use -debuggers. It may be excusable to put assignments into the -conditional espression of a "while" statement, though, like: - - while ((ch = getopt(argc, argv, "abn")) != -1) - /* ... */; - -Using assignments as truth values in conditional expressions may make -code particularly impenetrable. - -There are at least three types of "zero" known to C. These are the -integer zero (0), the null pointer constant (NULL), and the character -constant zero ('\0'). Yes, these are usually all technically the -integer zero. Use them in their correct contexts. (Purists will -point out that 0 is a valid null pointer constant; still, do not use 0 -to specify a null pointer constant. For further unconfusion, read the -section on null pointer constants in the C FAQ.) Do not use a lone -variable as a truth value unless it's of integer type. Thus: - - int i; - char *cp; - /* ... */ - if (i) - /* ... */; - if (cp != NULL) { - while (*cp != '\0') - /* ... */; - } - -Do not cast uses of NULL unless you're calling a function with a -variable number of arguments, in which case you should cast it to to -the appropriate pointer type. Likewise, do not cast the return value -from malloc() and friends; the prototype should declare them properly -as returning a void * and thus shouldn't require an explicit cast. - -Do not assume that realloc(NULL, size) will do the right thing, or -that free(NULL) will do the right thing. ANSI guarantees that it -will, but some old libraries (hopefully becoming obsolete) don't. -Also, don't assume that malloc(0) will return a non-NULL pointer. -Typically, though, the output of malloc(0) will be safe to pass to -realloc() and free(). - -In any case, reading the section in the C FAQ on null pointers is -highly recommended to remove confusion regarding null pointers in C, -since this is a subject of much confusion to even experienced -programmers. In particular, if you do not understand why using -calloc() to allocate a struct that contains pointer members or why -calling memset() to initialize such a struct to all-bytes-zero is -wrong, reread that section again. (Note that there are *lots* of -examples of code in the krb5 source tree that erroneously calls -memset() to zero a struct, and we should fix these somehow -eventually.) - -Control flow statements that have a single statement as their body -should nevertheless have braces around their bodies if the body is -more than one line long, especially in the case of stacked multiple -if-else clauses; use: - - if (x) { - if (y) - foo(); - else - bar(); - } - -instead of: - - /* bad style */ - if (x) - if (y) - foo(); - else - bar(); - -which, while legible to the compiler, may confuse human readers and -make the code less maintainable, especially if new branches get added -to any of the clauses. - -Also, you should almost never intersperse conditional compilation -directives with control flow statements, as some combination of -#define'd symbols may result in statements getting eaten by dangling -bits of control flow statements. When it is not possible to avoid -this questionable practice (you really should rewrite the relevant -code section), make use of redundant braces to ensure that a compiler -error will result in preference to incorrect runtime behavior (such as -inadvertantly providing someone with a root shell). - -Do not intersperse conditional compilation directives with control -flow statements in such a way that confuses emacs cc-mode. Not only -does emacs get confused, but the code becomes more difficult to read -and maintain. Therefore, avoid code like this: - - /* bad style */ - if (x) { - f(); - } - #ifdef FOO - else if (y) { - #else - else { - #endif - g(); - } - -Put comments after conditional compilation directives such as "#else" -and "#endif". Make them correspond to the sense of the value that -controls the compilation of the section they are closing, i.e. - - #ifdef FOO - /* ... */ - #else /* !FOO */ - /* ... */ - #endif /* !FOO */ - -Also, in the case of more complex conditional compilation directives, -write the comments like this: - - #if defined(FOO) || defined(BAR) - /* ... */ - #else /* !(defined(FOO) || defined(BAR)) */ - /* ... */ - #endif /* !(defined(FOO) || defined(BAR)) */ - -If you are writing a do-while loop that has only one statement in its -body, put braces around it anyway, since the while clause may be -mistaken for a while loop with an empty body. Don't do this: - - /* bad style */ - do - foo(); - while (x); - -Instead, write this: - - /* better style */ - do { - foo(); - } while (x); - -While it is syntactically correct to call through a function pointer -without applying a dereference operator to it, do not write code that -does this. It is easier to see that the function call is actually -taking place through a function pointer if you write an explicit -dereference. However, do not explicitly take the address of a -function in order to assign it to a function pointer, since a function -name degrades into a pointer. Thus: - - int (*fp)(void); - int foofunc(void); - fp = foofunc; - x = (*fp)(); - -In general, do not take the address of an array. It does not return a -pointer to the first element; it returns a pointer to the array -itself. These are often identical when cast to an integral type, but -they are inherently of different types themselves. Functions that -take array types or pointers to array types as arguments can be -particularly trouble-prone. - -If a function is declared to return a value, do not call "return" -without an argument or allow the flow of control to fall off the end -of the function. - -Always declare the return type of a function, even if it returns int. -Yes, this means declaring main() to return int, since main() is -required to return int by the standard. If a function is not supposed -to return a value, declare it as returning void rather than omitting -the return type, which will default the return type to int. - -Try to use ANSI C prototype-style function definitions in preference -to K&R style definitions. When using K&R style function definitions, -declare all the argument types, even those that are int, but beware of -any narrow types in the argument list. - -Do not declare variables in an inner scope, e.g. inside the compound -substatement of an if statement, unless the complexity of the code -really demands that the variables be declared that way. In such -situations, the function could probably stand to be broken up into -smaller chunks anyway. Do not declare variables in an inner scope -that shadow ones in an outer scope, since this leads to confusion. -Also, some debugging environments, such as gdb under Solaris, can't -see variables declared in an inner scope, so declaring such variables -will make maintenance more difficult as well. - -Parenthesize expressions that may be confusing, particularly where C's -precedences are broken. For example, the shift operators have lower -precedence than the +, -, *, /, and % operators. Perhaps the most -familiar C precedence quirk is that equality and relational operators -are of higher precedence than assignment operators. Less well known -is that the bitwise operators are of a lower precedence than equality -and relational operators. - -The sizeof operator takes either a unary expression or a parenthesized -type name. It is not necessary to parenthesize the operand of sizeof -if it is applied to a unary expression, but still, always parenthesize -the operand of the sizeof operator. The sizeof operator does not -evaluate its operand if it is a unary expression, so usages such as - - s = sizeof(++foo); - -should be avoided for the sake of sanity and readability. - -Don't pass around structures except by address. We may relax this -restriction for non-API function, though. - -For new functions, input parameters should go before output parameters -in the call signature. There are exceptions, such as a context-like -parameter. - -Every function should have block comment preceding it describing -briefly in complete sentences what it does, what inputs and outputs it -has, and what error codes it can return. It should also describe any -unsual aspects of the function. At some point we will want to put -some of this information into a machine-parsable form. - -Macros should have all-uppercase names. If it is necessary to use -multiple statements, use braces, and wrap the whole thing in a -do-while(0) construct, such as - - #define FOOMACRO(x, y) do { \ - foo = (x) + (y); \ - f(y); \ - } while (0) - -Leave off the semicolon at the end of a function-like macro, so that -it can be mostly used like a call to a function without a return -value. Line up the backslashes to make it more readable. Use M-x -c-backslash-region in emacs to do neat lined-up backslashes. -Parenthesize uses of arguments in the replacement text of a macro in -order to prevent weird interactions. - -Strive to make your code capable of compiling using "gcc -Wall --Wmissing-prototypes -Wtraditional -Wcast-qual -Wcast-align --Wconversion -Waggregate-return -pedantic" [XXX need to rethink this -somewhat] without generating any errors or warnings. Do not, however, -compile using the "-ansi" flag to gcc, since that can result in odd -behavior with header files on some systems, causing some necessary -symbols to not be defined. - -Namespaces ----------- - -The C standard reserves a bunch of namespaces for the implementation. -Don't stomp on them. For practical purposes, any identifier with a -leading underscore should not be used. (Technically, ^_[a-z].* are -reserved only for file scope, so should be safe for things smaller -than file scope, but it's better to be paranoid in this case.) - -POSIX reserves typedef names ending with _t as well. - -Recall that errno is a reserved identifier, and is permitted to be a -macro. Therefore, do not use errno as the name of a structure member, -etc. - -Reserved namespaces are somewhat more restricted than this; read the -appropriate section of the C standard if you have questions. - -If you're writing new library code, pick a short prefix and stick with -it for any identifier with external linkage. If for some reason a -library needs to have external symbols that should not be visible to -the application, pick another (related) prefix to use for the internal -globals. This applies to typedef names, tag names, and preprocessor -identifiers as well. - -For the krb5 library, the prefix for public global symbols is "krb5_". -Use "krb5int_" as a prefix for library internal globals. Avoid using -"__" in symbol names, as it may confuse C++ implementations. There -are admittedly a number of places where we leak thing into the -namespace; we should try to fix these. - -Header files should also not leak symbols. Usually using the upcased -version of the prefix you've picked will suffice, e.g. "KRB5_" as a -CPP symbol prefix corresponding to "krb5_". In general, do not define -macros that are lowercase, in order to avoid confusion and to prevent -namespace collisions. - -The C standard only guarantees six case-insensitive characters to be -significant in external identifiers; this is largely regarded as -obsolescent even in 1989 and we will ignore it. It does, however, -only guarantee 31 case-sensitive characters to be signficant in -internal identifiers, so do not use identifiers that differ beyond the -31st character. This is unlikely to be a problem, though. - -Aspects of C style in GNU coding std but not here -------------------------------------------------- - -* redundant parens to force extra indent of operators of different - precedences - -* redundant parens to force general extra indent of expressions that - are broken between lines - -* use of ^L characters to break up source files into pages - -* nitpicking about capitalization in comments of variable names when - their values are meant - -* commenting usages of static variables - -* casts to void - -* separation of word in names with underscores vs case change - -* enum vs #define'd integer constants - -* 14 char filename limits, MS-DOS filename limits - -* portability - -* system library function quirks - -* internationalization - -* mmap() - -Aspects of C style in BSD KNF but not here ------------------------------------------- - -* sorting of header files - -* sorting of struct members - -* separating struct tag decl and struct typedef - -* sorting of var decl - -* lining up var names in decls - -* newline after decls - -* usage of __P - -* usage of getopt - -* not initializing vars in decls - -* stdarg/varargs handling - -Emacs cc-mode style -------------------- - -Putting the following code in your .emacs file will result in mostly -the right thing happening with respect to formatting style. Note that -you may want to turn on auto-newline feature of cc-mode, though that -seems to have some bugs with brace-elseif-brace handling at least in -the version of cc-mode that comes with emacs 20.3. - - (defconst krb5-c-style - '("bsd" - (c-cleanup-list - brace-elseif-brace brace-else-brace defun-close-semi) - (c-comment-continuation-stars . "* ") - (c-electric-pound-behavior alignleft) - (c-hanging-braces-alist - (brace-list-open) - (class-open after) - (substatement-open after) - (block-close . c-snug-do-while) - (extern-lang-open after)) - (c-hanging-colons-alist - (case-label after) - (label after)) - (c-hanging-comment-starter-p) - (c-hanging-comment-ender-p) - (c-indent-comments-syntactically-p . t) - (c-label-minimum-indentation . 0) - (c-special-indent-hook))) - (defun krb5-c-hook () - (c-add-style "krb5" krb5-c-style t)) - (add-hook 'c-mode-common-hook 'krb5-c-hook) - -indent.pro settings -------------------- - -The following settings for the indent program should produce a -reasonable approximation to the C coding style described here, though -some manual cleanup may be necessary. Note that the gindent installed -in the gnu locker does not currently handle -psl correctly though. - --bap --br --ce --ci4 --cli0 --d0 --di8 --i4 --ip --l79 --nbc --ncdb --ndj --nfc1 --lp --npcs --psl --sc --sob - -MAKEFILES -========= - -[XXX needs to be written] - -TEST SUITES -=========== - -[XXX needs to be written] diff --git a/doc/copyright.texinfo b/doc/copyright.texinfo deleted file mode 100644 index 079d06e33..000000000 --- a/doc/copyright.texinfo +++ /dev/null @@ -1,203 +0,0 @@ -Copyright @copyright{} 1985-2002 by the Massachusetts Institute of Technology. - -@quotation -Export of software employing encryption from the United States of -America may require a specific license from the United States -Government. It is the responsibility of any person or organization -contemplating export to obtain such a license before exporting. -@end quotation - -WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute -this software and its documentation for any purpose and without fee is -hereby granted, provided that the above copyright notice appear in all -copies and that both that copyright notice and this permission notice -appear in supporting documentation, and that the name of M.I.T. not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. Furthermore if you -modify this software you must label your software as modified software -and not distribute it in such a fashion that it might be confused with -the original MIT software. M.I.T. makes no representations about the -suitability of this software for any purpose. It is provided ``as is'' -without express or implied warranty. - -@iftex -@vskip 12pt -@hrule -@vskip 12pt -@end iftex - -The following copyright and permission notice applies to the OpenVision -Kerberos Administration system located in kadmin/create, kadmin/dbutil, -kadmin/passwd, kadmin/server, lib/kadm5, and portions of lib/rpc: - -@quotation -Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved - -WARNING: Retrieving the OpenVision Kerberos Administration system source -code, as described below, indicates your acceptance of the following -terms. If you do not agree to the following terms, do not retrieve the -OpenVision Kerberos administration system. - -You may freely use and distribute the Source Code and Object Code -compiled from it, with or without modification, but this Source Code is -provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT -LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A -PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. -IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, -LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR -FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS -AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE -OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR -ANY OTHER REASON. - -OpenVision retains all copyrights in the donated Source Code. OpenVision -also retains copyright to derivative works of the Source Code, whether -created by OpenVision or by a third party. The OpenVision copyright -notice must be preserved if derivative works are made based on the -donated Source Code. - -OpenVision Technologies, Inc. has donated this Kerberos Administration -system to MIT for inclusion in the standard Kerberos 5 distribution. -This donation underscores our commitment to continuing Kerberos -technology development and our gratitude for the valuable work which has -been performed by MIT and the Kerberos community. -@end quotation - -@iftex -@vskip 12pt -@hrule -@vskip 12pt -@end iftex - -The implementation of the Yarrow pseudo-random number generator -in src/lib/crypto/yarrow has the following copyright: - -@quotation - -Copyright 2000 by Zero-Knowledge Systems, Inc. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Zero-Knowledge Systems, -Inc. not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. Zero-Knowledge Systems, Inc. makes no representations -about the suitability of this software for any purpose. It is -provided "as is" without express or implied warranty. - -ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL ZERO-KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -@end quotation - -@iftex -@vskip 12pt -@hrule -@vskip 12pt -@end iftex - -The implementation of the AES encryption algorithm in -src/lib/crypto/aes has the following copyright: - -@quotation - -Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. -All rights reserved. - -LICENSE TERMS - -The free distribution and use of this software in both source and binary -form is allowed (with or without changes) provided that: - -@enumerate -@item -distributions of this source code include the above copyright -notice, this list of conditions and the following disclaimer; -@item -distributions in binary form include the above copyright -notice, this list of conditions and the following disclaimer -in the documentation and/or other associated materials; -@item -the copyright holder's name is not used to endorse products -built using this software without specific written permission. -@end enumerate - -DISCLAIMER - -This software is provided 'as is' with no explcit or implied warranties -in respect of any properties, including, but not limited to, correctness -and fitness for purpose. - -@end quotation - -@iftex -@vskip 12pt -@hrule -@vskip 12pt -@end iftex - -@value{PRODUCT} includes documentation and software developed at the -University of California at Berkeley, which includes this copyright -notice: - -Copyright @copyright{} 1983 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: -@enumerate -@item -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -@item -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. -@item -All advertising materials mentioning features or use of this software -must display the following acknowledgement: -@quotation -This product includes software developed by the University of -California, Berkeley and its contributors. -@end quotation -@item -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. -@end enumerate - -@iftex -@vskip 12pt -@hrule -@vskip 12pt -@end iftex - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notices and this permission notice are -preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries a copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@iftex -@pagealignmacro -@end iftex diff --git a/doc/definitions.texinfo b/doc/definitions.texinfo deleted file mode 100644 index 1acf0f4d0..000000000 --- a/doc/definitions.texinfo +++ /dev/null @@ -1,193 +0,0 @@ -@c Set the "MIT" flag for the MIT edition; set the "CYGNUS" flag for -@c the Cygnus edition. -@clear CYGNUS -@set MIT -@set ADMINUSER joeadmin -@set COMPANY MIT -@set KDCSERVER kerberos -@set KDCSLAVE1 @value{KDCSERVER}-1 -@set KDCSLAVE2 @value{KDCSERVER}-2 -@set PRIMARYDOMAIN mit.edu -@set PRIMARYREALM ATHENA.MIT.EDU -@set PRODUCT Kerberos V5 -@set CPRODUCT Kerberos -@set LCPRODUCT krb5 -@set RANDOMHOST1 daffodil -@set RANDOMHOST1IP 10.0.0.6 -@set RANDOMHOST2 trillium -@set RANDOMHOST2IP 10.1.2.3 -@set RANDOMUSER johndoe -@set RANDOMUSER1 jennifer -@set RANDOMUSER2 david -@set RELEASE 1.3 -@set PREVRELEASE 1.2 -@set INSTALLDIR /usr/@value{LCPRODUCT} -@set PREVINSTALLDIR @value{INSTALLDIR} -@set ROOTDIR /usr/local -@set BINDIR /usr/local/bin -@set LOCALSTATEDIR @value{ROOTDIR}/var -@set SECONDDOMAIN example.com -@set SECONDREALM EXAMPLE.COM -@set UPDATED @today - -@ignore -The rest of the variables in this file are defaults for tags in the -configuration files. Each group of defaults come from the same file in -the code, which is specified in the ignore comment above the group. -After each variable, there should be a comment specifying the variable -in the code that holds the default variable, or the line in which the -default was set. -@end ignore - -@ignore -the following should be consistent with the variables set in -krb5/src/lib/krb5/krb/init_ctx.c -@end ignore -@set DefaultETypeList des3-cbc-sha1 arcfour-hmac-md5 des-cbc-crc des-cbc-md5 des-cbc-md4 -@comment DEFAULT_ETYPE_LIST -@set DefaultDefaultTgsEnctypes @value{DefaultETypeList} -@set DefaultDefaultTktEnctypes @value{DefaultETypeList} -@set DefaultPermittedEnctypes @value{DefaultETypeList} -@set DefaultClockskew 300 seconds, or five minutes -@comment libdefaults, clockskew -@set DefaultChecksumType RSA MD5 -@comment libdefaults, kdc_req_checksum_type, ap_req_checksum_type, safe_checksum_type -@set DefaultCcacheType 3 -@comment DEFAULT_CCACHE_TYPE -@set DefaultCcacheTypeMac 4 -@comment DEFAULT_CCACHE_TYPE -@set DefaultTktLifetime 10 hours -@comment libdefaults, tkt_lifetime -@set DefaultKDCTimesyncMac 1 -@set DefaultKDCTimesync 0 -@comment DEFAULT_KDC_TIMESYNC -@set DefaultKDCDefaultOptions KDC_OPT_RENEWABLE_OK -@comment line 194 - -@ignore -the following defaults should be consistent with default variables set -in krb5/src/include/krb5/stock/osconf.h -@end ignore -@set DefaultMasterKeyType des-cbc-crc -@comment DEFAULT_KDC_ENCTYPE -@set DefaultKadmindPort 749 -@comment DEFAULT_KADM5_PORT -@set DefaultAclFile @value{LOCALSTATEDIR}/krb5kdc/kadm5.acl -@comment DEFAULT_KADM5_ACL_FILE -@set DefaultAdminKeytab @value{LOCALSTATEDIR}/krb5kdc/kadm5.keytab -@comment DEFAULT_KADM5_KEYTAB -@set DefaultDatabaseName @value{LOCALSTATEDIR}/krb5kdc/principal -@comment DEFAULT_KDB_FILE -@set DefaultKdcPorts 88,750 -@comment DEFAULT_KDC_PORTLIST -@set DefaultKpasswdPort 464 -@comment DEFAULT_KPASSWD_PORT -@set DefaultSecondPort 750 -@comment KRB5_DEFAULT_SEC_PORT -@set DefaultPort 88 -@comment KRB5_DEFAULT_PORT -@set DefaultKeyStashFileStub @value{LOCALSTATEDIR}/krb5kdc/.k5. -@comment DEFAULT_KEYFILE_STUB -@set DefaultDefaultKeytabName /etc/krb5.keytab -@comment DEFAULT_KEYTAB_NAME -@set DefaultKpasswdPort 464 -@comment DEFAULT_KPASSWD_PORT -@set DefaultDefaultProfilePath /etc/krb5.conf -@comment DEFAULT_PROFILE_PATH -@set DefaultKDCRCache krb5kdc_rcache -@comment KDCRCACHE -@set DefaultRCTmpDirs /var/tmp, /usr/tmp, /var/usr/tmp, and /tmp - -@ignore -the following defaults should be consistent with the numbers set in -krb5/src/lib/kadm5/alt_prof.c -@end ignore -@set DefaultMaxLife 10 hours -@comment line 608 -@set DefaultMaxRenewableLife 0 -@comment line 622 -@set DefaultDefaultPrincipalExpiration 0 -@comment line 639 -@set DefaultSupportedEnctypes des3-hmac-sha1:normal des-cbc-crc:normal -@comment line 705 - -@ignore -the following defaults should be consistent with the values set in -krb5/src/include/krb5/kdb.h -@end ignore -@set DefaultDefaultPrincipalFlags postdateable, forwardable, tgt-based, renewable, proxiable, dup-skey, allow-tickets, and service enabled. -@comment KRB_KDC_DEFAULT_FLAGS set to 0 - -@ignore -the following defaults should be consistent with the values set in -include/krb5/kdb.h -@end ignore -@set DefaultMasterKeyName K/M -@comment KRB5_KDB_M_NAME - -@ignore -the following defaults should be consistent with the values set in -krb5/src/appl/bsd/login.c -@end ignore -@set DefaultKrb5GetTickets true -@comment login_krb5_get_tickets -@set DefaultKrb4GetTickets false -@comment login_krb4_get_tickets -@set DefaultKrb4Convert false -@comment login_krb4_convert -@set DefaultKrbRunAklog false -@comment login_krb_run_aklog -@set DefaultAklogPath $(prefix)/bin/aklog -@comment lines 955-956 -@set DefaultAcceptPasswd false -@comment login_accept_password - -@ignore -the following defaults should be consistent with the values set in -krb5/src/kdc/kerberos_v4 -@end ignore -@set DefaultV4Mode nopreauth -@comment KDC_V4_DEFAULT_MODE - -@ignore -these defaults are based on code in krb5/src/aclocal.m4 -@end ignore -@set DefaultDNSLookupKDC true -@set DefaultDNSLookupRealm false -@comment lines 1259-1300 - -@ignore -the following are based on variables in krb5/src/include/kerberosIV/krbports.h -@end ignore -@set DefaultKrbPropPort 754 -@comment KRB_PROP_PORT -@set DefaultKloginPort 543 -@comment KLOGIN_PORT -@set DefaultEkloginPort 2105 -@comment EKLOGIN_PORT -@set DefaultKshellPort 544 -@comment KRB_SHELL_PORT - -@ignore -/etc/services -@end ignore -@set DefaultTelnetPort 23 -@set DefaultFTPPort 21 -@set DefaultKrb524Port 4444 - -@comment src/include/kerberosIV/krb.h -@set DefaultKrb4Srvtab /etc/srvtab -@comment line 131 -@set DefaultKrb4Config /etc/krb.conf -@comment KRB_CONF -@set DefaultKrb4Realms /etc/krb.realms -@comment KRB_RLM_TRANS - -@comment krb5/src/lib/krb5/krb/get_in_tkt.c -@set DefaultRenewLifetime 0 -@set DefaultNoaddresses set -@set DefaultForwardable not set -@set DefaultProxiable not set - -@comment lib/krb5/krb/vfy_increds.c -@set DefaultVerifyApReqNofail not set diff --git a/doc/dnssrv.texinfo b/doc/dnssrv.texinfo deleted file mode 100644 index 1a401ac14..000000000 --- a/doc/dnssrv.texinfo +++ /dev/null @@ -1,93 +0,0 @@ -@value{COMPANY} recommends that your KDCs have a predefined set of -CNAME records (DNS hostname aliases), such as @code{@value{KDCSERVER}} -for the master KDC and -@code{@value{KDCSLAVE1}}, @code{@value{KDCSLAVE2}}, @dots{} for the -slave KDCs. This way, if you need to swap a machine, you only need to -change a DNS entry, rather than having to change hostnames. - -A new mechanism for locating KDCs of a realm through DNS has been added -to the @value{COMPANY} @value{PRODUCT} distribution. A relatively new -record type called @code{SRV} has been added to DNS. Looked up by a -service name and a domain name, these records indicate the hostname and -port number to contact for that service, optionally with weighting and -prioritization. (See RFC 2782 if you want more information. You can -follow the example below for straightforward cases.) - -The use with Kerberos is fairly straightforward. The domain name used -in the SRV record name is the domain-style Kerberos realm name. (It is -possible to have Kerberos realm names that are not DNS-style names, but -we don't recommend it for Internet use, and our code does not support it -well.) Several different Kerberos-related service names are used: - -@table @code -@item _kerberos._udp -This is for contacting any KDC by UDP. This entry will be used the most -often. Normally you should list port 88 on each of your KDCs. -@c Don't encourage continued use of port 750 for krb5. -@c It should be only for backwards compatibility with krb4. -@c Do the Mac/Windows krb4 libraries use this DNS entry? -@c The UNIX code does not. - -@item _kerberos._tcp -This is for contacting any KDC by TCP. The MIT KDC by default will not -listen on any TCP ports, so unless you've changed the configuration or -you're running another KDC implementation, you should leave this -unspecified. If you do enable TCP support, normally you should use -port 88. - -@item _kerberos-master._udp -This entry should refer to those KDCs, if any, that will immediately see -password changes to the Kerberos database. This entry is used only in -one case, when the user is logging in and the password appears to be -incorrect; the master KDC is then contacted, and the same password used -to try to decrypt the response, in case the user's password had recently -been changed and the first KDC contacted hadn't been updated. Only if -that fails is an ``incorrect password'' error given. - -If you have only one KDC, or for whatever reason there is no accessible -KDC that would get database changes faster than the others, you do not -need to define this entry. - -@item _kerberos-adm._tcp -This should list port @value{DefaultKadmindPort} on your master KDC. -Support for it is not complete at this time, but it will eventually be -used by the @code{kadmin} program and related utilities. For now, you -will also need the @code{admin_server} entry in @code{krb5.conf}. -(@xref{krb5.conf}.) - -@item _kpasswd._udp -This should list port @value{DefaultKpasswdPort} on your master KDC. -It is used when a user changes her password. - -@end table - -Be aware, however, that the DNS SRV specification requires that the -hostnames listed be the canonical names, not aliases. So, for example, -you might include the following records in your (BIND-style) zone file: - -@smallexample -$ORIGIN foobar.com. -_kerberos TXT "FOOBAR.COM" -kerberos CNAME daisy -kerberos-1 CNAME use-the-force-luke -kerberos-2 CNAME bunny-rabbit -_kerberos._udp SRV 0 0 88 daisy - SRV 0 0 88 use-the-force-luke - SRV 0 0 88 bunny-rabbit -_kerberos-master._udp SRV 0 0 88 daisy -_kerberos-adm._tcp SRV 0 0 749 daisy -_kpasswd._udp SRV 0 0 464 daisy -@end smallexample - -As with the DNS-based mechanism for determining the Kerberos realm of a -host, we recommend distributing the information this way for use by -other sites that may want to interact with yours using Kerberos, even if -you don't immediately make use of it within your own site. If you -anticipate installing a very large number of machines on which it will -be hard to update the Kerberos configuration files, you may wish to do -all of your Kerberos service lookups via DNS and not put the information -(except for @code{admin_server} as noted above) in future versions of -your @code{krb5.conf} files at all. Eventually, we hope to phase out -the listing of server hostnames in the client-side configuration files; -making preparations now will make the transition easier in the future. - diff --git a/doc/dnstxt.texinfo b/doc/dnstxt.texinfo deleted file mode 100644 index e06d220cf..000000000 --- a/doc/dnstxt.texinfo +++ /dev/null @@ -1,38 +0,0 @@ -Mapping hostnames onto Kerberos realms is done in one of two ways. - -The first mechanism, which has been in use for years in MIT-based -Kerberos distributions, works through a set of rules in -the @code{krb5.conf} configuration file. (@xref{krb5.conf}.) You can -specify mappings for an entire domain or subdomain, and/or on a -hostname-by-hostname basis. Since greater specificity takes precedence, -you would do this by specifying the mappings for a given domain or -subdomain and listing the exceptions. - -The second mechanism works by looking up the information in special -@code{TXT} records in the Domain Name Service. This is currently not -used by default because security holes could result if the DNS TXT -records were spoofed. If this mechanism is enabled on the client, -it will try to look up a @code{TXT} record for the DNS name formed by -putting the prefix @code{_kerberos} in front of the hostname in question. -If that record is not found, it will try using @code{_kerberos} and the -host's domain name, then its parent domain, and so forth. So for the -hostname BOSTON.ENGINEERING.FOOBAR.COM, the names looked up would be: - -@smallexample -_kerberos.boston.engineering.foobar.com -_kerberos.engineering.foobar.com -_kerberos.foobar.com -_kerberos.com -@end smallexample - -The value of the first TXT record found is taken as the realm name. -(Obviously, this doesn't work all that well if a host and a subdomain -have the same name, and different realms. For example, if all the hosts -in the ENGINEERING.FOOBAR.COM domain are in the ENGINEERING.FOOBAR.COM -realm, but a host named ENGINEERING.FOOBAR.COM is for some reason in -another realm. In that case, you would set up TXT records for all -hosts, rather than relying on the fallback to the domain name.) - -Even if you do not choose to use this mechanism within your site, you -may wish to set it up anyway, for use when interacting with other sites. - diff --git a/doc/document-list.texinfo b/doc/document-list.texinfo deleted file mode 100644 index 65058b96d..000000000 --- a/doc/document-list.texinfo +++ /dev/null @@ -1,24 +0,0 @@ -This document is one piece of the document set for @value{PRODUCT}. The -documents, and their intended audiences, are: - -@itemize @bullet -@item -@b{@value{PRODUCT} Installation Guide}: a concise guide for installing -@value{PRODUCT}. Kerberos administrators (particularly whoever will be -making site-wide decisions about the installation) and the system -administrators who will be installing the software should read this -guide. - -@item -@b{@value{PRODUCT} System Administrator's Guide}: a sysadmin's guide to -administering a Kerberos installation. The System Administrator's Guide -describes the administration software and suggests policies and -procedures for administering a Kerberos installation. Anyone who will -have administrative access to your Kerberos database should read this -guide. - -@item -@b{@value{PRODUCT} UNIX User's Guide}: a guide to using the Kerberos -UNIX client programs. All users on UNIX systems should read this guide, -particularly the ``Tutorial'' section. -@end itemize diff --git a/doc/glossary.texinfo b/doc/glossary.texinfo deleted file mode 100644 index d49a56a7f..000000000 --- a/doc/glossary.texinfo +++ /dev/null @@ -1,64 +0,0 @@ -@table @b -@item client -an entity that can obtain a ticket. This entity is usually either a -user or a host. - -@item host -a computer that can be accessed over a network. - -@item Kerberos -in Greek mythology, the three-headed dog that guards the entrance to the -underworld. In the computing world, Kerberos is a network security -package that was developed at MIT. - -@item KDC -Key Distribution Center. A machine that issues Kerberos tickets. - -@item keytab -a @b{key tab}le file containing one or more keys. A host or service -uses a @dfn{keytab} file in much the same way as a user uses his/her -password. - -@item principal -a string that names a specific entity to which a set of credentials may -be assigned. It can have an arbitrary number of components, but -generally has three: - -@table @b -@item primary -the first part of a Kerberos @i{principal}. In the case of a user, it -is the username. In the case of a service, it is the name of the -service. - -@item instance -the second part of a Kerberos @i{principal}. It gives information that -qualifies the primary. The instance may be null. In the case of a -user, the instance is often used to describe the intended use of the -corresponding credentials. In the case of a host, the instance is the -fully qualified hostname. - -@item realm -the logical network served by a single Kerberos database and a set of -Key Distribution Centers. By convention, realm names are generally all -uppercase letters, to differentiate the realm from the internet domain. -@end table - -@noindent -The typical format of a typical Kerberos principal is -primary/instance@@REALM. - -@item service -any program or computer you access over a network. Examples of services -include ``host'' (a host, @i{e.g.}, when you use @code{telnet} and -@code{rsh}), ``ftp'' (FTP), ``krbtgt'' (authentication; -cf. @i{ticket-granting ticket}), and ``pop'' (email). - -@item ticket -a temporary set of electronic credentials that verify the identity of a -client for a particular service. - -@item TGT -Ticket-Granting Ticket. A special Kerberos ticket that permits the -client to obtain additional Kerberos tickets within the same Kerberos -realm. -@end table diff --git a/doc/implement/.Sanitize b/doc/implement/.Sanitize deleted file mode 100644 index 1847a88d1..000000000 --- a/doc/implement/.Sanitize +++ /dev/null @@ -1,46 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -ChangeLog -Makefile -ccache-i.tex -changebar.sty -cksum-i.tex -crc-32-i.tex -encrypt-i.tex -fancyheadings.sty -fixunder.sty -functions.sty -implement.tex -kdb-i.tex -keytab-i.tex -libos-i.tex -rcache-i.tex - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/doc/implement/.cvsignore b/doc/implement/.cvsignore deleted file mode 100644 index 67a81b831..000000000 --- a/doc/implement/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -implement.ind -implement.log -implement.idx -implement.aux -implement.toc -implement.dvi -implement.ps diff --git a/doc/implement/ChangeLog b/doc/implement/ChangeLog deleted file mode 100644 index f20a0b8ae..000000000 --- a/doc/implement/ChangeLog +++ /dev/null @@ -1,16 +0,0 @@ -2001-11-06 Ken Raeburn - - * Makefile (clean): Delete *.ilg. - (implement.ind): Use makeindex not index. - -2000-02-25 Ken Raeburn - - * encrypt-i.tex (subsection{Functional interface}): Comment out - combine_keys until/unless it gets implemented. - -Wed Oct 12 02:19:07 1994 Theodore Y. Ts'o (tytso@dcl) - - * Makefile: Added better dependencies to do two-pass latex runs - automatically. Make "make clean" clean up the tex temp - files. - diff --git a/doc/implement/Makefile b/doc/implement/Makefile deleted file mode 100644 index 58fbc4b16..000000000 --- a/doc/implement/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -.SUFFIXES: .tex .dvi .ps - -STYLES=changebar.sty fixunder.sty functions.sty -LIBTEX= implement.tex ccache-i.tex rcache-i.tex keytab-i.tex libos-i.tex \ - kdb-i.tex encrypt-i.tex cksum-i.tex crc-32-i.tex implement.ind - - -all: implement.ps - - -implement.ps: implement.dvi - -# hard to capture two-pass semantics in Makefiles... -# implement.ind: implement.dvi -implement.ind: implement.idx - makeindex implement.idx - -implement.idx: - touch implement.ind - latex implement.tex - rm implement.ind - -clean: - rm -f *.toc *.log *.idx *.ind *.aux *.ilg - -really-clean: clean - rm -f *.dvi *.ps - - -implement.dvi: $(LIBTEX) $(STYLES) - -.tex.dvi: - latex $* - - -.dvi.ps: - dvips $*.dvi -o - diff --git a/doc/implement/ccache-i.tex b/doc/implement/ccache-i.tex deleted file mode 100644 index 66d7b61bf..000000000 --- a/doc/implement/ccache-i.tex +++ /dev/null @@ -1,224 +0,0 @@ -The credentials cache functions (some of which are macros which call to -specific types of credentials caches) deal with storing credentials -(tickets, session keys, and other identifying information) in a -semi-permanent store for later use by different programs. - -\subsubsection{The krb5_cc_ops structure} -In order to implement a new credentials cache type, the programmer should -declare a {\bf krb5_cc_ops} structure, and fill in the elements of the -structure appropriately, by implementing each of the credential cache -functions for the new credentials cache type. - -The prefix element specifies the prefix name of the the new credential -cache type. For example, if the prefix name is ``FILE'', then if the -program calls \funcname{krb5_cc_resolve} with a credential cache name -such as ``FILE:/tmp/krb5_cc_15806'', then \funcname{krb5_cc_resolve} -will call the resolve function (as defined by the {\bf krb5_cc_ops} -structure where the prefix element is ``FILE'') and pass it the -argument ``/tmp/krb5_cc_15806''. - -Before a new credentials cache type can be recognized by -\funcname{krb5_cc_resolve}, it must be registered with the Kerberos -library by calling \funcname{krb5_cc_register}. - -\begin{verbatim} -typedef struct _krb5_cc_ops { - char *prefix; - char *(*get_name)((krb5_ccache)); - krb5_error_code (*resolve)((krb5_ccache *, char *)); - krb5_error_code (*gen_new)((krb5_ccache *)); - krb5_error_code (*init)((krb5_ccache, krb5_principal)); - krb5_error_code (*destroy)((krb5_ccache)); - krb5_error_code (*close)((krb5_ccache)); - krb5_error_code (*store)((krb5_ccache, krb5_creds *)); - krb5_error_code (*retrieve)((krb5_ccache, krb5_flags, - krb5_creds *, krb5_creds *)); - krb5_error_code (*get_princ)((krb5_ccache, - krb5_principal *)); - krb5_error_code (*get_first)((krb5_ccache, - krb5_cc_cursor *)); - krb5_error_code (*get_next)((krb5_ccache, krb5_cc_cursor *, - krb5_creds *)); - krb5_error_code (*end_get)((krb5_ccache, krb5_cc_cursor *)); - krb5_error_code (*remove_cred)((krb5_ccache, krb5_flags, - krb5_creds *)); - krb5_error_code (*set_flags)((krb5_ccache, krb5_flags)); -} krb5_cc_ops; -\end{verbatim} - - -\subsubsection{Per-type functions} -The following entry points must be implemented for each type of -credentials cache. However, \funcname{resolve} and -\funcname{gen_new} are only called by the credentials cache glue code. -They are not called directly by the application. - - -\begin{funcdecl}{resolve}{krb5_error_code}{\funcout} -\funcarg{krb5_ccache *}{id} -\funcin -\funcarg{char *}{residual} -\end{funcdecl} - -Creates a credentials cache named by \funcparam{residual} (which may be -interpreted differently by each type of ccache). The cache is not -opened, but the cache name is held in reserve. - -\begin{funcdecl}{gen_new}{krb5_error_code}{\funcout} -\funcarg{krb5_ccache *}{id} -\end{funcdecl} - -Creates a new credentials cache whose name is guaranteed to be -unique. The cache is not opened. \funcparam{*id} is -filled in with a \datatype{krb5_ccache} which may be used in subsequent -calls to ccache functions. - -\begin{funcdecl}{init}{krb5_error_code}{\funcinout} -\funcarg{krb5_ccache}{id} -\funcin -\funcarg{krb5_principal}{primary_principal} -\end{funcdecl} - -Creates/refreshes a credentials cache identified by \funcparam{id} with -primary principal set to \funcparam{primary_principal}. -If the credentials cache already exists, its contents are destroyed. - -%Errors: permission errors, system errors. - -Modifies: cache identified by \funcparam{id}. - -\begin{funcdecl}{destroy}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\end{funcdecl} - -Destroys the credentials cache identified by \funcparam{id}, invalidates -\funcparam{id}, and releases any other resources acquired during use of -the credentials cache. Requires that \funcparam{id} identifies a valid -credentials cache. After return, \funcparam{id} must not be used unless -it is first reinitialized. - -%Errors: permission errors. - -\begin{funcdecl}{close}{krb5_error_code}{\funcinout} -\funcarg{krb5_ccache}{id} -\end{funcdecl} - -Closes the credentials cache \funcparam{id}, invalidates -\funcparam{id}, and releases \funcparam{id} and any other resources -acquired during use of the credentials cache. Requires that -\funcparam{id} identifies a valid credentials cache. After return, -\funcparam{id} must not be used unless it is first reinitialized. - - -\begin{funcdecl}{store}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_creds *}{creds} -\end{funcdecl} - -Stores \funcparam{creds} in the cache \funcparam{id}, tagged with -\funcparam{creds{\ptsto}client}. -Requires that \funcparam{id} identifies a valid credentials cache. - -%Errors: permission errors, storage failure errors. - -\begin{funcdecl}{retrieve}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_flags}{whichfields} -\funcarg{krb5_creds *}{mcreds} -\funcout -\funcarg{krb5_creds *}{creds} -\end{funcdecl} - -Searches the cache \funcparam{id} for credentials matching -\funcparam{mcreds}. The fields which are to be matched are specified by -set bits in \funcparam{whichfields}, and always include the principal -name \funcparam{mcreds{\ptsto}server}. -Requires that \funcparam{id} identifies a valid credentials cache. - -If at least one match is found, one of the matching credentials is -returned in \funcparam{*creds}. The credentials should be freed using -\funcname{krb5_free_credentials}. - -%Errors: error code if no matches found. - -\begin{funcdecl}{get_princ}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_principal *}{principal} -\end{funcdecl} - -Retrieves the primary principal of the credentials cache (as -set by the \funcname{init} request) -The primary principal is filled into \funcparam{*principal}; the caller -should release this memory by calling \funcname{krb5_free_principal} on -\funcparam{*principal} when finished. - -Requires that \funcparam{id} identifies a valid credentials cache. - -\begin{funcdecl}{get_first}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcout -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Prepares to sequentially read every set of cached credentials. -Requires that \funcparam{id} identifies a valid credentials cache opened by -\funcname{krb5_cc_open}. -\funcparam{cursor} is filled in with a cursor to be used in calls to -\funcname{get_next}. - -\begin{funcdecl}{get_next}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcout -\funcarg{krb5_creds *}{creds} -\funcinout -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Fetches the next entry from \funcparam{id}, returning its values in -\funcparam{*creds}, and updates \funcparam{*cursor} for the next request. -Requires that \funcparam{id} identifies a valid credentials cache and -\funcparam{*cursor} be a cursor returned by -\funcname{get_first} or a subsequent call to -\funcname{get_next}. - -%Errors: error code if no more cache entries. - -\begin{funcdecl}{end_get}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_cc_cursor *}{cursor} -\end{funcdecl} - -Finishes sequential processing mode and invalidates \funcparam{*cursor}. -\funcparam{*cursor} must never be re-used after this call. - -Requires that \funcparam{id} identifies a valid credentials cache and -\funcparam{*cursor} be a cursor returned by -\funcname{get_first} or a subsequent call to -\funcname{get_next}. - -%Errors: may return error code if \funcparam{*cursor} is invalid. - - -\begin{funcdecl}{remove_cred}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_flags}{which} -\funcarg{krb5_creds *}{cred} -\end{funcdecl} - -Removes any credentials from \funcparam{id} which match the principal -name {cred{\ptsto}server} and the fields in \funcparam{cred} masked by -\funcparam{which}. -Requires that \funcparam{id} identifies a valid credentials cache. - -%Errors: returns error code if nothing matches; returns error code if -%couldn't delete. - -\begin{funcdecl}{set_flags}{krb5_error_code}{\funcin} -\funcarg{krb5_ccache}{id} -\funcarg{krb5_flags}{flags} -\end{funcdecl} - -Sets the flags on the cache \funcparam{id} to \funcparam{flags}. Useful -flags are defined in {\tt }. - - diff --git a/doc/implement/changebar.sty b/doc/implement/changebar.sty deleted file mode 100644 index 61b7383f9..000000000 --- a/doc/implement/changebar.sty +++ /dev/null @@ -1,155 +0,0 @@ -% Change bar document-style option for LaTeX. -% -% Copyright (C) 1990 by David B. Johnson. - -% These macros draw a solid bar down the right margin of the output, -% covering a range of the input file that has been declared to be changed. -% -% The beginning and end of a change bar in the text are marked with -% \chgbarbegin and \chgbarend, respectively. For example, -% -% Here is some sample text \chgbarbegin that was -% changed\chgbarend{} and some that wasn't changed. -% -% The change bar is drawn continuously between the line of output -% containing the \chgbarbegin and the line of output containing the -% \chgbarend. These lines can end up on separate pages, and the -% division at page boundaries is handled automatically. - -% Two dimensions control the size and placement of the change bars: -% \chgbarwidth The width of a change bar -% \chgbarsep The distance between the text and the change bar - -% Warning: it does not appear to be possible to do this completely -% correctly, due to the time at which the verticle glue on a page is -% finally set, and the way that page breaks are decided. With -% \raggedbottom, this normally works fine. It hasn't been tested with -% \flushbottom, but will probably behave worse. In strange rare -% situations, a change bar might be drawn from the first line of a page -% up off the top of a page; this can usually be fixed by slightly moving -% the \chngbarend around, or by breaking a single change bar range -% into two ranges. - -\newdimen\chgbarwidth \newdimen\chgbarsep -\chgbarwidth 4pt -\chgbarsep .25in - -\def\chgbarbegin{\ifhmode\@chgbar{-2}\else\@chgbar{-3}\fi} -\def\chgbarend{\@chgbar{-4}\relax} - -\marginparpush 0pt - -% The remainder of this is hacked up based on the LaTeX 2.09 latex.tex. - -% copied from \marginpar -\def\@chgbar#1{\ifhmode \@bsphack\@floatpenalty -\@Mii\else - \@floatpenalty-\@Miii\fi\ifinner - \@parmoderr\@floatpenalty\z@ - \else\@next\@currbox\@freelist{\global - \count\@currbox#1}{\@floatpenalty\z@ \@fltovf - \def\@currbox{\@tempboxa}}\fi - \setbox\@tempboxa\vbox - \bgroup\end@float\@esphack} - -\newdimen\@chgbarbegin -\newif\if@inchgbar \@inchgbarfalse - -\def\@addmarginpar{% -\ifnum\count\@currbox = -2 % change bar begin from hmode - \global\@chgbarbegin\@pageht \global\advance\@chgbarbegin -\baselineskip - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -3 % change bar begin not from hmode - \global\@chgbarbegin\@pageht - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -4 % change bar end - \if@inchgbar\else\@latexbug\fi - \@tempdima\@pageht \advance\@tempdima -\@chgbarbegin - \nointerlineskip - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi -\hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@ -}} -\hss} - \nointerlineskip - \global\@inchgbarfalse - \@cons\@freelist\@currbox -\else - \@next\@marbox\@currlist{\@cons\@freelist\@marbox - \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi - \@tempdima\@mparbottom \advance\@tempdima -\@pageht - \advance\@tempdima\ht\@marbox \ifdim\@tempdima >\z@ - \@warning{Marginpar on page \thepage\space moved}\else\@tempdima\z@ \fi - \global\@mparbottom\@pageht \global\advance\@mparbottom\@tempdima - \global\advance\@mparbottom\dp\@marbox - \global\advance\@mparbottom\marginparpush - \advance\@tempdima -\ht\@marbox - \global\ht\@marbox\z@ \global\dp\@marbox\z@ - \vskip -\@pagedp \vskip\@tempdima\nointerlineskip - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\marginparsep - \else \hskip -\marginparsep \hskip -\marginparwidth \fi - \box\@marbox \hss} - \vskip -\@tempdima - \nointerlineskip - \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp} -\fi\fi\fi} - -\def\@makecol{\setbox\@outputbox\box\@cclv - \if@inchgbar - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \@tempdima\ht\@outputbox \advance\@tempdima -\@chgbarbegin - \advance\@tempdima -\baselineskip - \setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox \nointerlineskip \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi - \hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@}}\hss}} - \global\@chgbarbegin 0pt -\fi - \ifvoid\footins\else\setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox\vskip\skip\footins\footnoterule\unvbox\footins}\fi - \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats - \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth - \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox - \vskip-\dimen128\@textbottom} - \global\maxdepth\@maxdepth} - -\newenvironment{changebar}{\chgbarbegin}{\chgbarend} diff --git a/doc/implement/cksum-i.tex b/doc/implement/cksum-i.tex deleted file mode 100644 index c7f763738..000000000 --- a/doc/implement/cksum-i.tex +++ /dev/null @@ -1,31 +0,0 @@ -Kerberos v5 has the ability to use multiple checksum algorithms. Any -checksum implementation which desires to link with and be usable from the MIT -Kerberos v5 implementation must implement this interface: - -\subsection{Functional interface} - -\begin{funcdecl}{sum_func}{krb5_error_code}{\funcin} -\funcarg{krb5_pointer}{in} -\funcarg{size_t}{in_length} -\funcarg{krb5_pointer}{seed} -\funcarg{size_t}{seed_length} -\funcout -\funcarg{krb5_checksum *}{outcksum} -\end{funcdecl} - -This routine computes the desired checksum over \funcparam{in_length} bytes -at \funcparam{in}. \funcparam{seed_length} bytes of a seed (usually an -encryption key) are pointed to by \funcparam{seed}. Some checksum -algorithms may choose to ignore \funcparam{seed}. If -\funcparam{seed_length} is zero, then there is no seed available. -The routine places the resulting value into \funcparam{outcksum{\ptsto}contents}. - -\funcparam{outcksum{\ptsto}contents} must be set by the caller to point -to enough storage to contain the checksum; the size necessary is an -element of the \datatype{krb5_checksum_entry} structure. - -\subsection{Other data elements} -In addition to the above listed function entry point, each checksum algorithm -should have an entry in \globalname{krb5_cksumarray} and a -\datatype{krb5_checksum_entry} structure describing the entry points -and checksum size for the algorithm. diff --git a/doc/implement/crc-32-i.tex b/doc/implement/crc-32-i.tex deleted file mode 100644 index c5d07a33d..000000000 --- a/doc/implement/crc-32-i.tex +++ /dev/null @@ -1,20 +0,0 @@ -The \libname{libcrc32.a} library provides an implementation of the -CRC-32 checksum algorithm which conforms to the interface required by -the Kerberos library. - -\begin{funcdecl}{crc32_sum_func}{static krb5_error_code}{\funcin} -\funcarg{krb5_pointer}{in} -\funcarg{size_t}{in_length} -\funcarg{krb5_pointer}{seed} -\funcarg{size_t}{seed_length} -\funcout -\funcarg{krb5_checksum *}{outcksum} -\end{funcdecl} - -This routine computes a CRC-32 checksum over \funcparam{in_length} bytes -at \funcparam{in}, and places the resulting value into -\funcparam{outcksum{\ptsto}contents}. \funcparam{seed} is ignored. - -\funcparam{outcksum{\ptsto}contents} must be set by the caller to point -to at least 4 bytes of storage. - diff --git a/doc/implement/encrypt-i.tex b/doc/implement/encrypt-i.tex deleted file mode 100644 index 57e8c833a..000000000 --- a/doc/implement/encrypt-i.tex +++ /dev/null @@ -1,164 +0,0 @@ -Kerberos v5 has the ability to use multiple encryption systems. Any -encryption system which desires to link with and be usable from the MIT -Kerberos v5 implementation must implement at least this interface: - -\subsection{Functional interface} - -\begin{funcdecl}{encrypt_func}{krb5_error_code}{\funcvoid} -\funcarg{krb5_const_pointer}{in} -\funcarg{krb5_pointer}{out} -\funcarg{const size_t}{size} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{krb5_pointer}{ivec} -\end{funcdecl} -Encrypts \funcparam{size} bytes at \funcparam{in}, storing result in -\funcparam{out}. \funcparam{eblock} points to an encrypt block which -has been initialized by \funcname{process_key}. - -\funcparam{in} must include sufficient space beyond the \funcparam{size} -bytes of input data to hold pad and redundancy check bytes; the macro -\funcname{krb5_encrypt_size} can be used to compute this size. - -\funcparam{out} must be preallocated by the caller to contain sufficient -storage to hold the output; the macro \funcname{krb5_encrypt_size} can -be used to compute this size. - -\funcparam{ivec} points to an initial vector/seed to be used in the encryption. -If null, the cryptosystem may choose an appropriate initialization vector. - -%Errors: Returns errors. - -\begin{funcdecl}{decrypt_func}{krb5_error_code}{\funcvoid} -\funcarg{krb5_const_pointer}{in} -\funcarg{krb5_pointer}{out} -\funcarg{const size_t}{size} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{krb5_pointer}{ivec} -\end{funcdecl} -Decrypts \funcparam{size} bytes at \funcparam{in}, storing result in -\funcparam{out}. -\funcparam{eblock} points to an encrypt block which has been initialized -by \funcname{process_key}. - -\funcparam{size} must be a multiple of the encryption block size. - -\funcparam{out} must be preallocated by the caller to contain sufficient -storage to hold the output; this is guaranteed to be no more than -the input size. - -\funcparam{ivec} points to an initial vector/seed to be used in the decryption. -If null, the cryptosystem may choose an appropriate ivec. - -%Errors: Returns errors. - -\begin{funcdecl}{process_key}{krb5_error_code}{\funcvoid} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{const krb5_keyblock *}{keyblock} -\end{funcdecl} -Does any necessary key preprocessing (such as computing key -schedules for DES). -\funcparam{eblock{\ptsto}crypto_entry} must be set by the caller; the -other elements of \funcparam{eblock} are to be assigned by this function. -[In particular, \funcparam{eblock{\ptsto}key} must be set by this -function if the key is needed in raw form by the encryption routine.] - -The caller may not move or reallocate \funcparam{keyblock} before calling -\funcname{finish_key} on \funcparam{eblock}. - -%Errors: Returns errors. - -\begin{funcdecl}{finish_key}{krb5_error_code}{\funcvoid} -\funcarg{krb5_encrypt_block *}{eblock} -\end{funcdecl} -Does any necessary clean-up on \funcparam{eblock} (such as releasing -resources held by \funcparam{eblock{\ptsto}priv}. - -%Errors: Returns errors. - -\begin{funcdecl}{string_to_key}{krb5_error_code}{\funcvoid} -\funcarg{const krb5_keytype}{keytype} -\funcarg{krb5_keyblock *}{keyblock} -\funcarg{const krb5_data *}{data} -\funcarg{const krb5_data}{salt} -\end{funcdecl} -Converts the string pointed to by \funcparam{data} into an encryption key -of type \funcparam{keytype}. \funcparam{*keyblock} is filled in with -the key info; in particular, \funcparam{keyblock{\ptsto}contents} is to -be set to allocated storage. It is the responsibility of the caller to -release this storage when the generated key no longer needed. - -The routine may use \funcparam{salt} to seed or alter the conversion -algorithm. - -If the particular function called does not know how to make a -key of type \funcparam{keytype}, an error may be returned. - -%Errors: Returns errors. - -\begin{funcdecl}{init_random_key}{krb5_error_code}{\funcvoid} -\funcarg{const krb5_keyblock *}{seedblock} -\funcarg{krb5_pointer *}{seed} -\end{funcdecl} - -Initialize the random key generator using the encryption key -\funcparam{seedblock} and allocating private sequence information, filling -in \funcparam{*seed} with the address of such information. -\funcparam{*seed} is to be passed to \funcname{random_key} to provide -sequence information. - -\begin{funcdecl}{finish_random_key}{krb5_error_code}{\funcvoid} -\funcarg{krb5_pointer *}{seed} -\end{funcdecl} - -Free any resources held by \funcparam{seed} and assigned by -\funcname{init_random_key}. - -\begin{funcdecl}{random_key}{krb5_error_code}{\funcvoid} -\funcarg{krb5_pointer *}{seed} -\funcarg{krb5_keyblock **}{keyblock} -\end{funcdecl} - -Generate a random encryption key, allocating storage for it and -filling in the keyblock address in \funcparam{*keyblock}. -When the caller has finished using the keyblock, he should call -\funcname{krb5_free_keyblock} to release its storage. - -%\begin{funcdecl}{combine_keys}{krb5_error_code}{\funcin} -%\funcarg{const krb5_keyblock *}{key1} -%\funcarg{const krb5_keyblock *}{key2} -%\funcout -%\funcarg{krb5_keyblock **}{outkey} -%\end{funcdecl} -%Combine the two encryption keys \funcparam{key1} and \funcparam{key2} to -%generate a new output key \funcparam{outkey}. \funcparam{outkey} is -%filled in to point to the freshly-allocated key. When the caller is -%finished using the \funcparam{*outkey}, it should be freed with -%\funcname{krb5_free_keyblock}. - -\subsection{Other data elements} -In addition to the above listed function entry points, each encryption -system should have an entry in \globalname{krb5_csarray} and a -\datatype{krb5_cryptosystem_entry} structure describing the entry points -and key and padding sizes for the encryption system. - -\subsection{DES functions} -The DES functions conform to the encryption interface required by the -Kerberos version 5 library, and provide an encryption mechanism based on -the DES Cipher-block chaining mode (CBC), with the addition of a -cyclical redundancy check (CRC-32) for integrity checking upon -decryption. - -The functions have the same signatures as those described by the main -library document; the names are: -{\obeylines -\funcname{mit_des_encrypt_func} -\funcname{mit_des_decrypt_func} -\funcname{mit_des_process_key} -\funcname{mit_des_finish_key} -\funcname{mit_des_string_to_key} -\funcname{mit_des_init_random_key} -\funcname{mit_des_finish_random_key} -\funcname{mit_des_random_key} -} -The \datatype{krb5_cryptosystem_entry} for this cryptosystem is -\globalname{mit_des_cryptosystem_entry}. diff --git a/doc/implement/fancyheadings.sty b/doc/implement/fancyheadings.sty deleted file mode 100644 index a71de0fb5..000000000 --- a/doc/implement/fancyheadings.sty +++ /dev/null @@ -1,233 +0,0 @@ -% fancyheadings.sty version 1.0 -% Fancy headers and footers. -% Piet van Oostrum, Dept of Computer Science, University of Utrecht -% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands -% Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!hp4nl!ruuinf!piet) -% March, 1989. - -% Here is a documentstylestyle option that allows you to customize your -% page headers and footers in an easy way. It combines features that were -% separately available in other pagestyles, without introducing much -% complexity. You can define: -% - three-part headers and footers -% - rules in header and footer -% - headers and footers wider than \textwidth -% - multiline headers and footers -% - separate headers and footers for even and odd pages -% - separate headers and footers for chapter pages -% -% To use this pagestyle, you must include the ``fancyheadings'' style -% option in your \documentstyle, and issue the \pagestyle{fancy} command. -% The \pagestyle{fancy} command should be issued after any changes made to -% \textwidth. -% -% The page layout will be as follows: -% -% LHEAD CHEAD RHEAD -% ----------------------------------- (rule) -% -% page body -% -% -% ----------------------------------- (rule) -% LFOOT CFOOT RFOOT -% -% The L-fields will be leftadjusted, the C-fields centered and the -% R-fields rightadjusted. -% Each of the six fields and the two rules can be defined separately. -% -% Simple use: -% -% The header and footer fields can be defined by commands \lhead{LHEAD} -% and so on for the other fields. If the field depends on something in the -% document (e.g. section titles) you must in general use the \markboth and -% \markright commands, otherwise a title may end on the wrong page. You -% can do this e.g. by redefining the commands \chaptermark, \sectionmark -% and so on (see example below). The defaults for these marks are as in -% the standard pagestyles. The marks can be put into a header or footer -% field by referencing \leftmark and \rightmark. -% -% Rules in header and footer -% -% The thickness of the rules below the header and above the footer can be -% changed by redefining the length parameters \headrulewidth (default -% 0.4pt) and \footrulewidth (default 0). These may be redefined by the -% \setlength command. A thickness of 0pt makes the rule invisible. -% If you want to make more complicated changes, you have to redefine the -% commands \headrule and/or \footrule. -% -% Headers and footers wider than \textwidth -% -% The headers and footers are set in a box of width \headwidth. The -% default for this is the value of \textwidth. You can make it wider (or -% smaller) by redefining \headwidth with the \setlength or \addtolength -% command. The headers and footers will stick out the page on the same -% side as the marginal notes. For example to include the marginal notes, -% add both \marginparsep and \marginparwidth to \headwidth (see also the -% example below). -% -% Multiline headers and footers -% -% Each of the six fields is set in an appropriate parbox, so you can put a -% multiline part in it with the \\ command. It is also possible to put -% extra space in it with the \vspace command. Note that if you do this you -% will probably have to increase the \headheight or \footskip lengths. -% -% Separate headers and footers for even and odd pages -% -% If you want the headers and footers to be different on even- and -% odd-numbered pages in the ``twoside'' style, the field-defining macros -% can be given an optional argument, to be used on the even-numbered -% pages, like \lhead[EVEN-LHEAD]{ODD-RHEAD}. -% -% Separate headers and footers for chapter pages -% -% LaTeX gives a \thispagestyle{plain} command for the first page of the -% document, the first page of each chapter and a couple of other pages. It -% might be incompatible with your pagestyle. In this case you can use a -% slightly different version of the pagestyle, called \pagestyle{fancyplain}. -% This pagestyle redefines the pagestyle ``plain'' to also use pagestyle -% ``fancy'' with the following modifications: -% - the thicknesses of the rules is defined by \plainheadrulewidth and -% \plainfootrulewidth (both default 0). -% - the 6 fields may be defined separately for the plain pages by -% giving them the value \fancyplain{PLAIN-VALUE}{NORMAL-VALUE}. This -% construct may be used in both the optional argument and the normal -% argument. Thus \lhead[\fancyplain{F1}{F2}]{\fancyplain{F3}{F4}} -% specifies the LHEAD value in a two-sided document: -% F1 on an even-numbered ``plain'' page -% F2 on an even-numbered normal page -% F3 on an odd-numbered ``plain'' page -% F4 on an odd-numbered normal page. -% -% Defaults: -% -% \headrulewidth 0.4pt -% \footrulewidth 0pt -% \plainheadrulewidth 0pt -% \plainfootrulewidth 0pt -% -% \lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}} -% % i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages -% \chead{} -% \rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}} -% % i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages -% \lfoot{} -% \cfoot{\rm\thepage} % page number -% \rfoot{} -% -% Examples: -% -% To put two lines containing the section title and the subsection title -% in the righthandside corner, use: -% -% \documentstyle[fancyheadings]{article} -% \pagestyle{fancy} -% \renewcommand{\sectionmark}[1]{\markboth{#1}{}} -% \renewcommand{\subsectionmark}[1]{\markright{#1}} -% \rfoot{\leftmark\\\rightmark} -% -% The following definitions give an approximation of the style used in the -% LaTeX book: -% -% \documentstyle[fancyheadings]{book} -% \pagestyle{fancyplain} -% \addtolength{\headwidth}{\marginparsep} -% \addtolength{\headwidth}{\marginparwidth} -% \renewcommand{\chaptermark}[1]{\markboth{#1}{#1}} % remember chapter title -% \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} -% % section number and title -% \lhead[\fancyplain{}{\bf\thepage}]{\fancyplain{}{\bf\rightmark}} -% \rhead[\fancyplain{}{\bf\leftmark}]{\fancyplain{}{\bf\thepage}} -% \cfoot{} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\lhead{\@ifnextchar[{\@xlhead}{\@ylhead}} -\def\@xlhead[#1]#2{\gdef\@elhead{#1}\gdef\@olhead{#2}} -\def\@ylhead#1{\gdef\@elhead{#1}\gdef\@olhead{#1}} - -\def\chead{\@ifnextchar[{\@xchead}{\@ychead}} -\def\@xchead[#1]#2{\gdef\@echead{#1}\gdef\@ochead{#2}} -\def\@ychead#1{\gdef\@echead{#1}\gdef\@ochead{#1}} - -\def\rhead{\@ifnextchar[{\@xrhead}{\@yrhead}} -\def\@xrhead[#1]#2{\gdef\@erhead{#1}\gdef\@orhead{#2}} -\def\@yrhead#1{\gdef\@erhead{#1}\gdef\@orhead{#1}} - -\def\lfoot{\@ifnextchar[{\@xlfoot}{\@ylfoot}} -\def\@xlfoot[#1]#2{\gdef\@elfoot{#1}\gdef\@olfoot{#2}} -\def\@ylfoot#1{\gdef\@elfoot{#1}\gdef\@olfoot{#1}} - -\def\cfoot{\@ifnextchar[{\@xcfoot}{\@ycfoot}} -\def\@xcfoot[#1]#2{\gdef\@ecfoot{#1}\gdef\@ocfoot{#2}} -\def\@ycfoot#1{\gdef\@ecfoot{#1}\gdef\@ocfoot{#1}} - -\def\rfoot{\@ifnextchar[{\@xrfoot}{\@yrfoot}} -\def\@xrfoot[#1]#2{\gdef\@erfoot{#1}\gdef\@orfoot{#2}} -\def\@yrfoot#1{\gdef\@erfoot{#1}\gdef\@orfoot{#1}} - -\newdimen\headrulewidth -\newdimen\footrulewidth -\newdimen\plainheadrulewidth -\newdimen\plainfootrulewidth -\newdimen\headwidth -\newif\if@fancyplain \@fancyplainfalse -\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi} - -% Initialization of the head and foot text. - -\headrulewidth 0.4pt -\footrulewidth\z@ -\plainheadrulewidth\z@ -\plainfootrulewidth\z@ - -\lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}} -% i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages -\chead{} -\rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}} -% i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages -\lfoot{} -\cfoot{\rm\thepage} % page number -\rfoot{} - -% Put together a header or footer given the left, center and -% right text, fillers at left and right and a rule. -% The \lap commands put the text into an hbox of zero size, -% so overlapping text does not generate an errormessage. - -\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\hbox -{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[b]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5} - - -\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\footrule -\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[t]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5} - -\def\headrule{{\if@fancyplain\headrulewidth\plainheadrulewidth\fi -\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}} - -\def\footrule{{\if@fancyplain\footrulewidth\plainfootrulewidth\fi -\vskip-0.3\normalbaselineskip\vskip-\footrulewidth -\hrule\@width\headwidth\@height\footrulewidth\vskip0.3\normalbaselineskip}} - -\def\ps@fancy{ -\let\@mkboth\markboth -\@ifundefined{chapter}{\def\sectionmark##1{\markboth -{\uppercase{\ifnum \c@secnumdepth>\z@ - \thesection\hskip 1em\relax \fi ##1}}{}} -\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne - \thesubsection\hskip 1em\relax \fi ##1}}} -{\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth>\m@ne - \@chapapp\ \thechapter. \ \fi ##1}}{}} -\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@ - \thesection. \ \fi ##1}}}} -\def\@oddhead{\@fancyhead\relax\@olhead\@ochead\@orhead\hss} -\def\@oddfoot{\@fancyfoot\relax\@olfoot\@ocfoot\@orfoot\hss} -\def\@evenhead{\@fancyhead\hss\@elhead\@echead\@erhead\relax} -\def\@evenfoot{\@fancyfoot\hss\@elfoot\@ecfoot\@erfoot\relax} -\headwidth\textwidth} -\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy} -\def\ps@plain@fancy{\@fancyplaintrue\ps@fancy} diff --git a/doc/implement/fixunder.sty b/doc/implement/fixunder.sty deleted file mode 100644 index b7ae58dbf..000000000 --- a/doc/implement/fixunder.sty +++ /dev/null @@ -1,48 +0,0 @@ -% fixunder.sty, 31 May 1990, John T. Kohl -% -% The contents of this file are in the public domain. -% -% -% play games with _ to make it active and to provide a reasonable _ -% character (from \tt in most cases), and a discretionary word-break point. - -% -% Some \makeunder... macros for convenience in setting catcodes. -% -\def\makeunderactive{\catcode`\_=\active\relax} -\def\makeunderother{\catcode`\_=12\relax} -\def\makeunderletter{\catcode`\_=11\relax} -\def\makeundernormal{\catcode`\_=8\relax} -\makeunderother -\def\cctwlunder{_} - -% -% The hair here is to allow things like \index to work reasonably with -% the new definition of underscore when the argument to index is part of -% a macro replacement and as such gets tokenized before \index is -% evaluated. -% [in the normal case at top-level, \index{foo_bar} works since \index -% does some hair to make _ into a reasonable character code, and \index -% does NOT use a macro expansion. If you have something like -% \def\foo#1#2{\index{#1} bar #2} -% then \foo{baz_quux}{frobnitz} will result in baz_quux getting -% tokenized BEFORE \foo is expanded, so that the catcode hair in \index -% is to no avail.] -% -% \underrealfalse declares that you want to replace with the \tt _; -% \underrealtrue declares that you want to replace with \char95 (ASCII _). -% -% for things like \index which write things out to files, set -% \underrealfalse before evaluating the \index macro, and what actually -% gets written to the file is an _, rather than something like -% {\leavemode \kern... } (the typical definition of \_). -% -% the above example would then be -% \def\foo#1#2{\underrealfalse\index{#1}\underrealtrue bar #2} -% - -\newif\ifunderreal -\underrealfalse -\makeunderactive -\def_{\ifunderreal\cctwlunder\else\leavevmode {\tt \cctwlunder}\discretionary{}{}{}\fi} -\let\_=_ diff --git a/doc/implement/functions.sty b/doc/implement/functions.sty deleted file mode 100644 index a3165f811..000000000 --- a/doc/implement/functions.sty +++ /dev/null @@ -1,70 +0,0 @@ -% -% definitions related to function declarations/displays -% -\ifx\undefined\@psfonts -\def\argfont{\tt} -\else -\font\argfont = pcrb -\hyphenchar\argfont = -1 -\fi -\let\funcfont=\bf -\newcount\argc@ount -%\setlength{\marginparsep}{0.05in} -%\setlength{\marginparwidth}{1.45in} -% -% This function fixes up the function name to be displayed in the -% margin so that the krb5_, if any, is stripped. -% -% Note: this is a hack; what's really happening is that name beginning with -% krb5 will have its first five characters stripped from it. -% This means that 'Krb5abc' will get rewritten to be 'bc'. -% Unfortunately, we can't do better because of the underscore -% hacks that are going on elsewhere. -% -% WARNING: This is ugly; don't look at it too soon after lunch! -% [tytso:19900920.2231EDT] -\newif\if@krbfunc -\def\endkrb{} -\def\fix@parname#1{\expandafter\parse@krb#1\endkrb% -\endkrb\endkrb\endkrb\endkrb}% In case the argument is less -% than five letters, we don't want to -% lose on the argument parsing. -\def\parse@krb#1#2#3#4#5#6\endkrb{\@krbfuncfalse% -\if#1k\if#2r\if#3b\if#45\@krbfunctrue\fi\fi\fi\fi% -\if@krbfunc#6\else#1#2#3#4#5#6\fi} -% -% funcdecl is used as \begin{funcdecl}{funcname}{return type}{firstline} -% -% see fixunder.sty for comments on why the \underrealtrue & \underrealfalse -% stuff is here. -\newenvironment{funcdecl}[3]{\underrealtrue\index{#1}\underrealfalse% -\medbreak -\gdef\funcn@me{#1} -\argc@ount=0\noindent% -%the \mbox{} is to prevent the line/paragraph breaking from eating the -%fill space. -\marginpar[{{\sloppy \hfil\fix@parname{\funcn@me}\hfill\mbox{}}}]% -{{\sloppy \hfill\fix@parname{\funcn@me}\hfil\mbox{}}}% -\vbox\bgroup\begin{minipage}[t]{\textwidth}\begin{tabbing} -#2 \\ -{\bf #1}(\= \+ #3% -}{) -\end{tabbing}\vfil\end{minipage}\egroup\par\nopagebreak -} -\newcommand{\docomm@}{\ifnum\argc@ount >0, \\\fi} -\newcommand{\funcvoid}{\argc@ount=0} -\newcommand{\funcin}{\docomm@\argc@ount=0{\sl /* IN */}\\} -\newcommand{\funcinout}{\docomm@\argc@ount=0{\sl /* IN/OUT */}\\} -\newcommand{\funcout}{\docomm@\argc@ount=0{\sl /* OUT */}\\} -\newcommand{\funcarg}[2]{\docomm@#1 {\argfont #2}\advance\argc@ount by1} -\newcommand{\funcparam}[1]{{\argfont #1}} -\newcommand{\funcfuncarg}[2]{\docomm@#1 {\argfont #2}(\= \+ \argc@ount=0} -\newcommand{\funcendfuncarg}{), \- \\ \argc@ount=0} -\newcommand{\libname}[1]{{\argfont #1}} -\newcommand{\globalname}[1]{{\argfont #1}} -\newcommand{\ptsto}{->\discretionary{}{}{}} -\newcommand{\datatype}[1]{{\bf #1}} -\newcommand{\filename}[1]{{\sl #1\/}} - -\newcommand{\funcname}[1]{\underrealtrue\index{#1}\underrealfalse{\funcfont #1}()} -\newcommand{\funcnamenoparens}[1]{\underrealtrue\index{#1}\underrealfalse{\funcfont #1}} diff --git a/doc/implement/implement.tex b/doc/implement/implement.tex deleted file mode 100644 index 9aa62579a..000000000 --- a/doc/implement/implement.tex +++ /dev/null @@ -1,94 +0,0 @@ -\documentstyle[fixunder,functions,changebar,twoside,fancyheadings]{article} -\setlength{\oddsidemargin}{0in} -\setlength{\evensidemargin}{2.00in} -\setlength{\marginparsep}{0.05in} -\setlength{\marginparwidth}{1.95 in} -\setlength{\textwidth}{4.75in} -\setlength{\topmargin}{-.5in} -\setlength{\textheight}{9in} -\setlength{\parskip}{.1in} -\setlength{\parindent}{2em} -\setlength{\footrulewidth}{0.4pt} -\setlength{\plainfootrulewidth}{0.4pt} -\setlength{\plainheadrulewidth}{0.4pt} -\makeindex -\newif\ifdraft -\draftfalse -% -% Far, far too inconvenient... it's still very draft-like anyway.... -% [tytso:19900921.0018EDT] -% -%\typein{Draft flag? (type \noexpand\draftfalse if not draft...)} -\ifdraft -\pagestyle{fancyplain} -\addtolength{\headwidth}{\marginparsep} -\addtolength{\headwidth}{\marginparwidth} -\makeatletter -\renewcommand{\sectionmark}[1]{\markboth {\uppercase{\ifnum \c@secnumdepth >\z@ - \thesection\hskip 1em\relax \fi #1}}{}}% -\renewcommand{\subsectionmark}[1]{\markright {\ifnum \c@secnumdepth >\@ne - \thesubsection\hskip 1em\relax \fi #1}} -\makeatother -\lhead[\thepage]{\fancyplain{}{\sl\rightmark}} -\rhead[\fancyplain{}{\sl\rightmark}]{\thepage} -\lfoot[]{{\bf DRAFT---DO NOT REDISTRIBUTE}} -\rfoot[{\bf DRAFT---DO NOT REDISTRIBUTE}]{} -\cfoot{\thepage} -\else\pagestyle{headings}\fi - -%nlg- time to make this a real document - -\title{\Huge Kerberos V5 Implementer's Guide} -\date{\ifdraft \\ {\Large DRAFT---}\fi\today} -\author{MIT Information Systems} - -\begin{document} -\maketitle -\tableofcontents - -\section{Introduction} - - This document is designed to aide the programmer who plans to -change MIT's implementation of Kerberos significantly. It is geared towards -programmers who are already familiar with Kerberos and how MIT's -implementation is structured. - - Some of the more basic information needed can be found in the -API document, although many functions have been repeated where -additional information has been included for the implementer. The -function descriptions included are up to date, even if the description -of the functions may not be very verbose. - -\ifdraft\sloppy\fi - -\section{Cache and Key table functions} - -\subsection{Credentials cache functions} -\input{ccache-i.tex} - -\subsection{Replay cache functions} -\input{rcache-i.tex} - -\subsection{Key table functions} -\input{keytab-i.tex} - -\section{Operating-system specific functions} -\input{libos-i.tex} - -\section{Principal database functions} - -\input{kdb-i.tex} - -\section{Encryption system interface} -\input{encrypt-i.tex} - -\section{Checksum interface} -\input{cksum-i.tex} - -\section{CRC-32 checksum functions} -\input{crc-32-i.tex} - -\appendix -\cleardoublepage -\input{\jobname.ind} -\end{document} diff --git a/doc/implement/kdb-i.tex b/doc/implement/kdb-i.tex deleted file mode 100644 index dc81971bb..000000000 --- a/doc/implement/kdb-i.tex +++ /dev/null @@ -1,242 +0,0 @@ -The \libname{libkdb.a} library provides a principal database interface -to be used by the Key Distribution center and other database -manipulation tools. - - -\begin{funcdecl}{krb5_db_set_name}{krb5_error_code}{\funcin} -\funcarg{char *}{name} -\end{funcdecl} - -Set the name of the database to \funcparam{name}. -%Errors: If it doesn't exist, an error code is returned. - -Must be called before \funcname{krb5_db_init} or after -\funcname{krb5_db_fini}; must not be called while db functions are active. - -\begin{funcdecl}{krb5_db_set_nonblocking}{krb5_error_code}{\funcin} -\funcarg{krb5_boolean}{newmode} -\funcout -\funcarg{krb5_boolean *}{oldmode} -\end{funcdecl} - -Changes the locking mode of the database functions, returning the previous -mode in \funcparam{*oldmode}. - -If \funcparam{newmode} is TRUE, then the database is put into -non-blocking mode, which may result in ``database busy'' error codes from -the get, put, and iterate routines. - -If \funcparam{newmode} is FALSE, then the database is put into blocking mode, -which may result in delays from the get, put and iterate routines. - -The default database mode is blocking mode. - -\begin{funcdecl}{krb5_db_init}{krb5_error_code}{\funcvoid} -\end{funcdecl} - -Called before using \funcname{krb5_db_get_principal}, -\funcname{krb5_db_put_principal}, \funcname{krb5_db_iterate}, and -\funcname{krb5_db_set_nonblocking}. - -Does any required initialization. - -%Errors: init errors, system errors. - -\begin{funcdecl}{krb5_db_fini}{krb5_error_code}{\funcvoid} -\end{funcdecl} - -Called after all database operations are complete, to perform any required -clean-up. - -%Errors: sysytem errors. - - -\begin{funcdecl}{krb5_db_get_age}{krb5_error_code}{\funcin} -\funcarg{char *}{db_name} -\funcout -\funcarg{time_t *}{age} -\end{funcdecl} - -Retrieves the age of the database \funcname{db_name} (or the current -default database if \funcname{db_name} is NULL). - -\funcparam{*age} is filled in in local system time units, and represents -the last modification time of the database. - -%Errors: system errors. - - -\begin{funcdecl}{krb5_db_create}{krb5_error_code}{\funcin} -\funcarg{char *}{db_name} -\end{funcdecl} - -Creates a new database named \funcname{db_name}. Will not create a -database by that name if it already exists. The database must be -populated by the caller by using \funcname{krb5_db_put_principal}. - -%Errors: db exists, system errors. - -\begin{funcdecl}{krb5_db_rename}{krb5_error_code}{\funcin} -\funcarg{char *}{source} -\funcarg{char *}{dest} -\end{funcdecl} -Renames the database \funcarg{source} to \funcarg{dest} - -Any database named \funcarg{dest} is destroyed. - -%Errors: system errors. - -\begin{funcdecl}{krb5_db_get_principal}{krb5_error_code}{\funcin} -\funcarg{krb5_principal}{searchfor} -\funcout -\funcarg{krb5_db_entry *}{entries} -\funcinout -\funcarg{int *}{nentries} -\funcout -\funcarg{krb5_boolean *}{more} -\end{funcdecl} - -Retrieves the principal records named by \funcparam{searchfor}. - -\funcparam{entries} must point to an array of \funcparam{*nentries} -krb5_db_entry structures. -At most \funcparam{*nentries} structures are filled in, and -\funcparam{*nentries} is modified to reflect the number actually returned. - -\funcparam{*nentries} must be at least one (1) when this function is called. - -\funcparam{*more} is set to TRUE if there are more records that wouldn't fit -in the available space, and FALSE otherwise. - -The principal structures filled in have pointers to allocated storage; -\funcname{krb5_db_free_principal} should be called with -\funcparam{entries} and \funcparam{*nentries} -in order to free this storage when no longer needed. - - -\begin{funcdecl}{krb5_db_free_principal}{void}{\funcin} -\funcarg{krb5_db_entry *}{entries} -\funcarg{int}{nentries} -\end{funcdecl} - -Frees allocated storage held by \funcparam{entries} as filled in by -\funcname{krb5_db_get_principal}. - - -\begin{funcdecl}{krb5_db_put_principal}{krb5_error_code}{\funcin} -\funcarg{krb5_db_entry *}{entries} -\funcarg{int *}{nentries} -\end{funcdecl} - -Stores the \funcparam{*nentries} principal structures pointed to by -\funcparam{entries} in the database. - -\funcparam{*nentries} is updated upon return to reflect the number of records -acutally stored; the first \funcparam{*nentries} records will have been -stored in the database. - -%Errors: Returns error code if not all entries were stored. - -\begin{funcdecl}{krb5_db_iterate}{krb5_error_code}{\funcin} -\funcfuncarg{krb5_error_code}{(*func)} -\funcarg{krb5_pointer}{} -\funcarg{krb5_db_entry *}{} -\funcendfuncarg -\funcarg{krb5_pointer}{iterate_arg} -\end{funcdecl} - -Iterates over the database, fetching every entry in an unspecified order -and calling \funcparam{(*func)}(\funcparam{iterate_arg}, -\funcparam{principal}) where \funcparam{principal} points to a record from the -database. - -If \funcparam{(*func)}() ever returns an error code, the iteration -should be -aborted and that error code is returned by this function. - -\begin{funcdecl}{krb5_db_store_mkey}{krb5_error_code}{\funcin} -\funcarg{char *}{keyfile} -\funcarg{krb5_principal}{mname} -\funcarg{krb5_keyblock *}{key} -\end{funcdecl} - -Put the KDC database master key into the file \funcparam{keyfile}. If -\funcparam{keyfile} is NULL, then a default file name derived from the -principal name \funcparam{mname} is used. - -\begin{funcdecl}{krb5_db_fetch_mkey}{krb5_error_code}{\funcin} -\funcarg{krb5_principal}{mname} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{krb5_boolean}{fromkeyboard} -\funcarg{krb5_boolean}{twice} -\funcarg{krb5_data }{salt} -\funcinout -\funcarg{krb5_keyblock *}{key} -\end{funcdecl} - -Get the KDC database master key from somewhere, filling it into -\funcparam{*key}. -\funcparam{key{\ptsto}keytype} should be set to the desired key type. - -If \funcparam{fromkeyboard} is TRUE, then the master key is read as a password -from the user's terminal. In this case: -\funcparam{eblock} should point to a block with an appropriate -\funcname{string_to_key} function; if \funcparam{twice} is TRUE, the -password is read twice for verification; and if \funcparam{salt} is -non-NULL, it is used as the salt when converting the typed -password to the master key. - - -If \funcparam{fromkeyboard} is false, then the key is read from -a file whose name is derived from the principal name \funcparam{mname}. -Therefore, \funcparam{eblock}, \funcparam{twice} and \funcparam{salt} -are ignored. - - -\funcparam{mname} is the name of the key sought; this is often used by -\funcname{string_to_key} to aid in conversion of the password to a key. - -\begin{funcdecl}{krb5_kdb_encrypt_key}{krb5_error_code}{\funcin} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{const krb5_keyblock *}{in} -\funcinout -\funcarg{krb5_encrypted_keyblock *}{out} -\end{funcdecl} - -Encrypt a key for storage in the database. \funcparam{eblock} is used -to encrypt the key in \funcparam{in} into \funcparam{out}; the storage -pointed to by \funcparam{*out} is allocated before use and should be -freed when the caller is finished with it. - -\begin{funcdecl}{krb5_kdb_decrypt_key}{krb5_error_code}{\funcin} -\funcarg{krb5_encrypt_block *}{eblock} -\funcarg{const krb5_encrypted_keyblock *}{in} -\funcinout -\funcarg{krb5_keyblock *}{out} -\end{funcdecl} - -Decrypt a key from storage in the database. \funcparam{eblock} is used -to decrypt the key in \funcparam{in} into \funcparam{out}; the storage -pointed to by \funcparam{*out} is allocated before use and should be -freed when the caller is finished with it. - -\begin{funcdecl}{krb5_db_setup_mkey_name}{krb5_error_code}{\funcin} -\funcarg{const}{char *keyname} -\funcarg{const}{char *realm} -\funcout -\funcarg{char **}{fullname} -\funcarg{krb5_principal *}{principal} -\end{funcdecl} - -Given a key name \funcparam{keyname} and a realm name \funcparam{realm}, -construct a principal which can be used to fetch the master key from the -database. This principal is filled into \funcparam{*principal}; -\funcparam{*principal} should be freed by \funcname{krb5_free_principal} -when the caller is finished. - -If \funcparam{keyname} is NULL, the default key name will be used. - -If \funcparam{fullname} is not NULL, it is set to point to a string -representation of the complete principal name; its storage may be freed -by calling \funcname{free} on \funcparam{*fullname}. - diff --git a/doc/implement/keytab-i.tex b/doc/implement/keytab-i.tex deleted file mode 100644 index 697728721..000000000 --- a/doc/implement/keytab-i.tex +++ /dev/null @@ -1,204 +0,0 @@ -The key table functions deal with storing and retrieving service keys -for use by unattended services which participate in authentication exchanges. - -Keytab routines should all be atomic. Before a routine returns it -must make sure that all non-sharable resources it acquires are -released and in a consistent state. For example, an implementation is not -allowed to leave a file open for writing or to have a lock on a file. - -Note that all keytab implementations must support multiple concurrent -sequential scans. Another detail to note is that -the order of values returned from \funcname{get_next} is -unspecified and may be sorted to the implementor's convenience. - -\subsubsection{The krb5_kt_ops structure} -In order to implement a new key table type, the programmer should -declare a {\bf krb5_kt_ops} structure, and fill in the elements of the -structure appropriately, by implementing each of the key table -functions for the new key table type. - -In order to reduce the size of binary programs when static linking is -used, it is common to provide two \datatype{krb5_kt_ops} structures for -each key table type, one for reading only in which the pointers to the -add and delete functions are zero, and one for reading and writing. - -\begin{verbatim} -typedef struct _krb5_kt_ops { - char *prefix; - /* routines always present */ - krb5_error_code (*resolve)((char *, - krb5_keytab *)); - krb5_error_code (*get_name)((krb5_keytab, - char *, - int)); - krb5_error_code (*close)((krb5_keytab)); - krb5_error_code (*get)((krb5_keytab, - krb5_principal, - krb5_kvno, - krb5_keytab_entry *)); - krb5_error_code (*start_seq_get)((krb5_keytab, - krb5_kt_cursor *)); - krb5_error_code (*get_next)((krb5_keytab, - krb5_keytab_entry *, - krb5_kt_cursor *)); - krb5_error_code (*end_get)((krb5_keytab, - krb5_kt_cursor *)); - /* routines to be included on extended version (write routines) */ - krb5_error_code (*add)((krb5_keytab, - krb5_keytab_entry *)); - krb5_error_code (*remove)((krb5_keytab, - krb5_keytab_entry *)); -} krb5_kt_ops; -\end{verbatim} - -\subsubsection{Per-type functions that are always present} -The following entry points must be implemented for each type of -key table. However, \funcname{resolve}, \funcname{remove} and -\funcname{add} are only called by the key table glue code. -They are not called directly by the application. - - however, application programs are not expected to call -\funcname{resolve}, \funcname{remove}, -or \funcname{add} directly. - -\begin{funcdecl}{resolve}{krb5_error_code}{\funcin} -\funcarg{char *}{residual} -\funcout -\funcarg{krb5_keytab *}{id} -\end{funcdecl} - -Fills in \funcparam{*id} with a handle identifying the keytab with name -``residual''. The interpretation of ``residual'' is dependent on the -type of keytab. - -\begin{funcdecl}{get_name}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{char *}{name} -\funcin -\funcarg{int}{namesize} -\end{funcdecl} - -\funcarg{name} is filled in with the first \funcparam{namesize} bytes of -the name of the keytab identified by \funcname{id}. -If the name is shorter than \funcparam{namesize}, then \funcarg{name} -will be null-terminated. - -\begin{funcdecl}{close}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\end{funcdecl} - -Closes the keytab identified by \funcparam{id} and invalidates -\funcparam{id}, and releases any other resources acquired during use of -the key table. - -Requires that \funcparam{id} identifies a valid credentials cache. - -\begin{funcdecl}{get}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcarg{krb5_principal}{principal} -\funcarg{krb5_kvno}{vno} -\funcout -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Searches the keytab identified by \funcparam{id} for an entry whose -principal matches \funcparam{principal} and -whose key version number matches \funcparam{vno}. If \funcparam{vno} is -zero, the first entry whose principal matches is returned. - -%Errors: -This routine should return an error code if no suitable entry is -found. If an entry is found, the entry is returned in -\funcparam{*entry}; its contents should be deallocated by calling -\funcname{close} when no longer needed. - -\begin{funcdecl}{close}{krb5_error_code}{\funcinout} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Releases all storage allocated for \funcparam{entry}, which must point -to a structure previously filled in by \funcname{get} or -\funcname{get_next}. - -\begin{funcdecl}{start_seq_get}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{krb5_kt_cursor *}{cursor} -\end{funcdecl} - -Prepares to read sequentially every key in the keytab identified by -\funcparam{id}. -\funcparam{cursor} is filled in with a cursor to be used in calls to -\funcname{get_next}. - -\begin{funcdecl}{get_next}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcout -\funcarg{krb5_keytab_entry *}{entry} -\funcinout -\funcarg{krb5_kt_cursor}{cursor} -\end{funcdecl} - -Fetches the ``next'' entry in the keytab, returning it in -\funcparam{*entry}, and updates \funcparam{*cursor} for the next -request. If the keytab changes during the sequential get, an error -must be -%Errors: -guaranteed. \funcparam{*entry} should be freed after use by -calling -\funcname{close}. - -Requires that \funcparam{id} identifies a valid credentials cache. and -\funcparam{*cursor} be a cursor returned by -\funcname{start_seq_get} or a subsequent call to -\funcname{get_next}. - -%Errors: error code if no more cache entries or if the keytab changes. - -\begin{funcdecl}{end_get}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcarg{krb5_kt_cursor *}{cursor} -\end{funcdecl} - -Finishes sequential processing mode and invalidates \funcparam{cursor}, -which must never be re-used after this call. - -Requires that \funcparam{id} identifies a valid credentials cache. and -\funcparam{*cursor} be a cursor returned by -\funcname{start_seq_get} or a subsequent call to -\funcname{get_next}. - -%Errors: May return error code if \funcparam{cursor} is invalid. - -\subsubsection{Per-type functions to be included for write routines} - -\begin{funcdecl}{add}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Stores \funcparam{entry} in the keytab \funcparam{id}. -Fails if the entry already exists. - -This operation must, within the constraints of the operating system, not -return until it can verify that the write has completed succesfully. -For example, in a UNIX file-based implementation, this routine (or the part -of the underlying implementation that it calls) would be responsible for -doing an \funcname{fsync} on the file before returning. - -%Errors: -This routine should return an error code if \funcparam{entry} is -already present in the keytab or if the key could not be stored (quota -problem, etc). - -\begin{funcdecl}{remove}{krb5_error_code}{\funcin} -\funcarg{krb5_keytab}{id} -\funcarg{krb5_keytab_entry *}{entry} -\end{funcdecl} - -Searches the keytab \funcparam{id} for an entry that exactly matches -\funcparam{entry}. If one is found, it is removed from the keytab. - -%Errors: Returns an error code if not found. - diff --git a/doc/implement/libos-i.tex b/doc/implement/libos-i.tex deleted file mode 100644 index cdd4861ff..000000000 --- a/doc/implement/libos-i.tex +++ /dev/null @@ -1,34 +0,0 @@ -The operating-system specific functions provide an interface between the -other parts of the \libname{libkrb5.a} libraries and the operating system. - -Beware! Any of the functions below are allowed to be implemented as -macros. Prototypes for functions can be found in {\tt -}; other definitions (including macros, if used) are -in {\tt }. - -The following global symbols are provided in \libname{libos.a}. If you -wish to substitute for any of them, you must substitute for all of them -(they are all declared and initialized in the same object file): -\begin{description} -% These come from src/lib/osconfig.c -\item[extern char *\globalname{krb5_config_file}:] name of configuration file -\item[extern char *\globalname{krb5_trans_file}:] name of hostname/realm -name translation file -\item[extern char *\globalname{krb5_defkeyname}:] default name of key -table file -\item[extern char *\globalname{krb5_lname_file}:] name of aname/lname -translation database -\item[extern int \globalname{krb5_max_dgram_size}:] maximum allowable -datagram size -\item[extern int \globalname{krb5_max_skdc_timeout}:] maximum -per-message KDC reply timeout -\item[extern int \globalname{krb5_skdc_timeout_shift}:] shift factor -(bits) to exponentially back-off the KDC timeouts -\item[extern int \globalname{krb5_skdc_timeout_1}:] initial KDC timeout -\item[extern char *\globalname{krb5_kdc_udp_portname}:] name of KDC UDP port -\item[extern char *\globalname{krb5_default_pwd_prompt1}:] first prompt -for password reading. -\item[extern char *\globalname{krb5_default_pwd_prompt2}:] second prompt - -\end{description} - diff --git a/doc/implement/rcache-i.tex b/doc/implement/rcache-i.tex deleted file mode 100644 index e00a639da..000000000 --- a/doc/implement/rcache-i.tex +++ /dev/null @@ -1,142 +0,0 @@ -The replay cache functions deal with verifying that AP_REQ's do not -contain duplicate authenticators; the storage must be non-volatile for -the site-determined validity period of authenticators. - -Each replay cache has a string {\bf name} associated with it. The use of -this name is dependent on the underlying caching strategy (for -file-based things, it would be a cache file name). The -caching strategy should use non-volatile storage so that replay -integrity can be maintained across system failures. - -\subsubsection{The krb5_rc_ops structure} -In order to implement a new replay cache type, the programmer should -declare a {\bf krb5_rc_ops} structure, and fill in the elements of the -structure appropriately, by implementing each of the replay cache -functions for the new replay cache type. - -The prefix element specifies the prefix {bf name} of the the new replay -cache type. For example, if the prefix {\bf name} is ``dfl'', then if the -program calls \funcname{krb5_rc_resolve} with a credential cache name -such as ``dfl:host'', then \funcname{krb5_rc_resolve} -will call the resolve function (as defined by the {\bf krb5_rc_ops} -structure where the prefix element is ``dfl'') and pass it the -argument ``host''. - -Before a new replay cache type can be recognized by -\funcname{krb5_rc_resolve}, it must be registered with the Kerberos -library by calling \funcname{krb5_rc_register}. - -\begin{verbatim} -typedef struct _krb5_rc_ops { - char *type; - krb5_error_code (*init)((krb5_rcache,krb5_deltat)); - krb5_error_code (*recover)((krb5_rcache)); - krb5_error_code (*destroy)((krb5_rcache)); - krb5_error_code (*close)((krb5_rcache)); - krb5_error_code (*store)((krb5_rcache,krb5_donot_replay *)); - krb5_error_code (*expunge)((krb5_rcache)); - krb5_error_code (*get_span)((krb5_rcache,krb5_deltat *)); - char *(*get_name)((krb5_rcache)); - krb5_error_code (*resolve)((krb5_rcache, char *)); -} krb5_rc_ops; -\end{verbatim} - - -\subsubsection{Per-type functions} -The following entry points must be implemented for each type of -replay cache. - -\begin{funcdecl}{init}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\funcarg{krb5_deltat}{auth_lifespan} -\end{funcdecl} - -Creates/refreshes the replay cache identified by \funcparam{id} and sets its -authenticator lifespan to \funcparam{auth_lifespan}. If the -replay cache already exists, its contents are destroyed. - -%Errors: permission errors, system errors - -\begin{funcdecl}{recover}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\end{funcdecl} -Attempts to recover the replay cache \funcparam{id}, (presumably after a -system crash or server restart). - -%Errors: error indicating that no cache was found to recover - -\begin{funcdecl}{destroy}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Destroys the replay cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -%Errors: permission errors. - -\begin{funcdecl}{close}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Closes the replay cache \funcparam{id}, invalidates \funcparam{id}, -and releases any other resources acquired during use of the replay cache. -Requires that \funcparam{id} identifies a valid replay cache. - -%Errors: permission errors - -\begin{funcdecl}{store}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\funcarg{krb5_donot_replay *}{rep} -\end{funcdecl} -Stores \funcparam{rep} in the replay cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -Returns KRB5KRB_AP_ERR_REPEAT if \funcparam{rep} is already in the -cache. May also return permission errors, storage failure errors. - -\begin{funcdecl}{expunge}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\end{funcdecl} -Removes all expired replay information (i.e. those entries which are -older than then authenticator lifespan of the cache) from the cache -\funcparam{id}. Requires that \funcparam{id} identifies a valid replay -cache. - -%Errors: permission errors. - -\begin{funcdecl}{get_span}{krb5_error_code}{\funcin} -\funcarg{krb5_rcache}{id} -\funcout -\funcarg{krb5_deltat *}{auth_lifespan} -\end{funcdecl} -Fills in \funcparam{auth_lifespan} with the lifespan of -the cache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - -\begin{funcdecl}{resolve}{krb5_error_code}{\funcinout} -\funcarg{krb5_rcache}{id} -\funcin -\funcarg{char *}{name} -\end{funcdecl} - -Initializes private data attached to \funcparam{id}. This function MUST -be called before the other per-replay cache functions. - -Requires that \funcparam{id} points to allocated space, with an -initialized \funcparam{id{\ptsto}ops} field. - -Since \funcname{resolve} allocates memory, -\funcname{close} must be called to free the allocated memory, -even if neither \funcname{init} or -\funcname{recover} were successfully called by the application. - -%Returns: allocation errors. - - -\begin{funcdecl}{krb5_rc_get_name}{char *}{\funcin} -\funcarg{krb5_rcache}{id} -\end{funcdecl} - -Returns the name (excluding the type) of the rcache \funcparam{id}. -Requires that \funcparam{id} identifies a valid replay cache. - diff --git a/doc/implementor.texinfo b/doc/implementor.texinfo deleted file mode 100644 index 1d7707fda..000000000 --- a/doc/implementor.texinfo +++ /dev/null @@ -1,574 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c -@c Note: the above texinfo file must include the "doubleleftarrow" -@c definitions added by jcb. -@c %**start of header -@c guide -@setfilename krb5-implement.info -@settitle Kerberos V5 Installation Guide -@setchapternewpage odd @c chapter begins on next odd page -@c @setchapternewpage on @c chapter begins on next page -@c @smallbook @c Format for 7" X 9.25" paper -@c %**end of header - -@paragraphindent 0 -@iftex -@parskip 6pt plus 6pt -@end iftex - -@include definitions.texinfo -@set EDITION b7-1 - -@finalout @c don't print black warning boxes - -@titlepage -@title @value{PRODUCT} Implementor's Guide -@subtitle Release: @value{RELEASE} -@subtitle Document Edition: @value{EDITION} -@subtitle Last updated: @value{UPDATED} -@author @value{COMPANY} - -@page -@vskip 0pt plus 1filll - -@iftex -@include copyright.texinfo -@end iftex -@end titlepage - -@node Top, Introduction, (dir), (dir) -@comment node-name, next, previous, up - -@ifinfo -This file contains internal implementor's information for the -@value{RELEASE} release of @value{PRODUCT}. - -@include copyright.texinfo - -@end ifinfo - -@c The master menu is updated using emacs19's M-x texinfo-all-menus-update -@c function. Don't forget to run M-x texinfo-every-node-update after -@c you add a new section or subsection, or after you've rearranged the -@c order of sections or subsections. Also, don't forget to add an @node -@c comand before each @section or @subsection! All you need to enter -@c is: -@c -@c @node New Section Name - -@c @section New Section Name -@c -@c M-x texinfo-every-node-update will take care of calculating the -@c node's forward and back pointers. -@c -@c --------------------------------------------------------------------- - -@menu -* Introduction:: -* Socket API:: -* IPv6 Support:: -* Local Addresses:: -* Host Address Lookup:: -* Thread Safety:: -* Shared Libraries:: -@end menu - -@node Introduction, Socket API, Top, Top -@chapter Introduction - -This file contains internal implementor's information for -@value{PRODUCT}. It is currently contains information that was removed -from install.texi; eventually it will have more detailed information on -the internals of the @value{PRODUCT}. - -@node Socket API, IPv6 Support, Introduction, Top -@chapter Socket API - -Someone should describe the API subset we're allowed to use with -sockets, how and when to use @code{SOCKET_ERRNO}, @i{etc}. - -Note that all new code doing hostname and address translation should -use @code{getaddrinfo} and friends. (@xref{Host Address Lookup}.) - -@node IPv6 Support, Local Addresses, Socket API, Top -@chapter IPv6 Support - -Most of the IPv6 support is keyed on the macro @code{KRB5_USE_INET6}. -If this macro is not defined, there should be no references to -@code{AF_INET6}, @code{struct sockaddr_in6}, @i{etc}. - -The @code{configure} scripts will check for the existence of various -functions, macros and structure types to decide whether to enable the -IPv6 support. You can also use the @samp{--enable-ipv6} or -@samp{--disable-ipv6} options to override this decision. - -Regardless of the setting of @code{KRB5_USE_INET6}, some aspects of -the new APIs devised for IPv6 are used throughout the code, because it -would be too difficult maintain code for the IPv6 APIs and for the old -APIs at the same time. But for backwards compatibility, we try to -fake them if the system libraries don't provide them, at least for -now. This means we sometimes use slightly modified versions of the -APIs, but we try to keep the modifications as non-intrusive as -possible. Macros are used to rename struct tags and function names, -so don't @code{#undef} any of these names. - -@table @code - -@item getaddrinfo -@itemx getnameinfo -@itemx freeaddrinfo -@itemx gai_strerror -@itemx struct addrinfo -Always include the header file @code{fake-addrinfo.h} before using -these. If the native system doesn't provide them, the header file -will, using static functions that will call @code{gethostbyname} and -the like in the native libraries. (This also happens to be the way -the Winsock 2 headers work, depending on some of the predefined macros -indicating the target OS version.) - -We also provide ``wrapper'' versions on some systems where a native -implementation exists but the data it returns is broken in some way. - -So these may not always be thread-safe, and they may not always -provide IPv6 support, but the API will be consistent. - -@item struct sockaddr_storage -@itemx socklen_t -These are provided by @code{socket-utils.h}, if the native headers -don't provide them. @code{sockaddr_storage} contains a -@code{sockaddr_in}, so by definition it's big enough to hold one; it -also has some extra padding which will probably make it big enough to -hold a @code{sockaddr_in6} if the resulting binary should get run on a -kernel with IPv6 support. - -Question: Should these simply be moved into @code{port-sockets.h}? - -@end table - -IRIX 6.5.7 has no IPv6 support. Of the systems most actively in the -MIT's Athena environment (used by MIT's Kerberos UNIX developers), -this is the only one without built-in IPv6 support. In another year -or so we probably won't be using those systems any more, and we may -consider dropping support for systems without IPv6 support. - -Somewhere between IRIX 6.5.14 and 6.5.16, partial IPv6 support was -introduced to the extent that the configuration system detects the -IPv6 support and attempts to use it. Code compiles, but then upon -linking, one discovers that ``in6addr_any'' is not defined in any -system library. A work around the header file @code{fake-addrinfo.h} -is provided by providing a static copy. This run time IPv6 code has -still not been tested. - -Some utility functions or macros are also provided to give a -convenient shorthand for some operations, and to retain compile-time -type checking when possible (generally using inline functions but only -when compiling with GCC). - -@table @code - -@item socklen(struct sockaddr *) -Returns the length of the @code{sockaddr} structure, by looking at the -@code{sa_len} field if it exists, or by returning the known sizes of -@code{AF_INET} and @code{AF_INET6} address structures. - -@item sa2sin(struct sockaddr *) -@itemx sa2sin6(struct sockaddr *) -@itemx ss2sa(struct sockaddr_storage *) -@itemx ss2sin(struct sockaddr_storage *) -@itemx ss2sin6(struct sockaddr_storage *) -Pointer type conversions. Use these instead of plain casts, to get -type checking under GCC. - -@end table - -@node Local Addresses, Host Address Lookup, IPv6 Support, Top -@chapter Local Addresses - -(Last update: 2002-03-13.) - -Different systems have different ways of finding the local network -addresses. - -On Windows, @code{gethostbyname} is called on the local host name to get a -set of addresses. If that fails, a UDP socket is ``connected'' to a -particular IPv4 address, and the local socket name is retrieved, its -address being treated as the one local network address. Future -versions of the Windows code should be able to actually examine local -interfaces. - -On Mac OS 9 and earlier, a Mac-specific interface is used to look up -local addresses. Presumably, on Mac OS X we'll use that or the -general UNIX code. - -On (most?) UNIX systems, there is an @code{ioctl} called -@code{SIOCGIFCONF} which gets interface configuration information. -The behavior of this @code{ioctl} varies across UNIX systems though. -It takes as input a buffer to fill with data structures, but if the -buffer isn't big enough, the behavior isn't well defined. Sometimes -you get an error, sometimes you get incomplete data. Sometimes you -get a clear indication that more space was needed, sometimes not. A -couple of systems have additional @code{ioctl}s that can be used to -determine or at least estimate the correct size for the buffer. -Solaris has introduced @code{SIOCGLIFCONF} for querying IPv6 -addresses, and restricts @code{SIOCGIFCONF} to IPv4 only. (** We -should actually check if that's true.) - -We (Ken Raeburn in particular) ran some tests on various systems to -see what would happen with buffers of various sizes from much smaller -to much larger than needed for the actual data. The buffers were -filled with specific byte values, and then checked to see how much of -the buffer was actually written to. The "largest gap" values listed -below are the largest number of bytes we've seen left unused at the -end of the supplied buffer when there were more entries to return. -These values may of coures be dependent on the configurations of the -particular systems we wre testing with. (See -@code{lib/krb5/os/t_gifconf.c} for the test program.) - -NetBSD 1.5-alpha: The returned @code{ifc_len} is the desired amount of -space, always. The returned list may be truncated if there isn't -enough room; no overrun. Largest gap: 43. However, NetBSD has -@code{getifaddrs}, which hides all the ugliness within the C library. - -BSD/OS 4.0.1 (courtesy djm): The returned @code{ifc_len} is equal to -or less than the supplied @code{ifc_len}. Sometimes the entire buffer -is used; sometimes N-1 bytes; occasionally, the buffer must have quite -a bit of extra room before the next structure will be added. Largest -gap: 39. - -Solaris 7,8: Return @code{EINVAL} if the buffer space is too small for -all the data to be returned, including when @code{ifc_len} is 0. -Solaris is the only system I've found so far that actually returns an -error. No gap. However, @code{SIOCGIFNUM} may be used to query the -number of interfaces. - -Linux 2.2.12 (Red Hat 6.1 distribution, x86), 2.4.9 (RH 7.1, x86): The -buffer is filled in with as many entries as will fit, and the size -used is returned in @code{ifc_len}. The list is truncated if needed, -with no indication. Largest gap: 31. @emph{However}, this interface -does not return any IPv6 addresses. They must be read from a file -under @code{/proc}. (This appears to be what the @samp{ifconfig} -program does.) - -IRIX 6.5.7: The buffer is filled in with as many entries as will fit -in N-1 bytes, and the size used is returned in @code{ifc_len}. -Providing exactly the desired number of bytes is inadequate; the -buffer must be @emph{bigger} than needed. (E.g., 32->0, 33->32.) The -returned @code{ifc_len} is always less than the supplied one. Largest -gap: 32. - -AIX 4.3.3: Sometimes the returned @code{ifc_len} is bigger than the -supplied one, but it may not be big enough for @emph{all} the -interfaces. Sometimes it's smaller than the supplied value, even if -the returned list is truncated. The list is filled in with as many -entries as will fit; no overrun. Largest gap: 143. - -Older AIX: We're told by W. David Shambroom (DShambroom@@gte.com) in -PR krb5-kdc/919 that older versions of AIX have a bug in the -@code{SIOCGIFCONF} @code{ioctl} which can cause them to overrun the -supplied buffer. However, we don't yet have details as to which -version, whether the overrun amount was bounded (e.g., one -@code{ifreq}'s worth) or not, whether it's a real buffer overrun or -someone assuming it was because @code{ifc_len} was increased, etc. -Once we've got details, we can try to work around the problem. - -Digital UNIX 4.0F: If input @code{ifc_len} is zero, return an -@code{ifc_len} that's big enough to include all entries. (Actually, -on our system, it appears to be larger than that by 32.) If input -@code{ifc_len} is nonzero, fill in as many entries as will fit, and -set @code{ifc_len} accordingly. (Tested only with buffer previously -filled with zeros.) - -Tru64 UNIX 5.1A: Like Digital UNIX 4.0F, except the ``extra'' space -indicated when the input @code{ifc_len} is zero is larger. (We got -400 out when 320 appeared to be needed.) - -So... if the returned @code{ifc_len} is bigger than the supplied one, -we'll need at least that much space -- but possibly more -- to hold -all the results. If the returned value is smaller or the same, we may -still need more space. - -The heuristic we're using on most systems now is to keep growing the -buffer until the unused space is larger than an @code{ifreq} structure -by some safe margin. - -@node Host Address Lookup, Thread Safety, Local Addresses, Top -@chapter Host Address Lookup - -The traditional @code{gethostbyname} function is not thread-safe, and -does not support looking up IPv6 addresses, both of which are becoming -more important. New standards have been in development that should -address both of these problems. The most promising is -@code{getaddrinfo} and friends, which is part of the Austin Group and -UNIX 98(?) specifications. Code in the MIT tree is gradually being -converted to use this interface. - -@quotation -(Question: What about @code{inet_ntop} and @code{inet_pton}? We're -not using them at the moment, but some bits of code would be -simplified if we were to do so, when plain addresses and not socket -addresses are already presented to us.) -@end quotation - -The @code{getaddrinfo} function takes a host name and service name and -returns a linked list of structures indicating the address family, -length, and actual data in ``sockaddr'' form. (That is, it includes a -pointer to a @code{sockaddr_in} or @code{sockaddr_in6} structure.) -Depending on options set via the @code{hints} input argument, the results -can be limited to a single address family (@i{e.g.}, for IPv4 -applications), and the canonical name of the indicated host can be -returned. Either the host or service can be a null pointer, in which -case only the other is looked up; they can also be expressed in -numeric form. This interface is extensible to additional address -families in the future. The returned linked list can be freed with -the @code{freeaddrinfo} function. - -The @code{getnameinfo} function does the reverse -- given an address -in ``sockaddr'' form, it converts the address and port values into -printable forms. - -Errors returned by either of these functions -- as return values, not -global variables -- can be translated into printable form with the -@code{gai_strerror} function. - -Some vendors are starting to implement @code{getaddrinfo} and friends, -however, some of the implementations are deficient in one way or -another. - -@table @asis - -@item AIX -As of AIX 4.3.3, @code{getaddrinfo} returns sockaddr structures -without the family and length fields filled in. - -@item GNU libc -The GNU C library, used on GNU/Linux systems, has had a few problems -in this area. One version would drop some IPv4 addresses for some -hosts that had multiple IPv4 and IPv6 addresses. - -In GNU libc 2.2.4, when the DNS is used, the name referred to by PTR -records for each of the addresses is looked up and stored in the -@code{ai_canonname} field, or the printed numeric form of the address -is, both of which are wrong. - -@item IRIX -No known bugs here, but as of IRIX 6.5.7, the version we're using at -MIT, these functions had not been implemented. - -@item NetBSD -As of NetBSD 1.5, this function is not thread-safe. In 1.5X -(intermediate code snapshot between 1.5 and 1.6 releases), the -@code{ai_canonname} field can be empty, even if the -@code{AI_CANONNAME} flag was passed. In particular, this can happen -if a numeric host address string is provided. Also, numeric service -names appear not to work unless the stream type is given; specifying -the TCP protocol is not enough. - -@item Tru64 UNIX -In Tru64 UNIX 5.0, @code{getaddrinfo} is available, but requires that -@code{} be included before its use; that header file defines -@code{getaddrinfo} as a macro expanding to either @code{ogetaddrinfo} -or @code{ngetaddrinfo}, and apparently the symbol @code{getaddrinfo} -is not present in the system library, causing the @code{configure} -test for it to fail. Technically speaking, I [Ken] think Compaq has -it wrong here, I think the symbol is supposed to be available even if -the application uses @code{#undef}, but I have not confirmed it in the -spec. - -@item Windows -According to Windows documentation, the returned @code{ai_canonname} -field can be null even if the @code{AI_CANONNAME} flag is given. - -@end table - -For most systems where @code{getaddrinfo} returns incorrect data, -we've provided wrapper versions that call the system version and then -try to fix up the returned data. - -For systems that don't provide these functions at all, we've provided -replacement versions that neither are thread-safe nor support IPv6, -but will allow us to convert the rest of our code to assume the -availability of @code{getaddrinfo}, rather than having to use two -branches everywhere, one for @code{getaddrinfo} and one for -@code{gethostbyname}. These replacement functions do use -@code{gethostbyname} and the like; for some systems it would be -possible to use @code{gethostbyname2} or @code{gethostbyname_r} or -other such functions, to provide thread safety or IPv6 support, but -this has not been a priority for us, since most modern systems have -these functions anyways. And if they don't, they probably don't have -real IPv6 support either. - -Including @code{fake-addrinfo.h} will enable the wrapper or -replacement versions when needed. Depending on the system -configuration, this header file may define several static functions -(and declare them @code{inline} under GNU C), and leave it to the -compiler to discard any unused code. This may produce warnings on -some systems, and if the compiler isn't being too clever, may cause -several kilobytes of excess storage to be consumed on these backwards -systems. - -Do not assume that @code{ai_canonname} will be set when the -@code{AI_CANONNAME} flag is set. Check for a null pointer before -using it. - -@node Thread Safety, Shared Libraries, Host Address Lookup, Top -@chapter Thread Safety - -Hahahahahaha... We're not even close. - -We have started talking about it, though. Some stuff is ``kind of'' -thread safe because it operates on a @code{krb5_context} and we simply -assert that a context can be used only in one thread at a time. But -there are places where we use unsafe C library functions, and a few -places where we have modifiable static data in the libraries. - -Even if the Kerberos or C library functions aren't using static data -themselves, there are other instances of per-process data that have to -be dealt with before our library can become thread-safe. For example, -file locking with UNIX @code{flock()} is on a per-process basis; -for a single thread to be able to lock a file against accesses from -other threads, we'll have to implement per-thread locks for files on -top of the operating system per-process locks, and that means a global -(per-process) table listing all the locks. So it seems unlikely that -we will find an approach that eliminates all static modifiable data -from the library. - -A rough proposal for hooks for implementing locking was put forth, and -an IBM Linux group is experimenting with a trial implementation of it, -with a few changes. A few issues with the proposal have been -discussed on the @samp{krbdev} mailing list, and you can find the -discussion in the list archives. - -@node Shared Libraries, , Thread Safety, Top -@chapter Shared Libraries - -(These sections are old -- they should get updated.) - -@menu -* Shared Library Theory:: -* Operating System Notes for Shared Libraries:: -@end menu - -@node Shared Library Theory, Operating System Notes for Shared Libraries, Shared Libraries, Shared Libraries -@section Theory of How Shared Libraries are Used - -An explanation of how shared libraries are implemented on a given -platform is too broad a topic for this manual. Instead this will touch -on some of the issues that the Kerberos V5 tree uses to support version -numbering and alternate install locations. - -Normally when one builds a shared library and then links with it, the -name of the shared library is stored in the object -(i.e. libfoo.so). Most operating systems allows one to change name that -is referenced and we have done so, placing the version number into the -shared library (i.e. libfoo.so.0.1). At link time, one would reference -libfoo.so, but when one executes the program, the shared library loader -would then look for the shared library with the alternate name. Hence -multiple versions of shared libraries may be supported relatively -easily. @footnote{Under AIX for the RISC/6000, multiple versions of -shared libraries are supported by combining two or more versions of the -shared library into one file. The Kerberos build procedure produces -shared libraries with version numbers in the internal module names, so -that the shared libraries are compatible with this scheme. -Unfortunately, combining two shared libraries requires internal -knowledge of the AIX shared library system beyond the scope of this -document. Practicallyspeaking, only one version of AIX shared libraries -can be supported on a system, unless the multi-version library is -constructed by a programmer familiar with the AIX internals.} - -All operating systems (that we have seen) provide a means for programs -to specify the location of shared libraries. On different operating -systems, this is either specified when creating the shared library, and -link time, or both.@footnote{Both are necessary sometimes as the shared -libraries are dependent on other shared libraries} The build process -will hardwire a path to the installed destination. - -@node Operating System Notes for Shared Libraries, , Shared Library Theory, Shared Libraries -@section Operating System Notes for Shared Libraries - -From time to time users or developers suggest using GNU @code{Libtool} -or some other mechanism to generate shared libraries. Experience -with other packages suggests that Libtool tends to be difficult to -debug and when it works incorrectly, patches are required to generated -scripts to work around problems. So far, the Kerberos shared library -build mechanism, which sets a variety of makefile variables based on -operating system type and then uses those variables in the build -process has proven to be easier to debug and adequate to the task of -building shared libraries for Kerberos. - - -@menu -* NetBSD Shared Library Support:: -* AIX Shared Library Support:: -* Solaris Shared Library Support:: -* Alpha OSF/1 Shared Library Support:: -@end menu - -@node NetBSD Shared Library Support, AIX Shared Library Support, Operating System Notes for Shared Libraries, Operating System Notes for Shared Libraries -@subsection NetBSD Shared Library Support - -XXX I think this is horribly out of date and reflects pre-elf NetBSD. - -Shared library support has been tested under NetBSD 1.0A using -GCC 2.4.5. Due to the vagaries of the loader in the operating system, -the library load path needs to be specified in building libraries and in -linking with them. Unless the library is placed in a standard location -to search for libraries, this may make it difficult for developers to -work with the shared libraries. - -@node AIX Shared Library Support, Solaris Shared Library Support, NetBSD Shared Library Support, Operating System Notes for Shared Libraries -@subsection AIX Shared Library Support - - AIX specifies shared library versions by combining multiple -versions into a single file. Because of the complexity of this process, -no automatic procedure for building multi-versioned shared libraries is -provided. Therefore, supporting multiple versions of the Kerberos shared -libraries under AIX will require significant work on the part of a -programmer famiiliar with AIX internals. - - AIX allows a single library to be used both as a static library -and as a shared library. For this reason, the @samp{--enable-shared} -switch to configure builds only shared libraries. On other operating -systems, both shared and static libraries are built when this switch is -specified. As with all other operating systems, only non-shared static -libraries are built when @samp{--enable-shared} is not specified. - - The AIX 3.2.5 linker dumps core trying to build a shared -@samp{libkrb5.a} produced with the GNU C compiler. The native AIX -compiler works fine. In addition, the AIX 4.1 linker is able to build a -shared @samp{libkrb5.a} when GNU C is used. - - -@node Solaris Shared Library Support, Alpha OSF/1 Shared Library Support, AIX Shared Library Support, Operating System Notes for Shared Libraries -@subsection Solaris Shared Library Support - -Shared library support only works when using the Sunsoft C -compiler. We are currently using version 3.0.1. Modern versions of -Solaris do not have this problem. - - -The path to the shared library must be specified at link time as well as -when creating libraries. - - -@node Alpha OSF/1 Shared Library Support, , Solaris Shared Library Support, Operating System Notes for Shared Libraries -@subsection Alpha OSF/1 Shared Library Support - -Shared library support has been tested with V2.1 and higher of the -operating system. Shared libraries may be compiled both with GCC and the -native compiler. - -One of the nice features on this platform is that the paths to the -shared libraries is specified in the library itself without requiring -that one specify the same at link time. - -We are using the @samp{-rpath} option to @samp{ld} to place the library -load path into the executables. The one disadvantage of this is during -testing where we want to make sure that we are using the build tree -instead of a possibly installed library. The loader uses the contents of -@samp{-rpath} before LD_LIBRARY_PATH so we must specify a dummy _RLD_ROOT -and complete LD_LIBRARY_PATH in our tests. - -The one disadvantage with the method we are using.... - -@contents -@bye diff --git a/doc/install-old.texi b/doc/install-old.texi deleted file mode 100644 index 079590824..000000000 --- a/doc/install-old.texi +++ /dev/null @@ -1,2239 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename install.info -@settitle Kerberos V5 -@c For double-sided printing, uncomment: -@setchapternewpage odd -@c %**end of header - -@set EDITION BETA 6 -@set VERSION BETA 6 -@set UPDATED Mar 20, 1996 - -@ignore -@iftex -@finalout -@end iftex -@end ignore - -@ifinfo -This file documents how to build and install the Kerberos V5 -distribution. - -Copyright (C) 1995, 1996 Massachusetts Institute of Technology. - -All Rights Reserved. - -Export of this software from the United States of America may require a -specific license from the United States Government. It is the -responsibility of any person or organization contemplating export to -obtain any necessary licenses before exporting. - -WITHIN THAT CONSTRAINT, permission to use, copy, modify, and -distribute this software and its documentation for any purpose and -without fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright notice and -this permission notice appear in supporting documentation, and that -the name of M.I.T. not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. M.I.T. makes no representations about the suitability of -this software for any purpose. It is provided "as is" without express -or implied warranty. - -Athena(r), Hesiod(r), Moira(r), and Discuss(r) are registered trademarks of -the Massachusetts Institute of Technology (MIT). Project Athena, Athena -Dashboard, Athena MUSE, Kerberos, X Window System, and Zephyr are trademarks -of MIT. No commercial use of these trademarks may be made without prior -written permission of MIT. - -All other product names are trademarks of their respective companies. - -@end ifinfo - -@titlepage -@title Kerberos V5 -@subtitle Notes on Building and Installing Kerberos -@subtitle Edition @value{EDITION}, for Kerberos version @value{VERSION} -@subtitle @value{UPDATED} -@author by Theodore Ts'o - -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1995, 1996 Massachusetts Institute of Technology - -All Rights Reserved. - -Export of this software from the United States of America may require a -specific license from the United States Government. It is the -responsibility of any person or organization contemplating export to -obtain any necessary licenses before exporting. - -WITHIN THAT CONSTRAINT, permission to use, copy, modify, and -distribute this software and its documentation for any purpose and -without fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright notice and -this permission notice appear in supporting documentation, and that -the name of M.I.T. not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. M.I.T. makes no representations about the suitability of -this software for any purpose. It is provided "as is" without express -or implied warranty. - -Athena(r), Hesiod(r), Moira(r), and Discuss(r) are registered trademarks of -the Massachusetts Institute of Technology (MIT). Project Athena, Athena -Dashboard, Athena MUSE, Kerberos, X Window System, and Zephyr are trademarks -of MIT. No commercial use of these trademarks may be made without prior -written permission of MIT. - -All other product names are trademarks of their respective companies. - -@end titlepage - -@node Top, Introduction, (dir), (dir) -@comment node-name, next, previous, up - -@ifinfo -This file documents how to build and install the Kerberos V5 -distribution. - -This is edition @value{EDITION}, for Kerberos V5 version @value{VERSION}. - -@end ifinfo - -@c The master menu is updated using emacs19's M-x texinfo-all-menus-update -@c function. Don't forget to run M-x texinfo-every-node-update after -@c you add a new section or subsection, or after you've rearranged the -@c order of sections or subsections. Also, don't forget to add an @node -@c command before each @section or @subsection! All you need to enter -@c is: -@c -@c @node New Section Name - -@c @section New Section Name -@c -@c M-x texinfo-every-node-update will take care of calculating the -@c node's forward and back pointers. -@c - -@menu -* Introduction:: -* How Kerberos Works:: -* Building Kerberos:: -* Installation:: -* Troubleshooting:: - - --- The Detailed Node Listing --- - -How Kerberos Works: A Schematic Description - -* Network Services:: -* Kerberos Tickets:: -* The Kerberos Database:: -* Kerberos Realms:: -* The Ticket-Granting Ticket:: -* Network Services and the Master Database:: -* The User-Kerberos Interaction:: - -Network Services and the Master Database - -* The Keytab File:: - -Building Kerberos - -* Build Requirements:: How much disk space, etc. you need to - build Kerberos. -* Unpacking the Sources:: Preparing the source tree. -* Doing the Build:: Compiling Kerberos. -* Testing the Build:: Making sure Kerberos built correctly. -* Options to Configure:: -* osconf.h:: -* Shared Library Support:: -* OS Incompatibilities:: Special cases to watch for. -* Using Autoconf:: Modifying Kerberos V5's - configuration scripts. - -Doing the Build - -* Building Within a Single Tree:: -* Building with Separate Build Directories:: -* Building using lndir:: - -Testing the Build - -* The DejaGnu Tests:: - -Shared Library Support - -* Shared Library Theory:: -* NetBSD Shared Library Support:: -* AIX Shared Library Support:: -* Solaris 5.3 Shared Library Support:: -* Alpha OSF/1 Shared Library Support:: - -Operating System Incompatibilities - -* Ultrix 4.2/3:: -* Alpha OSF/1 V1.3:: -* Alpha OSF/1 V2.0++:: -* BSDI:: -* Solaris versions 2.0 through 2.3:: -* Solaris 2.X:: -* SGI Irix 5.X:: - -Installation - -* Background:: -* Installation on any Machine:: -* Installing the KDC:: -* Migrating from V4 to V5 Kerberos:: -* A Sample Application:: -* Installing Kerberos Applications:: -* Common Kerberos Service Names:: - -Installation on any Machine - -* Picking a Realm Name:: -* Configuration files:: -* Recommended Programs:: - -Configuration files - -* krb5.conf:: -* Converting V4 configuration files:: -* /etc/services:: - -Installing the KDC - -* kdc.conf:: -* Initializing the KDB:: -* Storing the Master Password:: -* Adding Users to the Database:: -* Starting the Kerberos Server:: -* Setting up Slave Kerberos Servers:: -* Inter-realm Kerberos Operation:: -* The Administration Server:: -* Testing the Kerberos Server:: - -Setting up Slave Kerberos Servers - -* Kerberos Slave Database Propagation:: -* Installing a Slave Server:: - -A Sample Application - -* Installing the Sample Application:: -* Testing the Sample Server:: - -Installing Kerberos Applications - -* Levels of Security:: -* Preparing a Workstation for Kerberos Application Servers:: -* BSD Utilities:: -* Telnet and FTP:: - -BSD Utilities - -* Checksums:: Checksum facility for dealing with active attacks. -* BSD Utility Configuration Example:: Sample @file{inetd.conf} entries for BSD utilities. -@end menu - -@node Introduction, How Kerberos Works, Top, Top -@chapter Introduction - -This document describes the procedures necessary to compile Kerberos V5 -from the source distribution, and then to install it at a particular -site. The reader is assumed to be familiar with C/UNIX development -tools. - -In any complex software, there will be bugs. Please send bug reports -or other problems you may uncover to the e-mail address -@b{krb5-bugs@@mit.edu}. Please mention which version of the Kerberos -V5 distribution you are using, and whether you have made any private -changes. Bug reports that include proposed fixes are especially -welcome. If you do include fixes, please send them using either -context diffs or unified diffs (using @samp{diff -c} or @samp{diff --u}, respectively). - -Please note that there are still a number of aspects of Kerberos V5 -which will likely change before the 1.0 release. -As these changes occur, we will update the documentation accordingly. - -@c As of this release, all the databases, including the aname to localname -@c ones now use version 1.85 of the Berkeley DB code. This may imply -@c database conversions for those running earlier releases of Kerberos -@c V5. We recommend that you dump your database with the old kdb5_edit and -@c restore with the new one. - - -@node How Kerberos Works, Building Kerberos, Introduction, Top -@chapter How Kerberos Works: A Schematic Description - -This section provides a simplified description of a general user's -interaction with the Kerberos system. This interaction happens -transparently--users don't need to know and probably don't care about -what's going on--but Kerberos administrators might find a schematic -description of the process useful. This description glosses over a lot -of details; for more information, see @i{Kerberos: An Authentication -Service for Open Network Systems}, a paper presented at Winter USENIX -1988, in Dallas, Texas. - -@menu -* Network Services:: -* Kerberos Tickets:: -* The Kerberos Database:: -* Kerberos Realms:: -* The Ticket-Granting Ticket:: -* Network Services and the Master Database:: -* The User-Kerberos Interaction:: -@end menu - -@node Network Services, Kerberos Tickets, How Kerberos Works, How Kerberos Works -@section Network Services and Their Client Programs - -In an environment that provides network services, you use @dfn{client} -programs to request service from @dfn{server} programs that are -somewhere on the network. Suppose you have logged in to a workstation -and you want to @samp{rlogin} to another machine. You use the local -@samp{rlogin} client program to contact the remote machine's -@samp{rlogind} daemon. - -@node Kerberos Tickets, The Kerberos Database, Network Services, How Kerberos Works -@section Kerberos Tickets - -Under Kerberos, the @samp{rlogind} daemon allows you to login to a -remote machine if you can provide @samp{rlogind} a Kerberos ticket -which proves your identity. In addition to the ticket, you must also -have possession of the corresponding ticket session key. The -combination of a ticket and the ticket's session key is known as a credential. - -Typically, a client program automatically obtains credentials -identifying the person using the client program. The credentials are -obtained from a Kerberos server that resides somewhere on the network. -A Kerberos server maintains a database of user, server, and password -information. - -@node The Kerberos Database, Kerberos Realms, Kerberos Tickets, How Kerberos Works -@section The Kerberos Database - -Kerberos will give you credentials only if you have an entry in the Kerberos -server's @dfn{Kerberos database}. Your database entry includes your -Kerberos @dfn{principal} (which is often just your username), and -your Kerberos password. Every Kerberos user must have an entry in this -database. - -@node Kerberos Realms, The Ticket-Granting Ticket, The Kerberos Database, How Kerberos Works -@section Kerberos Realms - -Each site (or administrative domain within a site) will have their own -Kerberos database, which contains information about the users and -services for that particular site or administrative domain. -A @dfn{Kerberos Realm} is used to distinguish the users and services in -one particular area of administrative control from another area of -administrative control. - -Each Kerberos realm will have at least one Kerberos server, where the -master Kerberos database for that site or administrative domain is -stored. A Kerberos realm may also have one or more @dfn{slave servers}, -which have read-only copies of the Kerberos database which are -periodically propagated from the master server. For more details on how -this is done, see @ref{Setting up Slave Kerberos Servers}. - -@node The Ticket-Granting Ticket, Network Services and the Master Database, Kerberos Realms, How Kerberos Works -@section The Ticket-Granting Ticket - -The @samp{kinit} command prompts for your password, and if you enter -it successfully, you will obtain a @dfn{ticket-granting ticket} and a -@dfn{ticket session key} which gives you the right to use the ticket. -This combination of the ticket and its associated key is also known as -your @dfn{credentials}. As illustrated below, client programs use -your ticket-granting ticket credentials in order to obtain -client-specific credentials as needed. - -Your credentials are stored in a @dfn{credentials cache}, which is often -simply just a file in @file{/tmp}. The credentials cache is also -referred to as the @dfn{ticket file}, especially in Kerberos V4 -documentation. It should be noted, however, that a credentials cache -does not have to be stored in a file. - -@node Network Services and the Master Database, The User-Kerberos Interaction, The Ticket-Granting Ticket, How Kerberos Works -@section Network Services and the Master Database - -The master database also contains entries for all network services that -require Kerberos authentication. Suppose that your site -has a machine, @samp{laughter.mit.edu}, that requires Kerberos -authentication from anyone who wants to @samp{rlogin} to it. The host's -Kerberos realm is @samp{ATHENA.MIT.EDU}. - -This service must be registered in the Kerberos database, using the -proper service name, which in this case is -@samp{host/laughter.mit.edu@@ATHENA.MIT.EDU}. The @kbd{/} character -separates the various @dfn{components} of the Kerberos principal; the -@kbd{@@} character separates the realm name from the rest of the -principal name. The first component, @samp{host}, denotes the name or -type of the service that is being offered: generic host-level access to -the machine. The second component, @samp{laughter.mit.edu}, names the -specific machine which is offering this service. There will generally -be many different machines, each offering one particular type of -service, and the second component serves to give each one of these -servers a different Kerberos name. - -@menu -* The Keytab File:: -@end menu - -@node The Keytab File, , Network Services and the Master Database, Network Services and the Master Database -@subsection The Keytab File - -For each service, there must also be a @dfn{service key} known only by -Kerberos and the service. On the Kerberos server, the service key is -stored in the Kerberos database. - -On the server host, these service keys are stored in the @dfn{Key -tables}, or @dfn{keytab files}. (Keytab files were previously -referred to as @dfn{srvtab files} in the V4 literature.) The service -keys that are used by services which run as root are often stored in -the file @file{/etc/v5srvtab}. - -@b{WARNING:} This service key is the equivalent of the service's -password, and must be kept secure. Data which is meant to be read only -by the service is encrypted using this key. - -@node The User-Kerberos Interaction, , Network Services and the Master Database, How Kerberos Works -@section The User--Kerberos Interaction - -Suppose that you (in the guise of a general user) walk up to a workstation -intending to login to it, and then @samp{rlogin} to the machine @samp{laughter}. -Here's what happens: - -@enumerate - -@item -You login to the workstation and use the @samp{kinit} command -to get a ticket-granting ticket. -This command prompts you for your Kerberos password. (On some systems -which have a modified @samp{/bin/login} program, this may be done as -part of the login process, not requiring the user to run a separate -program.) - -@enumerate A - -@item -The @samp{kinit} command sends your request to the Kerberos master -server machine. The server software looks for your principal name's -entry in the Kerberos database. - -@item -If this entry exists, the Kerberos server creates and returns a -ticket-granting ticket and the key which allows you to use it, encrypted -by your password. If @samp{kinit} can decrypt the Kerberos reply using -the password you provide, it stores this ticket in a credentials cache -on your local machine for later use. The name of the credentials cache -can be specified in the @samp{KRB5_CCNAME} environment variable. If -this variable is not set, the name of the file will be -@file{/tmp/krb5cc_}, where is your UNIX user-id, represented -in decimal format. -@end enumerate - -@item -Now you use the @samp{rlogin} client to access the machine -@samp{laughter}. - -@example -host% @b{rlogin laughter} -@end example - -@enumerate A - -@item -The @samp{rlogin} client checks your ticket file to see if you -have a ticket for the @samp{host} service for @samp{laughter}. -You don't, so @samp{rlogin} uses the credential cache's ticket-granting -ticket to make a request to the master server's ticket-granting service. - -@item -This ticket-granting service receives the -@samp{host/laughter.mit.edu} request and looks in the master database -for an @samp{host/laughter.mit.edu} entry. If the entry exists, the -ticket-granting service issues you a ticket for that service. That -ticket is also cached in your credentials cache. - -@item -The @samp{rlogin} client now sends that ticket to -the @samp{laughter} @samp{rlogind} service program. The service program -checks the ticket by using its own service key. If the ticket is valid, -it now knows your identity. If the ticket is valid and you are allowed -to login to @samp{laughter} (because the your name matches one in -/etc/passwd, or you are in the @file{.k5login} file), you will find -yourself logged into the machine. - -@end enumerate -@end enumerate - -@node Building Kerberos, Installation, How Kerberos Works, Top -@chapter Building Kerberos - -Starting with the Beta 4 distribution, we are using a new configuration -system, which was built using the Free Software Foundation's -@samp{autoconf} program. This system will hopefully make Kerberos V5 -much simpler to build and reduce the amount of effort required in -porting Kerberos V5 to a new platform. - -@menu -* Build Requirements:: How much disk space, etc. you need to - build Kerberos. -* Unpacking the Sources:: Preparing the source tree. -* Doing the Build:: Compiling Kerberos. -* Testing the Build:: Making sure Kerberos built correctly. -* Options to Configure:: -* osconf.h:: -* Shared Library Support:: -* OS Incompatibilities:: Special cases to watch for. -* Using Autoconf:: Modifying Kerberos V5's - configuration scripts. -@end menu - -@node Build Requirements, Unpacking the Sources, Building Kerberos, Building Kerberos -@section Build Requirements - -In order to build Kerberos V5, you will need approximately 60-70 -megabytes of disk space. The exact amount will vary depending on the -platform and whether the distribution is compiled with debugging symbol -tables or not. - -If you wish to keep a separate @dfn{build tree}, which contains the compiled -@file{*.o} file and executables, separate from your source tree, you -will need a @samp{make} program which supports @samp{VPATH}, or -you will need to use a tool such as @samp{lndir} to produce a symbolic -link tree for your build tree. - -@node Unpacking the Sources, Doing the Build, Build Requirements, Building Kerberos -@section Unpacking the Sources - -The first step in each of these build procedures is to unpack the source -distribution. The Kerberos V5 distribution comes in two compressed tar -files. The first file, which is generally named @file{krb5.src.tar.gz}, -contains the sources for all of Kerberos except for the crypto library, -which is found in the file @file{krb5.crypto.tar.gz}. - -Both files should be unpacked in the same directory, such as -@file{/u1/krb5}. (In the rest of this document, we will assume that you -have chosen to unpack the Kerberos V5 source distribution in this -directory.) - - -@node Doing the Build, Testing the Build, Unpacking the Sources, Building Kerberos -@section Doing the Build - -You have a number of different options in how to build Kerberos. If you -only need to build Kerberos for one platform, using a single directory -tree which contains both the source files and the object files is the -simplest. However, if you need to maintain Kerberos for a large number -of platforms, you will probably want to use separate build trees for -each platform. We recommend that you look at see @ref{OS -Incompatibilities} for notes that we have on particular operating -systems. - -@menu -* Building Within a Single Tree:: -* Building with Separate Build Directories:: -* Building using lndir:: -@end menu - -@node Building Within a Single Tree, Building with Separate Build Directories, Doing the Build, Doing the Build -@subsection Building Within a Single Tree - -If you don't want separate build trees for each architecture, then -use the following abbreviated procedure. - -@enumerate -@item - @code{cd /u1/krb5/src} -@item - @code{./configure} -@item - @code{make} -@end enumerate - -That's it! - -@node Building with Separate Build Directories, Building using lndir, Building Within a Single Tree, Doing the Build -@subsection Building with Separate Build Directories - -If you wish to keep separate build directories for each platform, you -can do so using the following procedure. (Note, this requires that your -@samp{make} program support @samp{VPATH}. GNU's make will provide this -functionality, for example.) If your @samp{make} program does not -support this, see the next section. - -For example, if you wish to create a build directory for @code{pmax} binaries -you might use the following procedure: - -@enumerate -@item -@code{mkdir /u1/krb5/pmax} -@item - @code{cd /u1/krb5/pmax} -@item - @code{../src/configure} -@item - @code{make} -@end enumerate - -@node Building using lndir, , Building with Separate Build Directories, Doing the Build -@subsection Building Using @samp{lndir} - -If you wish to keep separate build directories for each platform, and -you do not have access to a @samp{make} program which supports @samp{VPATH}, -all is not lost. You can use the @samp{lndir} program to create -symbolic link trees in your build directory. - -For example, if you wish to create a build directory for solaris binaries -you might use the following procedure: - -@enumerate -@item - @code{mkdir /u1/krb5/solaris} -@item - @code{cd /u1/krb5/solaris} -@item - @code{/u1/krb5/src/util/lndir `pwd`/../src} -@item - @code{./configure} -@item - @code{make} -@end enumerate - -You must give an absolute pathname to @samp{lndir} because it has a bug that -makes it fail for relative pathnames. Note that this version differs -from the latest version as distributed and installed by the XConsortium -with X11R6. Either version should be acceptable. - -@node Testing the Build, Options to Configure, Doing the Build, Building Kerberos -@section Testing the Build - -The Kerberos V5 distribution comes with built-in regression tests. To -run them, simply type the following command while in the top-level build -directory (i.e., the directory where you sent typed @samp{make} to start -building Kerberos; see @ref{Doing the Build}.): - -@example -% make check -@end example - -@menu -* The DejaGnu Tests:: -@end menu - -@node The DejaGnu Tests, , Testing the Build, Testing the Build -@subsection The DejaGnu Tests - -Some of the built-in regression tests are setup to use the DejaGnu -framework for running tests. These tests tend to be more comprehensive -than the normal built-in tests as they setup test servers and test -client/server activities. - -DejaGnu may be found wherever GNU software is archived. - -Most of the tests are setup to run as a non-privledged user. There are -two series of tests (@samp{rlogind} and @samp{telnetd}) which require -the ability to @samp{rlogin} as root to the local machine. Admittedly, -this does require the use of a @file{.rhosts} file or some other -authenticated means. @footnote{If you are fortunate enough to have a -previous version of Kerberos V5 or V4 installed, and the Kerberos rlogin -is first in your path, you can setup @file{.k5login} or @file{.klogin} -respectively to allow you access.} - -If you cannot obtain root access to your machine, all the other tests -will still run. Note however, with DejaGnu 1.2, the "untested testcases" -will cause the testsuite to exit with a non-zero exit status which -@samp{make} will consider a failure of the testing process. Do not worry -about this, as these tests are the last run when @samp{make check} is -executed from the top level of the build tree. - - -@node Options to Configure, osconf.h, Testing the Build, Building Kerberos -@section Options to Configure - -There are a number of options to @samp{configure} which you can use to -control how the Kerberos distribution is built. The following table -lists the most commonly used options to Kerberos V5's @samp{configure} -program. - -@table @code - -@item --help - -Provides help to configure. This will list the set of commonly used -options for building Kerberos. - -@item --prefix=DIR - -By default, Kerberos will install the package's files rooted at -`/usr/local' as in `/usr/local/bin', `/usr/local/sbin', etc. If you -desire a different location use this option. - -@item --exec-prefix=DIR - -This option allows one to separate the architecture independent programs -from the configuration files and manual pages. - -@item --with-cc=COMPILER - -Use @code{COMPILER} as the C compiler. - -@item --with-ccopts=FLAGS - -Use @code{FLAGS} as the default set of C compiler flags. - -Note that if you use the native Ultrix compiler on a -DECstation you are likely to lose if you pass no flags to cc; md4.c -takes an estimated 3,469 billion years to compile if you provide neither -the @samp{-g} flag nor the @samp{-O} flag to @samp{cc}. - -@item --with-cppopts=CPPOPTS - -Use @code{CPPOPTS} as the default set of C preprocessor flags. The most -common use of this option is to select certain @code{#define}'s for use -with the operating system's include files. - -@item --with-linker=LINKER - -Use @code{LINKER} as the default loader if it should be different from C -compiler as specified above. - -@item --with-ldopts=LDOPTS - -This option allows one to specify optional arguments to be passed to the -linker. This might be used to specify optional library paths. - -@item --with-krb4 - -This option enables Kerberos V4 backwards compatibility using the -builtin Kerberos V4 library. - -@item --with-krb4=KRB4DIR - -This option enables Kerberos V4 backwards compatibility. The directory -specified by @code{KRB4DIR} specifies where the V4 header files should -be found (@file{/KRB4DIR/include}) as well as where the V4 Kerberos -library should be found (@file{/KRB4DIR/lib}). - -@item --without-krb4 - -Disables Kerberos V4 backwards compatibility. This prevents Kerberos V4 -clients from using the V5 services including the KDC. This would be -useful if you know you will never install or need to interact with V4 -clients. - -@item --with-netlib[=libs] - -Allows for suppression of or replacement of network libraries. By -default, Kerberos V5 configuration will look for @code{-lnsl} and -@code{-lsocket}. If your operating system has a broken resolver library -(see @ref{Solaris versions 2.0 through 2.3}) or fails to pass the tests in -@file{src/tests/resolv} you will need to use this option. - -@item --enable-shared - -This option will turn on the building and use of shared library objects -in the Kerberos build. This option is only supported on certain -platforms. - -@item --with-vague-errors - -If enabled, gives vague and unhelpful error messages to the client... er, -attacker. (Needed to meet silly government regulations; most other -sites will want to keep this undefined.) - -@item --with-kdc-kdb-update - -Set this option if you want to allow the KDC to modify the Kerberos -database; this allows the last request information to be updated, as -well as the failure count information. Note that this doesn't work if -you're using slave servers!!! It also causes the database to be -modified (and thus needing to be locked) frequently. Please note that -the implementors do not regularly test this feature. - -@item --with-kdb-db=database - -The configuration process will try to determine a working set of -libraries required to implement the Kerberos database. Configure will -look for interfaces that use or emulate a @samp{ndbm} or @samp{dbm} -library. Failing that, a build in copy of the Berkeley DB code will be -used. You may decide to compile a different interface than the default -by specifying one of "ndbm", "dbm", or "db". - -An important note on platforms where the @samp{ndbm} implementation is -based on @sc{GDBM} (such as the Linux Slackware distribution). @sc{GDBM} -has its own built in file locking which prevents simultaneous access to -the database from two separate processes in which one wants to modify -the database while the otherone only wants to read. (i.e. the KDC and -administrative servers). In this case, you will need to specify the use -of the Berkeley DB. - -@end table - -For example, in order to configure Kerberos on a Solaris machine using -the @samp{suncc} with the optimizer turned on, run the configure -script with the following options: - -@example -% ./configure --with-cc=suncc --with-ccopts=-O -@end example - -@node osconf.h, Shared Library Support, Options to Configure, Building Kerberos -@section @file{osconf.h} - -There is one configuration file which you may wish to edit to control -various compile-time parameters in the Kerberos distribution: -@file{include/krb5/stock/osconf.h}. The list that follows is by no means -complete, just some of the more interesting variables. - -Please note: The former configuration file @file{config.h} no longer -exists as its functionality has been merged into the auto-configuration -process. @xref{Options to Configure}. - - -@table @code - -@item DEFAULT_PROFILE_PATH - -The pathname to the file which contains the profiles for the known -realms, their KDCs, etc. - -The profile file format is no longer the same format as Kerberos V4's -@file{krb.conf} file. - -@item DEFAULT_LNAME_FILENAME - -The pathname to the database that maps authentication names to local -account names. See kdb5_anadd(8). - -@item DEFAULT_KEYTAB_NAME - -The type and pathname to the default server keytab file (the equivalent -of Kerberos V4's @file{/etc/srvtab}). - -@item DEFAULT_KDC_ENCTYPE - -The default encryption type for the KDC. - -@item KDCRCACHE - -The name of the replay cache used by the KDC. - -@item RCTMPDIR - -The directory which stores replay caches. - -@item DEFAULT_KDB_FILE - -The location of the default database - -@end table - -@node Shared Library Support, OS Incompatibilities, osconf.h, Building Kerberos -@section Shared Library Support - -Shared library support is provided for a few operating systems. There -are restrictions as to which compiler to use when using shared -libraries. In all cases, executables linked with the shared libraries in -this build process will have built in the location of the libraries, -therefore obliterating the need for special LD_LIBRARY_PATH, et al environment -variables when using the programs. Except where noted, multiple versions -of the libraries may be installed on the same system and continue to -work. - -Currently the supported platforms are: NetBSD 1.0A, AIX 3.2.5, AIX 4.1, -Solaris 5.3, Alpha OSF/1 >= 2.1, HP-UX >= 9.X. - -To enable shared libraries on the above platforms, run the configure -script with the option @samp{--enable-shared}. - -One special note is that if the Kerberos V4 compatibility is compiled -in, you @b{must not} specify an alternate Kerberos V4 library from the -one in the tree or you will be missing references. - -@menu -* Shared Library Theory:: -* NetBSD Shared Library Support:: -* AIX Shared Library Support:: -* Solaris 5.3 Shared Library Support:: -* Alpha OSF/1 Shared Library Support:: -@end menu - -@node Shared Library Theory, NetBSD Shared Library Support, Shared Library Support, Shared Library Support -@subsection Theory of How Shared Libraries are Used - -An explanation of how shared libraries are implemented on a given -platform is too broad a topic for this manual. Instead this will touch -on some of the issues that the Kerberos V5 tree uses to support version -numbering and alternate install locations. - -Normally when one builds a shared library and then links with it, the -name of the shared library is stored in the object -(i.e. libfoo.so). Most operating systems allows one to change name that -is referenced and we have done so, placing the version number into the -shared library (i.e. libfoo.so.0.1). At link time, one would reference -libfoo.so, but when one executes the program, the shared library loader -would then look for the shared library with the alternate name. Hence -multiple versions of shared libraries may be supported relatively -easily. @footnote{Under AIX for the RISC/6000, multiple versions of -shared libraries are supported by combining two or more versions of the -shared library into one file. The Kerberos build procedure produces -shared libraries with version numbers in the internal module names, so -that the shared libraries are compatible with this scheme. -Unfortunately, combining two shared libraries requires internal -knowledge of the AIX shared library system beyond the scope of this -document. Practicallyspeaking, only one version of AIX shared libraries -can be supported on a system, unless the multi-version library is -constructed by a programmer familiar with the AIX internals.} - -All operating systems (that we have seen) provide a means for programs -to specify the location of shared libraries. On different operating -systems, this is either specified when creating the shared library, and -link time, or both.@footnote{Both are necessary sometimes as the shared -libraries are dependent on other shared libraries} The build process -will hardwire a path to the installed destination. - - -@node NetBSD Shared Library Support, AIX Shared Library Support, Shared Library Theory, Shared Library Support -@subsection NetBSD Shared Library Support - -Shared library support has been tested under NetBSD 1.0A using -GCC 2.4.5. Due to the vagaries of the loader in the operating system, -the library load path needs to be specified in building libraries and in -linking with them. Unless the library is placed in a standard location -to search for libraries, this may make it difficult for developers to -work with the shared libraries. - -@node AIX Shared Library Support, Solaris 5.3 Shared Library Support, NetBSD Shared Library Support, Shared Library Support -@subsection AIX Shared Library Support - - AIX specifies shared library versions by combining multiple -versions into a single file. Because of the complexity of this process, -no automatic procedure for building multi-versioned shared libraries is -provided. Therefore, supporting multiple versions of the Kerberos shared -libraries under AIX will require significant work on the part of a -programmer famiiliar with AIX internals. - - AIX allows a single library to be used both as a static library -and as a shared library. For this reason, the @samp{--enable-shared} -switch to configure builds only shared libraries. On other operating -systems, both shared and static libraries are built when this switch is -specified. As with all other operating systems, only non-shared static -libraries are built when @samp{--enable-shared} is not specified. - - The AIX 3.2.5 linker dumps core trying to build a shared -@samp{libkrb5.a} produced with the GNU C compiler. The native AIX -compiler works fine. In addition, the AIX 4.1 linker is able to build a -shared @samp{libkrb5.a} when GNU C is used. - - -@node Solaris 5.3 Shared Library Support, Alpha OSF/1 Shared Library Support, AIX Shared Library Support, Shared Library Support -@subsection Solaris 5.3 Shared Library Support - -Shared library support only works when using the Sunsoft C compiler. We -are currently using version 3.0.1. - -The path to the shared library must be specified at link time as well as -when creating libraries. - -@node Alpha OSF/1 Shared Library Support, , Solaris 5.3 Shared Library Support, Shared Library Support -@subsection Alpha OSF/1 Shared Library Support - -Shared library support has been tested with V2.1 and higher of the -operating system. Shared libraries may be compiled both with GCC and the -native compiler. - -One of the nice features on this platform is that the paths to the -shared libraries is specified in the library itself without requiring -that one specify the same at link time. - -We are using the @samp{-rpath} option to @samp{ld} to place the library -load path into the executables. The one disadvantage of this is during -testing where we want to make sure that we are using the build tree -instead of a possibly installed library. The loader uses the contents of -@samp{-rpath} before LD_LIBRARY_PATH so we must specify a dummy _RLD_ROOT -and complete LD_LIBRARY_PATH in our tests. - -The one disadvantage with the -method we are using - -@node OS Incompatibilities, Using Autoconf, Shared Library Support, Building Kerberos -@section Operating System Incompatibilities - -This section details operating system incompatibilities with Kerberos V5 -which have been reported to the developers at MIT. If you find additional -incompatibilities, and/or discover work arounds to such problems, please -send a report to @b{krb5-bugs@@mit.edu}. Thanks! - -@menu -* Ultrix 4.2/3:: -* Alpha OSF/1 V1.3:: -* Alpha OSF/1 V2.0++:: -* BSDI:: -* Solaris versions 2.0 through 2.3:: -* Solaris 2.X:: -* SGI Irix 5.X:: -@end menu - -@node Ultrix 4.2/3, Alpha OSF/1 V1.3, OS Incompatibilities, OS Incompatibilities -@subsection Ultrix 4.2/3 - -On the DEC MIPS platform, using the native compiler, @file{md4.c} and -@file{md5.c} can not be compiled with the optimizer set at level 1. -That is, you must specify either @samp{--with-ccopts=-O} and -@samp{--with-ccopts=-g} to configure. If you don't specify either, the -compile will never complete. - -The optimizer isn't hung; it just takes an exponentially long time. -Compiling 6 out of the 48 algorithmic steps takes 3 seconds; compiling 7 -steps takes 9 seconds; compiling 8 steps takes 27 seconds, and so on. -Calculations estimate it will finish in approximately 3,469 billion -years.... - -Using GCC instead of the native compiler will also work fine, both with -or without optimization. - -@node Alpha OSF/1 V1.3, Alpha OSF/1 V2.0++, Ultrix 4.2/3, OS Incompatibilities -@subsection Alpha OSF/1 V1.3 - -Using the native compiler, compiling with the @samp{-O} compiler flag -causes the @code{asn.1} library to be compiled incorrectly. - -Using GCC version 2.6.3 or later instead of the native compiler will also work -fine, both with or without optimization. - -@node Alpha OSF/1 V2.0++, BSDI, Alpha OSF/1 V1.3, OS Incompatibilities -@subsection Alpha OSF/1 V2.0++ - -There used to be a bug when using the native compiler in compiling -@file{md4.c} when compiled without either the @samp{-O} or @samp{-g} -compiler options. We have changed the code and there is no problem -under V2.1, but we do not have access to V2.0 to test and see if the -problem would exist there. (We welcome feedback on this issue). There -was never a problem in using GCC version 2.6.3. - -In version 3.2 and beyond of the operating system, we have not seen any -problems with the native compiler. - -@node BSDI, Solaris versions 2.0 through 2.3, Alpha OSF/1 V2.0++, OS Incompatibilities -@subsection BSDI - -BSDI versions 1.0 and 1.1 reportedly has a bad @samp{sed} which causes -it to go into an infinite loop during the build. The work around is -to use a @samp{sed} from somewhere else, such as GNU. (This may be -true for some versions of other systems derived from BSD 4.4, such as -NetBSD and FreeBSD.) - -@node Solaris versions 2.0 through 2.3, Solaris 2.X, BSDI, OS Incompatibilities -@subsection Solaris versions 2.0 through 2.3 - -The @code{gethostbyname()} routine is broken; it does not return a fully -qualified domain name, even if you are using the Domain Name Service -routines. Since Kerberos V5 uses the fully qualified domain name as the -second component of a service principal (i.e, -@samp{host/tsx-11.mit.edu@@ATHENA.MIT.EDU}), this causes problems for servers -who try to figure out their own fully qualified domain name. - -Workarounds: - -@enumerate - -@item - Supply your own resolver library. (such as bind-4.9.3pl1 availavle -from ftp.vix.com) - -@item - Upgrade to Solaris 2.4 - -@item - Make sure your /etc/nsswitch.conf has `files' before `dns' like: - -@example -hosts: files dns -@end example - -and then in /etc/hosts, make sure there is a line with your -workstation's IP address and hostname, with the fully qualified domain -name first. Example: - -@example -18.172.1.4 dcl.mit.edu dcl -@end example - -Note that making this change may cause other programs in your -environment to break or behave differently. - -@end enumerate - -@node Solaris 2.X, SGI Irix 5.X, Solaris versions 2.0 through 2.3, OS Incompatibilities -@subsection Solaris 2.X - -You @b{must} compile Kerberos V5 without the UCB compatibility -libraries. This means that @file{/usr/ucblib} must not be in the -LD_LIBRARY_PATH environment variable when you compile it. Alternatively -you can use the @code{-i} option to @samp{cc}, by using the specifying -@code{--with-ccopts=-i} option to @samp{configure}. - -@node SGI Irix 5.X, , Solaris 2.X, OS Incompatibilities -@subsection SGI Irix 5.X - -If you are building in a tree separate from the source tree, the vendors -version of make does not work properly with regards to -@samp{VPATH}. It also has problems with standard inference rules in 5.2 -(not tested yet in 5.3) so one needs to use GNU's make. - -Under 5.2, there is a bug in the optional System V @code{-lsocket} -library in which the routine @code{gethostbyname()} is broken. The -system supplied version in @code{-lc} appears to work though so one may -simply specify @code{--with-netlib} option to @samp{configure}. - -In 5.3, @code{gethostbyname()} is no longer present in @code{-lsocket} and -is no longer an issue. - -@node Using Autoconf, , OS Incompatibilities, Building Kerberos -@section Using @samp{Autoconf} - -(If you are not a developer, you can skip this section.) - -In most of the Kerberos V5 source directories, there is a -@file{configure} script which automatically determines the compilation -environment and creates the proper Makefiles for a particular platform. -These @file{configure} files are generated using @samp{autoconf} version -2.4, which can be found in the @file{src/util/autoconf} directory in the -distribution. - -Normal users will not need to worry about running @samp{autoconf}; the -distribution comes with the @file{configure} files already prebuilt. -Developers who wish to modify the @file{configure.in} files should see -@ref{Top, , Overview, autoconf, The Autoconf Manual}. - -Note that in order to run @samp{autoconf}, you must have GNU @samp{m4} -in your path. Before you use the @samp{autoconf} in the Kerberos V5 -source tree, you may also need to run @samp{configure}, and then run -@samp{make} in the @file{src/util/autoconf} directory in order to -properly set up @samp{autoconf}. - -One tool which is provided for the convenience of developers can be -found in @file{src/util/reconf}. This program should be run while the -current directory is the top source directory. It will automatically -rebuild any @file{configure} files which need rebuilding. If you know -that you have made a change that will require that all the -@file{configure} files need to be rebuilt from scratch, specify the -@code{--force} option: - -@example -% cd /u1/krb5/src -% ./util/reconf --force -@end example - -The developmental sources are a raw source tree (before it's been packaged -for public release), without the pre-built @file{configure} files. -In order to build from such a source tree, you must do: - -@example -% cd krb5/util/autoconf -% ./configure -% make -% cd ../.. -% util/reconf -@end example - -Then follow the instructions for building packaged source trees (above). -To install the binaries into a binary tree, do: - -@example -% cd /u1/krb5/src -% make all -% make install DESTDIR=somewhere-else -@end example - -@node Installation, Troubleshooting, Building Kerberos, Top -@chapter Installation - -When you are installing Kerberos for the first time at a site, you must -first decide on the realm name you will use for your site, and select a -machine to host the @dfn{Kerberos server}, which is also known as the -@dfn{KDC} (@dfn{Key Distribution Center}). The KDC must be located on a -secure machine, since its database contains the keys for the entire -realm. It is extremely important that the database be kept secure, if -the realm's Kerberos service is to remain secure. - -Once a KDC is installed and configured, you may then set up one or more -client machines, and one or more application machines. - -@menu -* Background:: -* Installation on any Machine:: -* Installing the KDC:: -* Migrating from V4 to V5 Kerberos:: -* A Sample Application:: -* Installing Kerberos Applications:: -* Common Kerberos Service Names:: -@end menu - -@node Background, Installation on any Machine, Installation, Installation -@section Background Information - -Your system's security is only as good as the security of your -@samp{root} password. You should take other precautions to protect your -system security in addition to installing Kerberos. Kerberos cannot -protect you from someone who is able to steal @samp{root} privileges. -Kerberos also does not protect you from break-ins caused by bugs in your -daemons (e.g., @samp{fingerd} or @samp{sendmail}). On almost all UNIX -systems, if intruders can break in as an ordinary users, they can obtain -superuser privileges by exploiting bugs or imperfect configuration files. - - -@node Installation on any Machine, Installing the KDC, Background, Installation -@section Installation on any Machine - -The following steps must be performed no matter what type of -machine (KDC, Client, or Application server) you are installing. All -machines functioning within the same administrative domain must use the -same Kerberos realm name; and all machines which are using Kerberos must -have the Kerberos configuration files properly installed. - -If you are installing Kerberos on a machine that will act only as a -Kerberos client, this section describes all that you need to do. If you -are installing a KDC, or an Kerberos Application server, you will also -need to complete the procedures detailed in @ref{Installing the KDC}, or -@ref{A Sample Application}, after you finish with the procedures found -in this section. - -@menu -* Picking a Realm Name:: -* Configuration files:: -* Recommended Programs:: -@end menu - -@node Picking a Realm Name, Configuration files, Installation on any Machine, Installation on any Machine -@subsection Picking a Realm Name - -Before you install Kerberos V5 at your site, you have to choose a -@dfn{realm name}, the name that specifies the system's administrative -domain. By convention, we suggest that you use your internet domain -name, in capital letters. (Kerberos realm names are case-sensitive, so -it's important that your realm name be in all upper case.) For example, -if your internet domain is @code{cygnus.com} (so that you have hostnames -such as @code{ftp.cygnus.com} and @code{tweedledum.cygnus.com}), then -your Kerberos realm should be @code{CYGNUS.COM}. Please note that -changing realm names is hard. Get it right the first time. - -@node Configuration files, Recommended Programs, Picking a Realm Name, Installation on any Machine -@comment node-name, next, previous, up@section -@subsection Configuration files - - -@menu -* krb5.conf:: -* Converting V4 configuration files:: -* /etc/services:: -@end menu - -@node krb5.conf, Converting V4 configuration files, Configuration files, Configuration files -@subsubsection The @file{krb5.conf} File - -The @file{krb5.conf} file contains information needed by the Kerberos V5 -library including a system's default Kerberos -realm, and the locations of the Kerberos servers. - -The @file{krb5.conf} uses an INI-style format. Sections are delimited by -square braces; within each section, there are relations where tags can -be assigned to have specific values. Tags can also contain a -subsection, which contains further relations or subsections. A tag can -be assigned to multiple values. - -Create a @file{/etc/krb5.conf} file using the following format: - -@example -[libdefaults] - default_realm = - -[realms] - = @{ - kdc = - admin_server = - default_domain = - @} - -[domain_realm] - <.domain.name> = -@end example - -Where @samp{realm_name} specifies the default realm to be used by that -particular system, and @samp{master_server_name} specifies the machine -name on which you will run the master server. The keywords @samp{kdc} -and @samp{admin_server} lists the location of the realms KDC and -administration servers. - -For example, if your realm name is @samp{ATHENA.MIT.EDU} and your master -server's name is @samp{kerberos.mit.edu}, the file should have these -contents: - -@example -[libdefaults] - default_realm = ATHENA.MIT.EDU - -[realms] - ATHENA.MIT.EDU = @{ - kdc = KERBEROS.MIT.EDU - admin_server = KERBEROS.MIT.EDU - default_domain = MIT.EDU - @} - -[domain_realm] - .mit.edu = ATHENA.MIT.EDU - mit.edu = ATHENA.MIT.EDU -@end example - - -In many situations, the default realm in which a host operates will be -identical to its Internet domain name, with the first component removed -and all letters capitalized. For example, @code{ftp.cygnus.com} is -traditionally in the realm @code{CYGNUS.COM}. -If this is not the case, you will need to establish a translation from -host name or domain name to realm name. This is accomplished with the -@samp{[domain_realm]} stanza. - -Each line of the translation file specifies either a host name or domain -name, and its associated realm: - -@example -[domain_realm] - <.domain.name> = KERBEROS.REALM1 - = KERBEROS.REALM2 -@end example - -For example, to map all hosts in the domain LSC.MIT.EDU to LSC.MIT.EDU -but the host FILMS.LSC.MIT.EDU to MIT.EDU your file would read: -@example -[domain_realm] - .LSC.MIT.EDU = LSC.MIT.EDU - FILMS.LSC.MIT.EDU = MIT.EDU -@end example - -If a particular host name matches both a domain name and a host name in -@samp{[domain_realm]}, the entry containing the host name takes precedence. - -See the @file{[SOURCE_DIR]/config-files/krb5.conf} file for an example -@file{krb5.conf} file. That file has examples of how to provide backup -servers for a given realm (additional lines with the same leading realm -name) and how to designate servers for remote realms. - -@node Converting V4 configuration files, /etc/services, krb5.conf, Configuration files -@subsubsection Conversion of V4 configuration files - -Kerberos V4's @file{krb.conf} and @file{krb.realms} files formats are no -longer used by the V5 library. A @sc{PERL} script has been provided to allow -for "easy" generation of an initial @file{krb5.conf}. It is located in -@file{[SOURCE_DIR]/config-files/convert-config-files}. The produced file -should be checked for errors. - -Note that if you are planning on using certain applications with -Kerberos V4 compatibility compiled in, the V4 library still needs the -files @file{krb.conf} and @file{krb.realms}. - - -@node /etc/services, , Converting V4 configuration files, Configuration files -@subsubsection /etc/services - -All hosts which will use Kerberos will need to have certain ports -defined in the system's @file{/etc/services} file. The file -@file{[SOURCEDIR]/config-files/services.append} contains the entries -which should be appended to the @file{/etc/services} file. Please note -that not all of the entries are required as several of the programs have -defaults built into the programs. This will be documented sometime in -the future. - -If you are using the Network Information Services (NIS) or Yellow -Pages (YP), you will need to add the services in the -@file{services.append} file to the services exported in the NIS or YP -server. - -@node Recommended Programs, , Configuration files, Installation on any Machine -@subsection Recommended Programs - -The following files should be installed on all machines which are -running Kerberos, either as a client, a KDC, or an application server: - -If you used the default @samp{make install} without using the -@samp{--prefix} argument to @file{configure}, then [K_USER] refers to -@file{/usr/local/bin}. - -@itemize @bullet -@item @file{/etc/krb5.conf} --- This files contains information required -by Kerberos V5 giving system defaults as well as locations of Kerberos -servers. -@item @file{[K_USER]/kinit} --- This program allows you to obtain -Kerberos credentials. -@item @file{[K_USER]/kdestroy} --- This program allows you to destroy -Kerberos credentials which are no longer needed. -@item @file{[K_USER]/klist} ---- This program allows you to list the -credentials found in your credentials cache. -@end itemize - -@node Installing the KDC, Migrating from V4 to V5 Kerberos, Installation on any Machine, Installation -@section Installing the KDC - -@menu -* kdc.conf:: -* Initializing the KDB:: -* Storing the Master Password:: -* Adding Users to the Database:: -* Starting the Kerberos Server:: -* Setting up Slave Kerberos Servers:: -* Inter-realm Kerberos Operation:: -* The Administration Server:: -* Testing the Kerberos Server:: -@end menu - -@node kdc.conf, Initializing the KDB, Installing the KDC, Installing the KDC -@subsection The optional @file{kdc.conf} profile - -There is an optional configuration file @file{kdc.conf} that allows one -to specify per-realm configuration data to be used by the Kerberos V5 -Authentication Service and Key Distribution Center. This information -includes database locations, key and per-realm defaults, port numbers, -ticket life times, etc. The location of the configuration file is -@file{/usr/local/lib/krb5kdc/kdc.conf}. - -See the man page or @file{[SOURCEDIR]/config-files/kdc.conf.M} for more -details. - -This document assumes that you do not have the @file{kdc.conf} -configuration file installed. - -Note also that @code{[logging]} subsection to @file{/etc/krb5.conf} can -be used to specify where to syslog messages regarding server activity. - -@node Initializing the KDB, Storing the Master Password, kdc.conf, Installing the KDC -@subsection Initializing the Kerberos Database - -Login to the Kerberos KDC, and use the @samp{su} command to become root. -If you installed the Kerberos administration tools -with the @samp{make install} command and the default pathnames, -they should be in the @file{/usr/local/admin} directory. -If you installed the tools in a different directory, -hopefully you know what it is. -From now on, we will refer to this directory as [ADMIN_DIR]. - -The default database will be located in the directory -@file{/usr/local/lib/krb5kdc} unless changed in the configuration -process. From now on, we will call this [DB_DIR]. - -The @samp{kdb5_create} command creates and initializes the master database. -It asks you to the database's master password. -Do not forget this password. -If you do, the database becomes useless. -(Your realm name should be substituted for [REALMNAME] below.) -@xref{Storing the Master Password} for an alternative way of dealing -with this master password. - -Because the install process does not create [DB_DIR] you need to do so -yourself. - -Use @samp{kdb5_create} as follows: - -@example -# @b{mkdir [DB_DIR]} -# @b{[ADMIN_DIR]/kdb5_create} -Initializing database '[DB_DIR]/principal' for realm '[REALMNAME]', -master key name 'K/M@@[REALMNAME]' -You will be prompted for the database Master Password. -It is important that you NOT FORGET this password. -Enter KDC database master key: @b{<-- [Enter the master password.]} -Re-enter KDC database master key to verify: @b{<-- [Re-enter it.]} -@end example - - -@node Storing the Master Password, Adding Users to the Database, Initializing the KDB, Installing the KDC -@subsection Storing the Master Password - -The @samp{kdb5_stash} command "stashes" the master password in the file -@file{[DB_DIR]/.k5.[REALM.NAME]} so that the Kerberos server can be started -automatically during an unattended reboot of the master server. Other -administrative programs use this hidden password so that they can access -the master database without someone having to manually provide the -master password. This command is an optional one; if you'd rather enter -the master password each time you start the Kerberos server, don't use -@samp{kdb5_stash}. - -On the one hand, if you use @samp{kdb5_stash}, a copy of the master key -will reside on a disk, which may not be acceptable; on the other hand, -if you don't use @samp{kdb5_stash}, the server cannot be started unless -someone is around to type the password manually. - -The command merely prompts for the master password: - -@example -# @b{[ADMIN_DIR]/kdb5_stash} -Enter KDC database master key: @b{<-- [Enter the master password.]} -@end example - -WARNING: If your Kerberos database master key is compromised and the -database is obtained, the security of your entire authentication system -is compromised. (If this happens to you, all of your user's passwords must -be set to new values manually --- i.e., not using Kerberos.) The master -key must be a carefully kept secret. If you keep backups, you must -guard all the master keys you use, in case someone has stolen an old -backup and wants to attack users' whose passwords haven't changed since -the backup was stolen. This is why we provide the option not to store -it on disk. - -@node Adding Users to the Database, Starting the Kerberos Server, Storing the Master Password, Installing the KDC -@subsection Adding Users to the Database - -The @samp{kdb5_edit} program may be used to add new users and services to -the master database, and to modify existing database -information. @xref{The Administration Server} for an alternative method -once the Kerberos environment is up and running. - -For example, to add yourself to the newly created database: (replace -@samp{[USERNAME]} with your username with. - -@example -# @b{[ADMIN_DIR]/kdb5_edit} -kdb5_edit: @b{ank [USERNAME]} -Enter password: @b{<-- [Enter your password.]} -Re-enter password for verification: @b{<-- [Re-enter it.]} -kdb5_edit: @b{quit} -@end example - -The @samp{ank} command is short for "add_new_key"; this command adds a -new user to the database. To see what other commands which @samp{kdb5_edit} -supports, type @kbd{? @key{RET}} at the @samp{kdb5_edit} prompt. - -@node Starting the Kerberos Server, Setting up Slave Kerberos Servers, Adding Users to the Database, Installing the KDC -@subsection Starting the Kerberos Server - -Assuming that you didn't use the @samp{--prefix} argument to -@file{configure}, then [K_SERVER] refers to @file{/usr/local/sbin}. - -In order to start the Kerberos server, simply run it. It will fork and -disassociate from the terminal unless the @samp{-n} argument is used. - -@example -# @b{[K_SERVER]/krb5kdc} -@end example - -If you have used the @samp{kdb5_stash} command to store the master database password, -the server will start automatically. -If you did not use @samp{kdb5_stash}, -use the following command: - -@example -# @b{[K_SERVER]/krb5kdc -m} -@end example - -The server will prompt you to enter the master password before actually -starting itself. - -@node Setting up Slave Kerberos Servers, Inter-realm Kerberos Operation, Starting the Kerberos Server, Installing the KDC -@subsection Setting up Slave Kerberos Servers - -Slave Kerberos servers allow clients to be able to get Kerberos tickets -even when the Master server is not available. Users will not be able to -change their passwords --- changes can only be made to database on the -Master server; however, users will be able to authenticate to -application servers, which is critically important in a distributed -client-server environment. The current implementation of the client code -does not provide load sharing in that the order of servers contacted is -the same as those listed in the @file{krb5.conf} file. - -@menu -* Kerberos Slave Database Propagation:: -* Installing a Slave Server:: -@end menu - -@node Kerberos Slave Database Propagation, Installing a Slave Server, Setting up Slave Kerberos Servers, Setting up Slave Kerberos Servers -@subsubsection Kerberos Slave Database Propagation - -In order to propagate the Kerberos database from the Master server to -the slaves, the @samp{kprop} and @samp{kpropd} client/server programs -are used. Periodically, the Master server will dump the Kerberos -database out into an ASCII format, using the @samp{kdb5_edit} program. -The master server will then run @samp{kprop} to propagate the dumped -database file to each slave server. - -On the slave server, the @samp{kpropd} program is invoked out of -@samp{inetd} server. After @samp{kprop} and @samp{kpropd} have -mutually authenticated with one another, and @samp{kpropd} is satisfied -with the identity of the Master server, then the dumped ASCII database -is transferred to the slave server in an encrypted fashion. After the -database is transfered, @samp{kpropd} will then run @samp{kdb5_edit} -with the appropriate arguments in order to undump the database into a -usable form by the KDC on the slave server. - -@node Installing a Slave Server, , Kerberos Slave Database Propagation, Setting up Slave Kerberos Servers -@subsubsection Installing a Slave Server - -@b{To be written.} - - -@node Inter-realm Kerberos Operation, The Administration Server, Setting up Slave Kerberos Servers, Installing the KDC -@subsection Inter-realm Kerberos Operation - -@b{To be written.} - -@node The Administration Server, Testing the Kerberos Server, Inter-realm Kerberos Operation, Installing the KDC -@subsection The Administration Server - -There is currently an administration server in the Kerberos source tree. -It is, however, very rough, and it will likely be significantly changed -or replaced before the 1.0 release. Hence, this manual does not -document the current administration server. Changes to the database can -be made by logging in to the KDC directly, and using the -@samp{kdb5_edit} program; see @ref{Adding Users to the Database}. - -@node Testing the Kerberos Server, , The Administration Server, Installing the KDC -@subsection Testing the Kerberos Server - -Use the @samp{kinit} command to obtain Kerberos credentials. This command -creates your credentials cache and stores your credentials in it. - -If you used the default @samp{make install} command and directories to -install the Kerberos user utilities, @samp{kinit} will be in the -@file{/usr/local/bin} directory. From now on, we'll refer to the Kerberos user -commands directory as [K_USER]. - -Use @samp{kinit} as follows: - -@example -% @b{[K_USER]/kinit [USERNAME]} -Password for [USERNAME]@@[REALMNAME]: @b{<-- enter your password} -@end example - - -Use the @samp{klist} program to list the contents of your ticket file. - -@example -% @b{[K_USER]/klist} -Ticket cache: /tmp/krb5cc_15806 -Default principal: [USERNAME]@@[REALMNAME] - - Valid starting Expires Service principal -31-Jan-95 21:58:32 1-Feb-95 05:57:39 krbtgt/[REALMMNAME]@@[REALMNAME] - -@end example - -@ignore -@c not yet... -If you have any problems, you can examine the log file -@file{/krb5/kerberos.log} on the Kerberos server machine to see if -there was some sort of error. -@end ignore - -@node Migrating from V4 to V5 Kerberos, A Sample Application, Installing the KDC, Installation -@section Migrating from V4 to V5 Kerberos - -@b{To be written.} A rough idea of the procedure that one may follow is -in @file{[SOURCE_DIR]/kdc/migration.doc}. - -@node A Sample Application, Installing Kerberos Applications, Migrating from V4 to V5 Kerberos, Installation -@section A Sample Application - -This release of Kerberos comes with a sample application server and a -corresponding client program. You will find this software -@file{[K_SERVER]/sserver} and @file{[K_USER]/sclient}, which is the -server's executable, and the client program's executable, respectively. - -The programs are rudimentary. -When they have been installed (the installation procedure is described -in detail later), they work as follows: - -@enumerate - -@item - The user starts @samp{sclient} and provides as arguments -to the command the name of the server machine and an optional port on -which to contact the server. - -@item - @samp{sclient} contacts the server machine and -authenticates the user to @samp{sserver}. - -@item - @samp{sserver} authenticates itself to @samp{sclient} (thus -performing mutual authentication), and -then returns a message to the client program. -This message contains the name of the Kerberos principal that was used -to authenticate to @samp{sserver}. - -@item - @samp{sclient} displays the server's message on the user's -terminal screen. - -@end enumerate - -@menu -* Installing the Sample Application:: -* Testing the Sample Server:: -@end menu - -@node Installing the Sample Application, Testing the Sample Server, A Sample Application, A Sample Application -@subsection Installing the Sample Application - -In general, -you use the following procedure to install a Kerberos-authenticated -server-client system. - -@enumerate - -@item - Add the appropriate entry to the Kerberos database using @samp{kdb_edit} - -@item - Create a @file{/etc/v5srvtab} file for the server machine. - -@item - Install the service program and the @file{/etc/v5srvtab} -file on the server machine. - -@item - Install the client program on the client machine. - -@item - Update the @file{/etc/services} file on the client and server machines. -@end enumerate - -We will use the sample application as an example, although programs -which do not take requests via the @samp{inetd} program may have -slightly different installation procedures. @samp{Inetd} starts -@samp{sserver} each time a client process contacts the server machine. -@samp{sserver} processes the request, terminates, then is restarted -when @samp{inetd} receives another @samp{sserver} request. When you -install the program on the server, you must add a @samp{sample} entry to -the server machine's @file{/etc/inetd.conf} file. - -The following description assumes that you are installing -@samp{sserver} on the machine @samp{jimi.mit.edu}. -Here's the process, step by step: - -@enumerate - -@item - Login as root or @samp{su} to root on the Kerberos server machine. -Use the @samp{kdb5_edit} program to create an entry for -@code{sample} in the Kerberos database: - -@example -# @b{[ADMIN_DIR]/kdb5_edit} -kdb5_edit: @b{add_random_key sample/jimi.mit.edu} -kdb5_edit: @b{quit} -@end example - -(Note: @samp{add_random_key} may be abbreviated as @samp{ark}.) - -@item - Use @samp{kdb5_edit} to create a @file{srvtab} file -for @samp{sserver}'s host machine: - -@example -# @b{[ADMIN_DIR]/kdb5_edit} -kdb5_edit: @b{extract_srvtab jimi.mit.edu sample} -'sample/jimi.mit.edu@@ATHENA.MIT.EDU' added to keytab 'WRFILE:jimi.mit.edu-new-srvtab' -kdb5_edit: @b{quit} -@end example - -(Note: @samp{extract_srvtab} may be abbreviated as @samp{xst}.) - -Transfer the @file{jimi.mit.edu-new-srvtab} file to @samp{jimi.mit.edu} -and install it as @file{/etc/v5srvtab}. - -@b{WARNING}: Note that this file is equivalent to the service's password and -should be treated with care. For example, it could be transferred by -removable media, but should not be sent over an open network in the -clear. This file should installed such that only the root user can read -it. - -@item - Add the following line to the @file{/etc/services} file on -@samp{jimi.mit.edu}, and on all machines that will run the -@samp{sample_client} program: - -@example -sample 906/tcp # Kerberos sample app server -@end example - -@item - Add a line similar to the following line to the @file{/etc/inetd.conf} -file on @samp{sample_server}'s machine: - -@example -sample stream tcp nowait switched root - [K_SERVER]/sserver sample_server -@end example - -where [K_SERVER] should be substituted with -the path to the @samp{sserver} program. -(This @file{inetd.conf} information should be placed on one line.) -You should examine existing lines in @file{/etc/inetd.conf} and use the -same format used by other entries (e.g. for telnet). Most systems do -not have a column for the `switched' keyword, and some do not have a -column for the username (usually `root', as above). - -@item - Restart @samp{inetd} by sending the current @samp{inetd} process -a hangup signal: - -@example -# @b{kill -HUP} @i{process_id_number} -@end example - -@item - The @samp{sserver} is now ready to take @samp{sclient} requests. - -@end enumerate - -@node Testing the Sample Server, , Installing the Sample Application, A Sample Application -@subsection Testing the Sample Server - -Assume that you have installed @samp{sserver} on @samp{jimi.mit.edu}. - -Login to your workstation and use the @samp{kinit} command to -obtain a Kerberos ticket-granting ticket: - -@example -% @b{[K_USER]/kinit [USERNAME]} -Password for [USERNAME]@@[REALMNAME]: @b{<--- Enter your password} -@end example - -Now use the @samp{sclient} program as follows: - -@example -% @b{[K_USER]/sclient jimi} -@end example - -The command should display something like the following: - -@example -sendauth succeeded, reply is: -reply len 29, contents: -You are [USERNAME]@@[REALMNAME] -@end example - -@node Installing Kerberos Applications, Common Kerberos Service Names, A Sample Application, Installation -@section Installing Kerberos Applications - - In addition to the sample application, Kerberos comes with -several servers that can be installed on workstations to provide secure -network services such as FTP, Telnet, and Rlogin. This section -describes these services and how to install them. First, a general -procedure is outlined for configuring a workstation to run Kerberos -application servers. Then, details of the particular configuration -options required by each server are presented. - - -@menu -* Levels of Security:: -* Preparing a Workstation for Kerberos Application Servers:: -* BSD Utilities:: -* Telnet and FTP:: -@end menu - -@node Levels of Security, Preparing a Workstation for Kerberos Application Servers, Installing Kerberos Applications, Installing Kerberos Applications -@subsection Levels of Security - - Before installing Kerberized servers, it is a good idea to -decide on a security policy for your environment. While developing a -comprehensive security policy is beyond the scope of these instructions, -there are several interactions between Kerberos servers and non-Kerberos -servers, as well as different modes in which Kerberos servers can run -that should be considered. In general, there are three levels of -connections: - -@enumerate - -@item -Encrypted Kerberos connections are the most secure services provided by -the Kerberos environment. Only encrypted services provide -confidentiality---encryption is required to make sure a passive -eavesdropper does not collect sensitive data, such as passwords, sent -over connections. Besides providing confidentiality, encryption -provides protection against active attacks. Without encryption or some -other form of integrity, an attacker may be able to insert commands or -change data in an authenticated session. - - -@item -The next level of security is Kerberos-authenticated services without -encryption. Without encryption, there is no confidentiality, and some -active attacks are possible. However, unencrypted services are faster -and are available commercially outside the United States. In addition, -the window of exposure to attack is generally limited to the lifetime of -a session---it is difficult for an attacker who does not have tickets to -start a new session if a Kerberos authentication exchange must take -place at the beginning of every session. - -@item -Passworded services provide the next lower level of security. -Unfortunately, it is all-to-easy for a passive attacker to use software -such as a packet sniffer to find passwords traveling over a network. -Additionally, once an attacker knows a password, they can start -additional sessions at future times until the password is changed from a -secure location. Despite the disadvantages of password-based network -services, there are some common reasons for enabling them. First, most -clients only support password-based services; not everyone has Kerberos -or other cryptographically-secure network services. Second, in some -environments, where the network is secure, passwords may be a reasonable -solution. Also, particularly on public-access systems, it is common to -enable password-based services for normal users, while using more-secure -services such as Kerberos for root logins by administrators. - -@item -The least secure common category of services are trust or host-based -services. These services use an IP address or client-supplied assertion -to provide authentication. Examples of host-based services include -@samp{rlogin}, @samp{rsh}, and the @samp{on} or @samp{rexd} service. It -is generally sufficient to know that a user exists on a target system, -and to know that a host-based or trust-based service is enabled in order -to exploit the service. Whenever possible, these services should be -disabled; there are few situations in which an a security policy is both -compatible with Kerberos and host-based services. -@end enumerate - - Next, decide whether Kerberos V4 compatibility is necessary. -Unencrypted Kerberos V4 services suffer from all the problems of -unencrypted Kerberos V5 services: lack of confidentiality and -susceptibility to active attack. In addition, the lack of a replay cache -in Kerberos V4 makes these active attacks much easier. Also, design bugs -in the Kerberos V4 BSD utilities such as @samp{rlogin}, @samp{rsh} and -@samp{rcp} cause the availability of an unencrypted service to -significantly decrease the security of a system, even if only the -encrypted service is ever used. For example, a system that runs both -encrypted and unencrypted Kerberos V4 @samp{rlogin} servers is less secure -than a system only running the encrypted service, even if users only -ever connect to the encrypted service. - - Therefore, if Kerberos V4 interoperability is desired or required, -try to avoid running unencrypted Kerberos V4 services wherever possible. -In particular, only enable encrypted @samp{rlogin} if at all possible. -Naturally, some environments will require additional Kerberos V4 -functionality, like @samp{rsh}. The Kerberos V5 versions of these services, -with Kerberos V4 interoperability enabled, are not any weaker than their -Kerberos V4 counterparts. So, if the existing Kerberos V4 security policy -allows these services, then enabling them under the Kerberos V5 security -policy should not be a problem. - - In addition, the issue of compatibility with older Kerberos V5 -clients must be considered. For the most part, this compatibility is -automatic, and has few security implications. The major exception to -this is the BSD utilities. Until Kerberos V5 Beta6, these utilities -inherited a few design defects from the Kerberos V4 BSD utilities. In -particular, the presence of an unencrypted service that was never used -adversely effected the security of an encrypted service. The solution -that was adopted preserves compatibility with Kerberos V5 Beta5 clients. -Unfortunately, older clients are incompatible with this scheme. If -interoperability with older clients is necessary, then the new scheme -for checksums can be disabled on the server. If these checksums are -disabled, there is a short window between when a connection is opened -and when the replay cache is updated where an active attack is possible. -Alternatively, sites wishing to enable all security features may wish to -disable compatibility with Kerberos V5 Beta5 BSD utilities. -@xref{Checksums}, for full details. - - In conclusion, as you prepare to install Kerberos application -servers, you should have answers to the following questions: - -@enumerate - -@item -What levels of services are appropriate for your security policy: -encrypted services, authenticated but not encrypted services, -password-based services, or host-based services? - -@item -Do you wish to enable Kerberos V4 compatibility? If so, do you need to -enable unencrypted services? - -@item -Do you need compatibility with Kerberos V5 clients before Beta5 -(released in May, 1995)? Do you wish to disable compatibility with -Beta5 clients for slightly enhanced security? -@end enumerate - - - -@node Preparing a Workstation for Kerberos Application Servers, BSD Utilities, Levels of Security, Installing Kerberos Applications -@subsection Preparing a Workstation for Kerberos Application Servers - - - The following procedure is very similar to the installation -procedure for the sample Kerberos server. @xref{Installing -the Sample Application}. However, instead of using the sample service, -this configuration is designed to set up host-based services. - -The following description assumes that you are installing @samp{sserver} -on the machine @samp{jimi.mit.edu}. Repeat these steps for each -workstation that will be running host-based servers. Note that it is -not necessary to run these procedures on client machines--machines used -only to connect to secure network services, but that do not run any -servers of their own. Here's the process, step by step: - -@enumerate - -@item - Login as root or @samp{su} to root on the Kerberos server machine. -Use the @samp{kdb5_edit} program to create a service entry for -@code{host} in the Kerberos database: - -@example -# @b{[ADMIN_DIR]/kdb5_edit} -kdb5_edit: @b{add_random_key host/jimi.mit.edu} -kdb5_edit: @b{quit} -@end example - -(Note: @samp{add_random_key} may be abbreviated as @samp{ark}.) - -@item - Use @samp{kdb5_edit} to create a @file{srvtab} file -for @samp{sserver}'s host machine: - -@example -# @b{[ADMIN_DIR]/kdb5_edit} -kdb5_edit: @b{extract_srvtab jimi.mit.edu host} -'host/jimi.mit.edu@@ATHENA.MIT.EDU' added to keytab 'WRFILE:jimi.mit.edu-new-srvtab' -kdb5_edit: @b{quit} -@end example - -(Note: @samp{extract_srvtab} may be abbreviated as @samp{xst}. Also, -additional services can be listed after @samp{host} on the -@samp{extract_srvtab} line; for example if the host jimi also runs the -sample server, the @samp{sample} service might have been listed after -host.) - -Transfer the @file{jimi.mit.edu-new-srvtab} file to @samp{jimi.mit.edu} -and install it as @file{/etc/v5srvtab}. - -@b{WARNING}: Note that this file is equivalent to the service's password and -should be treated with care. For example, it could be transferred by -removable media, but should not be sent over an open network in the -clear. This file should be installed such that only the root user can read -it. - -@item -Make sure that the @samp{/etc/services} file has been updated to include -Kerberos services. In particular, look for @samp{klogin}, -@samp{eklogin}, and @samp{kshell}. - -@item -For each server you plan to run, add a line to @file{/etc/inetd.conf}. -The following sections will give details on what this line should look -like for each Kerberos application service. - -@item -Consider removing non-Kerberized services like @samp{rlogin}, -@samp{rsh}, @samp{rexd}, and others, in accordance with the security policy you decided on in the last section. - -@item - Restart @samp{inetd}. On most systems, this is done by sending the current @samp{inetd} process -a hangup signal: - -@example -# @b{kill -HUP} @i{process_id_number} -@end example - -@item -Try using the Kerberos applications to connect to the host. - -@end enumerate - -@node BSD Utilities, Telnet and FTP, Preparing a Workstation for Kerberos Application Servers, Installing Kerberos Applications -@subsection BSD Utilities - - This section describes installing servers for the BSD utilities: -@samp{kshd} and @samp{klogind}. The @samp{klogind} server implements the -protocol used by the Kerberized @samp{rlogin} client. The @samp{kshd} -server implements the protocol used by the @samp{rsh} and @samp{rcp} -clients. - - These daemons take a common set of options to enable support for -different versions of Kerberos. The @samp{-5} option enables Kerberos -V5 support, and the @samp{-4} option enables Kerberos V4 support. At -least one of these options must be supplied or the server will refuse -all connections. Both options can be supplied if compatibility with -both versions of Kerberos is desired. - - Both the @samp{klogind} and @samp{kshd} take an @samp{-e} option -to control encryption; because of the design of the servers, it works -slightly differently. The Kerberos login service listens on two -different ports, one for encrypted connections, and one for unencrypted -connections. Because @samp{klogind} is started by @samp{inetd}, it -needs to know whether it is servicing an encrypted or unencrypted -connection. Thus, the @samp{-e} option tells @samp{klogind} that it is -listening to the encrypted port. Typically, systems that allow both -encrypted and unencrypted logins have two lines in @file{inetd.conf}, -one for the @samp{klogin} service and one for the @samp{eklogin} -service. The line for the @samp{eklogin} service uses the @samp{-e} -option, while the line for the @samp{klogin} service does not. Systems -only supporting encrypted logins simply have the @samp{eklogin} line. - - On the other hand, @samp{kshd} listens to encrypted and -unencrypted requests on the same port; information from the client -identifies the connection's encryption status. So, @samp{kshd} -interprets the @samp{-e} option to mean that encryption is required. If -this option is specified, unencrypted connections are dropped. Thus, -specifying @samp{-e} to @samp{kshd} is like only having a line for -@samp{eklogin}. - -@menu -* Checksums:: Checksum facility for dealing with active attacks. -* BSD Utility Configuration Example:: Sample @file{inetd.conf} entries for BSD utilities. -@end menu - -@node Checksums, BSD Utility Configuration Example, BSD Utilities, BSD Utilities -@subsubsection Checksums - - Under previous versions of Kerberos, it was possible for an active -attacker to change certain information in the initial authentication -exchange without this change being detected. Starting with Kerberos V5, -Beta6, this information is protected by a checksum passed in the -Kerberos authenticator. Ideally, the server could detect the presence -of this checksum and use it if it were present. This way, -administrators could be sure to use new clients that produced the -checksum, while users who were not as concerned about security could use -a wider range of clients. - - This is how the checksum feature works by default. -Unfortunately, clients previous to Kerberos V5, Beta5 used the checksum -field to incorporate semi-random data into the Kerberos authentication -exchange. It is impossible to distinguish these bogus checksums from -checksums that have been produced by modern clients, but modified by an -active attacker. Thus, the checksum feature is incompatible with -previous releases of Kerberos V5. Three modes of operation are provided -to meet the configuration needs of different sites: - -@enumerate - -@item -The @samp{-c} option to both @samp{kshd} and @samp{klogind} requires -that checksums be present and valid. This only works with clients more -recent than Kerberos V5, Beta6. An error will be given when an older -client tries to connect. This option is incompatible with Kerberos V4; -Kerberos V4 clients do not include a checksum. If this option is used -in conjunction with the @samp{-4} option for Kerberos V4 compatibility, -a warning about the configuration error will be logged on each -connection. - -@item -If no checksum-related option is specified, then checksums will be -validated if they are present, but not required. This is compatible with -Kerberos V4 and Kerberos V5 clients as early as Kerberos V5, Beta5. - -@item -If the @samp{-i} option is provided, then checksums are ignored, even if -present. This option is required to maintain compatibility with clients -older than Kerberos V5 Beta5. Site should upgrade to newer clients so -this option is not required. - -@end enumerate - -@node BSD Utility Configuration Example, , Checksums, BSD Utilities -@subsubsection BSD Utility Configuration Example - - This section includes sample entries for @file{/etc/inetd.conf}. -Sample configuration are presented for three systems. Note that while -the examples stretch over multiple lines, an entry for a single service -should be placed on only one line in @file{inetd.conf}. Also, not all -systems have all of the columns shown in the example. @xref{Installing -the Sample Application}, for details on adding services to -@file{inetd.conf}. - - The first system enables all security features. Only Kerberos -V5 encrypted connections are enabled, and checksums are required. -@example -eklogin stream tcp nowait root - [K_SERVER]/klogind klogind -5 -e -c -kshell stream tcp nowait root - [K_SERVER]/kshd kshd -5 -e -c -@end example - - - The second system enables encrypted services for both Kerberos -V5 and Kerberos V4. Checksums are not required, but since no V5 clients -earlier than Beta5 are used, they are not ignored. - -@example -eklogin stream tcp nowait root - [K_SERVER]/klogind klogind -5 -4 -e -kshell stream tcp nowait root - [K_SERVER]/kshd kshd -5 -4 -e -@end example - - - The final example has both encrypted and unencrypted services -enabled for both Kerberos V5 and Kerberos V4. Checksums are disabled to -preserve compatability with older V5 clients. - -@example -eklogin stream tcp nowait root - [K_SERVER]/klogind klogind -5 -4 -i -e -klogin stream tcp nowait root - [K_SERVER]/klogind klogind -5 -4 -i -kshell stream tcp nowait root - [K_SERVER]/kshd kshd -5 -4 -i -@end example - -@node Telnet and FTP, , BSD Utilities, Installing Kerberos Applications -@subsection Telnet and FTP - - The following are example entries for @file{inetd.conf} for the -@samp{telnetd} and @samp{ftpd} servers. @xref{Installing the Sample -Application}, for details on adding services to @file{inetd.conf}. Note -that unlike other @file{inetd.conf} examples in this document, these -line should replace existing lines for password-based services of the -same name. - - The first example only allows encrypted or authenticated connections. - -@example -telnet stream tcp nowait root - [K_SERVER]/telnetd telnetd -a user -ftp stream tcp nowait root - [K_server]/ftpd ftpd -a -@end example - - The second example also allows password-based connections to be -made. - -@example -telnet stream tcp nowait root - [K_SERVER]/telnetd telnetd -ftp stream tcp nowait root - [K_server]/ftpd ftpd -@end example - -@node Common Kerberos Service Names, , Installing Kerberos Applications, Installation -@section Common Kerberos Service Names - -The following service names are used by Kerberos client/server -applications. - -@table @code - -@item host -Used by @samp{telnet}, @samp{rlogin}, @samp{rsh}, @samp{rcp}, @samp{ftp} -and other services which generally give login access to the host. - -@item pop -Used by the Post Office Protocol. - -@item sample -Used by the Kerberos sample applications. - -@end table - -These service names are used as the first component of the server's -principal name, with the second component being the server's fully -qualified domain name, in lower case. - -@node Troubleshooting, , Installation, Top -@chapter Troubleshooting - -@b{To be written.} - -@contents -@bye diff --git a/doc/install.texinfo b/doc/install.texinfo deleted file mode 100644 index b105435e2..000000000 --- a/doc/install.texinfo +++ /dev/null @@ -1,1444 +0,0 @@ -\input texinfo-suppl.tex % contains @doubleleftarrow{} definition - % this line must come *before* \input texinfo -\input texinfo @c -*-texinfo-*- -@c %**start of header -@c guide -@setfilename krb5-install.info -@settitle Kerberos V5 Installation Guide -@setchapternewpage odd @c chapter begins on next odd page -@c @setchapternewpage on @c chapter begins on next page -@c @smallbook @c Format for 7" X 9.25" paper -@c %**end of header - -@paragraphindent 0 -@iftex -@parskip 6pt plus 6pt -@end iftex - -@include definitions.texinfo -@set EDITION 1.1 - -@finalout @c don't print black warning boxes - -@titlepage -@title @value{PRODUCT} Installation Guide -@subtitle Release: @value{RELEASE} -@subtitle Document Edition: @value{EDITION} -@subtitle Last updated: @value{UPDATED} -@author @value{COMPANY} - -@page -@vskip 0pt plus 1filll - -@end titlepage - -@node Top, Copyright, (dir), (dir) -@comment node-name, next, previous, up - -@ifinfo -This file documents how to install the @value{RELEASE} release of -@value{PRODUCT}. - -@end ifinfo - -@c The master menu is updated using emacs19's M-x texinfo-all-menus-update -@c function. Don't forget to run M-x texinfo-every-node-update after -@c you add a new section or subsection, or after you've rearranged the -@c order of sections or subsections. Also, don't forget to add an @node -@c comand before each @section or @subsection! All you need to enter -@c is: -@c -@c @node New Section Name - -@c @section New Section Name -@c -@c M-x texinfo-every-node-update will take care of calculating the -@c node's forward and back pointers. -@c -@c --------------------------------------------------------------------- - -@menu -* Copyright:: -* Introduction:: -* Realm Configuration Decisions:: -* Building Kerberos V5:: -* Installing Kerberos V5:: -* Upgrading Existing Kerberos V5 Installations:: -* Bug Reports for Kerberos V5:: -@end menu - -@node Copyright, Introduction, Top, Top -@unnumbered Copyright -@include copyright.texinfo - -@node Introduction, Realm Configuration Decisions, Copyright, Top -@chapter Introduction - -@menu -* What is Kerberos and How Does it Work?:: -* Why Should I use Kerberos?:: -* Please Read the Documentation:: -* Overview of This Guide:: -@end menu - -@node What is Kerberos and How Does it Work?, Why Should I use Kerberos?, Introduction, Introduction -@section What is Kerberos and How Does it Work? - -@value{PRODUCT} is based on the Kerberos authentication system developed -at MIT. Under Kerberos, a client (generally either a user or a service) -sends a request for a ticket to the Key Distribution Center (KDC). The -KDC creates a @dfn{ticket-granting ticket} (TGT) for the client, -encrypts it using the client's password as the key, and sends the -encrypted TGT back to the client. The client then attempts to decrypt -the TGT, using its password. If the client successfully decrypts the -TGT (@i{i.e.}, if the client gave the correct password), it keeps the -decrypted TGT, which indicates proof of the client's identity. - -The TGT, which expires at a specified time, permits the client to obtain -additional tickets, which give permission for specific services. The -requesting and granting of these additional tickets is user-transparent. - -@node Why Should I use Kerberos?, Please Read the Documentation, What is Kerberos and How Does it Work?, Introduction -@section Why Should I use Kerberos? - -Since Kerberos negotiates authenticated, and optionally encrypted, -communications between two points anywhere on the Internet, it provides -a layer of security that is not dependent on which side of a firewall -either client is on. Since studies have shown that half of the computer -security breaches in industry happen from @i{inside} firewalls, -@value{PRODUCT} from @value{COMPANY} will play a vital role in the -security of your network. - -@node Please Read the Documentation, Overview of This Guide, Why Should I use Kerberos?, Introduction -@section Please Read the Documentation - -As with any software package that uses a centrallized database, the -installation procedure is somewhat involved, and requires forethought -and planning. @value{COMPANY} has attempted to make this -@value{PRODUCT} Installation Guide as concise as possible, rather than -making it an exhaustive description of the details of Kerberos. -@ifset CYGNUS -Consequently, everything in this guide appears because @value{COMPANY} -believes that it is important. Please read and follow these -instructions carefully, and if there is anything you do not understand -or are not sure of, please don't hesitate to call us. -@end ifset -@ifset MIT -Consequently, everything in this guide appears because @value{COMPANY} -believes that it is important. Please read and follow these -instructions carefully. -@end ifset - -@include document-list.texinfo - -@node Overview of This Guide, , Please Read the Documentation, Introduction -@section Overview of This Guide - -@noindent -The next chapter describes the decisions you need to make before -installing @value{PRODUCT}. - -@noindent -Chapter three provided instructions for building the Kerberos sources. - -@noindent -Chapter four describes installation procedures for each class of -Kerberos machines: - -@enumerate -@item -Key Distribution Centers (KDCs). - -@enumerate A -@item -The Master KDC. - -@item -Slave KDCs. -@end enumerate - -@item -UNIX client machines - -@item -UNIX application server machines -@end enumerate - -@noindent -Note that a machine can be both a client machine and an application -server. - -@noindent -Chapter five describes procedure for updating previous installations of -@value{PRODUCT}. - -@noindent -Chapter six describes our problem reporting system. - -@node Realm Configuration Decisions, Building Kerberos V5, Introduction, Top -@chapter Realm Configuration Decisions - -Before installing @value{PRODUCT}, it is necessary to consider the -following issues: - -@itemize @bullet -@item -The name of your Kerberos realm (or the name of each realm, if you need -more than one). - -@item -How you will map your hostnames onto Kerberos realms. - -@item -Which ports your KDC and and kadmin (database access) services will use. - -@item -How many slave KDCs you need and where they should be located. - -@item -The hostnames of your master and slave KDCs. - -@item -How frequently you will propagate the database from the master KDC to -the slave KDCs. - -@item -Whether you need backward compatibility with Kerberos V4. -@end itemize - -@menu -* Kerberos Realms:: -* Mapping Hostnames onto Kerberos Realms:: -* Ports for the KDC and Admin Services:: -* Slave KDCs:: -* Hostnames for the Master and Slave KDCs:: -* Database Propagation:: -@end menu - -@node Kerberos Realms, Mapping Hostnames onto Kerberos Realms, Realm Configuration Decisions, Realm Configuration Decisions -@section Kerberos Realms - -Although your Kerberos realm can be any ASCII string, convention is to -make it the same as your domain name, in upper-case letters. For -example, hosts in the domain @value{SECONDDOMAIN} would be in the -Kerberos realm @value{SECONDREALM}. - -If you need multiple Kerberos realms, @value{COMPANY} recommends that -you use descriptive names which end with your domain name, such as -BOSTON.@value{SECONDREALM} and HOUSTON.@value{SECONDREALM}. - -@node Mapping Hostnames onto Kerberos Realms, Ports for the KDC and Admin Services, Kerberos Realms, Realm Configuration Decisions -@section Mapping Hostnames onto Kerberos Realms - -@include dnstxt.texinfo - -@node Ports for the KDC and Admin Services, Slave KDCs, Mapping Hostnames onto Kerberos Realms, Realm Configuration Decisions -@section Ports for the KDC and Admin Services - -The default ports used by Kerberos are port @value{DefaultPort} for the -KDC@footnote{Kerberos V4 used port @value{DefaultSecondPort}. If -necessary, you can run on both ports for backward compatibility.} and -port @value{DefaultKadmindPort} for the admin server. You can, however, -choose to run on other ports, as long as they are specified in each -host's @code{/etc/services} and @code{krb5.conf} files, and the -@code{kdc.conf} file on each KDC. For a more thorough treatment of -port numbers used by the @value{PRODUCT} programs, refer to the -``Configuring Your Firewall to Work With @value{PRODUCT}'' section of -the @cite{@value{PRODUCT} System Administrator's Guide}. - -@node Slave KDCs, Hostnames for the Master and Slave KDCs, Ports for the KDC and Admin Services, Realm Configuration Decisions -@section Slave KDCs - -Slave KDCs provide an additional source of Kerberos ticket-granting -services in the event of inaccessibility of the master KDC. The number -of slave KDCs you need and the decision of where to place them, both -physically and logically, depends on the specifics of your network. - -All of the Kerberos authentication on your network requires that each -client be able to contact a KDC. Therefore, you need to anticipate any -likely reason a KDC might be unavailable and have a slave KDC to take up -the slack. - -Some considerations include: - -@itemize @bullet -@item -Have at least one slave KDC as a backup, for when the master KDC is -down, is being upgraded, or is otherwise unavailable. - -@item -If your network is split such that a network outage is likely to cause a -network partition (some segment or segments of the network to become cut -off or isolated from other segments), have a slave KDC accessible to -each segment. - -@item -If possible, have at least one slave KDC in a different building from -the master, in case of power outages, fires, or other localized -disasters. -@end itemize - - - -@node Hostnames for the Master and Slave KDCs, Database Propagation, Slave KDCs, Realm Configuration Decisions -@section Hostnames for the Master and Slave KDCs - -@include dnssrv.texinfo - -@node Database Propagation, , Hostnames for the Master and Slave KDCs, Realm Configuration Decisions -@section Database Propagation - -The Kerberos database resides on the master KDC, and must be propagated -regularly (usually by a cron job) to the slave KDCs. In deciding how -frequently the propagation should happen, you will need to balance the -amount of time the propagation takes against the maximum reasonable -amount of time a user should have to wait for a password change to take -effect. - -If the propagation time is longer than this maximum reasonable time -(@i{e.g.,} you have a particularly large database, you have a lot of -slaves, or you experience frequent network delays), you may wish to -cut down on your propagation delay by performing the propagation in -parallel. To do this, have the master KDC propagate the database to one -set of slaves, and then have each of these slaves propagate the database -to additional slaves. - -@node Building Kerberos V5, Installing Kerberos V5, Realm Configuration Decisions, Top -@chapter Building @value{PRODUCT} - -@include build.texinfo - -@node Installing Kerberos V5, Upgrading Existing Kerberos V5 Installations, Building Kerberos V5, Top -@chapter Installing @value{PRODUCT} - -The sections of this chapter describe procedures for installing -@value{PRODUCT} on: - -@enumerate -@item -The KDCs - -@item -UNIX client machines - -@item -UNIX Application Servers -@end enumerate - -@menu -* Installing KDCs:: -* Installing and Configuring UNIX Client Machines:: -* UNIX Application Servers:: -@end menu - -@node Installing KDCs, Installing and Configuring UNIX Client Machines, Installing Kerberos V5, Installing Kerberos V5 -@section Installing KDCs - -The Key Distribution Centers (KDCs) issue Kerberos tickets. Each KDC -contains a copy of the Kerberos database. The master KDC contains the -master copy of the database, which it propagates to the slave KDCs at -regular intervals. All database changes (such as password changes) are -made on the master KDC. - -Slave KDCs provide Kerberos ticket-granting services, but not database -administration. This allows clients to continue to obtain tickets when -the master KDC is unavailable. - -@value{COMPANY} recommends that you install all of your KDCs to be able -to function as either the master or one of the slaves. This will enable -you to easily switch your master KDC with one of the slaves if -necessary. (@xref{Switching Master and Slave KDCs}.) This installation -procedure is based on that recommendation. - -@menu -* Install the Master KDC:: -* Install the Slave KDCs:: -* Back on the Master KDC:: -* Finish Installing the Slave KDCs:: -* Add Kerberos Principals to the Database:: -* Limit Access to the KDCs:: -* Switching Master and Slave KDCs:: -@end menu - -@node Install the Master KDC, Install the Slave KDCs, Installing KDCs, Installing KDCs -@subsection Install the Master KDC - -This installation procedure will require you to go back and forth a -couple of times between the master KDC and each of the slave KDCs. The -first few steps must be done on the master KDC. - -@menu -* Edit the Configuration Files:: -* krb5.conf:: -* kdc.conf:: -* Create the Database:: -* Add Administrators to the Acl File:: -* Add Administrators to the Kerberos Database:: -* Create a kadmind Keytab:: -* Start the Kerberos Daemons:: -@end menu - -@node Edit the Configuration Files, krb5.conf, Install the Master KDC, Install the Master KDC -@subsubsection Edit the Configuration Files - -Modify the configuration files, @code{/etc/krb5.conf} and -@code{@value{ROOTDIR}/var/krb5kdc/kdc.conf} to reflect the correct -information (such as the hostnames and realm name) for your realm. -@value{COMPANY} recommends that you keep @code{krb5.conf} in @code{/etc}. - -Most of the tags in the configuration have default values that will -work well for most sites. There are some tags in the @code{krb5.conf} -file whose values must be specified, and this section will explain -those as well as give an overview of all of the sections in both -configuration files. For more information on changing defaults with -the configuration files, see the @value{PRODUCT} System Administrator's -Guide sections on configuration files. - -@node krb5.conf, kdc.conf, Edit the Configuration Files, Install the Master KDC -@subsubsection krb5.conf - -@include krb5conf.texinfo - -If you are not using DNS TXT records, you must specify the -@code{default_realm} in the @code{libdefaults} section. If you are not -using DNS SRV records, you must include the @code{kdc} tag for each -realm in the @code{realms} section. To communicate with the kadmin -server in each realm, the @code{admin_server} tag must be set in the -@code{realms} section. If your domain name and realm name are not the -same, you must provide a translation in @code{domain_realm}. It is -also higly recommeneded that you create a @code{[logging]} stanza if -the computer will be functioning as a KDC so that the KDC and kadmind -will generate logging output. - -An example @code{krb5.conf} file: - -@smallexample -@group -[libdefaults] - default_realm = @value{PRIMARYREALM} - -[realms] - @value{PRIMARYREALM} = @{ - kdc = @value{KDCSERVER}.@value{PRIMARYDOMAIN} - kdc = @value{KDCSLAVE1}.@value{PRIMARYDOMAIN} - kdc = @value{KDCSLAVE2}.@value{PRIMARYDOMAIN} - admin_server = @value{KDCSERVER}.@value{PRIMARYDOMAIN} - @{ - -[logging] - kdc = FILE:/var/log/krb5kdc.log - admin_server = FILE:/var/log/kadmin.log - default = FILE:/var/log/krb5lib.log -@end group -@end smallexample - -@node kdc.conf, Create the Database, krb5.conf, Install the Master KDC -@subsubsection kdc.conf - -@include kdcconf.texinfo - -@node Create the Database, Add Administrators to the Acl File, kdc.conf, Install the Master KDC -@subsubsection Create the Database - -You will use the @code{kdb5_util} command @emph{on the Master KDC} to -create the Kerberos database and the optional stash file. The -@dfn{stash file} is a local copy of the master key that resides in -encrypted form on the KDC's local disk. The stash file is used to -authenticate the KDC to itself automatically before starting the -@code{kadmind} and @code{krb5kdc} daemons (@i{e.g.,} as part of the -machine's boot sequence). The stash file, like the keytab file -(see @xref{The Keytab File}, for more information) is a potential -point-of-entry for a break-in, -and if compromised, would allow unrestricted access to the Kerberos -database. If you choose to install a stash file, it should be readable -only by root, and should exist only on the KDC's local disk. The file -should not be part of any backup of the machine, unless access to the -backup data is secured as tightly as access to the master password -itself. - -Note that @code{kdb5_util} will prompt you for the master key for the -Kerberos database. This key can be any string. A good key is one you -can remember, but that no one else can guess. Examples of bad keys are -words that can be found in a dictionary, any common or popular name, -especially a famous person (or cartoon character), your username in any -form (@i{e.g.}, forward, backward, repeated twice, @i{etc.}), and any of -the sample keys that appear in this manual. One example of a key which -might be good if it did not appear in this manual is ``MITiys4K5!'', -which represents the sentence ``MIT is your source for Kerberos 5!'' -(It's the first letter of each word, substituting the numeral ``4'' for -the word ``for'', and includes the punctuation mark at the end.) - -The following is an example of how to create a Kerberos database and -stash file on the master KDC, using the @code{kdb5_util} command. (The -line that begins with @result{} is a continuation of the previous line.) -Replace @i{@value{PRIMARYREALM}} with the name of your Kerberos realm. - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kdb5_util create -r @value{PRIMARYREALM} -s -@b{Initializing database '@value{ROOTDIR}/var/krb5kdc/principal' for -@result{} realm '@value{PRIMARYREALM}', -master key name 'K/M@@@value{PRIMARYREALM}' -You will be prompted for the database Master Password. -It is important that you NOT FORGET this password.} -@iftex -@b{Enter KDC database master key:} @i{@doubleleftarrow{} Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter KDC database master key:} @i{<= Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{<= Type it again.} -@end ifinfo -@ifhtml -@b{Enter KDC database master key:} @i{<= Type the master password.} -@b{Re-enter KDC database master key to verify:} @i{<= Type it again.} -@end ifhtml -@b{shell%} -@end group -@end smallexample - -This will create five files in the directory specified in your -@code{kdc.conf} file: two Kerberos database files, @code{principal.db}, -and @code{principal.ok}; the Kerberos administrative database file, -@code{principal.kadm5}; the administrative database lock file, -@code{principal.kadm5.lock}; and the stash file, @code{.k5stash}. (The -default directory is @code{@value{ROOTDIR}/var/krb5kdc}.) If you do not -want a stash file, run the above command without the @code{-s} option. - -@node Add Administrators to the Acl File, Add Administrators to the Kerberos Database, Create the Database, Install the Master KDC -@subsubsection Add Administrators to the Acl File - -Next, you need create an Access Control List (acl) file, and put the -Kerberos principal of at least one of the administrators into it. The -filename should match the value you have set for ``acl_file'' in your -@code{kdc.conf} file. The default file name is -@samp{@value{DefaultAclFile}}. - -@include kadm5acl.texinfo - -@node Add Administrators to the Kerberos Database, Create a kadmind Keytab, Add Administrators to the Acl File, Install the Master KDC -@subsubsection Add Administrators to the Kerberos Database - -Next you need to add administrative principals to the Kerberos database. -(You must add at least one now.) To do this, use @code{kadmin.local} -@emph{on the master KDC}. The administrative principals you create -should be the ones you added to the ACL file. (See @xref{Add -Administrators to the Acl File}.) In the following example, the -administration principal @code{admin/admin} is created: - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kadmin.local -@b{kadmin.local:} addprinc admin/admin@@@value{PRIMARYREALM} -@b{NOTICE: no policy specified for "admin/admin@@@value{PRIMARYREALM}"; -assigning "default".} -@iftex -@b{Enter password for principal admin/admin@@@value{PRIMARYREALM}:} @i{@doubleleftarrow{} Enter a password.} -Re-enter password for principal admin/admin@@@value{PRIMARYREALM}: @i{@doubleleftarrow{} Type it again.} -@end iftex -@ifinfo -@b{Enter password for principal admin/admin@@@value{PRIMARYREALM}:} @i{<= Enter a password.} -Re-enter password for principal admin/admin@@@value{PRIMARYREALM}: @i{<= Type it again.} -@end ifinfo -@ifhtml -@b{Enter password for principal admin/admin@@@value{PRIMARYREALM}:} @i{<= Enter a password.} -Re-enter password for principal admin/admin@@@value{PRIMARYREALM}: @i{<= Type it again.} -@end ifhtml -@b{Principal "admin/admin@@@value{PRIMARYREALM}" created. -kadmin.local:} -@end group -@end smallexample - - - -@node Create a kadmind Keytab, Start the Kerberos Daemons, Add Administrators to the Kerberos Database, Install the Master KDC -@subsubsection Create a kadmind Keytab - -The kadmind keytab is the key that kadmind will use to decrypt -administrators' Kerberos tickets to determine whether or not it should -give them access to the database. You need to create the kadmin keytab -with entries for the principals @code{kadmin/admin} and -@code{kadmin/changepw}. (These principals are placed in the Kerberos -database automatically when you create it.) To create the kadmin -keytab, run @code{kadmin.local} and use the @code{ktadd} command, as in -the following example. (The line beginning with @result{} is a -continuation of the previous line.): - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kadmin.local -@b{kadmin.local:} ktadd -k @value{ROOTDIR}/var/krb5kdc/kadm5.keytab -@result{} kadmin/admin kadmin/changepw -@b{ Entry for principal kadmin/admin with kvno 5, encryption - type Triple DES cbc mode with HMAC/sha1 added to keytab - WRFILE:/usr/local/var/krb5kdc/kadm5.keytab. -Entry for principal kadmin/admin with kvno 5, encryption type DES cbc mode - with CRC-32 added to keytab - WRFILE:/usr/local/var/krb5kdc/kadm5.keytab. -Entry for principal kadmin/changepw with kvno 5, encryption - type Triple DES cbc mode with HMAC/sha1 added to keytab - WRFILE:/usr/local/var/krb5kdc/kadm5.keytab. -Entry for principal kadmin/changepw with kvno 5, - encryption type DES cbc mode with CRC-32 added to keytab - WRFILE:/usr/local/var/krb5kdc/kadm5.keytab. -kadmin.local:} quit -@b{shell%} -@end group -@end smallexample - -@noindent -As specified in the @samp{-k} argument, @code{ktadd} will save the -extracted keytab as @* @code{@value{ROOTDIR}/var/krb5kdc/kadm5.keytab}. -The filename you use must be the one specified in your @code{kdc.conf} -file. - -@need 2000 -@node Start the Kerberos Daemons, , Create a kadmind Keytab, Install the Master KDC -@subsubsection Start the Kerberos Daemons on the Master KDC - -At this point, you are ready to start the Kerberos daemons on the Master -KDC. To do so, type: - -@smallexample -@b{shell%} @value{ROOTDIR}/sbin/krb5kdc -@b{shell%} @value{ROOTDIR}/sbin/kadmind -@end smallexample - -@noindent -Each daemon will fork and run in the background. Assuming you want -these daemons to start up automatically at boot time, you can add them -to the KDC's @code{/etc/rc} or @code{/etc/inittab} file. You need to -have a stash file in order to do this. - -You can verify that they started properly by checking for their startup -messages in the logging locations you defined in @code{/etc/krb5.conf}. -(@xref{Edit the Configuration Files}.) For example: - -@smallexample -@b{shell%} tail /var/log/krb5kdc.log -Dec 02 12:35:47 beeblebrox krb5kdc[3187](info): commencing operation -@b{shell%} tail /var/log/kadmin.log -Dec 02 12:35:52 beeblebrox kadmind[3189](info): starting -@end smallexample - -Any errors the daemons encounter while starting will also be listed in -the logging output. - - -@node Install the Slave KDCs, Back on the Master KDC, Install the Master KDC, Installing KDCs -@subsection Install the Slave KDCs - -You are now ready to start configuring the slave KDCs. Assuming you are -setting the KDCs up so that you can easily switch the master KDC with -one of the slaves, you should perform each of these steps on the master -KDC as well as the slave KDCs, unless these instructions specify -otherwise. - - -@menu -* Create Host Keys for the Slave KDCs:: -* Extract Host Keytabs for the KDCs:: -* Set Up the Slave KDCs for Database Propagation:: -@end menu - -@node Create Host Keys for the Slave KDCs, Extract Host Keytabs for the KDCs, Install the Slave KDCs, Install the Slave KDCs -@subsubsection Create Host Keys for the Slave KDCs - -Each KDC needs a host principal in the Kerberos database. You can enter -these from any host, once the @code{kadmind} daemon is running. For -example, if your master KDC were called -@value{KDCSERVER}.@value{PRIMARYDOMAIN}, and you had two KDC slaves -named @value{KDCSLAVE1}.@value{PRIMARYDOMAIN} and -@value{KDCSLAVE2}.@value{PRIMARYDOMAIN}, you would type the following: - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kadmin -@b{kadmin:} addprinc -randkey host/@value{KDCSERVER}.@value{PRIMARYDOMAIN} -@b{NOTICE: no policy specified for "host/@value{KDCSERVER}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}"; -assigning "default" -Principal "host/@value{KDCSERVER}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}" created. -kadmin:} addprinc -randkey host/@value{KDCSLAVE1}.@value{PRIMARYDOMAIN} -@b{NOTICE: no policy specified for "host/@value{KDCSLAVE1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}"; -assigning "default" -Principal "host/@value{KDCSLAVE1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}" created.} -@b{kadmin:} addprinc -randkey host/@value{KDCSLAVE2}.@value{PRIMARYDOMAIN} -@b{NOTICE: no policy specified for "host/@value{KDCSLAVE2}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}"; -assigning "default" -Principal "host/@value{KDCSLAVE2}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}" created. -kadmin:} -@end group -@end smallexample - -@noindent -It is not actually necessary to have the master KDC server in the -Kerberos database, but it can be handy if: - -@itemize @bullet -@item -anyone will be logging into the machine as something other than root - -@item -you want to be able to swap the master KDC with one of the slaves if -necessary. -@end itemize - -@node Extract Host Keytabs for the KDCs, Set Up the Slave KDCs for Database Propagation, Create Host Keys for the Slave KDCs, Install the Slave KDCs -@subsubsection Extract Host Keytabs for the KDCs - -Each KDC (including the master) needs a keytab to decrypt tickets. -Ideally, you should extract each keytab locally on its own KDC. If this -is not feasible, you should use an encrypted session to send them across -the network. To extract a keytab on a KDC called -@value{KDCSERVER}.@value{PRIMARYDOMAIN}, you would execute the following -command: - -@smallexample -@group -@b{kadmin:} ktadd host/@value{KDCSERVER}.@value{PRIMARYDOMAIN} -@b{kadmin: Entry for principal host/@value{KDCSERVER}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} with - kvno 1, encryption type DES-CBC-CRC added to keytab - WRFILE:/etc/krb5.keytab. -kadmin:} -@end group -@end smallexample - -@noindent -Note that the principal must exist in the Kerberos database in order to -extract the keytab. - -@node Set Up the Slave KDCs for Database Propagation, , Extract Host Keytabs for the KDCs, Install the Slave KDCs -@subsubsection Set Up the Slave KDCs for Database Propagation - -The database is propagated from the master KDC to the slave KDCs via the -@code{kpropd} daemon. To set up propagation, create a file on each KDC, -named @code{@value{ROOTDIR}/var/krb5kdc/kpropd.acl}, containing the -principals for each of the KDCs. -@need 1200 -For example, if the master KDC were -@code{@value{KDCSERVER}.@value{PRIMARYDOMAIN}}, the slave KDCs were -@code{@value{KDCSLAVE1}.@value{PRIMARYDOMAIN}} and -@code{@value{KDCSLAVE2}.@value{PRIMARYDOMAIN}}, and the realm were -@code{@value{PRIMARYREALM}}, then the file's contents would be: - -@smallexample -@group -host/@value{KDCSERVER}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -host/@value{KDCSLAVE1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -host/@value{KDCSLAVE2}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} -@end group -@end smallexample - -@need 1000 -Then, add the following lines to @code{/etc/inetd.conf} file on each KDC -(the line beginnng with @result{} is a continuation of the previous -line): - -@smallexample -@group -krb5_prop stream tcp nowait root @value{ROOTDIR}/sbin/kpropd kpropd -eklogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -k -c -e -@end group -@end smallexample - -@noindent -The first line sets up the @code{kpropd} database propagation daemon. -The second line sets up the @code{eklogin} daemon, allowing -Kerberos-authenticated, encrypted rlogin to the KDC. - -You also need to add the following lines to @code{/etc/services} on each -KDC: - -@smallexample -@group -kerberos 88/udp kdc # Kerberos authentication (udp) -kerberos 88/tcp kdc # Kerberos authentication (tcp) -krb5_prop 754/tcp # Kerberos slave propagation -kerberos-adm 749/tcp # Kerberos 5 admin/changepw (tcp) -kerberos-adm 749/udp # Kerberos 5 admin/changepw (udp) -eklogin 2105/tcp # Kerberos encrypted rlogin -@end group -@end smallexample - -@node Back on the Master KDC, Finish Installing the Slave KDCs, Install the Slave KDCs, Installing KDCs -@subsection Back on the Master KDC - -Now that the slave KDCs are able to accept database propagation, you'll -need to propagate the database to each of them. - -@menu -* Propagate the Database to Each Slave KDC:: -@end menu - -@node Propagate the Database to Each Slave KDC, , Back on the Master KDC, Back on the Master KDC -@subsubsection Propagate the Database to Each Slave KDC - -First, create a dump of the database on the master KDC, as follows: - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/kdb5_util dump @value{ROOTDIR}/var/krb5kdc/slave_datatrans -@b{shell%} -@end group -@end smallexample - -Next, you need to manually propagate the database to each slave KDC, as -in the following example. (The lines beginning with @result{} are -continuations of the previous line.): - -@smallexample -@group -@value{ROOTDIR}/sbin/kprop -f @value{ROOTDIR}/var/krb5kdc/slave_datatrans -@result{} @value{KDCSLAVE1}.@value{PRIMARYDOMAIN} -@value{ROOTDIR}/sbin/kprop -f @value{ROOTDIR}/var/krb5kdc/slave_datatrans -@result{} @value{KDCSLAVE2}.@value{PRIMARYDOMAIN} -@end group -@end smallexample - -You will need a script to dump and propagate the database. The -following is an example of a bourne shell script that will do this. -(Note that the line that begins with @result{} is a continuation of the -previous line. Remember that you need to replace @value{ROOTDIR} with -the name of the directory in which you installed @value{PRODUCT}.) - -@smallexample -@group -#!/bin/sh - -kdclist = "@value{KDCSLAVE1}.@value{PRIMARYDOMAIN} @value{KDCSLAVE2}.@value{PRIMARYDOMAIN}" - -@value{ROOTDIR}/sbin/kdb5_util -R "dump -@result{} @value{ROOTDIR}/var/krb5kdc/slave_datatrans" - -for kdc in $kdclist -do -@value{ROOTDIR}/sbin/kprop -f @value{ROOTDIR}/var/krb5kdc/slave_datatrans $kdc -done -@end group -@end smallexample - -@noindent -You will need to set up a cron job to run this script at the intervals -you decided on earlier (@xref{Database Propagation}.) - -@node Finish Installing the Slave KDCs, Add Kerberos Principals to the Database, Back on the Master KDC, Installing KDCs -@subsection Finish Installing the Slave KDCs - -Now that the slave KDCs have copies of the Kerberos database, you can -create stash files for them and start the @code{krb5kdc} daemon. - -@menu -* Create Stash Files on the Slave KDCs:: -* Start the krb5kdc Daemon on Each KDC:: -@end menu - -@node Create Stash Files on the Slave KDCs, Start the krb5kdc Daemon on Each KDC, Finish Installing the Slave KDCs, Finish Installing the Slave KDCs -@subsubsection Create Stash Files on the Slave KDCs - -Create stash files, by issuing the following commands on each slave KDC: - -@smallexample -@group -@b{shell%} kdb5_util stash -@b{kdb5_util: Cannot find/read stored master key while reading master key -kdb5_util: Warning: proceeding without master key} -@iftex -@b{Enter KDC database master key:} @i{@doubleleftarrow{} Enter the database master key.} -@end iftex -@ifinfo -@b{Enter KDC database master key:} @i{<= Enter the database master key.} -@end ifinfo -@ifhtml -@b{Enter KDC database master key:} @i{<= Enter the database master key.} -@end ifhtml -@b{shell%} -@end group -@end smallexample - -As mentioned above, the stash file is necessary for your KDCs to be able -authenticate to themselves, such as when they reboot. You could run -your KDCs without stash files, but you would then need to type in the -Kerberos database master key by hand every time you start a KDC daemon. - -@node Start the krb5kdc Daemon on Each KDC, , Create Stash Files on the Slave KDCs, Finish Installing the Slave KDCs -@subsubsection Start the krb5kdc Daemon on Each KDC - -The final step in configuing your slave KDCs is to run the KDC daemon: - -@smallexample -@group -@b{shell%} @value{ROOTDIR}/sbin/krb5kdc -@end group -@end smallexample - -As with the master KDC, you will probably want to add this command to -the KDCs' @code{/etc/rc} or @code{/etc/inittab} files, so they will -start the krb5kdc daemon automatically at boot time. - -@node Add Kerberos Principals to the Database, Limit Access to the KDCs, Finish Installing the Slave KDCs, Installing KDCs -@subsection Add Kerberos Principals to the Database - -@need 1800 -Once your KDCs are set up and running, you are ready to use -@code{kadmin} to load principals for your users, hosts, and other -services into the Kerberos database. This procedure is described fully in the -``Adding or Modifying Principals'' section of the @value{PRODUCT} System -Administrator's Guide. (@xref{Create Host Keys for the Slave KDCs}, for a -brief description.) The keytab is generated by running @code{kadmin} -and issuing the @code{ktadd} command. - -@node Limit Access to the KDCs, Switching Master and Slave KDCs, Add Kerberos Principals to the Database, Installing KDCs -@subsection Limit Access to the KDCs - -To limit the possibility that your Kerberos database could be -compromised, @value{COMPANY} recommends that each KDC be a dedicated -host, with limited access. If your KDC is also a file server, FTP -server, Web server, or even just a client machine, someone who obtained -root access through a security hole in any of those areas could gain -access to the Kerberos database. - -@need 4700 -@value{COMPANY} recommends that your KDCs use the following -@code{/etc/inetd.conf} file. (Note: each line beginning with @result{} -is a continuation of the previous line.): - -@smallexample -@group -# -# Configuration file for inetd(1M). See inetd.conf(4). -# -# To re-configure the running inetd process, edit this file, then -# send the inetd process a SIGHUP. -# -# Syntax for socket-based Internet services: -# -@result{} -# -# Syntax for TLI-based Internet services: -# -# tli -# -# Ftp and telnet are standard Internet services. -# -# This machine is a secure Kerberos Key Distribution Center (KDC). -# Services are limited. -# -# -# Time service is used for clock synchronization. -# -time stream tcp nowait root internal -time dgram udp wait root internal -# -# Limited Kerberos services -# -krb5_prop stream tcp nowait root @value{ROOTDIR}/sbin/kpropd kpropd -eklogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -5 -c -e -@end group -@end smallexample - -@node Switching Master and Slave KDCs, , Limit Access to the KDCs, Installing KDCs -@subsection Switching Master and Slave KDCs - -You may occasionally want to use one of your slave KDCs as the master. -This might happen if you are upgrading the master KDC, or if your master -KDC has a disk crash. - -Assuming you have configured all of your KDCs to be able to function as -either the master KDC or a slave KDC (as this document recommends), all -you need to do to make the changeover is: - -If the master KDC is still running, do the following on the @emph{old} -master KDC: - -@enumerate -@item -Kill the @code{kadmind} process. - -@item -Disable the cron job that propagates the database. - -@item -Run your database propagation script manually, to ensure that the slaves -all have the latest copy of the database. (@xref{Propagate the Database -to Each Slave KDC}.) If there is a need to preserve per-principal -policy information from the database, you should do a ``kdb5_util dump --ov'' in order to preserve that information and propogate that dump file -securely by some means to the slave so that its database has the correct -state of the per-principal policy information. -@end enumerate - -On the @emph{new} master KDC: - -@enumerate -@item -Create a database keytab. (@xref{Create a kadmind Keytab}.) - -@item -Start the @code{kadmind} daemon. (@xref{Start the Kerberos Daemons}.) - -@item -Set up the cron job to propagate the database. (@xref{Propagate the -Database to Each Slave KDC}.) - -@item -Switch the CNAMEs of the old and new master KDCs. (If you don't do -this, you'll need to change the @code{krb5.conf} file on every client -machine in your Kerberos realm.) - -@end enumerate - -@node Installing and Configuring UNIX Client Machines, UNIX Application Servers, Installing KDCs, Installing Kerberos V5 -@section Installing and Configuring UNIX Client Machines - -Client machine installation is much more straightforward than -installation of the KDCs. - -@menu -* Client Programs:: -* Client Machine Configuration Files:: -@end menu - -@node Client Programs, Client Machine Configuration Files, Installing and Configuring UNIX Client Machines, Installing and Configuring UNIX Client Machines -@subsection Client Programs - -The Kerberized client programs are @code{login.krb5}, @code{rlogin}, -@code{telnet}, @code{ftp}, @code{rcp}, @code{rsh}, @code{kinit}, -@code{klist}, @code{kdestroy}, @code{kpasswd}, @code{ksu}, and -@code{krb524init}. All of these programs are in the directory -@code{@value{ROOTDIR}/bin}, except for @code{login.krb5} which is in -@code{@value{ROOTDIR}/sbin}. - -You will probably want to have your users put @code{@value{ROOTDIR}/bin} -ahead of @code{/bin} and @code{/usr/bin} in their paths, so they will by -default get the @value{PRODUCT} versions of @code{rlogin}, -@code{telnet}, @code{ftp}, @code{rcp}, and @code{rsh}. - -@value{COMPANY} recommends that you use @code{login.krb5} in place of -@code{/bin/login} to give your users a single-sign-on system. You will -need to make sure your users know to use their Kerberos passwords when -they log in. - -You will also need to educate your users to use the ticket management -programs @code{kinit}, -@c @code{krb524init}, -@code{klist}, @code{kdestroy}, and to use the Kerberos programs -@c @code{pfrom}, -@code{ksu}, and @code{kpasswd} in place of their non-Kerberos -counterparts -@c @code{from} -@code{su}, @code{passwd}, and @code{rdist}. - -@node Client Machine Configuration Files, , Client Programs, Installing and Configuring UNIX Client Machines -@subsection Client Machine Configuration Files - -Each machine running Kerberos must have a @code{/etc/krb5.conf} file. -(@xref{krb5.conf}.) - -@need 4000 -Also, for most UNIX systems, you must add the appropriate Kerberos -services to each client machine's @code{/etc/services} file. If you are -using the default configuration for @value{PRODUCT}, you should be able -to just insert the following code: - -@smallexample -@group -# -# Note --- if you are using Kerberos V4 and you either: -# -# (a) haven't converted all your master or slave KDCs to V5, or -# -# (b) are worried about inter-realm interoperability with other KDC's -# that are still using V4 -# -# you will need to switch the "kerberos" service to port 750 and create a -# "kerberos-sec" service on port 88. -# -kerberos @value{DefaultPort}/udp kdc # Kerberos V5 KDC -kerberos @value{DefaultPort}/tcp kdc # Kerberos V5 KDC -klogin @value{DefaultKloginPort}/tcp # Kerberos authenticated rlogin -kshell @value{DefaultKshellPort}/tcp cmd # and remote shell -kerberos-adm @value{DefaultKamdindPort}/tcp # Kerberos 5 admin/changepw -kerberos-adm @value{DefaultKamdindPort}/udp # Kerberos 5 admin/changepw -krb5_prop @value{DefaultKrbPropPort}/tcp # Kerberos slave propagation -@c kpop 1109/tcp # Pop with Kerberos -eklogin @value{DefaultEkloginPort}/tcp # Kerberos auth. & encrypted rlogin -krb524 @value{DefaultKrb524Port}/tcp # Kerberos 5 to 4 ticket translator -@end group -@end smallexample - -@noindent As described in the comments in the above code, if your master -KDC or any of your slave KDCs is running Kerberos V4, (or if you will be -authenticating to any Kerberos V4 KDCs in another realm) you will need -to switch the port number for @code{kerberos} to 750 and create a -@code{kerberos-sec} service (tcp and udp) on port 88, so the Kerberos -V4 KDC(s) will continue to work properly. - -@menu -* Mac OS X Configuration:: -@end menu - -@node Mac OS X Configuration, , Client Machine Configuration Files, Client Machine Configuration Files -@subsubsection Mac OS X Configuration - -To install Kerberos V5 on Mac OS X and Mac OS X Server, follow the -directions for generic Unix-based OS's, except for the -@code{/etc/services} updates described above. - -Mac OS X and Mac OS X Server use a database called NetInfo to store -the contents of files normally found in @code{/etc}. Instead of -modifying @code{/etc/services}, you should run the following commands -to add the Kerberos service entries to NetInfo: - -@smallexample -@group -$ niutil -create . /services/kerberos -$ niutil -createprop . /services/kerberos name kerberos kdc -$ niutil -createprop . /services/kerberos port 750 -$ niutil -createprop . /services/kerberos protocol tcp udp -$ niutil -create . /services/krbupdate -$ niutil -createprop . /services/krbupdate name krbupdate kreg -$ niutil -createprop . /services/krbupdate port 760 -$ niutil -createprop . /services/krbupdate protocol tcp -$ niutil -create . /services/kpasswd -$ niutil -createprop . /services/kpasswd name kpasswd kpwd -$ niutil -createprop . /services/kpasswd port 761 -$ niutil -createprop . /services/kpasswd protocol tcp -$ niutil -create . /services/klogin -$ niutil -createprop . /services/klogin port 543 -$ niutil -createprop . /services/klogin protocol tcp -$ niutil -create . /services/eklogin -$ niutil -createprop . /services/eklogin port 2105 -$ niutil -createprop . /services/eklogin protocol tcp -$ niutil -create . /services/kshell -$ niutil -createprop . /services/kshell name kshell krcmd -$ niutil -createprop . /services/kshell port 544 -$ niutil -createprop . /services/kshell protocol tcp -@end group -@end smallexample - -In addition to adding services to NetInfo, you must also modify the -resolver configuration in NetInfo so that the machine resolves its own -hostname as a FQDN (fully qualified domain name). By default, Mac OS X -and Mac OS X Server machines query NetInfo to resolve hostnames before -falling back to DNS. Because NetInfo has an unqualified name for all -the machines in the NetInfo database, the machine's own hostname will -resolve to an unqualified name. Kerberos needs a FQDN to look up keys -in the machine's keytab file. - -Fortunately, you can change the @code{lookupd} caching order to query -DNS first. Run the following NetInfo commands and reboot the machine: - -@smallexample -@group -$ niutil -create . /locations/lookupd/hosts -$ niutil -createprop . /locations/lookupd/hosts LookupOrder CacheAgent DNSAgent - NIAgent NILAgent -@end group -@end smallexample - -Once you have rebooted, you can verify that the resolver now behaves -correctly. Compile the Kerberos 5 distribution and run: - -@smallexample -@group -$ cd .../src/tests/resolve -$ ./resolve -@end group -@end smallexample - -This will tell you whether or not your machine returns FQDNs on name -lookups. If the test still fails, you can also try turning off DNS -caching. Run the following commands and reboot: - -@smallexample -@group -$ niutil -create . /locations/lookupd/hosts -$ niutil -createprop . /locations/lookupd/hosts LookupOrder DNSAgent - CacheAgent NIAgent NILAgent -@end group -@end smallexample - -The remainder of the setup of a Mac OS X client machine or application -server should be the same as for other UNIX-based systems. - -@node UNIX Application Servers, , Installing and Configuring UNIX Client Machines, Installing Kerberos V5 -@section UNIX Application Servers - -An application server is a host that provides one or more services over -the network. Application servers can be ``secure'' or ``insecure.'' A -``secure'' host is set up to require authentication from every client -connecting to it. An ``insecure'' host will still provide Kerberos -authentication, but will also allow unauthenticated clients to connect. - -If you have @value{PRODUCT} installed on all of your client machines, -@value{COMPANY} recommends that you make your hosts secure, to take -advantage of the security that Kerberos authentication affords. -However, if you have some clients that do not have @value{PRODUCT} -installed, you can run an insecure server, and still take advantage of -@value{PRODUCT}'s single sign-on capability. - -@menu -* Server Programs:: -* Server Configuration Files:: -* The Keytab File:: -* Some Advice about Secure Hosts:: -@end menu - -@node Server Programs, Server Configuration Files, UNIX Application Servers, UNIX Application Servers -@subsection Server Programs - -Just as @value{PRODUCT} provided its own Kerberos-enhanced versions of -client UNIX network programs, @value{PRODUCT} also provides -Kerberos-enhanced versions of server UNIX network daemons. These are -@code{ftpd}, @code{klogind}, @code{kshd}, and @code{telnetd}. -@c @code{popper}, -These programs are installed in the directory -@code{@value{ROOTDIR}/sbin}. You may want to add this directory to -root's path. - -@node Server Configuration Files, The Keytab File, Server Programs, UNIX Application Servers -@subsection Server Configuration Files - -For a @emph{secure} server, make the following changes to -@code{/etc/inetd.conf}: - -Find and comment out any lines for the services @code{ftp}, -@code{telnet}, @code{shell}, @code{login}, and @code{exec}. - -@need 1800 -Add the following lines. (Note: each line beginning with @result{} is -a continuation of the previous line.) - -@smallexample -@group -klogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -k -c -eklogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -k -c -e -kshell stream tcp nowait root @value{ROOTDIR}/sbin/kshd -@result{} kshd -k -c -A -ftp stream tcp nowait root @value{ROOTDIR}/sbin/ftpd -@result{} ftpd -a -telnet stream tcp nowait root @value{ROOTDIR}/sbin/telnetd -@result{} telnetd -a valid -@end group -@end smallexample - -For an @emph{insecure} server, make the following changes instead to -@code{/etc/inetd.conf}: - -@need 1800 -Find and comment out any lines for the services @code{ftp} and -@code{telnet}. - -Add the following lines. (Note: each line beginning with @result{} is -a continuation of the previous line.) -@smallexample -@group -klogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -k -c -eklogin stream tcp nowait root @value{ROOTDIR}/sbin/klogind -@result{} klogind -k -c -e -kshell stream tcp nowait root @value{ROOTDIR}/sbin/kshd -@result{} kshd -k -c -A -ftp stream tcp nowait root @value{ROOTDIR}/sbin/ftpd -@result{} ftpd -telnet stream tcp nowait root @value{ROOTDIR}/sbin/telnetd -@result{} telnetd -a none -@end group -@end smallexample - -@node The Keytab File, Some Advice about Secure Hosts, Server Configuration Files, UNIX Application Servers -@subsection The Keytab File - -All Kerberos server machines need a @dfn{keytab} file, called -@code{/etc/krb5.keytab}, to authenticate to the KDC. The keytab file is -an encrypted, local, on-disk copy of the host's key. The keytab file, -like the stash file (@ref{Create the Database}) is a potential -point-of-entry for a break-in, and if compromised, would allow -unrestricted access to its host. The keytab file should be readable -only by root, and should exist only on the machine's local disk. The -file should not be part of any backup of the machine, unless access to -the backup data is secured as tightly as access to the machine's root -password itself. - -In order to generate a keytab for a host, the host must have a principal -in the Kerberos database. The procedure for adding hosts to the -database is described fully in the ``Adding or Modifying Principals'' -section of the @cite{@value{PRODUCT} System Administrator's Guide}. -@xref{Create Host Keys for the Slave KDCs}. for a brief description.) -The keytab is generated by running @code{kadmin} and issuing the -@code{ktadd} command. - -@need 1100 -For example, to generate a keytab file to allow the host -trillium.@value{PRIMARYDOMAIN} to authenticate for the services -@code{host}, @code{ftp}, and @code{pop}, the administrator -@code{@value{ADMINUSER}} would issue the command (on -trillium.@value{PRIMARYDOMAIN}): - -@smallexample -@group -@b{trillium%} @value{ROOTDIR}/sbin/kadmin -@b{kadmin5:} ktadd host/trillium.@value{PRIMARYDOMAIN} ftp/trillium.@value{PRIMARYDOMAIN} -@result{} pop/trillium.@value{PRIMARYDOMAIN} -@b{kadmin: Entry for principal host/trillium.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} with -kvno 3, encryption type DES-CBC-CRC added to keytab -WRFILE:/etc/krb5.keytab. -kadmin: Entry for principal ftp/trillium.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} with -kvno 3, encryption type DES-CBC-CRC added to keytab -WRFILE:/etc/krb5.keytab. -kadmin: Entry for principal pop/trillium.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM} with -kvno 3, encryption type DES-CBC-CRC added to keytab -WRFILE:/etc/krb5.keytab. -kadmin5:} quit -@b{trillium%} -@end group -@end smallexample - -If you generate the keytab file on another host, you need to get a copy -of the keytab file onto the destination host (@code{trillium}, in the -above example) without sending it unencrypted over the network. If you -have installed the @value{PRODUCT} client programs, you can use -encrypted @code{rcp}. - -@node Some Advice about Secure Hosts, , The Keytab File, UNIX Application Servers -@subsection Some Advice about Secure Hosts - -@value{PRODUCT} can protect your host from certain types of break-ins, -but it is possible to install @value{PRODUCT} and still leave your host -vulnerable to attack. Obviously an installation guide is not the place -to try to include an exhaustive list of countermeasures for every -possible attack, but it is worth noting some of the larger holes and how -to close them. - -As stated earlier in this section, @value{COMPANY} recommends that on a -secure host, you disable the standard @code{ftp}, @code{login}, -@code{telnet}, @code{shell}, and @code{exec} services in -@code{/etc/inetd.conf}. We also recommend that secure hosts have an empty -@code{/etc/hosts.equiv} file and that there not be a @code{.rhosts} file -in @code{root}'s home directory. You can grant Kerberos-authenticated -root access to specific Kerberos principals by placing those principals -in the file @code{.k5login} in root's home directory. - -We recommend that backups of secure machines exclude the keytab file -(@code{/etc/krb5.keytab}). If this is not possible, the backups should -at least be done locally, rather than over a network, and the backup -tapes should be physically secured. - -Finally, the keytab file and any programs run by root, including the -@value{PRODUCT} binaries, should be kept on local disk. The keytab file -should be readable only by root. - -@node Upgrading Existing Kerberos V5 Installations, Bug Reports for Kerberos V5, Installing Kerberos V5, Top -@chapter Upgrading Existing @value{PRODUCT} Installations - -If you already have an existing Kerberos database that you created with -a prior release of Kerberos 5, you can upgrade it to work with the -current release with the @code{kdb5_util} command. It is only -necessary to perform this dump/undump procedure if you were running a -krb5-1.0.x KDC and are migrating to a krb5-1.1.x or newer KDC or if you -were running a krb5-1.1.x KDC and are migrating to a krb5-1.2.x or newer -KDC. The process for upgrading a Master KDC involves the following -steps: - -@enumerate - -@item Stop your current KDC and administration -server processes, if any. - -@item Dump your existing Kerberos database to an ASCII file with -@code{kdb5_util}'s ``dump'' command: - -@smallexample -@group -@b{shell%} cd @value{ROOTDIR}/var/krb5kdc -@b{shell%} kdb5_util dump old-kdb-dump -@b{shell%} kdb5_util dump -ov old-kdb-dump.ov -@b{shell%} -@end group -@end smallexample - -@item Create a new Master KDC installation (@xref{Install the Master -KDC}.). If you have a stash file for your current database, choose any -new master password but then copy your existing stash file to the -location specified by your kdc.conf; if you do not have a stash file for -your current database, you must choose the same master password. - -@item Load your old Kerberos database into the new system with -@code{kdb5_util}'s ``load'' command: - -@smallexample -@group -@b{shell%} cd @value{ROOTDIR}/var/krb5kdc -@b{shell%} kdb5_util load old-kdb-dump -@b{shell%} kdb5_util load -update old-kdb-dump.ov -@b{shell%} -@end group -@end smallexample - -@end enumerate - -The ``dump -ov'' and ``load -update'' commands are necessary in order to -preserve per-principal policy information, since the default dump format -filters out that information. If you omit those steps, the loaded -database database will lose the policy information for each principal -that has a policy. - -To update a Slave KDC, you must stop the old server processes on the -Slave KDC, install the new server binaries, reload the most recent slave -dump file, and re-start the server processes. - -@menu -* Upgrading to Triple-DES and RC4 Encryption Keys:: -@end menu - -@node Upgrading to Triple-DES and RC4 Encryption Keys, , Upgrading Existing Kerberos V5 Installations, Upgrading Existing Kerberos V5 Installations -@section Upgrading to Triple-DES Encryption Keys - -Beginning with the 1.2 release from @value{COMPANY}, Kerberos includes -a stronger encryption algorithm called ``triple DES'' -- essentially, -three applications of the basic DES encryption algorithm, greatly -increasing the resistance to a brute-force search for the key by an -attacker. This algorithm is more secure, but encryption is much -slower. - -Release 1.1 had some support for triple-DES service keys, but with -release 1.2 we have added support for user keys and session keys as -well. Release 1.0 had very little support for multiple cryptosystems, -and some of that software may not function properly in an environment -using triple-DES as well as plain DES. - -In the 1.3 release from @value{COMPANY}, Kerberos also includes the RC4 -encryption alogorithm, a stream cipher symmetric key algorithm -developed in 1987 by Ronald Rivest at RSA Data Security. Please note -that RC4 is not part of the IETF standard. - -Because of the way the MIT Kerberos database is structured, the KDC -will assume that a service supports only those encryption types for -which keys are found in the database. Thus, if a service has only a -single-DES key in the database, the KDC will not issue tickets for that -service that use triple-DES or RC4 session keys; it will instead issue -only single-DES session keys, even if other services are already -capable of using triple-DES or RC4. So if you make sure your -application server software is updated before adding a triple-DES or -RC4 key for the service, clients should be able to talk to services at -all times during the updating process. - -Normally, the listed @code{supported_enctypes} in @code{kdc.conf} are -all used when a new key is generated. You can control this with -command-line flags to @code{kadmin} and @code{kadmin.local}. You may -want to exclude triple-DES and RC4 by default until you have updated a -lot of your application servers, and then change the default to include -triple-DES and RC4. We recommend that you always include -@code{des-cbc-crc} in the default list. - -@node Bug Reports for Kerberos V5, , Upgrading Existing Kerberos V5 Installations, Top -@chapter Bug Reports for @value{PRODUCT} - -@include send-pr.texinfo - -@contents -@bye diff --git a/doc/kadm5/adb-unit-test.tex b/doc/kadm5/adb-unit-test.tex deleted file mode 100644 index 7016e0024..000000000 --- a/doc/kadm5/adb-unit-test.tex +++ /dev/null @@ -1,134 +0,0 @@ -\documentstyle[times,fullpage,rcsid]{article} - -\rcs$Header$ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcommand{\test}[1]{\begin{description} -\setlength{\itemsep}{0pt} -#1 -\end{description} - -} - -\newcommand{\numtest}[2]{\begin{description} -\setlength{\itemsep}{0pt} -\Number{#1} -#2 -\end{description} - -} - -\newcommand{\Number}[1]{\item[Number:] #1} -\newcommand{\Reason}[1]{\item[Reason:] #1} -%\newcommand{\Call}[1]{\item[Call:] #1} -\newcommand{\Expected}[1]{\item[Expected:] #1} -\newcommand{\Conditions}[1]{\item[Conditions:] #1} -\newcommand{\Priority}[1]{\item[Priority:] #1} -\newcommand{\Status}[1]{\item[Status:] #1} -%\newcommand{\Number}[1]{} -%\newcommand{\Reason}[1]{} -\newcommand{\Call}[1]{} -%\newcommand{\Expected}[1]{} -%\newcommand{\Conditions}[1]{} -%\newcommand{\Priority}[1]{} - -\title{OpenV*Secure Admin Database API\\ -Unit Test Description\footnote{\rcsHeader}} -\author{Jonathan I. Kamens} - -\begin{document} - -\maketitle - -%\tableofcontents - -\section{Introduction} - -The following is a description of a black-box unit test of the -OpenV*Secure Admin Database API (osa_adb). Each API function is -listed, followed by the tests that shoud be performed on it. - -The tests described here are based on the ``OV*Secure Admin Server -Implementation Design'' revision 1.14. - -\section{osa_adb_get_lock and osa_adb_release_lock} - -\numtest{1}{ -\Reason{A shared lock can be acquired.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{An exclusive lock can be acquired and released.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{A permanent lock can be acquired and released.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Attempting to release a lock when none is held fails with -NOTLOCKED.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Two processes can both acquire a shared lock.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{An attempt to acquire a shared lock while another process holds an -exclusive lock fails with CANTLOCK_DB.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{An attempt to acquire an exclusive lock while another process holds a -shared lock fails with CANTLOCK_DB.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{An attempt to open the database while a process holds a -permanent lock fails with NO_LOCKFILE.} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{An attempt to acquire an exclusive lock while a process holds a -permanent lock fails with NO_LOCKFILE.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Acquiring a permanent lock deletes the lockfile.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Releasing a permanent lock re-creates the lockfile.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{A process can perform a get operation while another process holds a -shared lock.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{A process that is running and has opened the adb principal database -can retrieve a principal created after the open occurred.} -\Status{Implemented, but not working} -} - -\end{document} diff --git a/doc/kadm5/api-funcspec.tex b/doc/kadm5/api-funcspec.tex deleted file mode 100644 index 626052251..000000000 --- a/doc/kadm5/api-funcspec.tex +++ /dev/null @@ -1,2015 +0,0 @@ -\documentstyle[12pt,fullpage,changebar,rcsid]{article} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\rcs$Id$ - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\v#1{\verb+#1+} - -\title{Kerberos Administration System \\ - KADM5 API Functional Specifications\thanks{\rcsId}} -\author{Barry Jaspan} - -\begin{document} - -\sloppy -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\section{Introduction} - -This document describes the Admin API that can be used to maintain -principals and policies. It describes the data structures used for -each function and the interpretation of each data type field, the -semantics of each API function, and the possible return codes. - -The Admin API is intended to be used by remote clients using an RPC -interface. It is implemented by the admin server running on the -Kerberos master server. It is also possible for a program running on -the Kerberos master server to use the Admin API directly, without -going through the admin server. - -\section{Versions of the API} - -The versions of this API and a brief description of the changes for -each are: - -\begin{description} -\item[KADM5_API_VERSION_1] The initial version of this API, written by -OpenVision Technologies and donated to MIT for including in the public -release. Originally called OVSEC_KADM_API_VERSION_1. Most everything -has been renamed in one way or another, including functions, header -files, and data structures. Where possible, the old OVSEC_KADM names -have been left behind for compatibility with version 1, and -KADM5_API_VERSION_1 is compatible with OVSEC_KADM_API_VERSION_1 at -compile-, link-, and run-time. - -The OVSEC_KADM name compatibility will not be extended to new -functionality in future versions because no existing OVSEC_KADM -clients will use that functionality; new clients should be written to -the KADM5 API. - -\item[KADM5_API_VERSION_2] This version contains the initial changes -necessary to make the OpenVision administration system work with the -mid-1996 MIT version of Kerberos 5. Changes include -\begin{enumerate} -\item The kadm5_init functions now take a structure of parameters -instead of just a realm name, allowing the calling program to specify -non-default values for various configuration options. See section -\ref{sec:configparams} for details. - -\item The KADM5 API has been extended to support new features of the -Kerberos database, including multiple encryption and salt types per -principal. See section \ref{sec:keys} for details. - -\item kadm5_get_principal now allows a principal's keys to be -retrieved {\it by local clients only}. This is necessary in order for -the kadm5 API to provide the primary Kerberos database interface. - -\item The KADM5 authorization system has been completely changed. - -\item The functions kadm5_flush, kadm5_get_principals, and -kadm5_get_policies have been added. - -\item The KADM5 API now obeys a caller-allocates rather than -callee-allocates system. kadm5_get_principal and kadm5_get_policy are -affected. -\end{enumerate} -\end{description} - -\section{Policies and Password Quality} - -The Admin API Password Quality mechanism provides the following -controls. Note that two strings are defined to be ``significantly -different'' if they differ by at least one character. The compare is not -case sensitive. - -\begin{itemize} -\item A minimum length can be required; a password with -fewer than the specified number of characters will not be accepted. - -\item A minimum number of character classes can be required; a -password that does not contain at least one character from at least -the specified number of character classes will not be accepted. The -character classes are defined by islower(), isupper(), isdigit(), -ispunct(), and other. - -\item Passwords can be required to be different from -previous passwords; a password that generates the same encryption key -as any of the principal's specified previous number of passwords will -not be accepted. This comparison is performed on the encryption keys -generated from the passwords, not on the passwords themselves. - -\item A single ``forbidden password'' dictionary can be specified for all -users; a password that is not significantly different from every word -in the dictionary will not be accepted. -\end{itemize} - -\section{Data Structures} - -This section describes the data structures used by the Admin API. -They are defined in $<$kadm5/admin.h$>$. - -\subsection{Principals, kadm5_principal_ent_t} -\label{sec:principal-structure} - -A Kerberos principal entry is represented by a kadm5_principal_ent_t. -It contains a subset of the information stored in the master Kerberos -database as well as the additional information maintained by the admin -system. In the current version, the only additional information is -the principal's policy and the aux_attributes flags. - -The principal may or may not have a policy enforced on it. If the -POLICY bit (see section \ref{sec:masks}) is set in aux_attributes, the -policy field names the principal's policy. If the POLICY bit is not -set in aux_attributes, no policy is enforced on the principal and the -value of the policy field is undefined. - -\begin{figure}[htbp] -\begin{verbatim} -typedef struct _kadm5_principal_ent_t { - krb5_principal principal; - - krb5_timestamp princ_expire_time; - krb5_timestamp last_pwd_change; - krb5_timestamp pw_expiration; - krb5_deltat max_life; - krb5_principal mod_name; - krb5_timestamp mod_date; - krb5_flags attributes; - krb5_kvno kvno; - krb5_kvno mkvno; - - char * policy; - u_int32 aux_attributes; - - krb5_deltat max_renewable_life; - krb5_timestamp last_success; - krb5_timestamp last_failed; - krb5_kvno fail_auth_count; - krb5_int16 n_key_data; - krb5_int16 n_tl_data; - krb5_tl_data *tl_data; - krb5_key_data *key_data; -} kadm5_principal_ent_rec, *kadm5_principal_ent_t; -\end{verbatim} -\caption{Definition of kadm5_principal_ent_t.} -\label{fig:princ-t} -\end{figure} - -The fields of an kadm5_principal_ent_t are interpreted as -follows. - -\begin{description} -\item[principal] The name of the principal; must conform to Kerberos -naming specifications. - -\item[princ_expire_time] The expire time of the principal as a Kerberos -timestamp. No Kerberos tickets will be issued for a principal after -its expire time. - -\item[last_pwd_change] The time this principal's password was last -changed, as a Kerberos timestamp. - -\item[pw_expiration] The expire time of the user's current password, as a -Kerberos timestamp. No application service tickets will be issued for the -principal once the password expire time has passed. Note that the user can -only obtain tickets for services that have the PW_CHANGE_SERVICE bit set in -the attributes field. - -\item[max_life] The maximum lifetime of any Kerberos ticket issued to -this principal. - -\item[attributes] A bitfield of attributes for use by the KDC. The -symbols and constant values are defined below; their interpretation -appears in the libkdb functional specification. - -\begin{tabular}{clr} -{\bf Name} & {\bf Value} \\ -KRB5_KDB_DISALLOW_POSTDATED & 0x00000001 \\ -KRB5_KDB_DISALLOW_FORWARDABLE & 0x00000002 \\ -KRB5_KDB_DISALLOW_TGT_BASED & 0x00000004 \\ -KRB5_KDB_DISALLOW_RENEWABLE & 0x00000008 \\ -KRB5_KDB_DISALLOW_PROXIABLE & 0x00000010 \\ -KRB5_KDB_DISALLOW_DUP_SKEY & 0x00000020 \\ -KRB5_KDB_DISALLOW_ALL_TIX & 0x00000040 \\ -KRB5_KDB_REQUIRES_PRE_AUTH & 0x00000080 \\ -KRB5_KDB_REQUIRES_HW_AUTH & 0x00000100 \\ -KRB5_KDB_REQUIRES_PWCHANGE & 0x00000200 \\ -KRB5_KDB_DISALLOW_SVR & 0x00001000 \\ -KRB5_KDB_PWCHANGE_SERVICE & 0x00002000 \\ -KRB5_KDB_SUPPORT_DESMD5 & 0x00004000 \\ -KRB5_KDB_NEW_PRINC & 0x00008000 -\end{tabular} - -\item[mod_name] The name of the Kerberos principal that most recently -modified this principal. - -\item[mod_date] The time this principal was last modified, as a Kerberos -timestamp. - -\item[kvno] The version of the principal's current key. - -\item[mkvno] The version of the Kerberos Master Key in effect when -this principal's key was last changed. In KADM5_API_VERSION_2, this -field is always zero. - -\item[policy] If the POLICY bit is set in aux_attributes, the name -of the policy controlling this principal. - -\item[aux_attributes] A bitfield of flags for use by the -administration system. Currently, the only valid flag is POLICY, and -it indicates whether or not the principal has a policy enforced on it. - -\item[max_renewable_life] The maximum renewable lifetime of any -Kerberos ticket issued to or for this principal. This field only -exists in KADM5_API_VERSION_2. - -\item[last_success] The KDC time of the last successful AS_REQ. This -is only updated if KRBCONF_KDC_MODIFIES_KDB is defined during -compilation of the KDC. This field only exists in -KADM5_API_VERSION_2. - -\item[last_failed] The KDC time of the last failed AS_REQ. This is -only updated if KRBCONF_KDC_MODIFIES_KDB is defined during compilation -of the KDC. This field only exists in KADM5_API_VERSION_2. - -\item[fail_auth_count] The number of consecutive failed AS_REQs. When -this number reaches KRB5_MAX_FAIL_COUNT, the KRB5_KDC_DISALLOW_ALL_TIX -is set on the principal. This is only updated if -KRBCONF_KDC_MODIFIES_KDB is defined during compilation. This field -only exists in KADM5_API_VERSION_2. - -\item[n_tl_data] The number of elements in the \v{tl_data} linked -list. This field only exists in KADM5_API_VERSION_2. - -\item[n_key_data] The number of elements in the \v{key_data} -array. This field only exists in KADM5_API_VERSION_2. - -\item[tl_data] A linked list of tagged data. This list is a mechanism -by which programs can store extended information in a principal entry, -without having to modify the database API. Each element is of type -krb5_tl_data: -\begin{verbatim} -typedef struct _krb5_tl_data { - struct _krb5_tl_data* tl_data_next; - krb5_int16 tl_data_type; - krb5_int16 tl_data_length; - krb5_octet * tl_data_contents; -} krb5_tl_data; -\end{verbatim} -% -The KADM5 API only allows elements whose tl_data_type is greater than -or equal to 256. Values less than 256 are reserved for internal use -by the KADM5 or kdb system. They are filtered out of the list -returned by kadm5_get_principal, and generate an error if given to -kadm5_modify_principal. - -The libkdb library defines the tagged data types -KRB5_TL_LAST_PWD_CHANGE, KRB5_TL_MOD_PRINC, and KRB5_TL_KADM_DATA, all -with values less than 256, which store the last password modification -time, time and modifier of last principal modification, and -administration system data. All of these entries are expected by the -administration system and parsed out into fields of the -kadm5_principal_ent_rec structure; as described above, they are not -included in the tl_data list. - -Tagged data elements with types greater than 256 are handled without -interpretation by KADM5. Note that an application that calls -kadm5_modify_principal with the KADM5_TL_DATA mask bit set is -responsible for providing the {\it complete} tl_data list, which it -necessarily must obtain from kadm5_get_principal. It is {\it never} -possible for an application to construct a complete tl_data list from -scratch. - -\item[key_data] An array of the principal's keys. The keys contained -in this array are encrypted in the Kerberos master key. See section -\ref{sec:keys} for a discussion of the krb5_key_data structure. -\end{description} - -\subsection{Policies, kadm5_policy_ent_t} -\label{sec:policy-fields} - -If the POLICY bit is set in aux_attributes, the \v{policy} name field -in the kadm5_principal_ent_t structure refers to a password policy -entry defined in a \v{kadm5_policy_ent_t}. - -\begin{verbatim} -typedef struct _kadm5_policy_ent_t { - char *policy; - - u_int32 pw_min_life; - u_int32 pw_max_life; - u_int32 pw_min_length; - u_int32 pw_min_classes; - u_int32 pw_history_num; - u_int32 policy_refcnt; -} kadm5_policy_ent_rec, *kadm5_policy_ent_t; -\end{verbatim} - -The fields of an kadm5_policy_ent_t are interpreted as follows. -Note that a policy's values only apply to a principal using that -policy. - -\begin{description} -\item[policy] The name of this policy, as a NULL-terminated string. -The ASCII characters between 32 (space) and 126 (tilde), inclusive, -are legal. - -\item[pw_min_life] The minimum password lifetime, in seconds. -A principal cannot change its password before pw_min_life seconds have -passed since last_pwd_change. - -\item[pw_max_life] The default duration, in seconds, used to compute -pw_expiration when a principal's password is changed. - -\item[pw_min_length] The minimum password length, in characters. A -principal cannot set its password to anything with fewer than this -number of characters. This value must be greater than zero. - -\item[pw_min_classes] The minimum number of character classes in the -password. This value can only be 1, 2, 3, 4, or 5. A principal cannot -set its password to anything with fewer than this number of character -classes in it. - -\item[pw_history_num] The number of past passwords that are -stored for the principal; the minimum value is 1 and the maximum value -is 10. A principal cannot set its password to any of its previous -pw_history_num passwords. The first ``previous'' password is the -current password; thus, a principal with a policy can never reset its -password to its current value. - -\item[policy_refcnt] The number of principals currently using this policy. -A policy cannot be deleted unless this number is zero. -\end{description} - -\subsection{Configuration parameters} -\label{sec:configparams} - -The KADM5 API acquires configuration information from the Kerberos -configuration file (\$KRB5_CONFIG or DEFAULT_PROFILE_PATH) and from -the KDC configuration file (\$KRB5_KDC_CONFIG or DEFAULT_KDC_PROFILE). -In KADM5_API_VERSION_2, some of the configuration parameters used by -the KADM5 API can be controlled by the caller by providing a -kadm5_config_params structure to kadm5_init: -% -\begin{verbatim} -typedef struct _kadm5_config_params { - u_int32 mask; - - /* Client and server fields */ - char *realm; - char *profile; - int kadmind_port; - - /* client fields */ - char *admin_server; - - /* server fields */ - char *dbname; - char *admin_dbname; - char *admin_lockfile; - char *acl_file; - char *dict_file; - char *admin_keytab; - - /* server library (database) fields */ - int mkey_from_kbd; - char *stash_file; - char *mkey_name; - krb5_enctype enctype; - krb5_deltat max_life; - krb5_deltat max_rlife; - krb5_timestamp expiration; - krb5_flags flags; - krb5_key_salt_tuple *keysalts; - krb5_int32 num_keysalts; -} kadm5_config_params; -\end{verbatim} -% -The following list describes each of the fields of the structure, -along with the profile relation it overrides, its mask value, its -default value, and whether it is valid on the client, server, or both, -or neither. -\begin{description} -\item[mask] No variable. No mask value. A bitfield specifying which -fields of the structure contain valid information. A caller sets this -mask before calling kadm5_init_*, indicating which parameters are -specified. The mask values are defined in $<$kadm5/admin.h$>$ and are -all prefixed with KADM5_CONFIG_; the prefix is not included in the -descriptions below. - -\item[realm] No variable. REALM. Client and server. The realm to -which these parameters apply, and the realm for which additional -parameters are to be acquired, if any. If this field is not specified -in the mask, the default local realm is used. - -\item[profile] Variable: profile (server only). PROFILE. Client and -server. The Kerberos profile to use. On the client, the default is -the value of the KRB5_CONFIG environment variable, or -DEFAULT_PROFILE_PATH if that is not set. On the server, the value of -the ``profile'' variable of the KDC configuration file will be used as -the first default if it exists; otherwise, the default is the value of -the KRB5_KDC_PROFILE environment variable or DEFAULT_KDC_PROFILE. - -\item[kadmind_port] Variable: kadmind_port. KADMIND_PORT. Client and -server. The port number the kadmind server listens on. The client -uses this field to determine where to connect, and the server to -determine where to listen. The default is 749, which has been -assigned by IANA. - -\item[admin_server] Variable: admin_server. ADMIN_SERVER. Client. -The host name of the admin server to which to connect. There is no -default. If the value of this field contains a colon (:), the text -following the colon is treated as an integer and assigned to the -kadmind_port field, overriding any value of the kadmind_port variable. - -\item[dbname] Variable: dbname. DBNAME. Server. The Kerberos -database name to use; the Kerberos database stores principal -information. The default is DEFAULT_KDB_FILE. - -\item[admin_dbname] Variable: admin_database_name. ADBNAME. -Neither. If the dbname field is set, this field is set to the value -of dbname followed by ``.kadm5''. - -\item[admin_lockfile] Variable: admin_database_lockfile. -ADB_LOCKFILE. Neither. If the admin_dbname field is set, this field -is set to the value of admin_dbname followed by ``.lock''. - -\item[acl_file] Variable: acl_file. ACL_FILE. Server. The admin -server's ACL file. The default is DEFAULT_KADM5_ACL_FILE. - -\item[dict_file] Variable: admin_dict_file. DICT_FILE. Server. The -admin server's dictionary file of passwords to disallow. No default. - -\item[admin_keytab] Variable: admin_keytab. ADMIN_KEYTAB. Server. -The keytab file containing the kadmin/admin and kadmin/changepw -entries for the server to use. The default is the value of the -KRB5_KTNAME environment variable, if defined, else -DEFAULT_KADM5_KEYTAB. - -\item[mkey_from_keyboard] No variable. MKEY_FROM_KEYBOARD. Server. -If non-zero, prompt for the master password via the tty instead of -using the stash file. If this mask bit is not set, or is set and the -value is zero, the stash file is used. - -\item[stash_file] Variable: key_stash_file. STASH_FILE. Server. The -file name containing the master key stash file. No default; libkdb -will work with a NULL value. - -\item[mkey_name] Variable: master_key_name. MKEY_NAME. Server. The -name of the master principal for the realm. No default; lbkdb will -work with a NULL value. - -\item[enctype] Variable: master_key_type. ENCTYPE. Server. The -encryption type of the master principal. The default is -DEFAULT_KDC_ENCTYPE. - -\item[max_life] Variable: max_life. MAX_LIFE. Maximum lifetime for -all tickets issued to the principal. The default is 28800, which is 8 -hours. - -\item[max_rlife, expiration, flags] Variables: max_renewable_life, -default_principal_expiration, default_principal_flags. MAX_LIFE, -MAX_RLIFE, EXPIRATION, FLAGS. Server. Default values for new -principals. All default to 0. - -\item[keysalts, num_keysalts] Variable: supported_enctypes. ENCTYPES. -Server. The list of supported encryption type/salt type tuples; both -fields must be assigned if ENCTYPES is set. The default is a list -containing one enctype, DES-CBC-CRC with normal salt. -\end{description} - -\subsection{Principal keys} -\label{sec:keys} - -In KADM5_API_VERSION_1, all principals had a single key. The -encryption method was always DES, and the salt type was determined -outside the API (by command-line options to the administration -server). - -In KADM5_API_VERSION_2, principals can have multiple keys, each with -its own encryption type and salt. Each time a principal's key is -changed with kadm5_create_principal, kadm5_chpass_principal or -kadm5_randkey_principal, existing key entries are removed and a key -entry for each encryption and salt type tuple specified in the -configuration parameters is added. There is no provision for -specifying encryption and salt type information on a per-principal -basis; in a future version, this will probably be part of the admin -policy. There is also presently no provision for keeping multiple key -versions for a single principal active in the database. - -A single key is represented by a krb5_key_data: -% -\begin{verbatim} -typedef struct _krb5_key_data { - krb5_int16 key_data_ver; /* Version */ - krb5_int16 key_data_kvno; /* Key Version */ - krb5_int16 key_data_type[2]; /* Array of types */ - krb5_int16 key_data_length[2]; /* Array of lengths */ - krb5_octet * key_data_contents[2]; /* Array of pointers */ -} krb5_key_data; -\end{verbatim} -% -\begin{description} -\item[key_data_ver] The verion number of the structure. Versions 1 -and 2 are currently defined. If key_data_ver is 1 then the key is -either a random key (not requiring a salt) or the salt is the normal -v5 salt which is the same as the realm and therefore doesn't need to -be saved in the database. - -\item[key_data_kvno] The key version number of this key. - -\item[key_data_type] The first element is the enctype of this key. In -a version 2 structure, the second element is the salttype of this key. -The legal encryption types are defined in $<$krb5.h$>$. The legal -salt types are defined in $<$k5-int.h$>$. - -\item[key_data_length] The first element is length this key. In a -version 2 structure, the second element is length of the salt for this -key. - -\item[key_data_contents] The first element is the content of this key. -In a version 2 structure, the second element is the contents of the -salt for this key. -\end{description} - -\subsection{Field masks} -\label{sec:masks} - -The API functions for creating, retrieving, and modifying principals -and policies allow for a relevant subset of the fields of the -kadm5_principal_ent_t and kadm5_policy_ent_t to be specified or -changed. The chosen fields are determined by a bitmask that is passed -to the relevant function. Each API function has different rules for -which mask values can be specified, and can specify whether a given -mask value is mandatory, optional, or forbidden. Mandatory fields -must be present and forbidden fields must not be present or an error -is generated. When creating a principal or policy, optional fields -have a default value if they are not specified. When modifying a -principal or policy, optional fields are unchanged if they are not -specified. When retrieving a principal, optional fields are simply -not provided if they are not specified; not specifying undeeded fields -for retrieval may improve efficiency. The values for forbidden fields -are defined in the function semantics. - -The masks for principals are in table \ref{tab:princ-bits} and the -masks for policies are in table \ref{tab:policy-bits}. They are -defined in $<$kadm5/admin.h$>$. The KADM5_ prefix has been removed -from the Name fields. In the Create and Modify fields, M means -mandatory, F means forbidden, and O means optional. Create fields -that are optional specify the default value. The notation ``K/M -value'' means that the field inherits its value from the corresponding -field in the Kerberos master principal, for KADM5_API_VERSION_1, and -from the configuration parameters for KADM5_API_VERSION_2. - -All masks for principals are optional for retrevial, {\it except} that -the KEY_DATA mask is illegal when specified by a remote client; for -details, see the function semantics for kadm5_get_principal. - -Note that the POLICY and POLICY_CLR bits are special. When POLICY is -set, the policy is assigned to the principal. When POLICY_CLR is -specified, the policy is unassigned to the principal and as a result -no policy controls the principal. - -For convenience, the mask KADM5_PRINCIPAL_NORMAL_MASK contains all of -the principal masks {\it except} KADM5_KEY_DATA and KADM5_TL_DATA, and -the mask KADM5_POLICY_NORMAL_MASK contains all of the policy masks. - -\begin{table}[htbp] -\begin{tabular}{@{}lclll} -{\bf Name} & {\bf Value} & {\bf Fields Affected} & {\bf Create} & - {\bf Modify} \\ -PRINCIPAL & 0x000001 & principal & M & F \\ -PRINC_EXPIRE_TIME & 0x000002 & princ_expire_time & O, K/M value & O \\ -PW_EXPIRATION & 0x000004 & pw_expiration & O, now+pw_max_life & O \\ -LAST_PWD_CHANGE & 0x000008 & last_pwd_change & F & F \\ -ATTRIBUTES & 0x000010 & attributes & O, 0 & O \\ -MAX_LIFE & 0x000020 & max_life & O, K/M value & O \\ -MOD_TIME & 0x000040 & mod_date & F & F \\ -MOD_NAME & 0x000080 & mod_name & F & F \\ -KVNO & 0x000100 & kvno & O, 1 & O \\ -MKVNO & 0x000200 & mkvno & F & F \\ -AUX_ATTRIBUTES & 0x000400 & aux_attributes & F & F \\ -POLICY & 0x000800 & policy & O, none & O \\ -POLICY_CLR & 0x001000 & policy & F & O \\ -MAX_RLIFE & 0x002000 & max_renewable_life & O, K/M value & O \\ -LAST_SUCCESS & 0x004000 & last_success & F & F \\ -LAST_FAILED & 0x008000 & last_failed & F & F \\ -FAIL_AUTH_COUNT & 0x010000 & fail_auth_count & F & O \\ -KEY_DATA & 0x020000 & n_key_data, key_data & F & F \\ -TL_DATA & 0x040000 & n_tl_data, tl_data & O, 0, NULL & O -\end{tabular} -\caption{Mask bits for creating, retrieving, and modifying principals.} -\label{tab:princ-bits} -\end{table} - -\begin{table}[htbp] -\begin{tabular}{@{}lclll} -Name & Value & Field Affected & Create & Modify \\ -POLICY & same & policy & M & F \\ -PW_MAX_LIFE & 0x004000 & pw_max_life & O, 0 (infinite) & O \\ -PW_MIN_LIFE & 0x008000 & pw_min_life & O, 0 & O \\ -PW_MIN_LENGTH & 0x010000 & pw_min_length & O, 1 & O \\ -PW_MIN_CLASSES & 0x020000 & pw_min_classes & O, 1 & O \\ -PW_HISTORY_NUM & 0x040000 & pw_history_num & O, 0 & O \\ -REF_COUNT & 0x080000 & pw_refcnt & F & F -\end{tabular} -\caption{Mask bits for creating/modifying policies.} -\label{tab:policy-bits} -\end{table} - -\section{Constants, Header Files, Libraries} - -$<$kadm5/admin.h$>$ includes a number of required header files, -including RPC, Kerberos 5, com_err, and admin com_err -defines. It contains prototypes for all kadm5 routines mentioned -below, as well as all Admin API data structures, type definitions and -defines mentioned in this document. - -Before \v{\#include}ing $<$kadm5/admin.h$>$, the programmer can -specify the API version number that the program will use by -\v{\#define}ing USE_KADM5_API_VERSION; for example, define that symbol -to be 1 to use KADM5_API_VERSION_1. This will ensure that the correct -functional protoypes and data structures are defined. If no version -symbol is defined, the most recent version supported by the header -files will be used. - -Some of the defines and their values contained in $<$kadm5/admin.h$>$ -include the following, whose KADM5_ prefixes have been removed. -Symbols that do not exist in KADM5_API_VERSION_2 do not have a KADM5_ -prefix, but instead retain only with OVSEC_KADM_ prefix for -compatibility. -\begin{description} -\item[admin service principal] ADMIN_SERVICE (``kadmin/admin'') -\item[admin history key] HIST_PRINCIPAL (``kadmin/history'') -\item[change password principal] CHANGEPW_SERVICE (``kadmin/changepw'') -\item[server acl file path] ACLFILE (``/krb5/ovsec_adm.acl''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\item[dictionary] WORDFILE (``/krb5/kadmind.dict''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\end{description} - -KADM5 errors are described in $<$kadm5/kadm_err.h$>$, which -is included by $<$kadm5/admin.h$>$. - -The locations of the admin policy and principal databases, as well as -defines and type definitions for the databases, are defined in -$<$kadm5/adb.h$>$. Some of the defines in that file are: -\begin{description} -\item[admin policy database] POLICY_DB (``/krb5/kadm5_policy.db''). In -KADM5_API_VERSION 2, this is controlled by configuration parameters. -\item[admin principal database] PRINCIPAL_DB -(``/krb5/ovsec_principal.db''). In KADM5_API_VERSION 2, this is -controlled by configuration parameters. -\end{description} - -Client applications will link against libkadm5clnt.a and server -programs against libkadm5srv.a. Client applications must also link -against: libgssapi_krb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, -libcom_err.a, and libdyn.a. Server applications must also link -against: libkdb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, libcom_err.a, -and libdyn.a. - -\section{Error Codes} - -The error codes that can be returned by admin functions are listed -below. Error codes indicated with a ``*'' can be returned by every -admin function and always have the same meaning; these codes are -omitted from the list presented with each function. - -The admin system guarantees that a function that returns an error code -has no other side effect. - -The Admin system will use \v{com_err} for error codes. Note that this -means \v{com_err} codes may be returned from functions that the admin -routines call (e.g. the kerberos library). Callers should not expect -that only KADM5 errors will be returned. The Admin system error code -table name will be ``ovk'', and the offsets will be the same as the -order presented here. As mentioned above, the error table include file -will be $<$kadm5/kadm_err.h$>$. - -Note that these error codes are also used as protocol error code -constants and therefore must not change between product releases. -Additional codes should be added at the end of the list, not in the -middle. The integer value of KADM5_FAILURE is 43787520; the -remaining values are assigned in sequentially increasing order. - -\begin{description} -\item[* KADM5_FAILURE] Operation failed for unspecified reason -\item[* KADM5_AUTH_GET] Operation requires ``get'' privilege -\item[* KADM5_AUTH_ADD] Operation requires ``add'' privilege -\item[* KADM5_AUTH_MODIFY] Operation requires ``modify'' privilege -\item[* KADM5_AUTH_DELETE] Operation requires ``delete'' privilege -\item[* KADM5_AUTH_INSUFFICIENT] Insufficient authorization for -operation -\item[* KADM5_BAD_DB] Database inconsistency detected -\item[KADM5_DUP] Principal or policy already exists -\item[KADM5_RPC_ERROR] Communication failure with server -\item[KADM5_NO_SRV] No administration server found for realm -\item[KADM5_BAD_HIST_KEY] Password history principal key version -mismatch -\item[KADM5_NOT_INIT] Connection to server not initialized -\item[KADM5_UNK_PRINC] Principal does not exist -\item[KADM5_UNK_POLICY] Policy does not exist -\item[KADM5_BAD_MASK] Invalid field mask for operation -\item[KADM5_BAD_CLASS] Invalid number of character classes -\item[KADM5_BAD_LENGTH] Invalid password length -\item[KADM5_BAD_POLICY] Illegal policy name -\item[KADM5_BAD_PRINCIPAL] Illegal principal name. -\item[KADM5_BAD_AUX_ATTR] Invalid auxillary attributes -\item[KADM5_BAD_HISTORY] Invalid password history count -\item[KADM5_BAD_MIN_PASS_LIFE] Password minimum life is greater -then password maximum life -\item[KADM5_PASS_Q_TOOSHORT] Password is too short -\item[KADM5_PASS_Q_CLASS] Password does not contain enough -character classes -\item[KADM5_PASS_Q_DICT] Password is in the password dictionary -\item[KADM5_PASS_REUSE] Cannot resuse password -\item[KADM5_PASS_TOOSOON] Current password's minimum life has not -expired -\item[KADM5_POLICY_REF] Policy is in use -\item[KADM5_INIT] Connection to server already initialized -\item[KADM5_BAD_PASSWORD] Incorrect password -\item[KADM5_PROTECT_PRINCIPAL] Cannot change protected principal -\item[* KADM5_BAD_SERVER_HANDLE] Programmer error! Bad Admin server handle -\item[* KADM5_BAD_STRUCT_VERSION] Programmer error! Bad API structure version -\item[* KADM5_OLD_STRUCT_VERSION] API structure version specified by application is no longer supported (to fix, recompile application against current Admin API header files and libraries) -\item[* KADM5_NEW_STRUCT_VERSION] API structure version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) -\item[* KADM5_BAD_API_VERSION] Programmer error! Bad API version -\item[* KADM5_OLD_LIB_API_VERSION] API version specified by application is no longer supported by libraries (to fix, update application to adhere to current API version and recompile) -\item[* KADM5_OLD_SERVER_API_VERSION] API version specified by application is no longer supported by server (to fix, update application to adhere to current API version and recompile) -\item[* KADM5_NEW_LIB_API_VERSION] API version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) -\item[* KADM5_NEW_SERVER_API_VERSION] API version specified by -application is unknown to server (to fix, obtain and install newest -Admin Server) -\item[KADM5_SECURE_PRINC_MISSING] Database error! Required principal missing -\item[KADM5_NO_RENAME_SALT] The salt type of the specified principal -does not support renaming -\item[KADM5_BAD_CLIENT_PARAMS] Illegal configuration parameter for -remote KADM5 client -\item[KADM5_BAD_SERVER_PARAMS] Illegal configuration parameter for -local KADM5 client. -\item[KADM5_AUTH_LIST] Operation requires ``list'' privilege -\item[KADM5_AUTH_CHANGEPW] Operation requires ``change-password'' privilege -\item[KADM5_BAD_TL_TYPE] Programmer error! Illegal tagged data list -element type -\item[KADM5_MISSING_CONF_PARAMS] Required parameters in kdc.conf missing -\item[KADM5_BAD_SERVER_NAME] Bad krb5 admin server hostname -\item[KADM5_AUTH_SETKEY] Operation requires ``set-key'' privilege -\item[KADM5_SETKEY_DUP_ENCTYPES] Multiple values for single or folded enctype -\end{description} - -\section{Authentication and Authorization} -\label{sec:auth} - -Two Kerberos principals exist for use in communicating with the Admin -system: kadmin/admin and kadmin/changepw. Both principals -have the KRB5_KDB_DISALLOW_TGT_BASED bit set in their attributes so -that service tickets for them can only be acquired via a -password-based (AS_REQ) request. Additionally, kadmin/changepw -has the KRB5_KDB_PWCHANGE_SERVICE bit set so that a principal with an -expired password can still obtain a service ticket for it. - -The Admin system accepts requests that are authenticated to either -service principal, but the sets of operations that can be performed by -a request authenticated to each service are different. In particular, -only the functions chpass_principal, randkey_principal, get_principal, -and get_policy can be performed by a request authenticated to the -kadmin/changepw service, and they can only be performed when the -target principal of the operation is the same as the authenticated -client principal; the function semantics descriptions below give the -precise details. This means that administrative operations can only -be performed when authenticated to the kadmin/admin service. The -reason for this distinction is that tickets for kadmin/changepw can be -acquired with an expired password, and the KADM system does not want -to allow an administrator with an expired password to perform -administrative operations on arbitrary principals. - -Each Admin API operation authenticated to the kadmin/admin service -requires a specific authorization to run. This version uses a simple -named privilege system with the following names and meanings: - -\begin{description} -\item[Get] Able to examine the attributes (NOT key data) of principals -and policies. -\item[Add] Able to add principals and policies. -\item[Modify] Able to modify attributes of existing principals and -policies; this does not include changing passwords. -\item[Delete] Able to remove principals and policies. -\item[List] Able to retrieve a list of principals and policies. -\item[Changepw] Able to change the password of principals. -\item[Setkey] Able to set principal keys directly. -\end{description} - -Privileges are specified via an external configuration file on the -Kerberos master server. - -Table \ref{tab:func-overview} summarizes the authorization -requirements of each function. Additionally, each API function -description identifies the privilege required to perform it. The -Authorization checks only happen if you are using the RPC mechanism. -If you are using the server-side API functions locally on the admin -server, the only authorization check is if you can access the -approporiate local files. - -\section{Functions} - -\subsection{Overview} - -The functions provided by the Admin API, and the authorization they -require, are listed in the table \ref{tab:func-overview}. The -``kadm5_'' prefix has been removed from each function name. - -The function semantics in the following sections omit details that are -the same for every function. - -\begin{itemize} -\item The effects of every function are atomic. - -\item Every function performs an authorization check and returns -the appropriate KADM5_AUTH_* error code if the caller does not -have the required privilege. No other information or error code is -ever returned to an unauthorized user. - -\item Every function checks its arguments for NULL pointers or other -obviously invalid values, and returns EINVAL if any are detected. - -\item Any function that performs a policy check uses the policy named -in the principal's policy field. If the POLICY bit is not set in the -principal's aux_attributes field, however, the principal has no -policy, so the policy check is not performed. - -\item Unless otherwise specified, all functions return KADM5_OK. -\end{itemize} - -\begin{table}[htbp] -\caption{Summary of functions and required authorization.} -\label{tab:func-overview} -\begin{tabular}{@{}llp{3.24in}} -\\ -{\bf Function Name} & {\bf Authorization} & {\bf Operation} \\ - -init & none & Open a connection with the kadm5 library. OBSOLETE -but still provided---use init_with_password instead. \\ -init_with_password & none & Open a connection with the kadm5 -library using a password to obtain initial credentials. \\ -init_with_skey & none & Open a connection with the kadm5 library -using the keytab entry to obtain initial credentials. \\ -destroy & none & Close the connection with the kadm5 library. \\ -flush & none & Flush all database changes to disk; no-op when called -remotely. \\ -create_principal & add & Create a new principal. \\ -delete_principal & delete & Delete a principal. \\ -modify_principal & modify & Modify the attributes of an existing - principal (not password). \\ -rename_principal & add and delete & Rename a principal. \\ -get_principal & get\footnotemark & Retrieve a principal. \\ -get_principals & list & Retrieve some or all principal names. \\ -chpass_principal & changepw\footnotemark[\thefootnote] & - Change a principal's password. \\ -chpass_principal_util & changepw\footnotemark[\thefootnote] & Utility wrapper around chpass_principal. \\ -randkey_principal & changepw\footnotemark[\thefootnote] & - Randomize a principal's key. \\ -setkey_principal & setkey & Explicitly set a principal's keys. \\ -decrypt_key & none & Decrypt a principal key. \\ -create_policy & add & Create a new policy. \\ -delete_policy & delete & Delete a policy. \\ -modify_policy & modify & Modify the attributes of a policy. \\ -get_policy & get & Retrieve a policy. \\ -get_policies & list & Retrieve some or all policy names. \\ -free_principal_ent & none & Free the memory associated with an - kadm5_principal_ent_t. \\ -free_policy_ent & none & Free the memory associated with an - kadm5_policy_ent_t. \\ -get_privs & none & Return the caller's admin server privileges. -\end{tabular} -\end{table} -\footnotetext[\thefootnote]{These functions also allow a principal to -perform the operation on itself; see the function's semantics for -details.} - -\subsection{kadm5_init_*} - -In KADM5_API_VERSION 1: - -\begin{verbatim} -kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init(char *client_name, char *pass, - char *service_name, char *realm, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) -\end{verbatim} - -In KADM5_API_VERSION 2: - -\begin{verbatim} -kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init(char *client_name, char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) - -kadm5_ret_t kadm5_init_with_creds(char *client_name, - krb5_ccache ccache, - char *service_name, - kadm5_config_params *params, - krb5_ui_4 struct_version, - krb5_ui_4 api_version, - void **server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -NOTE: kadm5_init is an obsolete function provided for backwards -compatibility. It is identical to kadm5_init_with_password. - -These three functions open a connection to the kadm5 library and -initialize any neccessary state information. They behave differently -when called from local and remote clients. - -In KADM5_API_VERSION_2, these functions take a kadm5_config_params -structure instead of a realm name as an argument. The semantics are -similar: if a NULL pointer is passed for the realm_params argument, -the default realm and default parameters for that realm, as specified -in the krb5 configuration file (e.g. /etc/krb5.conf) are used. If a -realm_params structure is provided, the fields that are set override -the default values. If a parameter is specified to the local or -remote libraries that does not apply to that side, an error code -(KADM5_BAD_CLIENT_PARAMS or KADM5_BAD_SERVER_PARAMS) is returned. See -section \ref{sec:configparams} for a discussion of configuration -parameters. - -For remote clients, the semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Acquires configuration parameters. In KADM5_API_VERSION_1, all -the defaults specified in the configuration file are used, according -to the realm. In KADM5_API_VERSION_2, the values in params_in are -merged with the default values. If an illegal mask value is -specified, KADM5_BAD_CLIENT_PARAMS is returned. - -\item Acquires a Kerberos ticket for the specified service. - -\begin{enumerate} -\item The ticket's client is client_name, which can be any valid -Kerberos principal. If client_name does not include a realm, the -default realm of the local host is used -\item The ticket's service is service_name@realm. service_name must -be one of the constants KADM5_ADMIN_SERVICE or -KADM5_CHANGEPW_SERVICE. -\item If realm is NULL, client_name's realm is used. - -\item For init_with_password, an initial ticket is acquired and -decoded with the password pass, which must be client_name's password. -If pass is NULL or an empty string, the user is prompted (via the tty) -for a password. - -\item For init_with_skey, an initial ticket is acquired and decoded -with client_name's key obtained from the specified keytab. If keytab -is NULL or an empty string the default keytab is used. - -\item For init_with_creds, ccache must be an open credential cache -that already has a ticket for the specified client and server. -Alternatively, if a site chooses to disable the DISALLOW_TGT_BASED -flag on the admin and changepw principals, the ccache can contain a -ticket-granting ticket for client_name. -\end{enumerate} - -\item Creates a GSS-API authenticated connection to the Admin server, -using the just-acquired Kerberos ticket. - -\item Verifies that the struct_version and api_version specified by -the caller are valid and known to the library. - -\item Sends the specified api_version to the server. - -\item Upon successful completion, fills in server_handle with a handle -for this connection, to be used in all subsequent API calls. -\end{enumerate} - -The caller should always specify KADM5_STRUCT_VERSION for the -struct_version argument, a valid and supported API version constant -for the api_version argument (currently, KADM5_API_VERSION_1 or -KADM5_API_VERSION_2), and a valid pointer in which the server handle -will be stored. - -If any kadm5_init_* is invoked locally its semantics are: - -\begin{enumerate} -\item Initializes all the com_err error tables used by the Admin -system. - -\item Acquires configuration parameters. In KADM5_API_VERSION_1, all -the defaults specified in the configuration file are used, according -to the realm. In KADM5_API_VERSION_2, the values in params_in are -merged with the default values. If an illegal mask value is -specified, KADM5_BAD_SERVER_PARAMS is returned. - -\item Initializes direct access to the KDC database. In -KADM5_API_VERISON_1, if pass (or keytab) is NULL or an empty string, -reads the master password from the stash file; otherwise, the non-NULL -password is ignored and the user is prompted for it via the tty. In -KADM5_API_VERSION_2, if the MKEY_FROM_KEYBOARD parameter mask is set -and the value is non-zero, reads the master password from the user via -the tty; otherwise, the master key is read from the stash file. -Calling init_with_skey or init_with_creds with the MKEY_FROM_KEYBOARD -mask set with a non-zero field is illegal, and calling them without -the mask set is exactly like calling init_with_password. - -\item Initializes the dictionary (if present) for dictionary checks. - -\item Parses client_name as a Kerberos principal. client_name should -usually be specified as the name of the program. - -\item Verifies that the struct_version and api_version specified by -the caller are valid. - -\item Fills in server_handle with a handle containing all state -information (version numbers and client name) for this ``connection.'' -\end{enumerate} -The service_name argument is not used. - -RETURN CODES: - -\begin{description} -\item[KADM5_NO_SRV] No Admin server can be found for the -specified realm. - -\item[KADM5_RPC_ERROR] The RPC connection to the server cannot be -initiated. - -\item[KADM5_BAD_PASSWORD] Incorrect password. - -\item[KADM5_SECURE_PRINC_MISSING] The principal -KADM5_ADMIN_SERVICE or KADM5_CHANGEPW_SERVICE does not -exist. This is a special-case replacement return code for ``Server -not found in database'' for these required principals. - -\item[KADM5_BAD_CLIENT_PARAMS] A field in the parameters mask was -specified to the remote client library that is not legal for remote -clients. - -\item[KADM5_BAD_SERVER_PARAMS] A field in the parameters mask was -specified to the local client library that is not legal for local -clients. -\end{description} - -\subsection{kadm5_flush} - -\begin{verbatim} -kadm5_ret_t kadm5_flush(void *server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -Flush all changes to the Kerberos databases, leaving the connection to -the Admin API open. This function behaves differently when called by -local and remote clients. - -For local clients, the function closes and reopens the Kerberos -database with krb5_db_fini() and krb5_db_init(), and closes and -reopens the Admin policy database with adb_policy_close() and -adb_policy_open(). Although it is unlikely, any other these functions -could return errors; in that case, this function calls -kadm5_destroy and returns the error code. Therefore, if -kadm5_flush does not return KADM5_OK, the connection to the -Admin server has been terminated and, in principle, the databases -might be corrupt. - -For remote clients, the function is a no-op. - -\subsection{kadm5_destroy} - -\begin{verbatim} -kadm5_ret_t kadm5_destroy(void *server_handle) -\end{verbatim} - -AUTHORIZATION REQUIRED: none - -Close the connection to the Admin server and releases all related -resources. This function behaves differently when called by local and -remote clients. - -For remote clients, the semantics are: - -\begin{enumerate} -\item Destroy the temporary credential cache created by -kadm5_init. - -\item Tear down the GSS-API context negotiated with the server. - -\item Close the RPC connection. - -\item Free storage space associated with server_handle, after erasing -its magic number so it won't be mistaken for a valid handle by the -library later. -\end{enumerate} - -For local clients, this function just frees the storage space -associated with server_handle after erasing its magic number. - -RETURN CODES: - -\subsection{kadm5_create_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_create_principal(void *server_handle, - kadm5_principal_ent_t princ, u_int32 mask, - char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: add - -\begin{enumerate} - -\item Return KADM5_BAD_MASK if the mask is invalid. -\item If the named principal exists, return KADM5_DUP. -\item If the POLICY bit is set and the named policy does not exist, -return KADM5_UNK_POLICY. -\item If KADM5_POLICY bit is set in aux_attributes check to see if -the password does not meets quality standards, return the appropriate -KADM5_PASS_Q_* error code if it fails. -\item Store the principal, set the key; see section \ref{sec:keys}. -\item If the POLICY bit is set, increment the named policy's reference -count by one. - -\item Set the pw_expiration field. -\begin{enumerate} -\item If the POLICY bit is set in mask, then if pw_max_life is non-zero, -set pw_expiration to now + pw_maxlife, otherwise set pw_max_life to -never. -\item If the PW_EXPIRATION bit is set in mask, set pw_expiration to -the requested value, overriding the value set above. -\end{enumerate} -NOTE: This is a change from the original semantics, in which policy -expiration was enforced even on administrators. The old semantics are -not preserved, even for version 1 callers, because this is a -server-specific policy decision; besides, the new semantics are less -restrictive, so all previous callers should continue to function -properly. - -\item Set mod_date to now and set mod_name to caller. -\item Set last_pwd_change to now. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_MASK] The field mask is invalid for a create -operation. -\item[KADM5_DUP] Principal already exists. -\item[KADM5_UNK_POLICY] Policy named in entry does not exist. -\item[KADM5_PASS_Q_*] Specified password does not meet policy -standards. -\end{description} - -\subsection{kadm5_delete_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_delete_principal(void *server_handle, krb5_principal princ); -\end{verbatim} - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return KADM5_UNK_PRINC if the principal does not exist. -\item If the POLICY bit is set in aux_attributes, decrement the named -policy's reference count by one. -\item Delete principal. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\end{description} - -\subsection{kadm5_modify_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_modify_principal(void *server_handle, - kadm5_principal_ent_t princ, u_int32 mask); -\end{verbatim} - -Modify the attributes of the principal named in -kadm5_principal_ent_t. This does not allow the principal to be -renamed or for its password to be changed. - -AUTHORIZATION REQUIRED: modify - -Although a principal's pw_expiration is usually computed based on its -policy and the time at which it changes its password, this function -also allows it to be specified explicitly. This allows an -administrator, for example, to create a principal and assign it to a -policy with a pw_max_life of one month, but to declare that the new -principal must change its password away from its initial value -sometime within the first week. - -\begin{enumerate} -\item Return KADM5_UNK_PRINC if the principal does not exist. -\item Return KADM5_BAD_MASK if the mask is invalid. -\item If POLICY bit is set but the new policy does not exist, return -KADM5_UNK_POLICY. -\item If either the POLICY or POLICY_CLR bits are set, update the -corresponding bits in aux_attributes. - -\item Update policy reference counts. -\begin{enumerate} -\item If the POLICY bit is set, then increment policy count on new -policy. -\item If the POLICY or POLICY_CLR bit is set, and the POLICY bit in -aux_attributes is set, decrement policy count on old policy. -\end{enumerate} - -\item Set pw_expiration appropriately. pw_expiration can change if: -the POLICY bit is set in mask, so the principal is changing to a -policy (either from another policy or no policy); the POLICY_CLR bit -is set in mask, so the principal is changing to no policy; or -PW_EXPIRATION is set. -\begin{enumerate} -\item If the POLICY bit is set in mask, set pw_expiration to -last_pwd_change + pw_max_life if pw_max_life is non-zero, otherwise -set pw_expiration to never. -\item If the POLICY_CLR biti s set in mask, set pw_expiration to -never. -\item If PW_EXPIRATION is set, set pw_expiration to the requested -value, overriding the value from the previous two cases. NOTE: This -is a change from the original semantics, in which policy expiration -was enforced even on administrators. The old semantics are not -preserved, even for version 1 callers, because this is a -server-specific policy decision; besides, the new semantics are less -restrictive, so all previous callers should continue to function -properly. -\end{enumerate} - -% Here is the previous, and confusing, text of pw_expiration semantics: -%\begin{enumerate} -%\item If the POLICY bit is not set in aux_attributes, then -%\begin{enumerate} -%\item if the PW_EXPIRATION bit is set, set pw_expiration to the given -%value, else -%\item set pw_expiration to never. -%\end{enumerate} -%\item Otherwise, if the PW_EXPIRATION bit is set, set pw_expiration to -%the sooner of the given value and last_pwd_change + pw_max_life. -%\item Otherwise, set pw_expiration to last_pwd_change + pw_max_life. -%\end{enumerate} - -\item Update the remaining fields specified in the mask. -\item Update mod_name field to caller and mod_date to now. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Entry does not exist. -\item[KADM5_BAD_MASK] The mask is not valid for a modify -operation. -\item[KADM5_UNK_POLICY] The POLICY bit is set but the new -policy does not exist. -\item[KADM5_BAD_TL_TYPE] The KADM5_TL_DATA bit is set in mask, and the -given tl_data list contains an element whose type is less than 256. -\end{description} - -\subsection{kadm5_rename_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_rename_principal(void *server_handle, krb5_principal source, - krb5_principal target); -\end{verbatim} - -AUTHORIZATION REQUIRED: add and delete - -\begin{enumerate} -\item Check to see if source principal exists, if not return -KADM5_UNK_PRINC error. -\item Check to see if target exists, if so return KADM5_DUP error. -\item Create the new principal named target, then delete the old -principal named source. All of target's fields will be the same as -source's fields, except that mod_name and mod_date will be updated to -reflect the current caller and time. -\end{enumerate} - -Note that since the principal name may have been used as the salt for -the principal's key, renaming the principal may render the principal's -current password useless; with the new salt, the key generated by -string-to-key on the password will suddenly be different. Therefore, -an application that renames a principal must also require the user to -specify a new password for the principal (and administrators should -notify the affected party). - -Note also that, by the same argument, renaming a principal will -invalidate that principal's password history information; since the -salt will be different, a user will be able to select a previous -password without error. - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Source principal does not exist. -\item[KADM5_DUP] Target principal already exist. -\end{description} - -\subsection{kadm5_chpass_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_chpass_principal(void *server_handle, krb5_principal princ, - char *pw); -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -Change a principal's password. See section \ref{sec:keys} for a -description of how the keys are determined. - -This function enforces password policy and dictionary checks. If the new -password specified is in the password dictionary, and the policy bit is set -KADM5_PASS_DICT is returned. If the principal's POLICY bit is set in -aux_attributes, compliance with each of the named policy fields is verified -and an appropriate error code is returned if verification fails. - -Note that the policy checks are only be performed if the POLICY bit is -set in the principal's aux_attributes field. - -\begin{enumerate} -\item Make sure principal exists, if not return KADM5_UNK_PRINC error. -\item If caller does not have modify privilege, (now - last_pwd_change) $<$ -pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the -principal's attributes, return KADM5_PASS_TOOSOON. -\item If the principal your are trying to change is kadmin/history -return KADM5_PROTECT_PRINCIPAL. -\item If the password does not meet the quality -standards, return the appropriate KADM5_PASS_Q_* error code. -\item Convert password to key; see section \ref{sec:keys}. -\item If the new key is in the principal's password history, return -KADM5_PASS_REUSE. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit is set, set pw_expiration to now + -max_pw_life. If the POLICY bit is not set, set pw_expiration to -never. -\item If the KRB5_KDB_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_Q_*] Requested password does not meet quality -standards. -\item[KADM5_PASS_REUSE] Requested password is in user's -password history. -\item[KADM5_PASS_TOOSOON] Current password has not reached minimum life -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special principal -\end{description} - - -\subsection{kadm5_chpass_principal_util} - -\begin{verbatim} -kadm5_ret_t -kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, - char *new_pw, char **pw_ret, - char *msg_ret); -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -This function is a wrapper around kadm5_chpass_principal. It can -read a new password from a user, change a principal's password, and -return detailed error messages. msg_ret should point to a char buffer -in the caller's space of sufficient length for the error messages -described below. 1024 bytes is recommended. It will also return the -new password to the caller if pw_ret is non-NULL. - -\begin{enumerate} -\item If new_pw is NULL, this routine will prompt the user for the new -password (using the strings specified by KADM5_PW_FIRST_PROMPT and -KADM5_PW_SECOND_PROMPT) and read (without echoing) the password input. -Since it is likely that this will simply call krb5_read_password only -terminal-based applications will make use of the password reading -functionality. If the passwords don't match the string ``New passwords do -not match - password not changed.'' will be copied into msg_ret, and the -error code KRB5_LIBOS_BADPWDMATCH will be returned. For other errors that -ocurr while reading the new password, copy the string ``$ -occurred while trying to read new password.'' followed by a blank line and -the string specified by CHPASS_UTIL_PASSWORD_NOT_CHANGED into msg_ret and -return the error code returned by krb5_read_password. - -\item If pw_ret is non-NULL, and the password was prompted, set *pw_ret to -point to a static buffer containing the password. If pw_ret is non-NULL -and the password was supplied, set *pw_ret to the supplied password. - -\item Call kadm5_chpass_principal with princ, and new_pw. - -\item If successful copy the string specified by CHPASS_UTIL_PASSWORD_CHANGED -into msg_ret and return zero. - -\item For a policy related failure copy the appropriate message (from below) -followed by a newline and ``Password not changed.'' into msg_ret -filling in the parameters from the principal's policy information. If -the policy information cannot be obtained copy the generic message if -one is specified below. Return the error code from -kadm5_chpass_principal. - -Detailed messages: -\begin{description} - -\item[PASS_Q_TOO_SHORT] -New password is too short. Please choose a -password which is more than $<$pw-min-len$>$ characters. - -\item[PASS_Q_TOO_SHORT - generic] -New password is too short. Please choose a longer password. - -\item[PASS_REUSE] -New password was used previously. Please choose a -different password. - -\item[PASS_Q_CLASS] -New password does not have enough character classes. Classes include -lower class letters, upper case letters, digits, punctuation and all -other characters. Please choose a password with at least -$<$min-classes$>$ character classes. - -\item[PASS_Q_CLASS - generic] -New password does not have enough character classes. Classes include -lower class letters, upper case letters, digits, punctuation and all -other characters. - -\item[PASS_Q_DICT] -New password was found in a dictionary of possible passwords and -therefore may be easily guessed. Please choose another password. See -the kpasswd man page for help in choosing a good password. - -\item[PASS_TOOSOON] -Password cannot be changed because it was changed too recently. Please -wait until $<$last-pw-change+pw-min-life$>$ before you change it. If you -need to change your password before then, contact your system -security administrator. - -\item[PASS_TOOSOON - generic] -Password cannot be changed because it was changed too recently. If you -need to change your now please contact your system security -administrator. -\end{description} - -\item For other errors copy the string ``$<$com_err message$>$ -occurred while trying to change password.'' following by a blank line -and ``Password not changed.'' into msg_ret. Return the error code -returned by kadm5_chpass_principal. -\end{enumerate} - - -RETURN CODES: - -\begin{description} -\item[KRB5_LIBOS_BADPWDMATCH] Typed new passwords did not match. -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_Q_*] Requested password does not meet quality -standards. -\item[KADM5_PASS_REUSE] Requested password is in user's -password history. -\item[KADM5_PASS_TOOSOON] Current password has not reached minimum -life. -\end{description} - -\subsection{kadm5_randkey_principal} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_randkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock **new_key) -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_randkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock **new_keys, int *n_keys) -\end{verbatim} - -AUTHORIZATION REQUIRED: changepw, or the calling principal being the -same as the princ argument. If the request is authenticated to the -kadmin/changepw service, the changepw privilege is disregarded. - -Generate and assign a new random key to the named principal, and -return the generated key in allocated storage. In -KADM5_API_VERSION_2, multiple keys may be generated and returned as an -array, and n_new_keys is filled in with the number of keys generated. -See section \ref{sec:keys} for a description of how the keys are -chosen. In KADM5_API_VERSION_1, the caller must free the returned -krb5_keyblock * with krb5_free_keyblock. In KADM5_API_VERSION_2, the -caller must free each returned keyblock with krb5_free_keyblock. - -If the principal's POLICY bit is set in aux_attributes and the caller does -not have modify privilege , compliance with the password minimum life -specified by the policy is verified and an appropriate error code is returned -if verification fails. - -\begin{enumerate} -\item If the principal does not exist, return KADM5_UNK_PRINC. -\item If caller does not have modify privilege, (now - last_pwd_change) $<$ -pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the -principal's attributes, return KADM5_PASS_TOOSOON. -\item If the principal you are trying to change is kadmin/history return -KADM5_PROTECT_PRINCIPAL. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit in aux_attributes is set, set pw_expiration to -now + max_pw_life. -\item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PASS_TOOSOON] The minimum lifetime for the current -key has not expired. -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special -principal -\end{description} - -This function can also be used as part of a sequence to create a new -principal with a random key. The steps to perform the operation -securely are - -\begin{enumerate} -\item Create the principal with kadm5_create_principal with a -random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set -in the attributes field. - -\item Randomize the principal's key with kadm5_randkey_principal. - -\item Call kadm5_modify_principal to reset the -KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. -\end{enumerate} - -The three steps are necessary to ensure secure creation. Since an -attacker might be able to guess the initial password assigned by the -client program, the principal must be disabled until the key can be -truly randomized. - -\subsection{kadm5_setkey_principal} - -\begin{verbatim} -kadm5_ret_t -kadm5_setkey_principal(void *server_handle, krb5_principal princ, - krb5_keyblock *new_keys, int n_keys) -\end{verbatim} - -AUTHORIZATION REQUIRED: setkey. This function does not allow the use -of regular changepw authorization because it bypasses the password -policy mechanism. - -This function only exists in KADM5_API_VERSION_2. - -Explicitly sets the specified principal's keys to the n_keys keys in -the new_keys array. The keys in new_keys should not be encrypted in -the Kerberos master key; this function will perform that operation -itself (the keys will be protected during transmission from the -calling client to the kadmind server by the AUTH_GSSAPI RPC layer). -This function completely bypasses the principal's password policy, if -set. - -\begin{enumerate} -\item If the principal does not exist, return KADM5_UNK_PRINC. -\item If the principal you are trying to change is kadmin/history return -KADM5_PROTECT_PRINCIPAL. -\item If new_keys contains more than one key of any ENCTYPE_DES_CBC_* -type that is folded, return KADM5_SETKEY_DUP_ENCTYPES. -\item Store old key in history. -\item Update principal to have new key. -\item Increment principal's key version number by one. -\item If the POLICY bit in aux_attributes is set, set pw_expiration to -now + max_pw_life. -\item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's -attributes, clear it. -\item Update last_pwd_change and mod_date to now, update mod_name to -caller. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special -principal -\end{description} - -This function can also be used as part of a sequence to create a new -principal with an explicitly key. The steps to perform the operation -securely are - -\begin{enumerate} -\item Create the principal with kadm5_create_principal with a -random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set -in the attributes field. - -\item Set the principal's key with kadm5_setkey_principal. - -\item Call kadm5_modify_principal to reset the -KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. -\end{enumerate} - -The three steps are necessary to ensure secure creation. Since an -attacker might be able to guess the initial password assigned by the -client program, the principal must be disabled until the key can be -truly randomized. - -\subsection{kadm5_get_principal} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principal(void *server_handle, krb5_principal princ, - kadm5_principal_ent_t *ent); -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principal(void *server_handle, krb5_principal princ, - kadm5_principal_ent_t ent, u_int32 mask); -\end{verbatim} - -AUTHORIZATION REQUIRED: get, or the calling principal being the same -as the princ argument. If the request is authenticated to the -kadmin/changepw service, the get privilege is disregarded. - -In KADM5_API_VERSION_1, return all of the principal's attributes in -allocated memory; if an error is returned entry is set to NULL. In -KADM5_API_VERSION_2, fill in the fields of the principal structure -specified in the mask; memory for the structure is not allocated. -Typically, a caller will specify the mask KADM5_PRINCIPAL_NORMAL_MASK, -which includes all the fields {\it except} key_data and tl_data to -improve time and memory efficiency. A caller that wants key_data and -tl_data can bitwise-OR those masks onto NORMAL_MASK. Note that even -if KADM5_TL_DATA is specified, this function will not return internal -tl_data elements whose type is less than 256. - -The caller must free the returned entry with kadm5_free_principal_ent. - -The function behaves differently for local and remote clients. For -remote clients, the KEY_DATA mask is illegal and results in a -KADM5_BAD_MASK error. - -RETURN CODES: - -\begin{description} -\item[KADM5_UNK_PRINC] Principal does not exist. -\item[KADM5_BAD_MASK] The mask is not valid for a get operation. - -\end{description} - -\subsection{kadm5_decyrpt_key} - -\begin{verbatim} -kadm5_ret_t kadm5_decrypt_key(void *server_handle, - kadm5_principal_ent_t entry, krb5_int32 - ktype, krb5_int32 stype, krb5_int32 - kvno, krb5_keyblock *keyblock, - krb5_keysalt *keysalt, int *kvnop) -\end{verbatim} - -AUTHORIZATION REQUIRED: none, local function - -Searches a principal's key_data array to find a key with the specified -enctype, salt type, and kvno, and decrypts the key into keyblock and -keysalt if found. entry must have been returned by -kadm5_get_principal with at least the KADM5_KEY_DATA mask set. -Returns ENOENT if the key cannot be found, EINVAL if the key_data -array is empty (as it always is in an RPC client). - -If ktype or stype is -1, it is ignored for the search. If kvno is -1, -ktype and stype are ignored and the key with the max kvno is returned. -If kvno is 0, only the key with the max kvno is returned and only if -it matches the ktype and stype; otherwise, ENOENT is returned. - -\subsection{kadm5_get_principals} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_principals(void *server_handle, char *exp, - char ***princs, int *count) -\end{verbatim} - -Retrieves the list of principal names. - -AUTHORIZATION REQUIRED: list - -If \v{exp} is NULL, all principal names are retrieved; otherwise, -principal names that match the expression exp are retrieved. -\v{princs} is filled in with a pointer to a NULL-terminated array of -strings, and \v{count} is filled in with the number of principal names -in the array. \v{princs} must be freed with a call to -\v{kadm5_free_name_list}. - -All characters in the expression match themselves except ``?'' which -matches any single character, ``*'' which matches any number of -consecutive characters, and ``[chars]'' which matches any single -character of ``chars''. Any character which follows a ``$\backslash$'' -matches itself exactly, and a ``$\backslash$'' cannot be the last -character in the string. - -\subsection{kadm5_create_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_create_policy(void *server_handle, - kadm5_policy_ent_t policy, u_int32 mask); -\end{verbatim} - -Create a new policy. - -AUTHORIZATION REQUIRED: add - -\begin{enumerate} -\item Check to see if mask is valid, if not return KADM5_BAD_MASK error. -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. - -\item Check to see if the policy already exists, if so return -KADM5_DUP error. -\item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, -3, 4, or 5, return KADM5_BAD_CLASS. -\item Create a new policy setting the appropriate fields determined -by the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_DUP] Policy already exists -\item[KADM5_BAD_MASK] The mask is not valid for a create -operation. -\item[KADM5_BAD_CLASS] The specified number of character classes -is invalid. -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\end{description} - -\subsection{kadm5_delete_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_delete_policy(void *server_handle, char *policy); -\end{verbatim} - -Deletes a policy. - -AUTHORIZATION REQUIRED: delete - -\begin{enumerate} -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. -\item Return KADM5_UNK_POLICY if the named policy does not exist. -\item Return KADM5_POLICY_REF if the named policy's refcnt is not 0. -\item Delete policy. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy does not exist. -\item[KADM5_POLICY_REF] Policy is being referenced. -\end{description} - -\subsection{kadm5_modify_policy} - -\begin{verbatim} -kadm5_ret_t -kadm5_modify_policy(void *server_handle, - kadm5_policy_ent_t policy, u_int32 mask); -\end{verbatim} - -Modify an existing policy. Note that modifying a policy has no affect -on a principal using the policy until the next time the principal's -password is changed. - -AUTHORIZATION REQUIRED: modify - -\begin{enumerate} -\item Return KADM5_BAD_POLICY if the policy name contains illegal -characters. -\item Check to see if mask is legal, if not return KADM5_BAD_MASK error. -\item Check to see if policy exists, if not return -KADM5_UNK_POLICY error. -\item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, -3, 4, or 5, return KADM5_BAD_CLASS. -\item Update the fields specified in the mask. -\end{enumerate} - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy not found. -\item[KADM5_BAD_MASK] The mask is not valid for a modify -operation. -\item[KADM5_BAD_CLASS] The specified number of character classes -is invalid. -\end{description} - -\subsection{kadm5_get_policy} - -In KADM5_API_VERSION_1: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t *ent); -\end{verbatim} - -In KADM5_API_VERSION_2: - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent); -\end{verbatim} - -AUTHORIZATION REQUIRED: get, or the calling principal's policy being -the same as the policy argument. If the request is authenticated to -the kadmin/changepw service, the get privilege is disregarded. - -In KADM5_API_VERSION_1, return the policy's attributes in allocated -memory; if an error is returned entry is set to NULL. In -KADM5_API_VERSION_2, fill in fields of the policy structure allocated -by the caller. The caller must free the returned entry with -kadm5_free_policy_ent - -RETURN CODES: - -\begin{description} -\item[KADM5_BAD_POLICY] The policy name contains illegal characters. -\item[KADM5_UNK_POLICY] Policy not found. -\end{description} - -\subsection{kadm5_get_policies} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_policies(void *server_handle, char *exp, - char ***pols, int *count) -\end{verbatim} - -Retrieves the list of principal names. - -AUTHORIZATION REQUIRED: list - -If \v{exp} is NULL, all principal names are retrieved; otherwise, -principal names that match the expression exp are retrieved. \v{pols} -is filled in with a pointer to a NULL-terminated array of strings, and -\v{count} is filled in with the number of principal names in the -array. \v{pols} must be freed with a call to -\v{kadm5_free_name_list}. - -All characters in the expression match themselves except ``?'' which -matches any single character, ``*'' which matches any number of -consecutive characters, and ``[chars]'' which matches any single -character of ``chars''. Any character which follows a ``$\backslash$'' -matches itself exactly, and a ``$\backslash$'' cannot be the last -character in the string. - -\subsection{kadm5_free_principal_ent, _policy_ent} - -\begin{verbatim} -void kadm5_free_principal_ent(void *server_handle, - kadm5_principal_ent_t princ); -\end{verbatim} - -In KADM5_API_VERSION_1, free the structure and contents allocated by a -call to kadm5_get_principal. In KADM5_API_VERSION_2, free the -contents allocated by a call to kadm5_get_principal. - -AUTHORIZATION REQUIRED: none (local operation) - -\begin{verbatim} -void kadm5_free_policy_ent(kadm5_policy_ent_t policy); -\end{verbatim} - -Free memory that was allocated by a call to kadm5_get_policy. If -the argument is NULL, the function returns succesfully. - -AUTHORIZATION REQUIRED: none (local operation) - -\subsection{kadm5_free_name_list} - -\begin{verbatim} -void kadm5_free_name_list(void *server_handle, - char **names, int *count); -\end{verbatim} - -Free the memory that was allocated by kadm5_get_principals or -kadm5_get_policies. names and count must be a matched pair of -values returned from one of those two functions. - -\subsection{kadm5_free_key_data} - -\begin{verbatim} -void kadm5_free_key_data(void *server_handle, - krb5_int16 *n_key_data, krb5_key_data *key_data) -\end{verbatim} - -Free the memory that was allocated by kadm5_randkey_principal. -n_key_data and key_data must be a matched pair of values returned from -that function. - -\subsection{kadm5_get_privs} - -\begin{verbatim} -kadm5_ret_t -kadm5_get_privs(void *server_handle, u_int32 *privs); -\end{verbatim} - -Return the caller's admin server privileges in the integer pointed to -by the argument. The Admin API does not define any way for a -principal's privileges to be set. Note that this function will -probably be removed or drastically changed in future versions of this -system. - -The returned value is a bitmask indicating the caller's privileges: - -\begin{tabular}{llr} -{\bf Privilege} & {\bf Symbol} & {\bf Value} \\ -Get & KADM5_PRIV_GET & 0x01 \\ -Add & KADM5_PRIV_ADD & 0x02 \\ -Modify & KADM5_PRIV_MODIFY & 0x04 \\ -Delete & KADM5_PRIV_DELETE & 0x08 \\ -List & KADM5_PRIV_LIST & 0x10 \\ -Changepw & KADM5_PRIV_CPW & 0x20 -\end{tabular} - -There is no guarantee that a caller will have a privilege indicated by -this function for any length of time or for any particular target; -applications using this function must still be prepared to handle all -possible KADM5_AUTH_* error codes. - -In the initial MIT Kerberos version of the admin server, permissions -depend both on the caller and the target; this function returns a -bitmask representing all privileges the caller can possibly have for -any possible target. - -\end{document} diff --git a/doc/kadm5/api-server-design.tex b/doc/kadm5/api-server-design.tex deleted file mode 100644 index cecdae1cb..000000000 --- a/doc/kadm5/api-server-design.tex +++ /dev/null @@ -1,1042 +0,0 @@ -\documentstyle[12pt,fullpage,changebar,rcsid]{article} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\rcs$Id$ - -\setlength{\parskip}{.7\baselineskip} -\setlength{\parindent}{0pt} - -\def\v#1{\verb+#1+} -\def\k#1{K$_#1$} - -\title{KADM5 Library and Server \\ Implementation Design\thanks{\rcsId}} -\author{Barry Jaspan} - -\begin{document} - -\sloppy -\maketitle - -{\setlength{\parskip}{0pt}\tableofcontents} - -\section{Overview} - -The KADM5 administration system is designed around the KADM5 API. The -``server-side'' library libkadm5srv.a implements the KADM5 API by -operating directly on the underlying KDC and admin databases. The -``client-side'' library libkadm5clnt.a implements the KADM5 API via an -RPC mechanism. The administration server kadmind accepts RPC requests -from the client-side library and translates them into calls to the -server-side library, performing authentication, authorization, and -logging along the way. - -The two libraries, libkadm5clnt.a and libkadm5srv.a, export the -identical kadm5 interface; for example, both contain definitions for -kadm5_get_principal, and all other kadm5 functions. In most cases, -the client library function just marshalls arguments and results into -and out of an RPC call, whereas the server library function performs -the actual operation on the database file. kadm5_init_*, however, are -substantially different even though they export the same interface: on -the client, they establish the RPC connection and GSS-API context, -whereas on the server side the open the database files, read in the -password dictionary, and the like. Also, the kadm5_free functions -operate on local process memory in both libraries. - -The admin server is implemented as a nearly-stateless transaction -server, where each admin API function represents a single transaction. -No per-client or per-connection information is stored; only local -database handles are maintained between requests. The RPC mechanism -provides access to remote callers' authentication credentials for -authorization purposes. - -The admin API is exported via an RPC interface that hides all details -about network encoding, authentication, and encryption of data on the -wire. The RPC mechanism does, however, allow the server to access the -underlying authentication credentials for authorization purposes. - -The admin system maintains two databases: -% -\begin{itemize} -\item The master Kerberos (KDC) database is used to store all the -information that the Kerberos server understands, thus allowing the -greatest functionality with no modifications to a standard KDC. - -\item The KDC database also stores kadm5-specific per-principal -information in each principal's krb5_tl_data list. In a prior -version, this data was stored in a separate admin principal database; -thus, when this document refers to ``the admin principal database,'' -it now refers to the appropriate krb5_tl_data entries in the KDC -database. - -\item The policy database stores kadm5 policy information. -\end{itemize} - -The per-principal information stored in the admin principal database -consists of the principal's policy name and an array of the -principal's previous keys. The old keys are stored encrypted in the -key of the special principal ``kadmin/history'' that is created by the -server library when it is first needed. Since a change in -kadmin/history's key renders every principal's key history array -useless, it can only be changed using the ovsec_adm_edit utility; that -program will reencrypt every principal's key history in the new -key.\footnote{ovsec_adm_edit has not yet been implemented, and there -are currently no plans to implement it; thus, the history cannot -currently be changed.} The server library refuses all requests to -change kadmin/history's key. - -\section{API Handles} - -Each call to kadm5_init_* on the client or server creates a new API -handle. The handles encapsulate the API and structure versions -specified by kadm5_init_*'s caller and all other internal data needed -by the library. A process can have multiple open API handles -simultaneously by calling kadm5_init_* multiple times, and call can -specify a different version, client or service principal, and so -forth. - -Each kadm5 function verifies the handle it is given with the -CHECK_HANDLE or _KADM5_CHECK_HANDLE macros. The CHECK_HANDLE macro -differs for the client and server library because the handle types -used by those libraries differ, so it is defined in both -$<$client_internal.h$>$ and $<$server_internal.h$>$ in the library -source directory. In each header file, CHECK_HANDLE first calls -GENERIC_CHECK_HANDLE, defined in $<$admin_internal.h$>$, which -verifies the magic number, API version, and structure version that is -contained in both client and server handles. CHECK_HANDLE then calls -either CLIENT_CHECK_HANDLE or SERVER_CHECK_HANDLE respectively to -verify the client- or server-library specific handle fields. - -The CHECK_HANDLE macro is useful because it inlines the handle check -instead of requiring a separate function call. However, using -CHECK_HANDLE means that a source file cannot be compiled once and -included into both the client and server library, because CHECK_HANDLE -is always either specific to either the client or server library, not -both. There are a number of functions that can be implemented with -the same code in both the client and server libraries, however, -including all of the kadm5_free functions and -kadm5_chpass_principal_util. The _KADM5_CHECK_HANDLE macro solves -this problem; instead of inlining the handle check, it calls the -function _kadm5_check_handle which is defined separately in both the -client and server library, in client_init.c and server_init.c. -Since these two files are only compiled once and put in a single -library, they simply verify the handle they are passed with -CHECK_HANDLE and return the result. - -\section{API Versioning} - -The KADM5 system is designed to support multiple versions of the KADM5 -API. Presently, two versions exist: KADM5_API_VERSION_1 and -KADM5_API_VERSION_2. The former is equivalant to the initial -OpenVision API, OVSEC_KADM_API_VERSION_1; the latter was created -during the initial integration of the OpenVision system into the MIT -release. - -Implementing a versioned API in C via with both local and RPC access -presents a number of design issues, some of them quite subtle. The -contexts in which versioning considerations must be made include: - -\begin{enumerate} -\item Typedefs, function declarations, and defined constants depend on -the API version a client is written to and must be correct at compile -time. - -\item Each function in the server library must behave according to the -API version specified by the caller at runtime to kadm5_init_*. - -\item The XDR functions used by the RPC layer to transmit function -arguments and results must encode data structures correctly depending -on the API version specified by the client at runtime. - -\item Each function in the client library must behave according to the -API version specified by the caller at runtime to kadm5_init_*. - -\item The RPC server (kadmind) must accept calls from a client using -any supported API version, and must then invoke the function in the -server library corresponding to the RPC with the API version indicated -by the client caller. - -\item When a first API function is invoked that needs to call a second -function in the API on its own behalf, and that second API function's -behavior depends on the API version specified, the first API function -must either be prepared to call the second API function at whatever -version its caller specifies or have a means of always calling the -second API function at a pre-determined version. -\end{enumerate} - -The following functions describe how each context is handled. - -\subsection{Designing for future compatibility} - -Any code whose behavior depends on the API version should be written -so as to be compatible with future, currently unknown API versions on -the grounds that any particuarly piece of API behavior will most -likely not change between versions. For example, in the current -system, the code is not written as ``if this is VERSION_1, do X, else -if this is VERSION_2, do Y''; instead, it is written as ``if this is -VERSION_1, do X; else, do Y.'' The former will require additional -work when VERSION_3 is defined, even if ``do Y'' is still the correct -action, whereas the latter will work without modification in that -case. - -\subsection{Header file declarations} - -Typedefs, defined constants and macros, and function declarations may -change between versions. A client is always written to a single, -specific API version, and thus expects the header files to define -everything according to that API. Failure of a header file to define -values correctly will result in either compiler warnings (e.g. if the -pointer type of a function argument changes) or fatal errors (e.g. if -the number of arguments to a function changes, or the fields of a -structure change). For example, in VERSION_1, kadm5_get_policy took a -pointer to a pointer to a structure, and in VERSION_2 it takes a -pointer to a structure; that would generate a warning if not correct. -In VERSION_1, kadm5_randkey_principal accepted three arguments but in -VERSION_2 accepts four; that would generate a fatal error. - -The header file defines everything correctly based on the value of the -USE_KADM5_API_VERSION constant. The constant can be assigned to an -integer corresponding to any supported API version, and defaults to -the newest version. The header files then simply use an \#ifdef to -include the right definitions: -% -\begin{verbatim} -#if USE_KADM5_API_VERSION == 1 -kadm5_ret_t kadm5_get_principal(void *server_handle, - krb5_principal principal, - kadm5_principal_ent_t *ent); -#else -kadm5_ret_t kadm5_get_principal(void *server_handle, - krb5_principal principal, - kadm5_principal_ent_t ent, - long mask); -#endif -\end{verbatim} - -\subsection{Server library functions} - -Server library functions must know how many and what type of arguments -to expect, and must operate on those arguments correctly, based on the -API version with which they are invoked. The API version is contained -in the handle that is alwasy passed as their first argument, generated -by kadm5_init_* (to which the client specified the API version to use -at run-time). - -In general, it is probably unsafe for a compiled function in a library -to re-interpret the number and type of defined arguments at run-time -since the calling conventions may not allow it; for example, a -function whose first argument was a short in one version and a pointer -in the next might fail if it simply typed-casted the argument. In -that case, the function would have to written to take variable -arguments (i.e. use $<$stdarg.h$>$) and extract them from the stack -based on the API version. Alternatively, a separate function for each -API version could be defined, and $<$kadm5/admin.h$>$ could be written -to \v{\#define} the exported function name based on the value of -USE_KADM5_API_VERSION. - -In the current system, it turns out, that isn't necessary, and future -implementors should take try to ensure that no version has semantics -that will cause such problems in the future. All the functions in -KADM5 that have different arguments or results between VERSION_1 and -VERSION_2 do so simply by type-casting their arguments to the -appropriate version and then have separate code paths to handle each -one correctly. kadm5_get_principal, in svr_principal.c, is a good -example. In VERSION_1, it took the address of a pointer to a -kadm5_principal_ent_t to fill in with a pointer to allocated memory; -in VERSION_2, it takes a pointer to a structure to fill in, and a mask -of which fields in that structure should be filled in. Also, the -contents of the kadm5_principal_ent_t changed slightly between the two -versions. kadm5_get_principal handles versioning as follows -(following along in the source code will be helpful): - -\begin{enumerate} -\item If VERSION_1, it saves away its entry argument (address of a -pointer to a structure) and resets its value to contain the address of -a locally stack-allocated entry structure; this allows most of the -function to written once, in terms of VERSION_2 semantics. If -VERSION_1, it also resets its mask argument to be -KADM5_PRINCIPAL_NORMAL_MASK, because that is the equivalent to -VERSION_1 behavior, which was to return all the fields of the -structure. - -\item The bulk of the function is implemented as expected for -VERSION_2. - -\item The new fields in the VERSION_2 entry structure are assigned -inside a block that is only execute if the caller specified -VERSION_2. This saves a little time for a VERSION_1 caller. - -\item After the entry structure is filled, the function checks again -if it was called as VERSION_1. If so, it allocates a new -kadm5_principal_ent_t_v1 structure (which is conveniently defined in -the header file) with malloc, copies the appropriate values from the -entry structure into the VERSION_1 entry structure, and then writes -the address of the newly allocated memory into address specified by -the original entry argument which it had previously saved away. -\end{enumerate} - -There is another complication involved in a function re-interpreting -the number of arguments it receives at compile time---it cannot assign -any value to an argument for which the client did not pass a value. -For example, a VERSION_1 client only passes three arguments to -kadm5_get_principal. If the implementation of kadm5_get_principal -notices that the caller is VERSION_1 and therefore assigns its fourth -argument, mask, to a value that mimics the VERSION_1 behavior, it may -inadvertently overwrite data on its caller's stack. This problem can -be avoided simply by using a true local variable in such cases, -instead of treating an unpassed argument as a local variable. - -\subsection{XDR functions} - -The XDR functions used to encode function arguments and results must -know how to encode the data for any API version. This is important -both so that all the data gets correctly transmitted and so that -protocol compatibility between clients or servers using the new -library but an old API version is maintained; specific, new kadmind -servers should support old kadm5 clients. - -The signature of all XDR functions is strictly defined: they take the -address of an XDR function and the address of the data object to be -encoded or decoded. It is thus impossible to provide the API version -of the data object as an additional argument to an XDR function. -There are two other means to convey the information, storing the API -version to use as a field in the data object itself and creating -separate XDR functions to handle each different version of the data -object, and both of them are used in KADM5. - -In the client library, each kadm5 function collects its arguments into -a single structure to be passed by the RPC; similarly, it expects all -of the results to come back as a single structure from the RPC that it -will then decode back into its constituent pieces (these are the -standard ONC RPC semantics). In order to pass versioning information -to the XDR functions, each function argument and result datatype has a -filed to store the API version. For example, consider -kadm5_get_principal's structures: -% -\begin{verbatim} -struct gprinc_arg { - krb5_ui_4 api_version; - krb5_principal princ; - long mask; -}; -typedef struct gprinc_arg gprinc_arg; -bool_t xdr_gprinc_arg(); - -struct gprinc_ret { - krb5_ui_4 api_version; - kadm5_ret_t code; - kadm5_principal_ent_rec rec; -}; -typedef struct gprinc_ret gprinc_ret; -bool_t xdr_gprinc_ret(); -\end{verbatim} -% -kadm5_get_principal (in client_principal.c) assigns the api_version -field of the gprinc_arg to the version specified by its caller, -assigns the princ field based on its arguments, and assigns the mask -field from its argument if the caller specified VERSION_2. It then -calls the RPC function clnt_call, specifying the XDR functions -xdr_gprinc_arg and xdr_gprinc_ret to handle the arguments and results. - -xdr_gprinc_arg is invoked with a pointer to the gprinc_arg structure -just described. It first encodes the api_version field; this allows -the server to know what to expect. It then encodes the krb5_principal -structure and, if api_version is VERSION_2, the mask. If api_version -is not VERSION_2, it does not encode {\it anything} in place of the -mask, because an old VERSION_1 server will not expect any other data -to arrive on the wire there. - -The server performs the kadm5_get_principal call and returns its -results in an XDR encoded gprinc_ret structure. clnt_call, which has -been blocking until the results arrived, invokes xdr_gprinc_ret with a -pointer to the encoded data for it to decode. xdr_gprinc_ret first -decodes the api_version field, and then the code field since that is -present in all versions to date. The kadm5_principal_ent_rec presents -a problem, however. The structure does not itself contain an -api_version field, but the structure is different between the two -versions. Thus, a single XDR function cannot decode both versions of -the structure because it will have no way to decide which version to -expect. The solution is to have two functions, -kadm5_principal_ent_rec_v1 and kadm5_principal_ent_rec, which always -decode according to VERSION_1 or VERSION_2, respectively. gprinc_ret -knows which one to invoke because it has the api_version field -returned by the server (which is always the same as that specified by -the client in the gpring_arg). - -In hindsight, it probably would have been better to encode the API -version of all structures directly in a version field in the structure -itself; then multiple XDR functions for a single data type wouldn't be -necessary, and the data objects would stand complete on their own. -This can be added in a future API version if desired. - -\subsection{Client library functions} - -Just as with server library functions, client library functions must -be able to interpret their arguments and provide result according to -the API version specified by the caller. Again, kadm5_get_principal -(in client_principal.c) is a good example. The gprinc_ret structure -that it gets back from clnt_call contains a kadm5_principal_ent_rec or -a kadm5_principal_ent_rec_v1 (the logic is simplified somewhat because -the VERSION_2 structure only has new fields added on the end). If -kadm5_get_principal was invoked with VERSION_2, that structure should -be copied into the pointer provided as the entry argument; if it was -invoked with VERSION_1, however, the structure should be copied into -allocated memory whose address is then written into the pointer -provided by the entry argument. Client library functions make this -determination based on the API version specified in the provided -handle, just like server library functions do. - -\subsection{Admin server stubs} - -When an RPC call arrives at the server, the RPC layer authenticates -the call using the GSS-API, decodes the arguments into their -single-structure form (ie: a gprinc_arg) and dispatches the call to a -stub function in the server (in server_stubs.c). The stub function -first checks the caller's authorization to invoke the function and, if -authorized, calls the kadm5 function corresponding to the RPC function -with the arguments specified in the single-structure argument. - -Once again, kadm5_get_principal is a good example for the issues -involved. The contents of the gprinc_arg given to the stub -(get_principal_1) depends on the API version the caller on the client -side specified; that version is available to the server in the -api_version field of the gprinc_arg. When the server calls -kadm5_get_principal in the server library, it must give that function -an API handle that contains the API version requested by the client; -otherwise the function semantics might not be correct. One -possibility would be for the server to call kadm5_init for each client -request, specifing the client's API version number and thus generating -an API handle with the correct version, but that would be -prohibitively inefficient. Instead, the server dips down in the -server library's internal abstraction barrier, using the function -new_server_handle to cons up a server handle based on the server's own -global_server_handle but using the API version specified by the -client. The server then passes the newly generated handle to -kadm5_get_principal, ensuring the right behavior, and creates the -gprinc_ret structure in a manner similar to that described above. - -Although new_server_handle solves the problem of providing the server -with an API handle containing the right API version number, it does -not solve another problem: that a single source file, server_stubs.c, -needs to be able to invoke functions with arguments appropriate for -multiple API versions. If the client specifies VERSION_1, for -example, the server must invoke kadm5_get_principal with three -arguments, but if the client specifies VERSION_2 the server must -invoke kadm5_get_principal with four arguments. The compiler will not -allow this inconsistency. The server defines wrapper functions in a -separate source file that match the old version, and the separate -source file is compiled with USE_KADM5_API_VERSION set to the old -version; see kadm5_get_principal_v1 in server_glue_v1.c. The server -then calls the correct variant of kadm5_get_principal_* based on the -API version and puts the return values into the gprinc_ret in a manner -similar to that described above. - -Neither of these solutions are necessarily correct. new_server_handle -violates the server library's abstraction barrier and is at best a -kludge; the server library should probably export a function to -provide this behavior without violating the abstraction; -alternatively, the librar should be modified so that having the server -call kadm5_init for each client RPC request would not be too -inefficient. The glue functions in server_glue_v1.c really are not -necessary, because the server stubs could always just pass dummy -arguments for the extra arguments; after all, the glue functions pass -{\it nothing} for the extra arguments, so they just end up as stack -garbage anyway. - -Another alternative to the new_server_handle problem is to have the -server always invoke server library functions at a single API version, -and then have the stubs take care of converting the function arguments -and results back into the form expected by the caller. In general, -however, this might require the stubs to duplicate substantial logic -already present in the server library and further violate the server -library's abstraction barrier. - -\subsection{KADM5 self-reference} - -Some kadm5 functions call other kadm5 functions ``on their own -behalf'' to perform functionality that is necessary but that does not -directly affect what the client sees. For example, -kadm5_chpass_principal has to enforce password policies; thus, it -needs to call kadm5_get_principal and, if the principal has a policy, -kadm5_get_policy and kadm5_modify_principal in the process of changing -a principal's password. This leads to a complication: what API handle -should kadm5_chpass_principal pass to the other kadm5 functions it -calls? - -The ``obvious,'' but wrong, answer is that it should pass the handle -it was given by its caller. The caller may provide an API handle -specifying any valid API version. Although the semantics of -kadm5_chpass_principal did not change between VERSION_1 and VERSION_2, -the declarations of both kadm5_get_principal and kadm5_get_policy -did. Thus, to use the caller's API handle, kadm5_chpass_principal -will have to have a separate code path for each API version, even -though it itself did not change bewteen versions, and duplicate a lot -of logic found elsewhere in the library. - -Instead, each API handle contains a ``local-use handle,'' or lhandle, -that kadm5 functions should use to call other kadm5 functions. For -example, the client-side library's handle structure is: -% -\begin{verbatim} -typedef struct _kadm5_server_handle_t { - krb5_ui_4 magic_number; - krb5_ui_4 struct_version; - krb5_ui_4 api_version; - char * cache_name; - int destroy_cache; - CLIENT * clnt; - krb5_context context; - kadm5_config_params params; - struct _kadm5_server_handle_t *lhandle; -} kadm5_server_handle_rec, *kadm5_server_handle_t; -\end{verbatim} -% -The lhandle field is allocated automatically when the handle is -created. All of the fields of the API handle that are accessed -outside kadm5_init are also duplicated in the lhandle; however, the -api_version field of the lhandle is always set to a {\it constant} -value, regardless of the API version specified by the caller to -kadm5_init. In the current implementation, the lhandle's api_version -is always VERSION_2. - -By passing the caller's handle's lhandle to recursively called kadm5 -functions, a kadm5 function is assured of invoking the second kadm5 -function with a known API version. Additionally, the lhandle's -lhandle field points back to the lhandle, in case kadm5 functions call -themselves more than one level deep; handle$->$lhandle always points -to the same lhandle, no matter how many times the indirection is -performed. - -This scheme might break down if a kadm5 function has to call another -kadm5 function to perform operations that they client will see and for -its own benefit, since the semantics of the recursively-called kadm5 -function may depend on the API version specified and the client may be -depending on a particular version's behavior. Future implementators -should avoid creating a situation in which this is possible. - -\section{Server Main} - -The admin server starts by trapping all fatal signals and directing -them to a cleanup-and-exit function. It then creates and exports the -RPC interface and enters its main loop. - -The main loop dispatches all incoming requests to the RPC mechanism. -In a previous version, after 15 seconds of inactivity, the server -closed all open databases; each database was be automatically reopened -by the API function implementations as necessary. That behavior -existed to protect against loss of written data before the process -exited. The current database libraries write all changes out to disk -immediately, however, so this behavior is no longer required or -performed. - -\section{Remote Procedure Calls} - -The RPC for the Admin system will be based on ONC RPC. ONC RPC is -used because it is a well-known, portable RPC mechanism. The -underlying external data representation (xdr) mechanisms for wire -encapsulation are well-known and extensible. Authentication to the -admin server and encryption of all RPC functional arguments and -results are be handled via the AUTH_GSSAPI authentication flavor of -ONC RPC. - -\section{Database Record Types} -\label{sec:db-types} - -\subsection{Admin Principal, osa_princ_ent_t} - -The admin principal database stores records of the type -osa_princ_ent_t (declared in $<$kadm5/adb.h$>$), which is the -subset of the kadm5_principal_ent_t structure that is not stored -in the Kerberos database plus the necessary bookkeeping information. -The records are keyed by the ASCII representation of the principal's -name, including the trailing NULL. - -\begin{verbatim} -typedef struct _osa_pw_hist_t { - int n_key_data; - krb5_key_data *key_data; -} osa_pw_hist_ent, *osa_pw_hist_t; - -typedef struct _osa_princ_ent_t { - char * policy; - u_int32 aux_attributes; - - unsigned int old_key_len; - unsigned int old_key_next; - krb5_kvno admin_history_kvno; - osa_pw_hist_ent *old_keys; - - - u_int32 num_old_keys; - u_int32 next_old_key; - krb5_kvno admin_history_kvno; - osa_pw_hist_ent *old_keys; -} osa_princ_ent_rec, *osa_princ_ent_t; -\end{verbatim} - -The fields that are different from kadm5_principal_ent_t are: - -\begin{description} -\item[num_old_keys] The number of previous keys in the old_keys array. -This value must be 0 $\le$ num_old_keys $<$ pw_history_num. - -\item[old_key_next] The index into old_keys where the next key should -be inserted. This value must be 0 $\le$ old_key_next $\le$ -num_old_keys. - -\item[admin_history_kvno] The key version number of the kadmin/history -principal's key used to encrypt the values in old_keys. If the server -library finds that kadmin/history's kvno is different from the value -in this field, it returns KADM5_BAD_HIST_KEY. - -\item[old_keys] The array of the principal's previous passwords, each -encrypted in the kadmin/history key. There are num_old_keys -elements. Each ``password'' in the array is itself an array of -n_key_data krb5_key_data structures, one for each keysalt type the -password was encoded in. -\end{description} - -\subsection{Policy, osa_policy_ent_t} - -The policy database stores records of the type osa_policy_ent_t -(declared in $<$kadm5/adb.h$>$) , which is all of -kadm5_policy_ent_t plus necessary bookkeeping information. The -records are keyed by the policy name. - -\begin{verbatim} -typedef struct _osa_policy_ent_t { - char *policy; - - u_int32 pw_min_life; - u_int32 pw_max_life; - u_int32 pw_min_length; - u_int32 pw_min_classes; - u_int32 pw_history_num; - - u_int32 refcnt; -} osa_policy_ent_rec, *osa_policy_ent_t; -\end{verbatim} - -\subsection{Kerberos, krb5_db_entry} - -The Kerberos database stores records of type krb5_db_entry, which is -defined in the $<$k5-int.h$>$ header file. The semantics of each -field are defined in the libkdb functional specification. - -\section{Database Access Methods} - -\subsection{Principal and Policy Databases} - -This section describes the database abstraction used for the admin -policy database; the admin principal database used to be treated in -the same manner but is now handled more directly as krb5_tl_data; -thus, nothing in this section applies to it any more. Since both -databases export equivalent functionality, the API is only described -once. The character T is used to represent both ``princ'' and -``policy''. The location of the principal database is defined by the -configuration parameters given to any of the kadm5_init functions in -the server library. - -Note that this is {\it only} a database abstraction. All functional -intelligence, such as maintaining policy reference counts or sanity -checking, must be implemented above this layer. - -Prototypes for the osa functions are supplied in -$<$kadm5/adb.h$>$. The routines are defined in libkadm5srv.a. They -require linking with the Berkely DB library. - -\subsubsection{Error codes} - -The database routines use com_err for error codes. The error code -table name is ``adb'' and the offsets are the same as the order -presented here. The error table header file is -$<$kadm5/adb_err.h$>$. Callers of the OSA routines should first call -init_adb_err_tbl() to initialize the database table. - -\begin{description} -\item[OSA_ADB_OK] Operation successful. -\item[OSA_ADB_FAILURE] General failure. -\item[OSA_ADB_DUP] Operation would create a duplicate database entry. -\item[OSA_ADB_NOENT] Named entry not in database. -\item[OSA_ADB_BAD_PRINC] The krb5_principal structure is invalid. -\item[OSA_ADB_BAD_POLICY] The specified policy name is invalid. -\item[OSA_ADB_XDR_FAILURE] The principal or policy structure cannot be -encoded for storage. -\item[OSA_ADB_BADLOCKMODE] Bad lock mode specified. -\item[OSA_ADB_CANTLOCK_DB] Cannot lock database, presumably because it -is already locked. -\item[OSA_ADB_NOTLOCKED] Internal error, database not locked when -unlock is called. -\item[OSA_ADB_NOLOCKFILE] KADM5 administration database lock file missing. -\end{description} - -Database functions can also return system errors. Unless otherwise -specified, database functions return OSA_ADB_OK. - -\subsubsection{Locking} - -All of the osa_adb functions except open and close lock and unlock the -database to prevent concurrency collisions. The overall locking -algorithm is as follows: - -\begin{enumerate} -\item osa_adb_open_T calls osa_adb_init_db to allocate the osa_adb_T_t -structure and open the locking file for further use. - -\item Each osa_adb functions locks the locking file and opens the -appropriate database with osa_adb_open_and_lock, performs its action, -and then closes the database and unlocks the locking file with -osa_adb_close_and_unlock. - -\item osa_adb_close_T calls osa_adb_fini_db to close the locking file -and deallocate the db structure. -\end{enumerate} - -Functions which modify the database acquire an exclusive lock, others -acqure a shared lock. osa_adb_iter_T acquires an exclusive lock for -safety but as stated below consequences of modifying the database in -the iteration function are undefined. - -\subsubsection{Function descriptions} - -\begin{verbatim} -osa_adb_ret_t osa_adb_create_T_db(kadm5_config_params *params) -\end{verbatim} -% -Create the database and lockfile specified in params. The database -must not already exist, or EEXIST is returned. The lock file is only -created after the database file has been created successfully. - -\begin{verbatim} -osa_adb_ret_t osa_adb_rename_T_db(kadm5_config_params *fromparams, - kadm5_config_params *toparams) -\end{verbatim} -% -Rename the database named by fromparams to that named by toparams. -The fromparams database must already exist; the toparams database may -exist or not. When the function returns, the database named by -fromparams no longer exists, and toparams has been overwritten with -fromparams. This function acquires a permanent lock on both databases -for the duration of its operation, so a failure is likely to leave the -databases unusable. - -\begin{verbatim} -osa_adb_ret_t osa_adb_destroy_policy_db(kadm5_config_params *params) -\end{verbatim} -% -Destroy the database named by params. The database file and lock file -are deleted. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_open_T(osa_adb_T_t *db, char *filename); -\end{verbatim} -% -Open the database named filename. Returns OSA_ADB_NOLOCKFILE if the -database does not exist or if the lock file is missing. The database -is not actually opened in the operating-system file sense until a lock -is acquire. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_close_T(osa_adb_T_t db); -\end{verbatim} -% -Release all shared or exclusive locks (on BOTH databases, since they -use the same lock file) and close the database. - -It is an error to exit while a permanent lock is held; -OSA_ADB_NOLOCKFILE is returned in this case. - -\begin{verbatim} -osa_adb_ret_t osa_adb_get_lock(osa_adb_T_t db, int mode) -\end{verbatim} - -Acquire a lock on the administration databases; note that both -databases are locked simultaneously by a single call. The mode -argument can be OSA_ADB_SHARED, OSA_ADB_EXCLUSIVE, or -OSA_ADB_PERMANENT. The first two and the third are really disjoint -locking semantics and should not be interleaved. - -Shared and exclusive locks have the usual semantics, and a program can -upgrade a shared lock to an exclusive lock by calling the function -again. A reference count of open locks is maintained by this function -and osa_adb_release_lock so the functions can be called multiple -times; the actual lock is not released until the final -osa_adb_release_lock. Note, however, that once a lock is upgraded -from shared to exclusive, or from exclusive to permanent, it is not -downgraded again until released completely. In other words, -get_lock(SHARED), get_lock(EXCLUSIVE), release_lock() leaves the -process with an exclusive lock with a reference count of one. An -attempt to get a shared or exclusive lock that conflicts with another -process results in the OSA_ADB_CANLOCK_DB error code. - -This function and osa_adb_release_lock are called automatically as -needed by all other osa_adb functions to acquire shared and exclusive -locks and so are not normally needed. They can be used explicitly by -a program that wants to perform multiple osa_adb functions within the -context of a single lock. - -Acquiring an OSA_ADB_PERMANENT lock is different. A permanent lock -consists of first acquiring an exclusive lock and then {\it deleting -the lock file}. Any subsequent attempt to acquire a lock by a -different process will fail with OSA_ADB_NOLOCKFILE instead of -OSA_ADB_CANTLOCK_DB (attempts in the same process will ``succeed'' -because only the reference count gets incremented). The lock file is -recreated by osa_adb_release_lock when the last pending lock is released. - -The purpose of a permanent lock is to absolutely ensure that the -database remain locked during non-atomic operations. If the locking -process dies while holding a permanent lock, all subsequent osa_adb -operations will fail, even through a system reboot. This is useful, -for example, for ovsec_adm_import which creates both new database -files in a temporary location and renames them into place. If both -renames do not fully complete the database will probably be -inconsistent and everything should stop working until an administrator -can clean it up. - -\begin{verbatim} -osa_adb_ret_t osa_adb_release_lock(osa_adb_T_t db) -\end{verbatim} - -Releases a shared, exclusive, or permanent lock acquired with -osa_adb_get_lock, or just decrements the reference count if multiple -locks are held. When a permanent lock is released, the lock file is -re-created. - -All of a process' shared or exclusive database locks are released when -the process terminates. A permanent lock is {\it not} released when -the process exits (although the exclusive lock it begins with -obviously is). - -\begin{verbatim} -osa_adb_ret_t -osa_adb_create_T(osa_adb_T_t db, osa_T_ent_t entry); -\end{verbatim} -% -Adds the entry to the database. All fields are defined. Returns -OSA_ADB_DUP if it already exists. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_destroy_T(osa_adb_T_t db, osa_T_t name); -\end{verbatim} - -Removes the named entry from the database. Returns OSA_ADB_NOENT if -it does not exist. - -\begin{verbatim} -osa_adb_ret_t -osa_adb_get_T(osa_adb_T_t db, osa_T_t name, - osa_princ_ent_t *entry); -\end{verbatim} - -Looks up the named entry in the db, and returns it in *entry in -allocated storage that must be freed with osa_adb_free_T. Returns -OSA_ADB_NOENT if name does not exist, OSA_ADB_MEM if memory cannot be -allocated. - -\begin{verbatim} -osa_adb_ret_t -osadb_adb_put_T(osa_adb_T_t db, osa_T_ent_t entry); -\end{verbatim} - -Modifies the existing entry named in entry. All fields must be filled -in. Returns OSA_DB_NOENT if the named entry does not exist. Note -that this cannot be used to rename an entry; rename is implemented by -deleting the old name and creating the new one (NOT ATOMIC!). - -\begin{verbatim} -void osa_adb_free_T(osa_T_ent_t); -\end{verbatim} - -Frees the memory associated with an osa_T_ent_t allocated by -osa_adb_get_T. - -\begin{verbatim} -typedef osa_adb_ret_t (*osa_adb_iter_T_func)(void *data, - osa_T_ent_t entry); - -osa_adb_ret_t osa_adb_iter_T(osa_adb_T_t db, osa_adb_iter_T_func func, - void *data); -\end{verbatim} - -Iterates over every entry in the database. For each entry ent in the -database db, the function (*func)(data, ent) is called. If func -returns an error code, osa_adb_iter_T returns an error code. If all -invokations of func return OSA_ADB_OK, osa_adb_iter_T returns -OSA_ADB_OK. The function func is permitted to access the database, -but the consequences of modifying the database during the iteration -are undefined. - -\subsection{Kerberos Database} - -Kerberos uses the libkdb interface to store krb5_db_entry records. It -can be accessed and modified in parallel with the Kerberos server, -using functions that are defined inside the KDC and the libkdb.a. The -libkdb interface is defined in the libkdb functional specifications. - -\subsubsection{Initialization and Key Access} - -Keys stored in the Kerberos database are encrypted in the Kerberos -master key. The admin server will therefore have to acquire the key -before it can perform any key-changing operations, and will have to -decrypt and encrypt the keys retrieved from and placed into the -database via krb5_db_get_principal and _put_principal. This section -describes the internal admin server API that will be used to perform -these functions. - -\begin{verbatim} -krb5_principal master_princ; -krb5_encrypt_block master_encblock; -krb5_keyblock master_keyblock; - -void kdc_init_master() -\end{verbatim} - -kdc_init_master opens the database and acquires the master key. It -also sets the global variables master_princ, master_encblock, and -master_keyblock: - -\begin{itemize} -\item master_princ is set to the name of the Kerberos master principal -(\v{K/M@REALM}). - -\item master_encblock is something I have no idea about. - -\item master_keyblock is the Kerberos master key -\end{itemize} - -\begin{verbatim} -krb5_error_code kdb_get_entry_and_key(krb5_principal principal, - krb5_db_entry *entry, - krb5_keyblock *key) -\end{verbatim} - -kdb_get_entry_and_key retrieves the named principal's entry from the -database in entry, and decrypts its key into key. The caller must -free entry with krb5_dbm_db_free_principal and free key-$>$contents with -free.\footnote{The caller should also \v{memset(key-$>$contents, 0, -key-$>$length)}. There should be a function krb5_free_keyblock_contents -for this, but there is not.} - -\begin{verbatim} -krb5_error_code kdb_put_entry_pw(krb5_db_entry *entry, char *pw) -\end{verbatim} - -kdb_put_entry_pw stores entry in the database. All the entry values -must already be set; this function does not change any of them except -the key. pw, the NULL-terminated password string, is converted to a -key using string-to-key with the salt type specified in -entry-$>$salt_type.\footnote{The salt_type should be set based on the -command line arguments to the kadmin server (see the ``Command Line'' -section of the functional specification).} - -\section{Admin Principal and Policy Database Implementation} - -The admin principal and policy databases will each be stored in a -single hash table, implemented by the Berkeley 4.4BSD db library. -Each record will consist of an entire osa_T_ent_t. The key into the -hash table is the entry name (for principals, the ASCII representation -of the name). The value is the T entry structure. Since the key and -data must be self-contained, with no pointers, the Sun xdr mechanisms -will be used to marshal and unmarshal data in the database. - -The server in the first release will be single-threaded in that a -request will run to completion (or error) before the next will run, -but multiple connections will be allowed simultaneously. - -\section{ACLs, acl_check} - -The ACL mechanism described in the ``Authorization ACLs'' section of -the functional specifications will be implemented by the acl_check -function. - -\begin{verbatim} -enum access_t { - ACCESS_DENIED = 0, - ACCESS_OK = 1, -}; - -enum access_t acl_check(krb5_principal princ, char *priv); -\end{verbatim} - -The priv argument must be one of ``get'', ``add'', ``delete'', or -``modify''. acl_check returns 1 if the principal princ has the named -privilege, 0 if it does not. - -\section{Function Details} - -This section discusses specific design issues for Admin API functions -that are not addresed by the functional specifications. - -\subsection{kadm5_create_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -The principal's initial key is not stored in the key history array at -creation time. - -\subsection{kadm5_delete_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -\subsection{kadm5_modify_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -If pw_history_num changes and the new value $n$ is smaller than the -current value of num_old_keys, old_keys should end up with the $n$ -most recent keys; these are found by counting backwards $n$ elements -in old_keys from old_key_next. old_key_nexts should then be reset to -0, the oldest of the saved keys, and num_old_keys set to $n$, the -new actual number of old keys in the array. - -\subsection{kadm5_chpass_principal, randkey_principal} - -The algorithm for determining whether a password is in the principal's -key history is complicated by the use of the kadmin/history \k{h} -encrypting key. - -\begin{enumerate} -\item For kadm5_chpass_principal, convert the password to a key -using string-to-key and the salt method specified by the command line -arguments. - -\item If the POLICY bit is set and pw_history_num is not zero, check -if the new key is in the history. -\begin{enumerate} -\item Retrieve the principal's current key and decrypt it with \k{M}. -If it is the same as the new key, return KADM5_PASS_REUSE. -\item Retrieve the kadmin/history key \k{h} and decrypt it with \k{M}. -\item Encrypt the principal's new key in \k{h}. -\item If the principal's new key encrypted in \k{h} is in old_keys, -return KADM5_PASS_REUSE. -\item Encrypt the principal's current key in \k{h} and store it in -old_keys. -\item Erase the memory containing \k{h}. -\end{enumerate} - -\item Encrypt the principal's new key in \k{M} and store it in the -database. -\item Erase the memory containing \k{M}. -\end{enumerate} - -To store the an encrypted key in old_keys, insert it as the -old_key_next element of old_keys, and increment old_key_next by one -modulo pw_history_num. - -\subsection{kadm5_get_principal} - -If the named principal exists in either the Kerberos or admin -principal database, but not both, return KADM5_BAD_DB. - -\end{document} diff --git a/doc/kadm5/api-unit-test.tex b/doc/kadm5/api-unit-test.tex deleted file mode 100644 index 3e3f6e2bf..000000000 --- a/doc/kadm5/api-unit-test.tex +++ /dev/null @@ -1,2677 +0,0 @@ -\documentstyle[times,fullpage,rcsid]{article} - -\rcs$Header$ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Make _ actually generate an _, and allow line-breaking after it. -\let\underscore=\_ -\catcode`_=13 -\def_{\underscore\penalty75\relax} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcommand{\test}[1]{\begin{description} -\setlength{\itemsep}{0pt} -#1 -\end{description} - -} - -\newcommand{\numtest}[2]{\begin{description} -\setlength{\itemsep}{0pt} -\Number{#1} -#2 -\end{description} - -} - -\newcommand{\Number}[1]{\item[Number:] #1} -\newcommand{\Reason}[1]{\item[Reason:] #1} -\newcommand{\Expected}[1]{\item[Expected:] #1} -\newcommand{\Conditions}[1]{\item[Conditions:] #1} -\newcommand{\Priority}[1]{\item[Priority:] #1} -\newcommand{\Status}[1]{\item[Status:] #1} -\newcommand{\Vtwonote}[1]{\item[V2 note:] #1} -\newcommand{\Version}[1]{\item[Version:] #1} -\newcommand{\Call}[1]{} -%\newcommand{\Call}[1]{\item[Call:] #1} -%\newcommand{\Number}[1]{} -%\newcommand{\Reason}[1]{} -%\newcommand{\Expected}[1]{} -%\newcommand{\Conditions}[1]{} -%\newcommand{\Priority}[1]{} - -\title{KADM5 Admin API\\ -Unit Test Description\footnote{\rcsHeader}} -\author{Jonathan I. Kamens} - -\begin{document} - -\maketitle - -%\tableofcontents - -\section{Introduction} - -The following is a description of a black-box unit test of the KADM5 -API. Each API function is listed, followed by the tests that shoud be -performed on it. - -The tests described here are based on the ``Kerberos Administration -System KADM5 API Functional Specifications'', revision 1.68. This -document was originally written based on the OpenVision API functional -specifications, version 1.41, dated August 18, 1994, and many -indications of the original version remain. - -All tests which test for success should verify, using some means other -than the return value of the function being tested, that the requested -operation was successfully performed. For example: for init, test -that other operations can be performed after init; for destroy, test -that other operations can't be performed after destroy; for modify -functions, verify that all modifications to the database which should -have taken place did, and that the new, modified data is in effect; -for get operations, verify that the data retrieved is the data that -should actually be in the database. - -The tests would be better if they compared the actual contents of the -database before and after each test, rather than relying on the KADM5 -API to report the results of changes. - -Similarly, all tests which test for failure should verify that the -no component of the requested operation took place. For example: if -init fails, other operations should not work. If a modify fails, all -data in the database should be the same as it was before the attempt -to modify, and the old data should still be what is enforced. -Furthermore, tests which test for failure should verify that the -failure code returned is correct for the specific failure condition -tested. - -Most of the tests listed below should be run twice -- once locally on -the server after linking against the server API library, and once -talking to the server via authenticated Sun RPC after linking against -the client API library. Tests which should only be run locally or via -RPC are labelled with a ``local'' or ``RPC''. - -Furthermore, in addition to the tests labelled below, a test should be -implemented to verify that a client can't perform operations on the -server through the client API library when it's linked against -standard Sun RPC instead of OpenV*Secure's authenticated Sun RPC. -This will require a client with a modified version of ovsec_kadm_init -which doesn't call auth_gssapi_create. This client should call this -modified ovsec_kadm_init and then call some other admin API function, -specifying arguments to both functions that would work if the -authenticated Sun RPC had been used, but shouldn't if authentication -wasn't used. The test should verify that the API function call after -the init doesn't succeed. - -There is also another test to see if all the API functions handle getting an -invalid server handle correctly. This is not done as part of the tests that -are run through the TCL program cause the TCL program has no way of -invalidating a server handle. So there is a program that calls init and -changes the handle magic number, and then attempts to call each API function -with the corrupted server handle. - -A number of tests have been added or changed to correspond with KADM5 -API version 2. Tests which are only performed against the newer -version specify the version number in the test description. - -\section{ovsec_kadm_init} - -\numtest{1}{ -\Reason{An empty string realm is rejected.} -\Status{Implemented} -\Vtwonote{The empty string is now passed as the realm field of the -parameters structure.} -} - -\numtest{2}{ -\Reason{A realm containing invalid characters is rejected.} -\Status{Implemented} -\Vtwonote{The invalid character is now passed as the realm field of the -parameters structure.} -} - -\numtest{2.5}{ -\Reason{A non-existent realm is rejected.} -\Status{Implemented} -\Vtwonote{The non-existent realm is now passed as the realm field of the -parameters structure.} -} - -\numtest{3}{ -\Reason{A bad service name representing an existing principal - (different from the client principal) is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{A bad service name representing a non-existent - principal is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{A bad service name identical to the (existing) client - name is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{A null password causes password prompting.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{An empty-string causes password prompting} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{An incorrect password which is the password of another - user is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{An incorrect password which isn't the password of any - user is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{A null client_name is rejected.} -\Status{Implemented} -} - -% Empty string client name is legal. -%\numtest{11}{ -%\Reason{An empty-string client_name is rejected.} -%} - -\numtest{12}{ -\Reason{A client_name referring to a non-existent principal in - the default realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{A client_name referring to a non-existent principal - with the local realm specified explicitly is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{A client_name referring to a non-existent principal in - a nonexistent realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Reason{A client_name referring to an existing principal in a - nonexistent realm is rejected.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{17}{ -\Reason{Valid invocation (explicit client realm).} -\Status{Implemented} -} - -\numtest{18}{ -\Reason{Valid invocation (CHANGEPW_SERVICE).} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Valid invocation (explicit service realm).} -\Status{Implemented} -\Vtwonote{The explicit realm is now passed as the realm field of the -configuration parameters.} -} - -\numtest{20}{ -\Reason{Valid invocation (database access allowed after init).} -\Status{Implemented} -} - -%\numtest{21}{ -%\Reason{Init fails when called twice in a row.} -%\Status{Implemented} -%} - -\numtest{22}{ -\Reason{A null password causes master-key prompting.} -\Conditions{local} -\Status{Implemented} -\Vtwonote{Obsolete.} -} - -\numtest{22.5}{ -\Reason{A empty string password causes master-key prompting.} -\Conditions{local} -\Status{Implemented} -\Vtwonote{Obsolete.} -} - -%\numtest{23}{ -%\Reason{A non-null password causes reading from the kstash.} -%\Conditions{local} -%\Status{Implemented} -%} - -\numtest{24}{ -\Reason{Null service name is ignored in local invocation.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{25}{ -\Reason{Non-null service name is ignored in local invocation.} -\Conditions{local} -\Status{Implemented} -} - -%\numtest{26}{ -%\Reason{Can't do ``get'' operation before calling init.} -%\Status{Implemented} -%} - -%\numtest{27}{ -%\Reason{Can't do ``add'' operation before calling init.} -%\Status{Implemented} -%} - -%\numtest{28}{ -%\Reason{Can't do ``modify'' operation before calling init.} -%\Status{Implemented} -%} - -%\numtest{29}{ -%\Reason{Can't do ``delete'' operation before calling init.} -%\Status{Implemented} -%} - -\numtest{30}{ -\Reason{Can init after failed init attempt.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{31}{ -\Priority{High} -\Reason{Return BAD_STRUCT_VERSION when the mask bits are set to invalid values} -\Status{Implemented} -} - -\numtest{32}{ -\Priority{High} -\Reason{Return BAD_STRUCT_VERSION when the mask bits are not set} -\Status{Implemented} -} - -\numtest{33}{ -\Priority{High} -\Reason{Return OLD_STRUCT_VERSION when attempting to use an old/unsupported - structure version} -\Status{Implemented} -} - -\numtest{34}{ -\Priority{High} -\Reason{Return NEW_STRUCT_VERSION when attempting to use a newer version of - of the structure then what is supported} -\Status{Implemented} -} - -\numtest{35}{ -\Priority{High} -\Reason{Return BAD_API_VERSION when the mask bits are set to invalid values} -\Status{Implemented} -} - -\numtest{36}{ -\Priority{High} -\Reason{Return BAD_API_VERSION when the mask bits are not set} -\Status{Implemented} -} - -\numtest{37}{ -\Priority{High} -\Reason{Return OLD_LIB_API_VERSION when using an old/unsuppored - api version number} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{38}{ -\Priority{High} -\Reason{Return OLD_SERVER_API_VERSION attempting to use an - old/unsupported api version number} -\Conditions{local} -\Status{Implemented} -} - -\numtest{39}{ -\Priority{High} -\Reason{Return NEW_LIB_API_VERSION when using a newer api - version number then supported} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{40}{ -\Priority{High} -\Reason{Return NEW_SERVER_API_VERSION when using a newer api version - number then supported} -\Conditions{local} -\Status{Implemented} -} - -\numtest{41}{ -\Priority{High} -\Reason{Return BAD_XXX_VERSION when the API and the structure - version numbers are reversed} -\Status{Implemented} -} - -\numtest{42}{ -\Priority{High} -\Reason{Succeeds when using valid api and struct version numbers and masks} -\Status{Implemented} -} - -\numtest{43}{ -\Priority{Low} -\Reason{Returns two different server handle when called twice with same info} -} - -\numtest{44}{ -\Priority{Low} -\Reason{Returns two different server handles when called twice with - different info} -} - -\numtest{45}{ -\Priority{Bug fix, secure-install/3390} -\Reason{Returns SECURE_PRINC_MISSING when ADMIN_SERVICE does not -exist.} -\Status{Implemented} -} - -\numtest{46}{ -\Priority{Bug fix, secure-install/3390} -\Reason{Returns SECURE_PRINC_MISSING when CHANGEPW_SERVICE does not -exist.} -\Status{Implemented} -} - -\numtest{100}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the profile field of the configuration parameters, if -set.} -\Status{Implemented} -} - -\numtest{101}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the kadmind_port field of the configuration parameters, -if set.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{102}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the admin_server field of the configuration parameters, -if set with only an admin server name.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{102.5}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the admin_server field of the configuratin parameters, -if set with a host name and port number.} -\Conditions{RPC} -} - -\numtest{103}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the dbname field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{104}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the admin_dbname field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{105}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the admin_lockfile field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{106}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the mkey_from_kbd field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{107}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the stash_file field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{108}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the mkey_name field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{109}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the max_life field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{110}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the max_rlife field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{111}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the expiration field of the configuration parameters, if -set.} -\Status{Implemented} -\Conditions{local} -} - -\numtest{112}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the flags field of the configuration parameters, if -set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{113}{ -\Version{KADM5_API_VERSION_2} -\Reason{Obeys the keysalts and num_keysalts field of the configuration -parameters, if set.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{114}{ -\Version{KADM5_API_VERSION_2} -\Reason{Returns KADM5_BAD_SERVER_PARAMS if any client-only parameters -are specified to server-side init.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{115}{ -\Version{KADM5_API_VERSION_2} -\Reason{Returns KADM5_BAD_CLIENT_PARAMS if any client-only parameters -are specified to server-side init.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{116}{ -\Version{KADM5_API_VERSION_2} -\Reason{Two calls to init with clients having different privileges -succeedes, and both clients maintain their correct privileges.} -\Priority{Bug fix} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{117}{ -\Version{KADM5_API_VERSION_2} -\Reason{The max_life field defaults to value specified in the API -Functional Specification when kdc.conf is unreadable.} -\Priority{Bug fix, krb5-admin/18} -\Conditions{local} -\Status{Implemented} -} - -\numtest{150}{ -\Version{KADM5_API_VERSION_2} -\Reason{init_with_creds works when given an open ccache with a valid -credential for ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{151}{ -\Version{KADM5_API_VERSION_2} -\Reason{init_with_creds works when given an open ccache with a valid -credential for CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{152}{ -\Version{KADM5_API_VERSION_2} -\Reason{init_with_creds fails with KADM5_GSS_ERROR when given an open -ccache with no credentials.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{153}{ -\Version{KADM5_API_VERSION_2} -\Reason{init_with_creds fails with KADM5_GSS_ERROR when given an open -ccache without credentials for ADMIN_SERVICE or CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{154}{ -\Version{KADM5_API_VERSION_2} -\Reason{If the KRB5_KDC_PROFILE environment variable is set to a filename -that does not exist, init fails with ENOENT.} -\Conditions{RPC} -\Status{Implemented} -} - -\section{ovsec_kadm_destroy} - -\numtest{1}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -%\numtest{2}{ -%\Reason{Valid invocation (``get'' not allowed after destroy).} -%\Status{Implemented} -%} - -%\numtest{3}{ -%\Reason{Valid invocation (``add'' not allowed after destroy).} -%\Status{Implemented} -%} - -%\numtest{4}{ -%\Reason{Valid invocation (``modify'' not allowed after destroy).} -%\Status{Implemented} -%} - -%\numtest{5}{ -%\Reason{Valid invocation (``delete'' not allowed after destroy).} -%\Status{Implemented} -%} - -%\numtest{6}{ -%\Reason{Fails if database not initialized.} -%\Status{Implemented} -%} - -%\numtest{7}{ -%\Reason{Fails if invoked twice in a row.} -%\Status{Implemented} -%} - -\numtest{8}{ -\Reason{Database can be reinitialized after destroy.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{client} -} - -\section{ovsec_kadm_create_principal} - -%In the tests below, ``getu'' refers to a user who has only ``get'' access, -%''addu'' refers to a user who has only ``add'' access, ``modifyu'' refers to -%a user who has only ``modify'' access, and ``deleteu'' refers to a user -%who has only ``delete'' access. ``amu'' refers to a user with ``add'' and -%''modify'' access. ``new_princ'' refers to a principal entry structure -%filled in as follows: -% -% krb5_parse_name("newuser", \&new_princ.principal); -% krb5_timeofday(\&new_princ.princ_expire_time); -% new_princ.princ_expire_time += 130; -% krb5_timeofday(\&new_princ.last_pwd_change); -% new_princ.last_pwd_change += 140; -% krb5_timeofday(\&new_princ.pw_expiration); -% new_princ.pw_expiration += 150; -% new_princ.max_life = 160; -% krb5_parse_name("usera", \&new_princ.mod_name); -% krb5_timeofday(\&new_princ.mod_date); -% new_princ.mod_date += 170; -% new_princ.attributes = 0xabcdabcd; -% new_princ.kvno = 180; -% new_princ.mkvno = 190; -% new_princ.policy = null; -% new_princ.aux_attributes = 0xdeadbeef; -% -%The offsets of 130 through 190 above are used to ensure that the -%fields are all known to be different from each other, so that -%accidentally switched fields can be detected. Some of the fields in -%this structure may be changed by the tests, but they should clean up -%after themselves. - -%\numtest{1}{ -%\Reason{Fails if database not initialized.} -%\Status{Implemented} -%} - -\numtest{2}{ -\Reason{Fails on null princ argument.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails on null password argument.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails on empty-string password argument.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails when mask contains undefined bit.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails when mask contains LAST_PWD_CHANGE bit.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails when mask contains MOD_TIME bit.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails when mask contains MOD_NAME bit.} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{Fails when mask contains MKVNO bit.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails when mask contains AUX_ATTRIBUTES bit.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Fails when mask contains POLICY_CLR bit.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{Fails for caller with no access bits.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{Fails when caller has ``get'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{Fails when caller has ``modify'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Reason{Fails when caller has ``delete'' access and not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Fails when caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{17}{ -\Reason{Fails on attempt to create existing principal.} -\Status{Implemented} -} - -\numtest{18}{ -\Reason{Fails when password is too short.} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Fails when password has too few classes.} -\Status{Implemented} -} - -\numtest{20}{ -\Reason{Fails when password is in dictionary.} -\Status{Implemented} -} - -\numtest{21}{ -\Reason{Nonexistent policy is rejected.} -\Status{Implemented} -} - -\numtest{22}{ -\Reason{Fails on invalid principal name.} -\Status{Implemented} -} - -\numtest{23}{ -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Succeeds when caller has ``add'' access and another one.} -\Status{Implemented} -} - -%\numtest{25}{ -%\Reason{Fails when password is too short, when override_qual is true.} -%} - -%\numtest{26}{ -%\Reason{Fails when password has too few classes, when -% override_qual is true.} -%} - -%\numtest{27}{ -%\Reason{Fails when password is in dictionary, when override_qual is -% true.} -%} - -\numtest{28}{ -\Reason{Succeeds when assigning policy.} -\Status{Implemented} -} - -\numtest{29}{ -\Priority{High} -\Reason{Allows 0 (never) for princ_expire_time.} -\Status{Implemented} -} - -\numtest{30}{ -\Reason{Allows 0 (never) for pw_expiration when there's no policy.} -\Status{Implemented} -} - -\numtest{31}{ -\Reason{Allows 0 (never) for pw_expiration when there's a policy with - 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{32}{ -\Reason{Accepts 0 (never) for pw_expiration when there's a policy with - non-zero pw_max_life, and sets pw_expiration to zero. -\Status{Implemented} -} - -\numtest{33}{ -\Reason{Accepts and sets non-zero pw_expiration when no policy.} -\Status{Implemented} -} - -\numtest{34}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with zero pw_max_life.} -\Status{Implemented} -} - -\numtest{35}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with pw_max_life later than the specified pw_expiration.} -\Status{Implemented} -} - -\numtest{36}{ -\Reason{Accepts and sets non-zero pw_expiration greater than now_pw_max_life.} -\Status{Implemented} -} - -\numtest{37}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if there's no policy and no - specified pw_expiration.} -\Status{Implemented} -} - -\numtest{38}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if it isn't specified and the - policy has a 0 (never) pw_max_life.} -\Status{Implemented} -} - -\numtest{39}{ -\Priority{High} -\Reason{Sets pw_expiration to now + pw_max_life if it isn't specified - and the policy has a non-zero pw_max_life.} -\Status{Implemented} -} - -\numtest{40}{ -\Priority{High} -\Reason{Allows 0 (forever) for max_life.} -\Status{Implemented} -} - -\numtest{41}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on success.} -} - -\numtest{42}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on failure.} -} - -\numtest{43}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{44}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - - -\section{ovsec_kadm_delete_principal} - -%\numtest{1}{ -%\Reason{Fails if database not initialized.} -%\Status{Implemented} -%} - -\numtest{2}{ -\Reason{Fails on null principal.} -\Status{Implemented} -} - -% Empty string principal is legal. -%\numtest{3}{ -%\Reason{Fails on empty-string principal.} -%} - -% There is not invalid principal names -%\numtest{4}{ -%\Reason{Fails on invalid principal name.} -%} - -\numtest{5}{ -\Priority{High} -\Reason{Fails on nonexistent principal.} -\Status{Implemented} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails when caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails if caller has ``add'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails if caller has ``modify'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Fails if caller has ``get'' access and not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Fails if caller has no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Valid invocation.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Valid invocation (on principal with policy).} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - - -\section{ovsec_kadm_modify_principal} - -%\numtest{1}{ -%\Reason{Fails if database not initialized.} -%\Status{Implemented} -%} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if user connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails on mask with undefined bit set.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails on mask with PRINCIPAL set.} -\Status{Implemented} -} - -\numtest{5}{ -\Priority{High} -\Reason{Fails on mask with LAST_PWD_CHANGE set.} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails on mask with MOD_TIME set.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails on mask with MOD_NAME set.} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails on mask with MKVNO set.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Fails on mask with AUX_ATTRIBUTES set.} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails on nonexistent principal.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for user with ``get'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Fails for user with ``add'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Fails for user with ``delete'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{16}{ -\Reason{Succeeds for user with ``modify'' and another access.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Fails when nonexistent policy is specified.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Succeeds when existent policy is specified.} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Updates policy count when setting policy from none.} -\Status{Implemented} -} - -\numtest{20}{ -\Reason{Updates policy count when clearing policy from set.} -\Status{Implemented} -} - -\numtest{21}{ -\Reason{Updates policy count when setting policy from other policy.} -\Status{Implemented} -} - -\numtest{21.5}{ -\Reason{Policy reference count remains unchanged when policy is - changed to itself.} -\Status{Implemented.} -} - -\numtest{22}{ -\Reason{Allows 0 (never) for pw_expiration when there's no policy.} -\Status{Implemented} -} - -\numtest{23}{ -\Reason{Allows 0 (never) for pw_expiration when there's a policy with - 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Accepts 0 (never) for pw_expiration when there's a policy with - non-zero pw_max_life, but actually sets pw_expiration to - last_pwd_change + pw_max_life.} -\Status{Implemented} -} - -\numtest{25}{ -\Reason{Accepts and sets non-zero pw_expiration when no policy.} -\Status{Implemented} -} - -\numtest{26}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with zero pw_max_life.} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Accepts and sets non-zero pw_expiration when there's a policy - with pw_max_life later than the specified pw_expiration.} -\Status{Implemented} -} - -\numtest{28}{ -\Reason{Accepts non-zero pw_expiration and limits it to last_pwd_change + - pw_max_life when it's later than last_pwd_change + non-zero - pw_max_life in policy.} -\Status{Implemented} -} - -\numtest{29}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) when a policy is cleared and -no pw_expiration is specified.} -\Status{Implemented} -} - -\numtest{30}{ -\Priority{High} -\Reason{Sets pw_expiration to 0 (never) if it isn't specified and the - new policy has a 0 (never) pw_max_life.} -\Status{Implemented} -} - -\numtest{31}{ -\Priority{High} -\Reason{Sets pw_expiration to now + pw_max_life if it isn't specified - and the new policy has a non-zero pw_max_life.} -\Status{Implemented} -} - -\numtest{32}{ -\Priority{High} -\Reason{Accepts princ_expire_time change.} -\Status{Implemented} -} - - - -\numtest{33}{ -\Priority{High} -\Reason{Accepts attributes change.} -\Status{Implemented} -} - -\numtest{33.25}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_KDB_REQUIRES_PW_CHANGE).} -\Status{Implemented} -} - -\numtest{33.5}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_DISALLOW_TGT_BASE).} -\Status{Implemented} -} - -\numtest{33.75}{ -\Priority{High} -\Reason{Accepts attributes change (KRB5_PW_CHANGE_SERVICE).} -\Status{Implemented} -} - -\numtest{34}{ -\Priority{High} -\Reason{Accepts max_life change.} -\Status{Implemented} -} - -\numtest{35}{ -\Priority{High} -\Reason{Accepts kvno change.} -\Status{Implemented} -} - -\numtest{36}{ -\Reason{Behaves correctly when policy is set to the same as it was - before.} -\Status{Implemented} -} - -\numtest{37}{ -\Reason{Behaves properly when POLICY_CLR is specified and there was no - policy before.} -\Status{Implemented} -} - -\numtest{38}{ -\Priority{High} -\Reason{Accepts 0 (never) for princ_expire_time.} -\Status{Implemented} -} - -\numtest{39}{ -\Priority{High} -\Reason{Accepts 0 for max_life.} -\Status{Implemented} -} - -\numtest{40}{ -\Reason{Rejects null principal argument.} -\Status{Implemented} -} - -\numtest{41}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on success.} -} - -\numtest{42}{ -\Priority{High} -\Reason{Doesn't modify or free mod_name on failure.} -} - -\numtest{43}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{44}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\numtest{100}{ -\Version{KADM5_API_VERSION_2} -\Priority{bug-fix} -\Reason{Accepts max_rlife change.} -\Status{Implemented} -} - -\numtest{101}{ -\Version{KADM5_API_VERSION_2} -\Reason{Rejects last_success change.} -\Status{Implemented} -} - -\numtest{102}{ -\Version{KADM5_API_VERSION_2} -\Reason{Rejects last_failed change.} -\Status{Implemented} -} - -\numtest{103}{ -\Version{KADM5_API_VERSION_2} -\Reason{Rejects fail_auth_count change.} -\Status{Implemented} -} - -\numtest{103.5}{ -\Version{KADM5_API_VERSION_2} -\Reason{Rejects key_data change.} -\Status{Implemented} -} - -\numtest{104}{ -\Version{KADM5_API_VERSION_2} -\Reason{Accepts tl_data change when all types are greater than 256.} -\Status{Implemented} -} - -\numtest{105}{ -\Version{KADM5_API_VERSION_2} -\Reason{Returns KADM5_BAD_TL_TYPE when given tl_data with a type less -than 256.} -\Status{Implemented} -} - -\section{ovsec_kadm_rename_principal} - -%\numtest{1}{ -%\Reason{Fails if database not initialized.} -%\Status{Implemented} -%} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if user connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails for user with ``modify'' access and not ``add'' or -``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for user with ``get'' access and not ``add'' or -``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails for user with ``modify'' and ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for user with ``modify'' and ``delete'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``get'' and ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Reason{Fails for user with ``get'' and ``delete'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Fails for user with ``modify'', ``get'' and ``add'', but not - ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Fails for user with ``modify'', ``get'' and ``delete'', but - not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Fails for user with ``delete'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Succeeds for user with ``add'' and ``delete'', when that user -has non-name-based salt.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Fails if target principal name exists.} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\numtest{18}{ -\Priority{bug fix} -\Reason{Returns NO_RENAME_SALT when asked to rename a principal whose -salt depends on the principal name.} -\Status{Implemented} -} - -\section{ovsec_kadm_chpass_principal} -\label{ovseckadmchpassprincipal} - -\subsection{Quality/history enforcement tests} - -This section lists a series of tests which will be run a number of -times, with various parameter settings (e.g., which access bits user -has, whether user connected with ADMIN_SERVICE or CHANGEPW_SERVICE, -etc.). The table following the -list of tests gives the various parameter settings under which the -tests should be run, as well which should succeed and which should -fail for each choice of parameter settings. - -\subsubsection{List of tests} - -The test number of each of these tests is an offset from the base -given in the table below. - -\numtest{1}{ -\Priority{High} -\Reason{With history setting of 1, change password to itself.} -} - -\numtest{2}{ -\Reason{With history setting of 2 but no password changes since - principal creation, change password to itself.} -} - -\numtest{3}{ -\Reason{With history setting of 2 and one password change since - principal creation, change password to itself - and directly previous password.} -} - -\numtest{4}{ -\Priority{High} -\Reason{With a history setting of 3 and no password changes, - change password to itself.} -} - -\numtest{5}{ -\Priority{High} -\Reason{With a history setting of 3 and 1 password change, - change password to itself or previous password.} -} - -\numtest{6}{ -\Priority{High} -\Reason{With a history setting of 3 and 2 password changes, - change password to itself and the two previous passwords.} -} - -\numtest{7}{ -\Priority{High} -\Reason{Change to previously unused password when now - - last_pwd_change $<$ pw_min_life.} -} - -\numtest{8}{ -\Priority{High} -\Reason{Change to previously unused password that doesn't contain enough - character classes.} -} - -\numtest{9}{ -\Priority{High} -\Reason{Change to previously unused password that's too short.} -} - -\numtest{10}{ -\Priority{High} -\Reason{Change to previously unused password that's in the dictionary.} -} - -\subsubsection{List of parameter settings} - -In the table below, ``7 passes'' means that test 7 above passes and -the rest of the tests fail. - -\begin{tabular}{llllll} -Base & Modify access? & Own password? & Service & Pass/Fail \\ \hline -0 & No & Yes & ADMIN & all fail \\ -20 & No & Yes & CHANGEPW & all fail \\ -40 & No & No & ADMIN & all fail \\ -60 & No & No & CHANGEPW & all fail \\ -80 & Yes & Yes & ADMIN & 7 passes \\ -100 & Yes & Yes & CHANGEPW & all fail \\ -120 & Yes & No & ADMIN & 7 passes \\ -140 & Yes & No & CHANGEPW & all fail \\ -\end{tabular} - -\subsection{Other quality/history tests} - -\numtest{161}{ -\Priority{High} -\Reason{With history of 1, can change password to anything other than - itself that doesn't conflict with other quality - rules.} -} - -\numtest{162}{ -\Reason{With history of 2 and 2 password changes, can change password - to original password.} -} - -\numtest{163}{ -\Priority{High} -\Reason{With history of 3 and 3 password changes, can change password - to original password.} -} - -\numtest{164}{ -\Priority{High} -\Reason{Can change password when now - last_pwd_change $>$ pw_min_life.} -} - -\numtest{165}{ -\Priority{High} -\Reason{Can change password when it contains exactly the number of - classes required by the policy.} -} - -\numtest{166}{ -\Priority{High} -\Reason{Can change password when it is exactly the length required by - the policy.} -} - -\numtest{167}{ -\Priority{High} -\Reason{Can change password to a word that isn't in the dictionary.} -} - - -\subsection{Other tests} - -%\numtest{168}{ -%\Reason{Fails if database not initialized.} -%} - -\numtest{169}{ -\Reason{Fails for non-existent principal.} -} - -\numtest{170}{ -\Reason{Fails for null password.} -} - -\numtest{171}{ -\Priority{High} -\Reason{Fails for empty-string password.} -} - -\numtest{172}{ -\Priority{High} -\Reason{Pw_expiration is set to now + max_pw_life if policy exists and - has non-zero max_pw_life.} -} - -\numtest{173}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if policy exists and has zero - max_pw_life.} -} - -\numtest{174}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if no policy.} -} - -\numtest{175}{ -\Priority{High} -\Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when password is - successfully changed.} -} - -\numtest{176}{ -\Priority{High} -\Reason{Fails for user with no access bits, on other's password.} -} - -\numtest{177}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify'' access, on - other's password.} -} - -\numtest{178}{ -\Reason{Fails for user with ``delete'' but not ``modify'' access, on - other's password.} -} - -\numtest{179}{ -\Reason{Fails for user with ``add'' but not ``modify'' access, on - other's password.} -} - -\numtest{180}{ -\Reason{Succeeds for user with ``get'' and ``modify'' access, on - other's password.} -\Status{Implemented} -} - -\numtest{180.5}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' but not ``get'' access, on - other's password.} -\Conditions{RPC} -\Status{Implemented} -} -\numtest{180.625}{ -\Priority{High} -\Reason{Fails for user with modify when connecting with CHANGEPW_SERVICE on - others password} -\Conditions{RPC} -\Status{Implemented} -} -\numtest{180.75}{ -\Priority{High} -\Reason{Fails for user with modify when connecting with CHANGEPW_SERVICE - on other's password which has expired} -\Conditions{RPC} -\Status{Implemented} -} - -%\numtest{181}{ -%\Reason{Password that would succeed if override_qual were false fails -% if override_qual is true.} -%\Expected{Returns CANNOT_OVERRIDE.} -%} - -\numtest{182}{ -\Priority{High} -\Reason{Can not change key of ovsec_adm/history principal.} -\Status{Implemented} -} - -\numtest{183}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{184}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\numtest{200}{ -\Version{KADM5_API_VERSION_2} -\Reason{Creates a key for the principal for each unique encryption -type/salt type in use.} -\Status{Implemented} -} - -\section{ovsec_kadm_chpass_principal_util} - -Rerun all the tests listed for ovsec_kadm_chpass_principal above in -Section \ref{ovseckadmchpassprincipal}. Verify that they succeed -and fail in the same circumstances. Also verify that in each failure -case, the error message returned in msg_ret is as specified in the -functional specification. - -Also, run the following additional tests. - -\numtest{1}{ -\Reason{Null msg_ret is rejected.} -} - -\numtest{2}{ -\Priority{High} -\Reason{New password is put into pw_ret, when it's prompted for.} -} - -\numtest{3}{ -\Priority{High} -Reason{New password is put into pw_ret, when it's supplied by the - caller.} -} - -\numtest{4}{ -\Priority{High} -\Reason{Successful invocation when pw_ret is null.} -} - - - -\section{ovsec_kadm_randkey_principal} - -\subsection{TOOSOON enforcement tests} - -This test should be run a number of times, as indicated in the table -following it. The table also indicates the expected result of each -run of the test. - -\test{ -\Reason{Change key when now - last_pwd_change $<$ pw_min_life.} -} - -\subsubsection{List of parameter settings} - -\begin{tabular}{llllll} -Number & Modify Access? & Own Key? & Service & Pass/Fail & Implemented? \\ \hline -1 & No & Yes & ADMIN & fail & Yes \\ -3 & No & Yes & CHANGEPW & fail & Yes \\ -5 & No & No & ADMIN & fail \\ -7 & No & No & CHANGEPW & fail \\ -9 & Yes & Yes & ADMIN & pass \\ -11 & Yes & Yes & CHANGEPW & fail \\ -13 & Yes & No & ADMIN & pass & Yes \\ -15 & Yes & No & CHANGEPW & fail & Yes \\ -\end{tabular} - -\subsection{Other tests} - -\numtest{17}{ -\Reason{Fails if database not initialized.} -} - -\numtest{18}{ -\Reason{Fails for non-existent principal.} -} - -\numtest{19}{ -\Reason{Fails for null keyblock pointer.} -} - -\numtest{20}{ -\Priority{High} -\Reason{Pw_expiration is set to now + max_pw_life if policy exists and - has non-zero max_pw_life.} -} - -\numtest{21}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if policy exists and has zero - max_pw_life.} -} - -\numtest{22}{ -\Priority{High} -\Reason{Pw_expiration is set to 0 if no policy.} -} - -\numtest{23}{ -\Priority{High} -\Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when key is - successfully changed.} -} - -\numtest{24}{ -\Priority{High} -\Reason{Fails for user with no access bits, on other's password.} -} - -\numtest{25}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify'' access, on - other's password.} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{26}{ -\Reason{Fails for user with ``delete'' but not ``modify'' access, on - other's password.} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{27}{ -\Reason{Fails for user with ``add'' but not ``modify'' access, on - other's password.} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{28}{ -\Reason{Succeeds for user with ``get'' and ``modify'' access, on - other's password.} -\Status{Implemented} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{28.25}{ -\Priority{High} -\Reason{Fails for user with get and modify access on others password - When conneceted with CHANGEPW_SERVICE} -\Status{Implemented} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{28.5}{ -\Priority{High} -\Reason{Succeeds for user with ``modify'' but not ``get'' access, on - other's password.} -\Status{Implemented} -\Vtwonote{Change-password instead of modify access.} -} - -\numtest{29}{ -\Reason{The new key that's assigned is truly random. XXX not sure how - to test this.} -} - -\numtest{30}{ -\Reason{Succeeds for own key, no other access bits when connecting with CHANGEPW service} -\Status{Implemented} -} -\numtest{31}{ -\Reason{Succeeds for own key, no other access bits when connecting with ADMIM service} -\Status{Implemented} -} - -\numtest{32}{ -\Reason{Cannot change ovsec_adm/history key} -\Status{Implemented} -} - -\numtest{33}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{34}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\numtest{100}{ -\Version{KADM5_API_VERSION_2} -\Reason{Returns a key for each unique encryption type specified in the -keysalts.} -} - -\section{ovsec_kadm_get_principal} - -\numtest{1}{ -\Reason{Fails for null ent.} -\Status{Implemented} -} - -\numtest{2}{ -\Reason{Fails for non-existent principal.} -\Status{Implemented} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for user with no access bits, retrieving other principal.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{4}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``get'', getting principal - other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for user with ``modify'' but not ``get'', getting - principal other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Reason{Fails for user with ``delete'' but not ``get'', getting - principal other than his own, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for user with ``delete'' but not ``get'', getting - principal other than his own, using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for user with ``get'', getting principal other than his - own, using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Succeeds for user without ``get'', retrieving self, using - ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{10}{ -\Reason{Succeeds for user without ``get'', retrieving self, using - CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Succeeds for user with ``get'', retrieving self, using - ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{12}{ -\Reason{Succeeds for user with ``get'', retrieving self, using - CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Succeeds for user with ``get'', retrieving other user, using - ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{14}{ -\Reason{Succeeds for user with ``get'' and ``modify'', retrieving - other principal, using ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\numtest{100}{ -\Version{KADM5_API_VERSION_2} -\Reason{If KADM5_PRINCIPAL_NORMAL_MASK is specified, the key_data and -tl_data fields are NULL/zero.} -\Status{Implemented} -} - -\numtest{101}{ -\Version{KADM5_API_VERSION_2} -\Reason{If KADM5_KEY_DATA is specified, the key_data fields contain -data but the contents are all NULL.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{102}{ -\Version{KADM5_API_VERSION_2} -\Reason{If KADM5_KEY_DATA is specified, the key_data fields contain -data and the contents are all non-NULL.} -\Conditions{local} -\Status{Implemented} -} - -\numtest{103}{ -\Version{KADM5_API_VERSION_2} -\Reason{If KADM5_TL_DATA is specified, the tl_data field contains the -correct tl_data and no entries whose type is less than 256.} -\Status{Implemented} -} - - -\section{ovsec_kadm_create_policy} - -\numtest{1}{ -\Reason{Fails for mask with undefined bit set.} -\Status{Implemented - untested} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for mask without POLICY bit set.} -\Status{Implemented - untested} -} - -\numtest{4}{ -\Reason{Fails for mask with REF_COUNT bit set.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for invalid policy name.} -\Status{Implemented - untested} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for existing policy name.} -\Status{Implemented} -} - -\numtest{7}{ -\Reason{Fails for null policy name.} -\Status{Implemented - untested} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_life.} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_life.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Accepts 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Accepts non-zero for pw_max_life.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_length.} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_length.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{High} -\Reason{Accepts 1 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Accepts 4 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Rejects 5 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{19}{ -\Priority{High} -\Reason{Rejects 0 for pw_history_num.} -\Status{Implemented} -} - -\numtest{20}{ -\Priority{High} -\Reason{Accepts 1 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21}{ -\Priority{High} -\Reason{Accepts 10 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21.5}{ -\Reason{Rejects 11 for pw_history_num.} -\Status{Implemented - untested} -} - -\numtest{22}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{23}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``add''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Fails for user with ``modify'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented - untested} -} - -\numtest{25}{ -\Reason{Fails for user with ``delete'' but not ``add.''} -\Conditions{RPC} -\Status{Implemented - untested} -} - -\numtest{26}{ -\Priority{High} -\Reason{Succeeds for user with ``add.''} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Succeeds for user with ``get'' and ``add.''} -\Status{Implemented - untested} -} - -\numtest{28}{ -\Reason{Rejects null policy argument.} -\Status{Implemented - untested} -} - -\numtest{29}{ -\Reason{Rejects pw_min_life greater than pw_max_life.} -} - -\numtest{30}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{31}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - - -\section{ovsec_kadm_delete_policy} - -\numtest{1}{ -\Reason{Fails for null policy name.} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{4}{ -\Reason{Fails for bad policy name.} -} - -\numtest{5}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``delete''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``modify'' but not ``delete''.} -\Conditions{RPC} -} - -\numtest{9}{ -\Reason{Fails for user with ``get'' but not ``delete.''} -\Conditions{RPC} -} - -\numtest{10}{ -\Priority{High} -\Reason{Succeeds for user with only ``delete''.} -\Status{Implemented} -} - -\numtest{11}{ -\Reason{Succeeds for user with ``delete'' and ``add''.} -} - -\numtest{12}{ -\Priority{High} -\Reason{Fails for policy with non-zero reference count.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - - -\section{ovsec_kadm_modify_policy} - -\numtest{1}{ -\Reason{Fails for mask with undefined bit set.} -\Conditions{RPC} -} - -\numtest{2}{ -\Priority{High} -\Reason{Fails if caller connected with CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{3}{ -\Reason{Fails for mask with POLICY bit set.} -} - -\numtest{4}{ -\Reason{Fails for mask with REF_COUNT bit set.} -\Status{Implemented} -} - -\numtest{5}{ -\Reason{Fails for invalid policy name.} -} - -\numtest{6}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{7}{ -\Reason{Fails for null policy name.} -} - -\numtest{8}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{9}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_life.} -\Status{Implemented} -} - -\numtest{10}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_life.} -\Status{Implemented} -} - -\numtest{11}{ -\Priority{High} -\Reason{Accepts 0 for pw_max_life.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Accepts non-zero for pw_max_life.} -\Status{Implemented} -} - -\numtest{13}{ -\Priority{High} -\Reason{Accepts 0 for pw_min_length.} -\Status{Implemented} -} - -\numtest{14}{ -\Priority{High} -\Reason{Accepts non-zero for pw_min_length.} -\Status{Implemented} -} - -\numtest{15}{ -\Priority{High} -\Reason{Rejects 0 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{16}{ -\Priority{High} -\Reason{Accepts 1 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Accepts 4 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Rejects 5 for pw_min_classes.} -\Status{Implemented} -} - -\numtest{19}{ -\Priority{High} -\Reason{Rejects 0 for pw_history_num.} -\Status{Implemented} -} - -\numtest{20}{ -\Priority{High} -\Reason{Accepts 1 for pw_history_num.} -\Status{Implemented} -} - -\numtest{21}{ -\Priority{High} -\Reason{Accepts 10 for pw_history_num.} -\Status{Implemented} -} - -\numtest{22}{ -\Priority{High} -\Reason{Fails for user with no access bits.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{23}{ -\Priority{High} -\Reason{Fails for user with ``get'' but not ``modify''.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{24}{ -\Reason{Fails for user with ``add'' but not ``modify.''} -\Conditions{RPC} -} - -\numtest{25}{ -\Reason{Fails for user with ``delete'' but not ``modify.''} -\Conditions{RPC} -} - -\numtest{26}{ -\Priority{High} -\Reason{Succeeds for user with ``modify.''} -\Status{Implemented} -} - -\numtest{27}{ -\Reason{Succeeds for user with ``get'' and ``modify.''} -} - -\numtest{28}{ -\Reason{Rejects null policy argument.} -} - -\numtest{29}{ -\Reason{Rejects change which makes pw_min_life greater than - pw_max_life.} -} - -\numtest{30}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{31}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - -\section{ovsec_kadm_get_policy} - -\numtest{1}{ -\Reason{Fails for null policy.} -} - -\numtest{2}{ -\Reason{Fails for invalid policy name.} -} - -\numtest{3}{ -\Priority{High} -\Reason{Fails for empty-string policy name.} -\Status{Implemented} -} - -\numtest{4}{ -\Reason{Fails for non-existent policy name.} -} - -\numtest{5}{ -\Reason{Fails for null ent.} -} - -\numtest{6}{ -\Priority{High} -\Reason{Fails for user with no access bits trying to get other's - policy, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{7}{ -\Priority{High} -\Reason{Fails for user with ``add'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{8}{ -\Reason{Fails for user with ``modify'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -} - -\numtest{9}{ -\Reason{Fails for user with ``delete'' but not ``get'' trying to get - other's policy, using ADMIN_SERVICE.} -\Conditions{RPC} -} - -\numtest{10}{ -\Reason{Fails for user with ``delete'' but not ``get'' trying to get - other's policy, using CHANGEPW_SERVICE.} -\Conditions{RPC} -} - -\numtest{11}{ -\Priority{High} -\Reason{Succeeds for user with only ``get'', trying to get own policy, - using ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{12}{ -\Priority{High} -\Reason{Succeeds for user with only ``get'', trying to get own policy, - using CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{13}{ -\Reason{Succeeds for user with ``add'' and ``get'', trying to get own - policy, using ADMIN_SERVICE.} -} - -\numtest{14}{ -\Reason{Succeeds for user with ``add'' and ``get'', trying to get own - policy, using CHANGEPW_SERVICE.} -} - -\numtest{15}{ -\Reason{Succeeds for user without ``get'', trying to get own policy, - using ADMIN_SERVICE.} -} - -\numtest{16}{ -\Priority{High} -\Reason{Succeeds for user without ``get'', trying to get own policy, - using CHANGEPW_SERVICE.} -\Status{Implemented} -} - -\numtest{17}{ -\Priority{High} -\Reason{Succeeds for user with ``get'', trying to get other's policy, - using ADMIN_SERVICE.} -\Status{Implemented} -} - -\numtest{18}{ -\Priority{High} -\Reason{Fails for user with ``get'', trying to get other's policy, - using CHANGEPW_SERVICE.} -\Conditions{RPC} -\Status{Implemented} -} - -\numtest{19}{ -\Reason{Succeeds for user with ``modify'' and ``get'', trying to get - other's policy, using ADMIN_SERVICE.} -} - -\numtest{20}{ -\Reason{Fails for user with ``modify'' and ``get'', trying to get - other's policy, using CHANGEPW_SERVICE.} -} - -\numtest{21}{ -\Priority{High} -\Reason{Returns BAD_SERVER_HANDLE when a null server handle is passed in} -\Status{Implemented} -} - -\numtest{22}{ -\Priority{Low} -\Reason{Connects to correct server when mutliple handles exist} -\Conditions{RPC} -} - - -\section{ovsec_kadm_free_principal_ent} - -In addition to the tests listed here, a memory-leak detector such as -TestCenter, Purify or dbmalloc should be used to verify that the -memory freed by this function is really freed. - -\numtest{1}{ -\Reason{Null princ succeeds.} -} - -\numtest{2}{ -\Reason{Non-null princ succeeds.} -} - - -\section{ovsec_kadm_free_policy_ent} - -In addition to the tests listed here, a memory-leak detector such as -TestCenter, Purify or dbmalloc should be used to verify that the -memory freed by this function is really freed. - -\numtest{1}{ -\Reason{Null policy succeeds.} -} - -\numtest{2}{ -\Reason{Non-null policy succeeds.} -} - - - -\section{ovsec_kadm_get_privs} - -\numtest{1}{ -\Reason{Fails for null pointer argument.} -} - -This test should be run with the 16 possible combinations of access -bits (since there are 4 access bits, there are $2^4 = 16$ possible -combinations of them): - -\numtest{2}{ -\Priority{High} -\Reason{Returns correct bit mask for access bits of user.} -\Conditions{RPC} -} - -This test should be run locally: - -\numtest{3}{ -\Priority{High} -\Reason{Returns 0x0f.} -\Conditions{local} -} - -\end{document} diff --git a/doc/kadm5/changebar.sty b/doc/kadm5/changebar.sty deleted file mode 100644 index c49e8be18..000000000 --- a/doc/kadm5/changebar.sty +++ /dev/null @@ -1,157 +0,0 @@ -% Change bar document-style option for LaTeX. -% -% Copyright (C) 1990 by David B. Johnson. -% -% dbj@titan.rice.edu (Dave Johnson) - -% These macros draw a solid bar down the right margin of the output, -% covering a range of the input file that has been declared to be changed. -% -% The beginning and end of a change bar in the text are marked with -% \chgbarbegin and \chgbarend, respectively. For example, -% -% Here is some sample text \chgbarbegin that was -% changed\chgbarend{} and some that wasn't changed. -% -% The change bar is drawn continuously between the line of output -% containing the \chgbarbegin and the line of output containing the -% \chgbarend. These lines can end up on separate pages, and the -% division at page boundaries is handled automatically. - -% Two dimensions control the size and placement of the change bars: -% \chgbarwidth The width of a change bar -% \chgbarsep The distance between the text and the change bar - -% Warning: it does not appear to be possible to do this completely -% correctly, due to the time at which the verticle glue on a page is -% finally set, and the way that page breaks are decided. With -% \raggedbottom, this normally works fine. It hasn't been tested with -% \flushbottom, but will probably behave worse. In strange rare -% situations, a change bar might be drawn from the first line of a page -% up off the top of a page; this can usually be fixed by slightly moving -% the \chngbarend around, or by breaking a single change bar range -% into two ranges. - -\newdimen\chgbarwidth \newdimen\chgbarsep -\chgbarwidth 4pt -\chgbarsep .25in - -\def\chgbarbegin{\ifhmode\@chgbar{-2}\else\@chgbar{-3}\fi} -\def\chgbarend{\@chgbar{-4}\relax} - -\marginparpush 0pt - -% The remainder of this is hacked up based on the LaTeX 2.09 latex.tex. - -% copied from \marginpar -\def\@chgbar#1{\ifhmode \@bsphack\@floatpenalty -\@Mii\else - \@floatpenalty-\@Miii\fi\ifinner - \@parmoderr\@floatpenalty\z@ - \else\@next\@currbox\@freelist{\global - \count\@currbox#1}{\@floatpenalty\z@ \@fltovf - \def\@currbox{\@tempboxa}}\fi - \setbox\@tempboxa\vbox - \bgroup\end@float\@esphack} - -\newdimen\@chgbarbegin -\newif\if@inchgbar \@inchgbarfalse - -\def\@addmarginpar{% -\ifnum\count\@currbox = -2 % change bar begin from hmode - \global\@chgbarbegin\@pageht \global\advance\@chgbarbegin -\baselineskip - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -3 % change bar begin not from hmode - \global\@chgbarbegin\@pageht - \global\@inchgbartrue - \@cons\@freelist\@currbox -\else -\ifnum\count\@currbox = -4 % change bar end - \if@inchgbar\else\@latexbug\fi - \@tempdima\@pageht \advance\@tempdima -\@chgbarbegin - \nointerlineskip - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi -\hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@ -}} -\hss} - \nointerlineskip - \global\@inchgbarfalse - \@cons\@freelist\@currbox -\else - \@next\@marbox\@currlist{\@cons\@freelist\@marbox - \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi - \@tempdima\@mparbottom \advance\@tempdima -\@pageht - \advance\@tempdima\ht\@marbox \ifdim\@tempdima >\z@ - \@warning{Marginpar on page \thepage\space moved}\else\@tempdima\z@ \fi - \global\@mparbottom\@pageht \global\advance\@mparbottom\@tempdima - \global\advance\@mparbottom\dp\@marbox - \global\advance\@mparbottom\marginparpush - \advance\@tempdima -\ht\@marbox - \global\ht\@marbox\z@ \global\dp\@marbox\z@ - \vskip -\@pagedp \vskip\@tempdima\nointerlineskip - \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\marginparsep - \else \hskip -\marginparsep \hskip -\marginparwidth \fi - \box\@marbox \hss} - \vskip -\@tempdima - \nointerlineskip - \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp} -\fi\fi\fi} - -\def\@makecol{\setbox\@outputbox\box\@cclv - \if@inchgbar - \@tempcnta\@ne - \if@twocolumn - \if@firstcolumn \@tempcnta\m@ne \fi - \else - \if@mparswitch - \ifodd\c@page \else\@tempcnta\m@ne \fi - \fi - \if@reversemargin \@tempcnta -\@tempcnta \fi - \fi - \@tempdima\ht\@outputbox \advance\@tempdima -\@chgbarbegin - \advance\@tempdima -\baselineskip - \setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox \nointerlineskip \hbox to\columnwidth - {\ifnum \@tempcnta >\z@ - \hskip\columnwidth \hskip\chgbarsep - \else \hskip -\chgbarsep \fi - \hbox{\vbox to 0pt{\vss - \hrule \@height\@tempdima \@width\chgbarwidth \@depth\z@}}\hss}} - \global\@chgbarbegin 0pt -\fi - \ifvoid\footins\else\setbox\@outputbox - \vbox{\boxmaxdepth \maxdepth - \unvbox\@outputbox\vskip\skip\footins\footnoterule\unvbox\footins}\fi - \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats - \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth - \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox - \vskip-\dimen128\@textbottom} - \global\maxdepth\@maxdepth} - -\newenvironment{changebar}{\chgbarbegin}{\chgbarend} diff --git a/doc/kadm5/fullpage.sty b/doc/kadm5/fullpage.sty deleted file mode 100644 index d5a2bf5b0..000000000 --- a/doc/kadm5/fullpage.sty +++ /dev/null @@ -1,9 +0,0 @@ -\marginparwidth 0pt -\oddsidemargin 0pt -\evensidemargin 0pt -\marginparsep 0pt - -\topmargin 0pt - -\textwidth 6.5in -\textheight 8.5 in diff --git a/doc/kadm5/rcsid.sty b/doc/kadm5/rcsid.sty deleted file mode 100644 index 3ad7826ff..000000000 --- a/doc/kadm5/rcsid.sty +++ /dev/null @@ -1,5 +0,0 @@ -\def\rcs$#1: #2${\expandafter\def\csname rcs#1\endcsname{#2}} - -% example usage: -% \rcs$Version$ -% Version \rcsVersion diff --git a/doc/kadm5acl.texinfo b/doc/kadm5acl.texinfo deleted file mode 100644 index 468a9b93a..000000000 --- a/doc/kadm5acl.texinfo +++ /dev/null @@ -1,113 +0,0 @@ -The format of the file is: - -@smallexample -Kerberos_principal permissions [target_principal] [restrictions] -@end smallexample - -The Kerberos principal (and optional target principal) can include the -``@b{*}'' wildcard, so if you want any principal with the instance -``admin'' to have full permissions on the database, you could use the -principal ``@code{*/admin@@REALM}'' where ``REALM'' is your Kerberos -realm. @code{target_principal} can also include backreferences to -@code{Kerberos_principal}, in which "@b{*@i{number}}" matches the -component @i{number} in the @code{Kerberos_principal}. - -Note: a common use of an @i{admin} instance is so you can grant -separate permissions (such as administrator access to the Kerberos -database) to a separate Kerberos principal. For example, the user -@code{@value{ADMINUSER}} might have a principal for his administrative -use, called @code{@value{ADMINUSER}/admin}. This way, -@code{@value{ADMINUSER}} would obtain @code{@value{ADMINUSER}/admin} -tickets only when he actually needs to use those permissions. - -The permissions are represented by single letters; UPPER-CASE letters -represent negative permissions. The permissions are: - -@table @b -@itemx a -allows the addition of principals or policies in the database. -@itemx A -disallows the addition of principals or policies in the database. -@itemx d -allows the deletion of principals or policies in the database. -@itemx D -disallows the deletion of principals or policies in the database. -@itemx m -allows the modification of principals or policies in the database. -@itemx M -disallows the modification of principals or policies in the database. -@itemx c -allows the changing of passwords for principals in the database. -@itemx C -disallows the changing of passwords for principals in the database. -@itemx i -allows inquiries to the database. -@itemx I -disallows inquiries to the database. -@itemx l -allows the listing of principals or policies in the database. -@itemx L -disallows the listing of principals or policies in the database. -@itemx s -allows the explicit setting of the key for a principal -@itemx S -disallows the explicit setting of the key for a principal -@itemx * -All privileges (admcil). -@itemx x -All privileges (admcil); identical to ``*''. -@end table - -The restrictions are a string of flags. Allowed restrictions are: - -@table @b -@itemx [+ -]@i{flagname} -flag is forced to indicated value. The permissible flags are the same -as the @code{+} and @code{-} flags for the @code{kadmin addprinc} and -@code{modprinc} commands. -@itemx -clearpolicy -policy is forced to clear -@itemx -policy @i{pol} -policy is forced to be @i{pol} -@itemx expire @i{time} -@itemx pwexpire @i{time} -@itemx maxlife @i{time} -@itemx maxrenewlife @i{time} -associated value will be forced to MIN(@i{time}, requested value) -@end table - -The above flags act as restrictions on any add or modify operation -which is allowed due to that ACL line. - -Here is an example of a @code{kadm5.acl} file. Note that order is -important; permissions are determined by the first matching entry. - -@smallexample -@group -*/admin@@@value{PRIMARYREALM} * -@value{ADMINUSER}@@@value{PRIMARYREALM} ADMCIL -@value{ADMINUSER}/*@@@value{PRIMARYREALM} il */root@@@value{PRIMARYREALM} -*@@@value{PRIMARYREALM} cil *1/admin@@@value{PRIMARYREALM} -*/*@@@value{PRIMARYREALM} i -*/admin@@@value{SECONDREALM} * -maxlife 9h -postdateable -@end group -@end smallexample - -@noindent In the above file, any principal in the -@value{PRIMARYREALM} realm with an @code{admin} instance has all -administrative privileges. The user @code{@value{ADMINUSER}} -has all permissions with his @code{admin} instance, -@code{@value{ADMINUSER}/admin@@@value{PRIMARYREALM}} (matches the first -line). He has no permissions at all with his @code{null} instance, -@code{@value{ADMINUSER}@@@value{PRIMARYREALM}} (matches the second line). -His root instance has @i{inquire} and @i{list} permissions with any -other principal that has the instance @code{root}. Any principal -in @value{PRIMARYREALM} can inquire, list, or change the password of -their @code{admin} instance, but not any other @code{admin} instance. -Any principal in the realm @code{@value{PRIMARYREALM}} (except for -@code{@value{ADMINUSER}@@@value{PRIMARYREALM}}, as mentioned above) has -@i{inquire} privileges. Finally, any principal with an admin instance -in @value{SECONDREALM} has all permissions, but any principal that they -create or modify will not be able to get postdateable tickets or tickets -with a life of longer than 9 hours. - diff --git a/doc/kadmin/.Sanitize b/doc/kadmin/.Sanitize deleted file mode 100644 index 148fae1be..000000000 --- a/doc/kadmin/.Sanitize +++ /dev/null @@ -1,33 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -kpasswd.protocol -kadmin.protocol - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/doc/kadmin/ChangeLog b/doc/kadmin/ChangeLog deleted file mode 100644 index 5599867c9..000000000 --- a/doc/kadmin/ChangeLog +++ /dev/null @@ -1,14 +0,0 @@ -2001-06-22 Ezra Peisach - - * draft-ietf-cat-kerb-chg-password-02.txt: Describes protocol in - use by krb5_change_password(). - - * README: Describes which admin protocol is used with which server. - -Thu Sep 7 15:51:56 1995 Theodore Y. Ts'o - - * kpasswd.protocol: Added official IANA port assignment. (We've - actually had it for quite a while, but I never got around - to adding it to the document.) - - diff --git a/doc/kadmin/README b/doc/kadmin/README deleted file mode 100644 index b3e53bfc8..000000000 --- a/doc/kadmin/README +++ /dev/null @@ -1,46 +0,0 @@ -There are several different admin protocols in our source tree. - -a) V4 server protocol - not documented - -b) Old kadmin protocol - which was in the beta code (kadmin/v5passwdd) - -c) Newer kadm5 gssrpc based code (kadmin/server) - -d) Simple password changing protocol implemented in our kadmin server -with client in clients/kpasswd. - - - -This file will attempt to link the files in this directory with where -the code is used in the source tree. - - -- kpasswd.protocol: Describes the password changing protocol in - src/kadmin/v5passwdd. - include/krb5/adm.h has some defintions. - - Client and server provided - -- kadmin.protocol: Describes other administrative protocol options that - src/kadmin/v5passwdd supports - - No client in the source tree uses it. - -- draft-ietf-cat-kerb-chg-password-02.txt: Describes the - password changing service that - clients/kpasswd uses through krb5_change_password() - located in lib/krb5/os/changepw.c - - kadmin/server/schpw.c implements this as part of - the kadmin server. - - This is version 1 of the protocol. Version 2 is - in the IETF draft stage and is very different. - - Currently: Version 1 is supported - but we may not - be implementing the TCP handling aspects. - -- ../doc/kadm5: Describes the current protocol. - - kadmin/passwd (which is not installed) uses - the kadm5 protocol for password changing. diff --git a/doc/kadmin/draft-ietf-cat-kerb-chg-password-02.txt b/doc/kadmin/draft-ietf-cat-kerb-chg-password-02.txt deleted file mode 100644 index e235bec58..000000000 --- a/doc/kadmin/draft-ietf-cat-kerb-chg-password-02.txt +++ /dev/null @@ -1,311 +0,0 @@ - - - - -Network Working Group M. Horowitz - Stonecast, Inc. -Internet-Draft August, 1998 - - Kerberos Change Password Protocol - -Status of this Memo - - This document is an Internet-Draft. Internet-Drafts are working - documents of the Internet Engineering Task Force (IETF), its areas, - and its working groups. Note that other groups may also distribute - working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as ``work in progress.'' - - To learn the current status of any Internet-Draft, please check the - ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow - Directories on ftp.ietf.org (US East Coast), nic.nordu.net - (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific - Rim). - - Distribution of this memo is unlimited. Please send comments to the - mailing list. - -Abstract - - The Kerberos V5 protocol [RFC1510] does not describe any mechanism - for users to change their own passwords. In order to promote - interoperability between workstations, personal computers, terminal - servers, routers, and KDC's from multiple vendors, a common password - changing protocol is required. - - - -Overview - - When a user wishes to change his own password, or is required to by - local policy, a simple request of a password changing service is - necessary. This service must be implemented on at least one host for - each Kerberos realm, probably on one of the kdc's for that realm. - The service must accept requests on UDP port 464 (kpasswd), and may - accept requests on TCP port 464 as well. - - The protocol itself consists of a single request message followed by - a single reply message. For UDP transport, each message must be - fully contained in a single UDP packet. - - - - - - - - -Horowitz [Page 1] - -Internet Draft Kerberos Change Password Protocol August, 1998 - - -Request Message - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | message length | protocol version number | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | AP_REQ length | AP-REQ data / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / KRB-PRIV message / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - message length (16 bits) - Contains the length of the message, including this field, in bytes - (big-endian integer) - protocol version number (16 bits) - Contains the hex constant 0x0001 (big-endian integer) - AP-REQ length (16 bits) - length (big-endian integer) of AP-REQ data, in bytes. - AP-REQ data, as described in RFC1510 (variable length) - This AP-REQ must be for the service principal - kadmin/changepw@REALM, where REALM is the REALM of the user who - wishes to change his password. The Ticket in the AP-REQ must be - derived from an AS request (thus having the INITIAL flag set), and - must include a subkey in the Authenticator. - KRB-PRIV message, as described in RFC1510 (variable length) - This KRB-PRIV message must be generated using the subkey in the - Authenticator in the AP-REQ data. The user-data component of the - message must consist of the user's new password. - - The server must verify the AP-REQ message, decrypt the new password, - perform any local policy checks (such as password quality, history, - authorization, etc.) required, then set the password to the new value - specified. - - The principal whose password is to be changed is the principal which - authenticated to the password changing service. This protocol does - not address administrators who want to change passwords of principal - besides their own. - - -Reply Message - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | message length | protocol version number | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | AP_REP length | AP-REP data / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / KRB-PRIV or KRB-ERROR message / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - message length (16 bits) - - - -Horowitz [Page 2] - -Internet Draft Kerberos Change Password Protocol August, 1998 - - - Contains the length of the message, including this field, in bytes - (big-endian integer), - protocol version number (16 bits) - Contains the hex constant 0x0001 (big-endian integer) - AP-REP length (16 bits) - length of AP-REP data, in bytes. If the the length is zero, then - the last field will contain a KRB-ERROR message instead of a KRB- - PRIV message. - AP-REP data, as described in RFC1510 (variable length) - The AP-REP corresponding to the AP-REQ in the request packet. - KRB-PRIV or KRB-ERROR message, as described in RFC1510 (variable - length) - If the AP-REP length is zero, then this field contains a KRB-ERROR - message. Otherwise, it contains a KRB-PRIV message. This KRB- - PRIV message must be generated using the subkey in the - Authenticator in the AP-REQ data. - - The user-data component of the KRB-PRIV message, or e-data - component of the KRB-ERROR message, must consist of the following - data: - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | result code | result string / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - result code (16 bits) - The result code must have one of the following values (big- - endian integer): - 0x0000 if the request succeeds. (This value is not permitted - in a KRB-ERROR message.) - 0x0001 if the request fails due to being malformed - 0x0002 if the request fails due to a "hard" error processing - the request (for example, there is a resource or other - problem causing the request to fail) - 0x0003 if the request fails due to an error in authentication - processing - 0x0004 if the request fails due to a "soft" error processing - the request (for example, some policy or other similar - consideration is causing the request to be rejected). - 0xFFFF if the request fails for some other reason. - Although only a few non-zero result codes are specified here, - the client should accept any non-zero result code as indicating - failure. - result string (variable length) - This field should contain information which the server thinks - might be useful to the user, such as feedback about policy - failures. The string must be encoded in UTF-8. It may be - omitted if the server does not wish to include it. If it is - present, the client should display the string to the user. - This field is analogous to the string which follows the numeric - code in SMTP, FTP, and similar protocols. - - - - -Horowitz [Page 3] - -Internet Draft Kerberos Change Password Protocol August, 1998 - - -Dropped and Modified Messages - - An attacker (or simply a lossy network) could cause either the - request or reply to be dropped, or modified by substituting a KRB- - ERROR message in the reply. - - If a request is dropped, no modification of the password/key database - will take place. If a reply is dropped, the server will (assuming a - valid request) make the password change. However, the client cannot - distinguish between these two cases. - - In this situation, the client should construct a new authenticator, - re-encrypt the request, and retransmit. If the original request was - lost, the server will treat this as a valid request, and the password - will be changed normally. If the reply was lost, then the server - should take care to notice that the request was a duplicate of the - prior request, because the "new" password is the current password, - and the password change time is within some implementation-defined - replay time window. The server should then return a success reply - (an AP-REP message with result code == 0x0000) without actually - changing the password or any other information (such as modification - timestamps). - - If a success reply was replaced with an error reply, then the - application performing the request would return an error to the user. - In this state, the user's password has been changed, but the user - believes that it has not. If the user attempts to change the - password again, this will probably fail, because the user cannot - successfully provide the old password to get an INITIAL ticket to - make the request. This situation requires administrative - intervention as if a password was lost. This situation is, - unfortunately, impossible to prevent. - - -Security Considerations - - This document deals with changing passwords for Kerberos. Because - Kerberos is used for authentication and key distribution, it is - important that this protocol use the highest level of security - services available to a particular installation. Mutual - authentication is performed, so that the server knows the request is - valid, and the client knows that the request has been received and - processed by the server. - - There are also security issues relating to dropped or modified - messages which are addressed explicitly. - - -References - - [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network - Authentication Service (V5)", RFC 1510, September 1993. - - - - - -Horowitz [Page 4] - -Internet Draft Kerberos Change Password Protocol August, 1998 - - -Author's Address - - Marc Horowitz - Stonecast, Inc. - 108 Stow Road - Harvard, MA 01451 - - Phone: +1 978 456 9103 - Email: marc@stonecast.net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Horowitz [Page 5] - diff --git a/doc/kadmin/kadmin.protocol b/doc/kadmin/kadmin.protocol deleted file mode 100644 index 5e48945f6..000000000 --- a/doc/kadmin/kadmin.protocol +++ /dev/null @@ -1,382 +0,0 @@ - -This document references, accompanies and extends the password changing -protocol document, "A Proposal for a Standardized Kerberos Password -Changing Protocol" by Theodore Ts'o. - -Administrative Command Extensions to the Password Changing Protocol -=================================================================== -The following commands and their accompanying definitions are an -extension to the password changing protocol which allow remote -administrative clients to perform functions analogous to those which -are performed using the local database editing utility. These -commands are encoded in the "command request" PDU described in the -password changing protocol, and the server's responses to these -commands are encoded in the "command reply" PDU. - -These commands are (optional commands are marked with an asterisk, new -or changed commands are marked with a plus sign): - ADD-PRINCIPAL - DELETE-PRINCIPAL - RENAME-PRINCIPAL - MODIFY-PRINCIPAL - OTHER-CHANGEPW - OTHER-RANDOM-CHANGEPW - INQUIRE-PRINCIPAL - EXTRACT-KEY (*+) - ADD-KEY (+) - DELETE-KEY (+) - -In order to support these additional commands, the following additional -status codes are also defined: - -Number Symbolic Name Meaning -64 P_ALREADY_EXISTS The specified principal already exists. -65 P_DOES_NOT_EXIST The specified principal does not exist. -66 NOT_AUTHORIZED The access control list on the server prevents - this operation. -67 BAD_OPTION Either: 1) A bad option was specified; 2) A - conflicting set of options would result from - this operation; or 3) Existing options prevent - this type of operation. -68 VALUE_REQUIRED The specified option requires a value. -69 SYSTEM_ERROR A system error occurred while processing a - request. -70(+) KEY_ALREADY_EXISTS The specified key already exists. -71(+) KEY_DOES_NOT_EXIST The specified key does not exist. - -The add principal operation ---------------------------- -o Command String "ADD-PRINCIPAL" -o Arguments - - name of new principal - - either "KEYWORD=value" or "KEYWORD". - . - . - . -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_ALREADY_EXISTS - new principal already exists - BAD_OPTION - bad option supplied - VALUE_REQUIRED - value required with keyword -o Supplemental Returns - NONE - if successful - error message text - if failure -o Description - If the specified principal does not exist, the arguments parse - correctly, and the arguments when combined with defaulted values - do not produce a conflicting set of options then add the specified - principal with the specified attributes. See below for the list of - settable attributes. -o Access Required - Client principal must have ADD_PRINCIPAL permission. - -The delete principal operation ------------------------------- -o Command String "DELETE-PRINCIPAL" -o Argument - - principal to delete -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - old principal does not exist -o Supplemental returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, then delete it from the database. -o Access Required - Client principal must have DELETE_PRINCIPAL permission. - -The rename principal operation ------------------------------- -o Command String "RENAME-PRINCIPAL" -o Arguments - - original name - - new name -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - old principal does not exist - P_ALREADY_EXISTS - new principal already exists -o Supplemental Returns - NONE - if successful - error message text - if failure -o Description - If the original principal exists and the new principal name does not - exist, rename the original principal to the specified name. -o Access Required - Client principal must have ADD_PRINCIPAL and DELETE_PRINCIPAL - permission. - -The modify principal operation ------------------------------- -o Command String "MODIFY-PRINCIPAL" -o Arguments - - name of principal - - either KEYWORD=value or KEYWORD. - . - . - . -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - principal doesn't exist - BAD_OPTION - bad option supplied - VALUE_REQUIRED - value required with keyword -o Supplemental returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, the arguments parse correctly, and - the arguments when combined with existing values do not produce a - conflicting set of options, then modify the specified principal with - the specified attributes. See below for the list of settable - attributes. -o Access Required - Client principal must have MODIFY_PRINCIPAL permission. - -The change password operation ------------------------------ -o Command String "OTHER-CHANGEPW" -o Arguments - - principal to change password for - - new password -o Returns - SUCCESS - operation successful - PW_UNACCEPT - specified password is bad - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - old principal does not exist - BAD_OPTION - principal has a random key -o Supplemental returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, and does not have a random key, - then change the password to the specified password. The original - password is NOT required. -o Access Required - Client principal must have CHANGEPW permission. - -The change random password command ----------------------------------- -o Command String "OTHER-RANDOM-CHANGEPW" -o Argument - - principal to change password for -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - old principal does not exist - BAD_OPTION - principal does not have a random key -o Supplemental Returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, and has a random key, then - generate a new random password. The original password is NOT - required. -o Access Required - Client principal must have CHANGEPW permission. - -The inquire principal command ------------------------------ -o Command String "INQUIRE-PRINCIPAL" -o Argument - - name of principal or null argument -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - principal doesn't exist -o Supplemental Returns - If the return is SUCCESS - - name of next principal in database - - KEYWORD=value list - . - . - . - Otherwise - error message text - if failure -o Description - If a principal is specified, then the database is searched for that - particular principal and its attributes are returned as keyword-value - pairs. If no principal is specified, then the first database entry - is returned. The name of the next principal in the database is always - returned to allow for scanning. See below for the list of attributes - that can be returned. -o Access Required - Client principal must have INQUIRE_PRINCIPAL permission. - -The OPTIONAL extract service key table entry command ----------------------------------------------------- -o Command String "EXTRACT-KEY" -o Arguments - - instance to extract for - - name to extract for -o Returns - SUCCESS - operation successful - CMD_UNKNOWN - operation not supported by server - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not allowed to perform this - P_DOES_NOT_EXIST - principal does not exist -o Supplemental Returns - - if successful - error message text - if failure -o Description - If the specified name/instance exists in the database, then - extract the service key entry and return it in . - The description of follows below. -o Access Required - Client principal must have EXTRACT permission. - -The add key operation ---------------------- -o Command String "ADD-KEY" -o Arguments - - name of the principal - - current password value - - name of the key in the form - :. - . - . - . -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not authorized to perform this - KEY_ALREADY_EXISTS - one or more of the specified - keytypes already exist. - BAD_OPTION - bad keytype:saltype specified - BAD_PW - supplied password is incorrect -o Supplemental Returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, the keyname(s) parse - correctly the specified password is successfully verified - against the existing key(s), and the specified keyname(s) do - not exist, then these keytype(s) are added to the principal. -o Access Required - Client principal must have MODIFY_PRINCIPAL permission. - -The delete key operation ------------------------- -o Command String "DELETE-KEY" -o Arguments - - name of the principal - - current password value - - name of the key in the form - :, or name of the - key in the form :: - - . - . - . -o Returns - SUCCESS - operation successful - SYSTEM_ERROR - system error - NOT_AUTHORIZED - not authorized to perform this - KEY_DOES_NOT_EXIST - one or more of the specified - keytypes do not exist. - BAD_OPTION - bad keytype:saltype specified - BAD_PW - supplied password is incorrect -o Supplemental Returns - NONE - if successful - error message text - if failure -o Description - If the specified principal exists, the keyname(s) parse - correctly the specified password is successfully verified - against the existing key(s), and the specified keyname(s) - exist, then they are deleted from the principal. -o Access Required - Client principal must have MODIFY_PRINCIPAL permission. - -Keywords --------- -The following list of keywords are used for the ADD-PRINCIPAL and -MODIFY-PRINCIPAL commands and are returned from the -INQUIRE-PRINCIPAL command. - -Valid Keyword Value Type Value -------- --------------- --------------- -------------------------------------- - (S) PASSWORD New password. - (SR) MAXLIFE The maximum lifetime of tickets for - this principal in seconds. - (SR) MAXRENEWLIFE The maximum renewable lifetime of - tickets for this principal in seconds. - (SR) EXPIRATION When the new principal expires. - (SR) PWEXPIRATION When the password expires for this - principal. - (SR) RANDOMKEY Specifies that this is to have a - random key generated for it. - (SR) FLAGS Specifies flag value for this - principal's attributes field in the - database. - (R) LASTSUCCESS Last successful password entry. - (R) LASTFAILED Last failed password attempt. - (R) FAILCOUNT Number of failed password attempts. - (SR) AUXDATA Tagged auxiliary value (see below) - (R) KEYDATA Key value (see below) - (SR) EXTRADATA Extra data (see below) - -The valid field indicates whether an attribute is Settable (e.g. appropriate -for use with ADD-PRINCIPAL, et. al.; Returnable (e.g. returned by -INQUIRE-PRINCIPAL); or both Settable and Returnable. - -o -The type denotes data which is stored in the database as a -tagged value. The protocol representation consists of a 4-byte network order -integer to denote the tag with the remaining data providing the value. If -encoded data is to be encapsulated, it must be in network order. In summary: - AUXDATA= -For example, to encode the value for tag 1 with a 4-byte value of 32 71 1e 30 -in network order, the encoding would be: - AUXDATA=00 00 00 01 32 71 1e 30 - -o -The type denotes data which is stored in the database on a per-key -basis. The protocol representation is consists of a 4-byte network order -integer to denote a particular key. This integer is implementation dependent -and is only used to correlate different entries. This integer -is followed by a 4-byte network order integer which denotes the attribute type. -Currently, only three are supported: -1 denotes the key version; 1 denotes the -key type and 2 denotes the salt type. This attribute type integer is followed -by the attribute value and an optional per-attribute value. In summary: - KEYDATA=[] -For example, to encode the value of a key with keytype 3, salttype 5, with key -version number 32, key data of 12 34 56 78 90 ab cd ef and salt data of f0 e1 -d2 c3 b4 a5 96 87, the encoding would be (using key-tag de ad be ef): - (key version number 32) - KEYDATA=de ad be ef ff ff ff ff 00 00 00 20 - (key keytype 3, value 1234567890abcdef) - KEYDATA=de ad be ef 00 00 00 01 00 00 00 03 12 34 56 78 90 ab cd ef - (key salttype 5, value f0e1d2c3b4a59687) - KEYDATA=de ad be ef 00 00 00 02 00 00 00 05 f0 e1 d2 c3 b4 a5 96 87 - -o -The type is exactly that. Unspecified. Any data may be encoded -here without restriction. - -Keytab Entry ------------- -If the EXTRACT SERVICE KEY function is supported, then the successful -response to this command is the key entry. This is a series of 6 -reply components as follows: - -component type value ---------- --------------- ----------------------------------------- - 1 Principal name - 2 Key entry timestamp - 3 Key's version number. - 4 Key's keytype. - 5 Key's encryption type. - 6 Key's key value. - -All of these components are mandatory. - diff --git a/doc/kadmin/kpasswd.protocol b/doc/kadmin/kpasswd.protocol deleted file mode 100644 index 7d77a2183..000000000 --- a/doc/kadmin/kpasswd.protocol +++ /dev/null @@ -1,303 +0,0 @@ - - - - A Proposal for a Standardized - Kerberos Password Changing Protocol - - **DRAFT** **DRAFT** **DRAFT** - - by Theodore Ts'o - September 7, 1995 - -Rationale -========= - -Currently, the Kerberos administration server which is being shipped -with the Beta Kerberos V5 distributions from MIT has not been of -sufficient quality for vendors to ship it in their products. Hence, -many vendors are creating and deploying proprietary administration -servers. In general, this is not a big problem --- relatively few -users are Kerberos administrators and thus the Kerberos administration -clients are used by relatively few users. - -There is a big exception to this, however, which is the functionality of -a user being able to change his or her own password. Application -programs may want to include this functionality in their programs; it -would be desireable for there to be a standardized protocol for doing -this. Standardized Kerberos desktop management programs (such as -Cornell's Authman) would also benefit from a standardized protocol; this -way, they will do not need to implement many vendor-specific Kerberos -administration protocols. Similarily, at least one terminal server -vendor has come to expressing their concern that there was not a -standardized password changing protocol, since they wanted their product -to offer this functionality. - -This protocol is designed to address these concerns. - - -Protocol Description -==================== - -The protocol used by the password changing protocol is intentionally -very simple. This is to encourage its widespread implementation, even -in cases where there are size constraints (i.e., in a terminal server). - -The protocol will use a TCP stream connection using port 464. The -symbolic name of this port is kpasswd: - - kpasswd 464/tcp - - -The following encoding standards are used throughout. - -Integers are sent as 4 byte objects, where the most significant byte -is sent first, and the least signifcant byte is sent last. (i.e., -standard Internet network byte order.) - -Protocol data units (PDU's) are sent across using the following -encoding. First, the size of the PDU is sent as a 4 byte integer, -followed by the PDU itself. PDU's used by the protocol will be either a -KRB_AP_REQ message, a KRB_AP_REP message, a "command request" PDU, or a -"command response" PDU. (The last two PDU's are encoded using a -KRB_PRIV message. For definitions of the KRB_AP_REQ, KRB_AP_REP, and -KRB_PRIV message, see the Kerberos V5 protocol specification found in -RFC 1510.) - -The PDU's which are encoded using the KRB_PRIV message must include the -sequence number field --- the client and server must fill in each -successive PDU that it sends with a monotonically increasing sequence -number. The initial sequence number in each direction are negotiated in -the KRB_AP_REQ and KRB_AP_REP messages. - -The size of a Protoocl Data Unit SHOULD not exceed 16,384 bytes. If an -implementation receives a PDU which is larger that 16,384 bytes, the -implementation MAY consider this a fatal error and terminate the TCP -connection. An implementation MUST be able to receive PDU's of at least -16,384 bytes. - -The "command request" PDU -------------------------- - -The "command request" PDU is sent from the client to server. This PDU -uses the following structure: First, the number of arguments, sent -across as an integer. The number of arguments MUST be greater than -zero. It is then followed by the arguments themselves, which are -encoded as an integer length followed by the value of the argument. - -The first argument is "command name". The command name is a NETASCII -string, and it may not contain an ASCII null. Command names are case -insentive. Valid command names are defined below; any site-, or vendor- -specific extensions to this protocol should use command names which -begin with the letter 'X'. - -The other arguments (if any) are dependent on the command specified by -the first argument. - -In other words: - - Number of Arguments (integer, must be greater than zero) - Arg size 1 (integer) - Arg data 1 (octet string, command name) - ... - Arg size N (integer) - Arg data N (octet string) - -This structure is then encrypted using the Kerberos V5 KRB_PRIV message. - -The "command reply" PDU ------------------------ - -In response to a "command request" PDU, the server will send to the -client a "command reply" PDU. The structure of a "command reply" PDU is -as follows: - - status code (integer) - Number of reply components (integer, may be zero) - Arg size 1 (integer) - Arg data 1 (octet string) - ... - Arg size N (integer) - Arg data N (octet string) - -This structure is then encrypted using the Kerberos V5 KRB_PRIV message. - -The status code may be one of the following values: - -# Symbolic name Meaning - -0 SUCCESS The command was executed without any errors -1 CMD_UNKNOWN Command not recognized -2 PW_UNACCEPT The password chosen by the user is unnacceptable. -3 BAD_PW The old password furnished by the user is not correct. -4 NOT_IN_TKT The ticket used to authenticate to the server - did not have the TKT_FLAG_INITIAL flag set. -5 CANT_CHANGE The server is not able to change the password - due to no fault of the user. (For - example, the database may be in - read-only mode for maintance reasons.) -6 LANG_NOT_SUPPORTED The requested language is not supported. - -The error codes below 127, and above 256 are reserved for future -expansion. Local extensions of this protocol should use error codes -between 128 and 255. - -The user text in the reply message is generally some sort of -explanatory text, which should be displayed to the user. - - -Connection Establishment -======================== - -When a connection is made the password changing client exchanges the -following PDU's: - -Client Server ------- ------ - -KRB_AP_REQ -------> - - <------- KRB_AP_REP - -KRB_AP_REQ and KRB_AP_REP are the respective Kerberos V5 messages. The -client will autenticate to the server using the service name -changepw/@, where should be -substituted with the name of the Kerberos realm of the password changing -server. The client MUST set the MUTUAL-REQUIRED flag in the KRB_AP_REQ -message, which indicates that server shall send a KRB_AP_REP message for -the purposes of establishing mutual authentication between the client -and the server. - -Protocol Commands -================== - -After the connection is established, the client may then send any -number of "command request" PDUs; after each command request PDU is -sent, the client should wait for a "command reply" PDU from the -server. - -If after 30 seconds inactivity, the client does not send a "command -request" PDU, the server MAY elect to terminate the TCP connection. - -The following commands defined in this standard: - - QUIT - CHECKPW - CHANGEPW - MOTD (*) - MIME (*) - LANGUAGE (*) - -The commands marked with a (*) are optional; servers may or may not -elect to support these commands. If the commands are not supported, the -server shall return a status code of CMD_UNKNOWN. - -The quit command ----------------- - -The name of this command is "QUIT", and it takes no arguments. The -response to this command must be the error code "NO_ERROR". There may -be an optional reply component, which will consist of user text which -should be displayed to the user. After processing this command, the -server will terminate the connection. - -Kerberos password changing servers MUST implement this command. - - -The check password command ---------------------------- - -The name of this command is "CHECKPW", and it takes one argument, -which is a proposed password. The server will evaluate this password -according to its criteria and return either an NO_ERROR or PW_UNACCEPT -error code. - -There may be an optional reply component which consists of user text -which should be displayed to the user. It will typically explain why -the password was unacceptable. - -Kerberos password changing servers MUST implement this command. - - -The change password command ---------------------------- - -The name of this command is "CHANGEPW", and it takes two arguments. The -first argument is the old password, and the second password is the new -password. The response from this command will generally be one of the -following error codes: NO_ERROR, PW_UNACCEPT, BAD_PW, NOT_IN_TKT, -CANT_CHANGE. - -This command changes the password of the Kerberos principal which the -client used to authenticate to the server. For security reasons, the -server should check to make sure that the ticket used to authenticate to -the server had the TKT_FLG_INITIAL flag set; if this flag is not set in -the ticket, then when the client attempts to use the "CHANGEPW" command, -the server should return the NOT_IN_TKT error. - -There may be an optional reply component which consists of user text -which should be displayed to the user, explaining why the password was -unacceptable or why the user's password could not be changed. - -Kerberos password changing servers MUST implement this command. - - -The Message of the Day command ------------------------------- - -The name of this command is "MOTD", and it takes zero or one additional -arguments. The optional argument is a magic token passed back from a -previous MOTD command. If this magic token is sent, the server MAY use -it to determine use it to determine what (if any) messages should be -displayed to the user. - -This command returns one or two reply components. The first reply -component is a magic token; the magic token shall be a NETASCII string -which may not contain an ASCII null character, and its length shall be -less than 64 characters. A client MAY store this magic token between -invocations of the client, and send it to the server the next time the -MOTD command is requested. - -The second (optional) reply component contains text which should be -displayed to the user. - -Kerberos password changing servers MAY optionally implement this command. - - -The MIME command ----------------- - -The name of this command is "MIME", and it takes zero additional -arguments. - -This command indicates that the client is willing to accept -MIME-enhanced textual messages in place of the standard NETASCII textual -messages. - -If this command is not sent, the server MUST send all textual messages -using NETASCII, with used as a line breaks, and line lengths no -more than 80 characters. If this command is sent, and the server -returns a status code of SUCCESS, the server MUST send textual messages -as MIME-enhanced textual messages. The server may refuse to send MIME -messages by sending a status code of CMD_UNKNOWN. - -Kerberos password changing servers MAY optionally implement this command. - - -The Language Command ---------------------- - -The name of this command is "LANGUAGE", and it takes one additional -argument, which indicates the language that the textual messages should -be sent back in. This additional argument must be consist of NETASCII -characters, with ASCII nulls not allowed. The argument shall be case -insensitive. What constitute valid arguments to this command are a -local matter. [Since ISO apparently doesn't have a standard way of -referring to different languages or dialects.] - -This command indicates that the client would prefer that textual -messages be sent back using the requested language. If the server does -not support the requested language, the server may refuse the request by -sending the error code LANG_NOT_SUPPORTED. - -Kerberos password changing servers MAY optionally implement this command. - diff --git a/doc/kdcconf.texinfo b/doc/kdcconf.texinfo deleted file mode 100644 index 51583714e..000000000 --- a/doc/kdcconf.texinfo +++ /dev/null @@ -1,24 +0,0 @@ -The @code{kdc.conf} file contains KDC configuration information, -including defaults used when issuing Kerberos tickets. Normally, you -should install your @code{kdc.conf} file in the directory -@code{@value{ROOTDIR}/var/krb5kdc}. You can override the default -location by setting the environment variable @samp{KRB5_KDC_PROFILE}. - -The @code{kdc.conf} file is set up in the same format as the -@code{krb5.conf} file. (@xref{krb5.conf}.) The @code{kdc.conf} file -may contain any or all of the following three sections: - -@table @b -@item kdcdefaults -Contains default values for overall behavior of the KDC. - -@item realms -Contains subsections keyed by Kerberos realm names. Each subsection -describes realm-specific information, including where to find the -Kerberos servers for that realm. - -@item logging -Contains relations which determine how Kerberos programs are to perform -logging. -@end table - diff --git a/doc/krb425.texinfo b/doc/krb425.texinfo deleted file mode 100644 index c239b2f54..000000000 --- a/doc/krb425.texinfo +++ /dev/null @@ -1,301 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c Note: the above texinfo file must include the "doubleleftarrow" -@c definitions added by jcb. -@c %**start of header -@c guide -@setfilename krb425.info -@settitle Upgrading to Kerberos V5 from Kerberos V4 -@c @setchapternewpage odd @c chapter begins on next odd page -@c @setchapternewpage on @c chapter begins on next page -@c @smallbook @c Format for 7" X 9.25" paper -@c %**end of header - -@paragraphindent 0 -@iftex -@parskip 6pt plus 6pt -@end iftex - -@include definitions.texinfo -@set EDITION 1.0 -@set UPDATED October 8, 1996 - -@finalout @c don't print black warning boxes - -@titlepage -@title Upgrading to @value{PRODUCT} from Kerberos V4 -@subtitle Release: @value{RELEASE} -@subtitle Document Edition: @value{EDITION} -@subtitle Last updated: @value{UPDATED} -@author @value{COMPANY} - -@page -@vskip 0pt plus 1filll - -@end titlepage - -@node Top, Copyright, (dir), (dir) - -@ifinfo -This document describes how to convert to @value{PRODUCT} from Kerberos V4. -@end ifinfo - -@menu -* Copyright:: -* Introduction:: -* Configuration Files:: -* Upgrading KDCs:: -* Upgrading Application Servers:: -* Upgrading Client machines:: -* Firewall Considerations:: -@end menu - -@node Copyright, Introduction, Top, Top -@unnumbered Copyright -@include copyright.texinfo - -@node Introduction, Configuration Files, Copyright, Top -@chapter Introduction - -As with most software upgrades, @value{PRODUCT} is generally backward -compatible but not necessarily forward compatible. The @value{PRODUCT} -daemons can interoperate with Kerberos V4 clients, but most of the -Kerberos V4 daemons can not interoperate with Kerberos V5 clients. This -suggests the following strategy for performing the upgrade: - -@enumerate -@item -@strong{Upgrade your KDCs.} This must be done first, so that -interactions with the Kerberos database, whether by Kerberos V5 clients -or by Kerberos V4 clients, will succeed. - -@item -@strong{Upgrade your servers.} This must be done before upgrading -client machines, so that the servers are able to respond to both -Kerberos V5 and Kerberos V4 queries. - -@item -@strong{Upgrade your client machines.} Do this only after your KDCs and -application servers are upgraded, so that all of your Kerberos V5 -clients will be talking to Kerberos V5 daemons. -@end enumerate - -@node Configuration Files, Upgrading KDCs, Introduction, Top -@chapter Configuration Files - -The Kerberos @code{krb5.conf} and KDC @code{kdc.conf} configuration -files allow additional tags for Kerberos V4 compatibility. - -@menu -* krb5.conf:: -* kdc.conf:: -@end menu - -@node krb5.conf, kdc.conf, Configuration Files, Configuration Files -@section krb5.conf - -If you used the defaults, both when you installed Kerberos V4 and when -you installed @value{PRODUCT}, you should not need to include any of -these tags. However, some or all of them may be necessary for -nonstandard installations. - -@menu -* libdefaults:: -* realms (krb5.conf):: -@end menu - -@node libdefaults, realms (krb5.conf), krb5.conf, krb5.conf -@subsection [libdefaults] - -In the [libdefaults] section, the following additional tags may be used: - -@table @b -@item krb4_srvtab -Specifies the location of the Kerberos V4 srvtab file. Default is -@value{DefaultKrb4Srvtab}. - -@item krb4_config -Specifies the location of the Kerberos V4 configuration file. Default -is @value{DefaultKrb4Config}. - -@item krb4_realms -Specifies the location of the Kerberos V4 domain/realm translation -file. Default is @value{DefaultKrb4Realms}. -@end table - -@node realms (krb5.conf), , libdefaults, krb5.conf -@subsection [realms] - -In the [realms] section, the following Kerberos V4 tags may be used: -@table @b -@itemx default_domain -Identifies the default domain for hosts in this realm. This is needed -for translating V4 principal names (which do not contain a domain name) -to V5 principal names. The default is your Kerberos realm name, -converted to lower case. - -@itemx v4_instance_convert -This subsection allows the administrator to configure exceptions to the -default_domain mapping rule. It contains V4 instances (tag name) which -should be translated to some specific hostname (tag value) as the second -component in a Kerberos V5 principal name. - -@itemx v4_realm -This relation allows the administrator to configure a different -realm name to be used when converting V5 principals to V4 -ones. This should only be used when running separate V4 and V5 -realms, with some external means of password sychronization -between the realms. - -@end table - -@node kdc.conf, , krb5.conf, Configuration Files -@section kdc.conf - -Because Kerberos V4 requires a different type of salt for the encryption -type, you will need to change the @code{supported_enctypes} line in the -[realms] section to: - -@smallexample -supported_enctypes = des-cbc-crc:normal des-cbc-crc:v4 -@end smallexample - -This is the only change needed to the @code{kdc.conf} file. - -@node Upgrading KDCs, Upgrading Application Servers, Configuration Files, Top -@chapter Upgrading KDCs - -To convert your KDCs from Kerberos V4 to @value{PRODUCT}, do the -following: - -@enumerate -@item -Install @value{PRODUCT} on each KDC, according to the instructions in -the @value{PRODUCT} Installation Guide, up to the point where it tells -you to create the database. - -@item -Find the @code{kadmind} (V4) daemon process on the master KDC and kill -it. This will prevent changes to the Kerberos database while you -convert the database to the new Kerberos V5 format. - -@item -Create a dump of the V4 database in the directory where your V5 database -will reside by issuing the command: - -@smallexample -% kdb_util dump @value{ROOTDIR}/var/krb5kdc/v4-dump -@end smallexample - -@item -Load the V4 dump into a Kerberos V5 database, by issuing the command: - -@smallexample -% kdb5_util load_v4 v4-dump -@end smallexample - -@item -Create a Kerberos V5 stash file, if desired, by issuing the command: - -@smallexample -% kdb5_util stash -@end smallexample - -@item -Proceed with the rest of the @value{PRODUCT} installation as described -in the @value{PRODUCT} Installation Guide. When you get to the section -that tells you to start the @code{krb5kdc} and @code{kadmind} daemons, -first find and kill the Kerberos V4 @code{kerberos} daemon on each of -the KDCs. Then start the @code{krb5kdc} and @code{kadmind} daemons as -You will need to specify an argument to the @code{-4} command line option to enable Kerberos 4 compatibility. -See the @code{krb5kdc} man page for details. -directed. Finally, start the Kerberos V5 to V4 ticket translator -daemon, @code{krb524d}, by issuing the command: - -@smallexample -% @value{ROOTDIR}/sbin/krb524d -m > /dev/null & -@end smallexample - -If you have a stash file and you start the @code{krb5kdc} and -@code{kadmind} daemons at boot time, you should add the above line to -your @code{/etc/rc} (or @code{/etc/rc.local}) file on each KDC. -@end enumerate - -@node Upgrading Application Servers, Upgrading Client machines, Upgrading KDCs, Top -@chapter Upgrading Application Servers - -Install @value{PRODUCT} on each application server, according to the -instructions in the @value{PRODUCT} Installation Guide, with the -following exceptions: - -@itemize @bullet -@item -In the file @code{/etc/services}, add or edit the lines described in the -@value{PRODUCT} Installation Guide, with the following exception: - -in place of: - -@smallexample -@group -kerberos @value{DefaultPort}/udp kdc # Kerberos V5 KDC -kerberos @value{DefaultPort}/tcp kdc # Kerberos V5 KDC -@end group -@end smallexample - -@noindent -add instead: - -@smallexample -@group -kerberos-sec @value{DefaultPort}/udp kdc # Kerberos V5 KDC -kerberos-sec @value{DefaultPort}/tcp kdc # Kerberos V5 KDC -@end group -@end smallexample - -@item -Convert your Kerberos V4 srvtab file to Kerberos V5 keytab file as -follows: - -@smallexample -@group -@b{#} @value{ROOTDIR}/sbin/ktutil -@b{ktutil:} rst /etc/krb-srvtab -@b{ktutil:} wkt /etc/krb5.keytab -@b{ktutil:} q -@b{#} -@end group -@end smallexample -@end itemize - -@node Upgrading Client machines, Firewall Considerations, Upgrading Application Servers, Top -@chapter Upgrading Client machines - -Install @value{PRODUCT} on each client machine, according to the -instructions in the @value{PRODUCT} Installation Guide. - -Tell your users to add the appropriate directory to their paths. On -UNIX machines, this will probably be @code{@value{BINDIR}}. - -Note that if you upgrade your client machines before all of your -application servers are upgraded, your users will need to use the -Kerberos V4 programs to connect to application servers that are still -running Kerberos V4. (The one exception is the UNIX version of -@value{PRODUCT} telnet, which can connect to a Kerberos V4 and Kerberos -V5 application servers.) Users can use either the Kerberos V4 or -@value{PRODUCT} programs to connect to Kerberos V5 servers. - -@node Firewall Considerations, , Upgrading Client machines, Top -@chapter Firewall Considerations - -@value{PRODUCT} uses port @value{DefaultPort}, which is the port -assigned by the IETF, for KDC requests. Kerberos V4 used port -@value{DefaultSecondPort}. If your users will need to get to any KDCs -outside your firewall, you will need to allow TCP and UDP requests on -port @value{DefaultPort} for your users to get to off-site Kerberos V5 -KDCs, and on port @value{DefaultSecondPort} for your users to get to -off-site Kerberos V4 KDCs. - -@contents -@c second page break makes sure right-left page alignment works right -@c with a one-page toc, even though we don't have setchapternewpage odd. -@c end of texinfo file -@bye diff --git a/doc/krb5-protocol/.Sanitize b/doc/krb5-protocol/.Sanitize deleted file mode 100644 index d37d1b7f1..000000000 --- a/doc/krb5-protocol/.Sanitize +++ /dev/null @@ -1,35 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -krb5.constants -rfc1510.errata -rfc1510.txt -3-des.txt - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/doc/krb5-protocol/3-des.txt b/doc/krb5-protocol/3-des.txt deleted file mode 100644 index ce6484547..000000000 --- a/doc/krb5-protocol/3-des.txt +++ /dev/null @@ -1,81 +0,0 @@ -For inclusion into RFC 1510 ---------------------------- -The assigned encryption type designating the use of triple DES is 5. - -The assigned checksum type designating the use of encrypting and MD5 -checksum with triple DES keys is 9. - -Triple DES is implemented using three DES keys. An Electronic CodeBook -encryption (3-DES ECB) is done by doing a DES ECB encryption of an eight -octet data block with the first DES key, performing a DES ECB decryption -of the resulting data block with the second key and performing a DES ECB -encryption of the result with the third key. - -The encryption of a data stream in Cipher Block Chaining mode is -accomplished by eXclusive-ORing each eight-octet data block with the -cipher computed from the previous data block, and then performing a -3-DES ECB encryption. The first data block is eXclusive-ORed with an -initial vector, which is commonly zero prior to performing the 3-DES -ECB. - -The string-to-key algorithm that is used for converting a user's -password into a 3-DES key is a one-way function, evenly distributing the -user's input in the resulting key. The user's input is appended with -the salt information (typically the realm name), and 168-folded to -produce three DES keys sans parity. The 168 bits are then expanded to -include odd parity, for use within the DES routines. If any of the keys -are weak or semi-weak, they are strengthened by eXclusive-ORing the -questionable key with the constant 00000000000000F0. The three DES keys -are then used to encrypt themselves in 3-DES CBC mode with a zero -initial vector. This result is once again encrypted using the same keys -and key schedule and an initial vector of the last eight octets. The -result is then parity adjusted. If the final result yields weak or -semi-weak keys, they are also strengthened in the same manner as the -input keys. - -The n-fold operation used by the string-to-key algorithm -replicates the input bit array X until its length is the least common -multiple of n bits and the length of X. Before each replication, the -input is circularly rotated to the right by 13 bit positions. The -successive n-bit chunks of the resulting bit array are then added -together with end-around carry to yield a n-bit result. The first bit -position in the arrays is treated as the most significant bit. - - - -Glossary --------- -n-fold - To n-fold a bit array X into n bits, replicate the input value to a length - that is the least common multiple of n bits and the length of X. Before - each successive repetition, circularly rotate the input X to the right by - 13 bit positions. The successive n-bit chunks are added together (where - the first bit is the most significant bit) with end-around carry (that is, - adding the carry result from the most significant bits to the least - significant bits) to yield a n-bit result. - -Triple-DES ECB mode: - - Three DES keys are used in turn to perform a DES ECB encryption of an - eight-octet data block with the first key, followed by a DES ECB - decryption of the resulting data block with the second key, followed - by a DES ECB encryption of the resulting data block with the last key. - -Triple-DES CBC mode: - An input data stream is padded on the right by zeroes to an eight-octet - boundary. The first eight octet block is eXclusive-ORed with an initial - vector eight-octet block. This result is triple-DES ECB encrypted with - three DES keys. Subsequent eight-octet data blocks are eXclusive-ORed - with the cipher text produced from the 3-DES ECB encryption of the previous - block and then the data block is 3-DES ECB encrypted with the same DES keys. - -Triple-DES String to key computation: - The input string (appended with any salt data) is 168-folded into a 21 octet - (168 bit) string. Each successive set of 7 octets is treated as a DES key - sans parity. The DES keys are then adjusted to include parity by computing - a parity bit for each successive seven bits to form eight octets. - The resulting DES keys including parity are then used to encrypt themselves - using Triple-DES CBC encryption with a zero initial vector. The result - is then adjusted for parity to produce three valid DES keys. Each key is - checked for weakness, and if it is determined to be weak or semi-weak, the - first octet of each weak key is eXclusive-ORed with the value 0xF0. diff --git a/doc/krb5-protocol/krb5.constants b/doc/krb5-protocol/krb5.constants deleted file mode 100644 index e7cc5b80e..000000000 --- a/doc/krb5-protocol/krb5.constants +++ /dev/null @@ -1,156 +0,0 @@ -8.3. Protocol constants and associated values - - The following tables list constants used in the protocol and defines - their meanings. - - ----------------+-----------+----------+----------------+--------------- -Encryption type|etype value|block size|minimum pad size|confounder size ----------------+-----------+----------+----------------+--------------- -NULL 0 1 0 0 -des-cbc-crc 1 8 4 8 -des-cbc-md4 2 8 0 8 -des-cbc-md5 3 8 0 8 - 4 -des3-cbc-md5 5 8 0 8 - 6 -des3-cbc-sha1 7 8 0 8 - 0x8003 - --------------------------------+-------------------+------------- -Checksum type |sumtype value |checksum size --------------------------------+-------------------+------------- -CRC32 1 4 -rsa-md4 2 16 -rsa-md4-des 3 24 -des-mac 4 16 -des-mac-k 5 8 -rsa-md4-des-k 6 16 -rsa-md5 7 16 -rsa-md5-des 8 24 - 9 - 10 -nist-sha1 11 20 -hmac-sha1-des3 12 20 - --------------------------------+----------------- -padata type |padata-type value --------------------------------+----------------- -PA-TGS-REQ 1 -PA-ENC-TIMESTAMP 2 -PA-PW-SALT 3 - 4 -PA-ENC-UNIX-TIME 5 -PA-SANDIA-SECUREID 6 -PA-SESAME 7 -PA-OSF-DCE 8 -PA-CYBERSAFE-SECUREID 9 -PA-AFS3-SALT 10 -PA-ETYPE-INFO 11 -PAM-SAM-CHALLENGE 12 -PAM-SAM-RESPONSE 13 - --------------------------------+------------- -authorization data type |ad-type value --------------------------------+------------- -reserved values 0-63 -AD-OSF-DCE 64 -AD-SESAME 65 - --------------------------------+----------------- -alternate authentication type |method-type value --------------------------------+----------------- -reserved values 0-63 -ATT-CHALLENGE-RESPONSE 64 - --------------------------------+------------- -transited encoding type |tr-type value --------------------------------+------------- -DOMAIN-X500-COMPRESS 1 -reserved values all others - - ---------------+-------+----------------------------------------- -Label |Value |Meaning or MIT code ---------------+-------+----------------------------------------- - -pvno 5 current Kerberos protocol version number - -message types - -KRB_AS_REQ 10 Request for initial authentication -KRB_AS_REP 11 Response to KRB_AS_REQ request -KRB_TGS_REQ 12 Request for authentication based on TGT -KRB_TGS_REP 13 Response to KRB_TGS_REQ request -KRB_AP_REQ 14 application request to server -KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL -KRB_SAFE 20 Safe (checksummed) application message -KRB_PRIV 21 Private (encrypted) application message -KRB_CRED 22 Private (encrypted) message to forward credentials -KRB_ERROR 30 Error response - -name types - -KRB_NT_UNKNOWN 0 Name type not known -KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or for users -KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt) -KRB_NT_SRV_HST 3 Service with host name as instance (telnet, rcommands) -KRB_NT_SRV_XHST 4 Service with host as remaining components -KRB_NT_UID 5 Unique ID - -error codes - -KDC_ERR_NONE 0 No error -KDC_ERR_NAME_EXP 1 Client's entry in database has expired -KDC_ERR_SERVICE_EXP 2 Server's entry in database has expired -KDC_ERR_BAD_PVNO 3 Requested protocol version # not supported -KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old master key -KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old master key -KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database -KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database -KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in database -KDC_ERR_NULL_KEY 9 The client or server has a null key -KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating -KDC_ERR_NEVER_VALID 11 Requested start time is later than end time -KDC_ERR_POLICY 12 KDC policy rejects request -KDC_ERR_BADOPTION 13 KDC cannot accommodate requested option -KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption type -KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type -KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type -KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type -KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked -KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been revoked -KDC_ERR_TGT_REVOKED 20 TGT has been revoked -KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again later -KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again later -KDC_ERR_KEY_EXPIRED 23 Password has expired - change to reset -KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information was invalid -KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authentication required* -KDC_ERR_SERVER_NOMATCH 26 Requested server and ticket don't match -KDC_ERR_MUST_USE_USER2USER 27 Server principal valid for user2user only -KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field failed -KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired -KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid -KRB_AP_ERR_REPEAT 34 Request is a replay -KRB_AP_ERR_NOT_US 35 The ticket isn't for us -KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match -KRB_AP_ERR_SKEW 37 Clock skew too great -KRB_AP_ERR_BADADDR 38 Incorrect net address -KRB_AP_ERR_BADVERSION 39 Protocol version mismatch -KRB_AP_ERR_MSG_TYPE 40 Invalid msg type -KRB_AP_ERR_MODIFIED 41 Message stream modified -KRB_AP_ERR_BADORDER 42 Message out of order -KRB_AP_ERR_BADKEYVER 44 Specified version of key is not available -KRB_AP_ERR_NOKEY 45 Service key not available -KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed -KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction -KRB_AP_ERR_METHOD 48 Alternative authentication method required* -KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message -KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in message -KRB_ERR_GENERIC 60 Generic error (description in e-text) -KRB_ERR_FIELD_TOOLONG 61 Field is too long for this implementation - - *This error carries additional information in the e-data field. The - contents of the e-data field for this message is described in section - 5.9.1. - diff --git a/doc/krb5-protocol/rfc1510.errata b/doc/krb5-protocol/rfc1510.errata deleted file mode 100644 index 602325b27..000000000 --- a/doc/krb5-protocol/rfc1510.errata +++ /dev/null @@ -1,105 +0,0 @@ ----rfc1510.eratta---as of Auguest 10, 1994--- - -1. [19940312] The following lines describes corrections to pseudocode - in rfc1510 as of March 12, 1994. - - A: Throughout the pseudocode (section A), flags.ALLOW-POSTDATE should be - replaced by flags.MAY-POSTDATE. kdc-options.ALLOW-POSTDATE is - correct, however. - -A.2: In the processing for the kdc-options.POSTDATE (imperitive), both - the POSTDATED and the INVALID flag should be set. The setting of the - POSTDATE flag was inadvertantly omitted. - - You should change: - - if (req.kdc-options.POSTDATED is set) then - if (against_postdate_policy(req.from)) then - error_out(KDC_ERR_POLICY); - endif - set new_tkt.flags.INVALID; - new_tkt.starttime := req.from; - else - omit new_tkt.starttime; /* treated as authtime when - - To: - if (req.kdc-options.POSTDATED is set) then - if (against_postdate_policy(req.from)) then - error_out(KDC_ERR_POLICY); - endif - set new_tkt.flags.POSTDATED; <**** - set new_tkt.flags.INVALID; - new_tkt.starttime := req.from; - else - omit new_tkt.starttime; /* treated as authtime when - -A.6: In section A.6, all occursences of kdc-options.POSTDATE (imperitive) - should be replaced by kdc-options.ALLOW-POSTDATE and tgt.flags.POSTDATE - should be replaced by tgt.flags.MAY-POSTDATE. - - Note that instances of POSTDATED (adjective) are correct. - - ---- -2. [19940614] Processing of the etype filed, described in 3.1.3, and 5.4.1. - -If a there are multiple encryption keys registered for a client in the -Kerberos database (or if the key registered supports multiple -encryption types; e.g. DES-CBC-CRC and DES-CBC-MD5), then the etype -field from the AS request is used by the KDC to select the encryption -method to be used for encrypting the response to the client. If there -is more than one supported, strong encryption type in the etype list, -the first valid etype for which an encryption key is available is -used. The encryption method used to respond to a TGS request is taken -from the keytype of the session key found in the ticket granting -ticket. - -When the etype field is present in a KDC request, whether an AS or TGS -request, the KDC will attempt to assign the type of the random session -key from the list of methods in the etype field. The KDC will select -the appropriate type using the list of methods provided together with -information from the Kerberos database indicating acceptable -encryption methods for the application server. The KDC will not issue -tickets with a weak session key encryption type. - ---- -3. [19940707] Case of realm names for DNS based realm names, - - The following should appear in section 7.1 before the description - of the four classed of realm names (before "There are presently...") - - Kerberos realm names are case sensitive. Realm names that differ - only in the case of the characters are not equivalent. - - The domain example should be changes from: - domain: host.subdomain.domain (example) - - To: - - domain: ATHENA.MIT.EDU (example) - - The following should be append to the domain name paragraph of - section 7.1 (following "nor slashes (/).") - - Domain names must be converted to upper case when used as realm names. - ---- -4. [19940707] Official name of host is instance for NT-SRV-HST - - Append to paragraph 7.2.1: - - When a host has an official name and one or more aliases, the - official name of the host must be used when constructing the name - of the server principal. - ---- - -5. [19940722] The protocol is standards track - - In the 3rd paragraph of the overview delete: - - ", and are not being submitted for consideration as - an Internet standard at this time" - - as it contradicts the first sentence of the RFC. - diff --git a/doc/krb5-protocol/rfc1510.txt b/doc/krb5-protocol/rfc1510.txt deleted file mode 100644 index bc810cc50..000000000 --- a/doc/krb5-protocol/rfc1510.txt +++ /dev/null @@ -1,6275 +0,0 @@ - - - - - - -Network Working Group J. Kohl -Request for Comments: 1510 Digital Equipment Corporation - C. Neuman - ISI - September 1993 - - - The Kerberos Network Authentication Service (V5) - -Status of this Memo - - This RFC specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" for the standardization state and status - of this protocol. Distribution of this memo is unlimited. - -Abstract - - This document gives an overview and specification of Version 5 of the - protocol for the Kerberos network authentication system. Version 4, - described elsewhere [1,2], is presently in production use at MIT's - Project Athena, and at other Internet sites. - -Overview - - Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, - Moira, and Zephyr are trademarks of the Massachusetts Institute of - Technology (MIT). No commercial use of these trademarks may be made - without prior written permission of MIT. - - This RFC describes the concepts and model upon which the Kerberos - network authentication system is based. It also specifies Version 5 - of the Kerberos protocol. - - The motivations, goals, assumptions, and rationale behind most design - decisions are treated cursorily; for Version 4 they are fully - described in the Kerberos portion of the Athena Technical Plan [1]. - The protocols are under review, and are not being submitted for - consideration as an Internet standard at this time. Comments are - encouraged. Requests for addition to an electronic mailing list for - discussion of Kerberos, kerberos@MIT.EDU, may be addressed to - kerberos-request@MIT.EDU. This mailing list is gatewayed onto the - Usenet as the group comp.protocols.kerberos. Requests for further - information, including documents and code availability, may be sent - to info-kerberos@MIT.EDU. - - - - - -Kohl & Neuman [Page 1] - -RFC 1510 Kerberos September 1993 - - -Background - - The Kerberos model is based in part on Needham and Schroeder's - trusted third-party authentication protocol [3] and on modifications - suggested by Denning and Sacco [4]. The original design and - implementation of Kerberos Versions 1 through 4 was the work of two - former Project Athena staff members, Steve Miller of Digital - Equipment Corporation and Clifford Neuman (now at the Information - Sciences Institute of the University of Southern California), along - with Jerome Saltzer, Technical Director of Project Athena, and - Jeffrey Schiller, MIT Campus Network Manager. Many other members of - Project Athena have also contributed to the work on Kerberos. - Version 4 is publicly available, and has seen wide use across the - Internet. - - Version 5 (described in this document) has evolved from Version 4 - based on new requirements and desires for features not available in - Version 4. Details on the differences between Kerberos Versions 4 - and 5 can be found in [5]. - -Table of Contents - - 1. Introduction ....................................... 5 - 1.1. Cross-Realm Operation ............................ 7 - 1.2. Environmental assumptions ........................ 8 - 1.3. Glossary of terms ................................ 9 - 2. Ticket flag uses and requests ...................... 12 - 2.1. Initial and pre-authenticated tickets ............ 12 - 2.2. Invalid tickets .................................. 12 - 2.3. Renewable tickets ................................ 12 - 2.4. Postdated tickets ................................ 13 - 2.5. Proxiable and proxy tickets ...................... 14 - 2.6. Forwardable tickets .............................. 15 - 2.7. Other KDC options ................................ 15 - 3. Message Exchanges .................................. 16 - 3.1. The Authentication Service Exchange .............. 16 - 3.1.1. Generation of KRB_AS_REQ message ............... 17 - 3.1.2. Receipt of KRB_AS_REQ message .................. 17 - 3.1.3. Generation of KRB_AS_REP message ............... 17 - 3.1.4. Generation of KRB_ERROR message ................ 19 - 3.1.5. Receipt of KRB_AS_REP message .................. 19 - 3.1.6. Receipt of KRB_ERROR message ................... 20 - 3.2. The Client/Server Authentication Exchange ........ 20 - 3.2.1. The KRB_AP_REQ message ......................... 20 - 3.2.2. Generation of a KRB_AP_REQ message ............. 20 - 3.2.3. Receipt of KRB_AP_REQ message .................. 21 - 3.2.4. Generation of a KRB_AP_REP message ............. 23 - 3.2.5. Receipt of KRB_AP_REP message .................. 23 - - - -Kohl & Neuman [Page 2] - -RFC 1510 Kerberos September 1993 - - - 3.2.6. Using the encryption key ....................... 24 - 3.3. The Ticket-Granting Service (TGS) Exchange ....... 24 - 3.3.1. Generation of KRB_TGS_REQ message .............. 25 - 3.3.2. Receipt of KRB_TGS_REQ message ................. 26 - 3.3.3. Generation of KRB_TGS_REP message .............. 27 - 3.3.3.1. Encoding the transited field ................. 29 - 3.3.4. Receipt of KRB_TGS_REP message ................. 31 - 3.4. The KRB_SAFE Exchange ............................ 31 - 3.4.1. Generation of a KRB_SAFE message ............... 31 - 3.4.2. Receipt of KRB_SAFE message .................... 32 - 3.5. The KRB_PRIV Exchange ............................ 33 - 3.5.1. Generation of a KRB_PRIV message ............... 33 - 3.5.2. Receipt of KRB_PRIV message .................... 33 - 3.6. The KRB_CRED Exchange ............................ 34 - 3.6.1. Generation of a KRB_CRED message ............... 34 - 3.6.2. Receipt of KRB_CRED message .................... 34 - 4. The Kerberos Database .............................. 35 - 4.1. Database contents ................................ 35 - 4.2. Additional fields ................................ 36 - 4.3. Frequently Changing Fields ....................... 37 - 4.4. Site Constants ................................... 37 - 5. Message Specifications ............................. 38 - 5.1. ASN.1 Distinguished Encoding Representation ...... 38 - 5.2. ASN.1 Base Definitions ........................... 38 - 5.3. Tickets and Authenticators ....................... 42 - 5.3.1. Tickets ........................................ 42 - 5.3.2. Authenticators ................................. 47 - 5.4. Specifications for the AS and TGS exchanges ...... 49 - 5.4.1. KRB_KDC_REQ definition ......................... 49 - 5.4.2. KRB_KDC_REP definition ......................... 56 - 5.5. Client/Server (CS) message specifications ........ 58 - 5.5.1. KRB_AP_REQ definition .......................... 58 - 5.5.2. KRB_AP_REP definition .......................... 60 - 5.5.3. Error message reply ............................ 61 - 5.6. KRB_SAFE message specification ................... 61 - 5.6.1. KRB_SAFE definition ............................ 61 - 5.7. KRB_PRIV message specification ................... 62 - 5.7.1. KRB_PRIV definition ............................ 62 - 5.8. KRB_CRED message specification ................... 63 - 5.8.1. KRB_CRED definition ............................ 63 - 5.9. Error message specification ...................... 65 - 5.9.1. KRB_ERROR definition ........................... 66 - 6. Encryption and Checksum Specifications ............. 67 - 6.1. Encryption Specifications ........................ 68 - 6.2. Encryption Keys .................................. 71 - 6.3. Encryption Systems ............................... 71 - 6.3.1. The NULL Encryption System (null) .............. 71 - 6.3.2. DES in CBC mode with a CRC-32 checksum (descbc-crc)71 - - - -Kohl & Neuman [Page 3] - -RFC 1510 Kerberos September 1993 - - - 6.3.3. DES in CBC mode with an MD4 checksum (descbc-md4) 72 - 6.3.4. DES in CBC mode with an MD5 checksum (descbc-md5) 72 - 6.4. Checksums ........................................ 74 - 6.4.1. The CRC-32 Checksum (crc32) .................... 74 - 6.4.2. The RSA MD4 Checksum (rsa-md4) ................. 75 - 6.4.3. RSA MD4 Cryptographic Checksum Using DES - (rsa-md4-des) ......................................... 75 - 6.4.4. The RSA MD5 Checksum (rsa-md5) ................. 76 - 6.4.5. RSA MD5 Cryptographic Checksum Using DES - (rsa-md5-des) ......................................... 76 - 6.4.6. DES cipher-block chained checksum (des-mac) - 6.4.7. RSA MD4 Cryptographic Checksum Using DES - alternative (rsa-md4-des-k) ........................... 77 - 6.4.8. DES cipher-block chained checksum alternative - (des-mac-k) ........................................... 77 - 7. Naming Constraints ................................. 78 - 7.1. Realm Names ...................................... 77 - 7.2. Principal Names .................................. 79 - 7.2.1. Name of server principals ...................... 80 - 8. Constants and other defined values ................. 80 - 8.1. Host address types ............................... 80 - 8.2. KDC messages ..................................... 81 - 8.2.1. IP transport ................................... 81 - 8.2.2. OSI transport .................................. 82 - 8.2.3. Name of the TGS ................................ 82 - 8.3. Protocol constants and associated values ......... 82 - 9. Interoperability requirements ...................... 86 - 9.1. Specification 1 .................................. 86 - 9.2. Recommended KDC values ........................... 88 - 10. Acknowledgments ................................... 88 - 11. References ........................................ 89 - 12. Security Considerations ........................... 90 - 13. Authors' Addresses ................................ 90 - A. Pseudo-code for protocol processing ................ 91 - A.1. KRB_AS_REQ generation ............................ 91 - A.2. KRB_AS_REQ verification and KRB_AS_REP generation 92 - A.3. KRB_AS_REP verification .......................... 95 - A.4. KRB_AS_REP and KRB_TGS_REP common checks ......... 96 - A.5. KRB_TGS_REQ generation ........................... 97 - A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation 98 - A.7. KRB_TGS_REP verification ......................... 104 - A.8. Authenticator generation ......................... 104 - A.9. KRB_AP_REQ generation ............................ 105 - A.10. KRB_AP_REQ verification ......................... 105 - A.11. KRB_AP_REP generation ........................... 106 - A.12. KRB_AP_REP verification ......................... 107 - A.13. KRB_SAFE generation ............................. 107 - A.14. KRB_SAFE verification ........................... 108 - - - -Kohl & Neuman [Page 4] - -RFC 1510 Kerberos September 1993 - - - A.15. KRB_SAFE and KRB_PRIV common checks ............. 108 - A.16. KRB_PRIV generation ............................. 109 - A.17. KRB_PRIV verification ........................... 110 - A.18. KRB_CRED generation ............................. 110 - A.19. KRB_CRED verification ........................... 111 - A.20. KRB_ERROR generation ............................ 112 - -1. Introduction - - Kerberos provides a means of verifying the identities of principals, - (e.g., a workstation user or a network server) on an open - (unprotected) network. This is accomplished without relying on - authentication by the host operating system, without basing trust on - host addresses, without requiring physical security of all the hosts - on the network, and under the assumption that packets traveling along - the network can be read, modified, and inserted at will. (Note, - however, that many applications use Kerberos' functions only upon the - initiation of a stream-based network connection, and assume the - absence of any "hijackers" who might subvert such a connection. Such - use implicitly trusts the host addresses involved.) Kerberos - performs authentication under these conditions as a trusted third- - party authentication service by using conventional cryptography, - i.e., shared secret key. (shared secret key - Secret and private are - often used interchangeably in the literature. In our usage, it takes - two (or more) to share a secret, thus a shared DES key is a secret - key. Something is only private when no one but its owner knows it. - Thus, in public key cryptosystems, one has a public and a private - key.) - - The authentication process proceeds as follows: A client sends a - request to the authentication server (AS) requesting "credentials" - for a given server. The AS responds with these credentials, - encrypted in the client's key. The credentials consist of 1) a - "ticket" for the server and 2) a temporary encryption key (often - called a "session key"). The client transmits the ticket (which - contains the client's identity and a copy of the session key, all - encrypted in the server's key) to the server. The session key (now - shared by the client and server) is used to authenticate the client, - and may optionally be used to authenticate the server. It may also - be used to encrypt further communication between the two parties or - to exchange a separate sub-session key to be used to encrypt further - communication. - - The implementation consists of one or more authentication servers - running on physically secure hosts. The authentication servers - maintain a database of principals (i.e., users and servers) and their - secret keys. Code libraries provide encryption and implement the - Kerberos protocol. In order to add authentication to its - - - -Kohl & Neuman [Page 5] - -RFC 1510 Kerberos September 1993 - - - transactions, a typical network application adds one or two calls to - the Kerberos library, which results in the transmission of the - necessary messages to achieve authentication. - - The Kerberos protocol consists of several sub-protocols (or - exchanges). There are two methods by which a client can ask a - Kerberos server for credentials. In the first approach, the client - sends a cleartext request for a ticket for the desired server to the - AS. The reply is sent encrypted in the client's secret key. Usually - this request is for a ticket-granting ticket (TGT) which can later be - used with the ticket-granting server (TGS). In the second method, - the client sends a request to the TGS. The client sends the TGT to - the TGS in the same manner as if it were contacting any other - application server which requires Kerberos credentials. The reply is - encrypted in the session key from the TGT. - - Once obtained, credentials may be used to verify the identity of the - principals in a transaction, to ensure the integrity of messages - exchanged between them, or to preserve privacy of the messages. The - application is free to choose whatever protection may be necessary. - - To verify the identities of the principals in a transaction, the - client transmits the ticket to the server. Since the ticket is sent - "in the clear" (parts of it are encrypted, but this encryption - doesn't thwart replay) and might be intercepted and reused by an - attacker, additional information is sent to prove that the message - was originated by the principal to whom the ticket was issued. This - information (called the authenticator) is encrypted in the session - key, and includes a timestamp. The timestamp proves that the message - was recently generated and is not a replay. Encrypting the - authenticator in the session key proves that it was generated by a - party possessing the session key. Since no one except the requesting - principal and the server know the session key (it is never sent over - the network in the clear) this guarantees the identity of the client. - - The integrity of the messages exchanged between principals can also - be guaranteed using the session key (passed in the ticket and - contained in the credentials). This approach provides detection of - both replay attacks and message stream modification attacks. It is - accomplished by generating and transmitting a collision-proof - checksum (elsewhere called a hash or digest function) of the client's - message, keyed with the session key. Privacy and integrity of the - messages exchanged between principals can be secured by encrypting - the data to be passed using the session key passed in the ticket, and - contained in the credentials. - - The authentication exchanges mentioned above require read-only access - to the Kerberos database. Sometimes, however, the entries in the - - - -Kohl & Neuman [Page 6] - -RFC 1510 Kerberos September 1993 - - - database must be modified, such as when adding new principals or - changing a principal's key. This is done using a protocol between a - client and a third Kerberos server, the Kerberos Administration - Server (KADM). The administration protocol is not described in this - document. There is also a protocol for maintaining multiple copies of - the Kerberos database, but this can be considered an implementation - detail and may vary to support different database technologies. - -1.1. Cross-Realm Operation - - The Kerberos protocol is designed to operate across organizational - boundaries. A client in one organization can be authenticated to a - server in another. Each organization wishing to run a Kerberos - server establishes its own "realm". The name of the realm in which a - client is registered is part of the client's name, and can be used by - the end-service to decide whether to honor a request. - - By establishing "inter-realm" keys, the administrators of two realms - can allow a client authenticated in the local realm to use its - authentication remotely (Of course, with appropriate permission the - client could arrange registration of a separately-named principal in - a remote realm, and engage in normal exchanges with that realm's - services. However, for even small numbers of clients this becomes - cumbersome, and more automatic methods as described here are - necessary). The exchange of inter-realm keys (a separate key may be - used for each direction) registers the ticket-granting service of - each realm as a principal in the other realm. A client is then able - to obtain a ticket-granting ticket for the remote realm's ticket- - granting service from its local realm. When that ticket-granting - ticket is used, the remote ticket-granting service uses the inter- - realm key (which usually differs from its own normal TGS key) to - decrypt the ticket-granting ticket, and is thus certain that it was - issued by the client's own TGS. Tickets issued by the remote ticket- - granting service will indicate to the end-service that the client was - authenticated from another realm. - - A realm is said to communicate with another realm if the two realms - share an inter-realm key, or if the local realm shares an inter-realm - key with an intermediate realm that communicates with the remote - realm. An authentication path is the sequence of intermediate realms - that are transited in communicating from one realm to another. - - Realms are typically organized hierarchically. Each realm shares a - key with its parent and a different key with each child. If an - inter-realm key is not directly shared by two realms, the - hierarchical organization allows an authentication path to be easily - constructed. If a hierarchical organization is not used, it may be - necessary to consult some database in order to construct an - - - -Kohl & Neuman [Page 7] - -RFC 1510 Kerberos September 1993 - - - authentication path between realms. - - Although realms are typically hierarchical, intermediate realms may - be bypassed to achieve cross-realm authentication through alternate - authentication paths (these might be established to make - communication between two realms more efficient). It is important - for the end-service to know which realms were transited when deciding - how much faith to place in the authentication process. To facilitate - this decision, a field in each ticket contains the names of the - realms that were involved in authenticating the client. - -1.2. Environmental assumptions - - Kerberos imposes a few assumptions on the environment in which it can - properly function: - - + "Denial of service" attacks are not solved with Kerberos. There - are places in these protocols where an intruder intruder can - prevent an application from participating in the proper - authentication steps. Detection and solution of such attacks - (some of which can appear to be not-uncommon "normal" failure - modes for the system) is usually best left to the human - administrators and users. - - + Principals must keep their secret keys secret. If an intruder - somehow steals a principal's key, it will be able to masquerade - as that principal or impersonate any server to the legitimate - principal. - - + "Password guessing" attacks are not solved by Kerberos. If a - user chooses a poor password, it is possible for an attacker to - successfully mount an offline dictionary attack by repeatedly - attempting to decrypt, with successive entries from a - dictionary, messages obtained which are encrypted under a key - derived from the user's password. - - + Each host on the network must have a clock which is "loosely - synchronized" to the time of the other hosts; this - synchronization is used to reduce the bookkeeping needs of - application servers when they do replay detection. The degree - of "looseness" can be configured on a per-server basis. If the - clocks are synchronized over the network, the clock - synchronization protocol must itself be secured from network - attackers. - - + Principal identifiers are not recycled on a short-term basis. A - typical mode of access control will use access control lists - (ACLs) to grant permissions to particular principals. If a - - - -Kohl & Neuman [Page 8] - -RFC 1510 Kerberos September 1993 - - - stale ACL entry remains for a deleted principal and the - principal identifier is reused, the new principal will inherit - rights specified in the stale ACL entry. By not re-using - principal identifiers, the danger of inadvertent access is - removed. - -1.3. Glossary of terms - - Below is a list of terms used throughout this document. - - - Authentication Verifying the claimed identity of a - principal. - - - Authentication header A record containing a Ticket and an - Authenticator to be presented to a - server as part of the authentication - process. - - - Authentication path A sequence of intermediate realms transited - in the authentication process when - communicating from one realm to another. - - Authenticator A record containing information that can - be shown to have been recently generated - using the session key known only by the - client and server. - - - Authorization The process of determining whether a - client may use a service, which objects - the client is allowed to access, and the - type of access allowed for each. - - - Capability A token that grants the bearer permission - to access an object or service. In - Kerberos, this might be a ticket whose - use is restricted by the contents of the - authorization data field, but which - lists no network addresses, together - with the session key necessary to use - the ticket. - - - - - - -Kohl & Neuman [Page 9] - -RFC 1510 Kerberos September 1993 - - - Ciphertext The output of an encryption function. - Encryption transforms plaintext into - ciphertext. - - - Client A process that makes use of a network - service on behalf of a user. Note that - in some cases a Server may itself be a - client of some other server (e.g., a - print server may be a client of a file - server). - - - Credentials A ticket plus the secret session key - necessary to successfully use that - ticket in an authentication exchange. - - - KDC Key Distribution Center, a network service - that supplies tickets and temporary - session keys; or an instance of that - service or the host on which it runs. - The KDC services both initial ticket and - ticket-granting ticket requests. The - initial ticket portion is sometimes - referred to as the Authentication Server - (or service). The ticket-granting - ticket portion is sometimes referred to - as the ticket-granting server (or service). - - Kerberos Aside from the 3-headed dog guarding - Hades, the name given to Project - Athena's authentication service, the - protocol used by that service, or the - code used to implement the authentication - service. - - - Plaintext The input to an encryption function or - the output of a decryption function. - Decryption transforms ciphertext into - plaintext. - - - Principal A uniquely named client or server - instance that participates in a network - communication. - - - - -Kohl & Neuman [Page 10] - -RFC 1510 Kerberos September 1993 - - - Principal identifier The name used to uniquely identify each - different principal. - - - Seal To encipher a record containing several - fields in such a way that the fields - cannot be individually replaced without - either knowledge of the encryption key - or leaving evidence of tampering. - - - Secret key An encryption key shared by a principal - and the KDC, distributed outside the - bounds of the system, with a long lifetime. - In the case of a human user's - principal, the secret key is derived - from a password. - - - Server A particular Principal which provides a - resource to network clients. - - - Service A resource provided to network clients; - often provided by more than one server - (for example, remote file service). - - - Session key A temporary encryption key used between - two principals, with a lifetime limited - to the duration of a single login "session". - - - Sub-session key A temporary encryption key used between - two principals, selected and exchanged - by the principals using the session key, - and with a lifetime limited to the duration - of a single association. - - - Ticket A record that helps a client authenticate - itself to a server; it contains the - client's identity, a session key, a - timestamp, and other information, all - sealed using the server's secret key. - It only serves to authenticate a client - when presented along with a fresh - Authenticator. - - - -Kohl & Neuman [Page 11] - -RFC 1510 Kerberos September 1993 - - -2. Ticket flag uses and requests - - Each Kerberos ticket contains a set of flags which are used to - indicate various attributes of that ticket. Most flags may be - requested by a client when the ticket is obtained; some are - automatically turned on and off by a Kerberos server as required. - The following sections explain what the various flags mean, and gives - examples of reasons to use such a flag. - -2.1. Initial and pre-authenticated tickets - - The INITIAL flag indicates that a ticket was issued using the AS - protocol and not issued based on a ticket-granting ticket. - Application servers that want to require the knowledge of a client's - secret key (e.g., a passwordchanging program) can insist that this - flag be set in any tickets they accept, and thus be assured that the - client's key was recently presented to the application client. - - The PRE-AUTHENT and HW-AUTHENT flags provide addition information - about the initial authentication, regardless of whether the current - ticket was issued directly (in which case INITIAL will also be set) - or issued on the basis of a ticket-granting ticket (in which case the - INITIAL flag is clear, but the PRE-AUTHENT and HW-AUTHENT flags are - carried forward from the ticket-granting ticket). - -2.2. Invalid tickets - - The INVALID flag indicates that a ticket is invalid. Application - servers must reject tickets which have this flag set. A postdated - ticket will usually be issued in this form. Invalid tickets must be - validated by the KDC before use, by presenting them to the KDC in a - TGS request with the VALIDATE option specified. The KDC will only - validate tickets after their starttime has passed. The validation is - required so that postdated tickets which have been stolen before - their starttime can be rendered permanently invalid (through a hot- - list mechanism). - -2.3. Renewable tickets - - Applications may desire to hold tickets which can be valid for long - periods of time. However, this can expose their credentials to - potential theft for equally long periods, and those stolen - credentials would be valid until the expiration time of the - ticket(s). Simply using shortlived tickets and obtaining new ones - periodically would require the client to have long-term access to its - secret key, an even greater risk. Renewable tickets can be used to - mitigate the consequences of theft. Renewable tickets have two - "expiration times": the first is when the current instance of the - - - -Kohl & Neuman [Page 12] - -RFC 1510 Kerberos September 1993 - - - ticket expires, and the second is the latest permissible value for an - individual expiration time. An application client must periodically - (i.e., before it expires) present a renewable ticket to the KDC, with - the RENEW option set in the KDC request. The KDC will issue a new - ticket with a new session key and a later expiration time. All other - fields of the ticket are left unmodified by the renewal process. - When the latest permissible expiration time arrives, the ticket - expires permanently. At each renewal, the KDC may consult a hot-list - to determine if the ticket had been reported stolen since its last - renewal; it will refuse to renew such stolen tickets, and thus the - usable lifetime of stolen tickets is reduced. - - The RENEWABLE flag in a ticket is normally only interpreted by the - ticket-granting service (discussed below in section 3.3). It can - usually be ignored by application servers. However, some - particularly careful application servers may wish to disallow - renewable tickets. - - If a renewable ticket is not renewed by its expiration time, the KDC - will not renew the ticket. The RENEWABLE flag is reset by default, - but a client may request it be set by setting the RENEWABLE option - in the KRB_AS_REQ message. If it is set, then the renew-till field - in the ticket contains the time after which the ticket may not be - renewed. - -2.4. Postdated tickets - - Applications may occasionally need to obtain tickets for use much - later, e.g., a batch submission system would need tickets to be valid - at the time the batch job is serviced. However, it is dangerous to - hold valid tickets in a batch queue, since they will be on-line - longer and more prone to theft. Postdated tickets provide a way to - obtain these tickets from the KDC at job submission time, but to - leave them "dormant" until they are activated and validated by a - further request of the KDC. If a ticket theft were reported in the - interim, the KDC would refuse to validate the ticket, and the thief - would be foiled. - - The MAY-POSTDATE flag in a ticket is normally only interpreted by the - ticket-granting service. It can be ignored by application servers. - This flag must be set in a ticket-granting ticket in order to issue a - postdated ticket based on the presented ticket. It is reset by - default; it may be requested by a client by setting the ALLOW- - POSTDATE option in the KRB_AS_REQ message. This flag does not allow - a client to obtain a postdated ticket-granting ticket; postdated - ticket-granting tickets can only by obtained by requesting the - postdating in the KRB_AS_REQ message. The life (endtime-starttime) - of a postdated ticket will be the remaining life of the ticket- - - - -Kohl & Neuman [Page 13] - -RFC 1510 Kerberos September 1993 - - - granting ticket at the time of the request, unless the RENEWABLE - option is also set, in which case it can be the full life (endtime- - starttime) of the ticket-granting ticket. The KDC may limit how far - in the future a ticket may be postdated. - - The POSTDATED flag indicates that a ticket has been postdated. The - application server can check the authtime field in the ticket to see - when the original authentication occurred. Some services may choose - to reject postdated tickets, or they may only accept them within a - certain period after the original authentication. When the KDC issues - a POSTDATED ticket, it will also be marked as INVALID, so that the - application client must present the ticket to the KDC to be validated - before use. - -2.5. Proxiable and proxy tickets - - At times it may be necessary for a principal to allow a service to - perform an operation on its behalf. The service must be able to take - on the identity of the client, but only for a particular purpose. A - principal can allow a service to take on the principal's identity for - a particular purpose by granting it a proxy. - - The PROXIABLE flag in a ticket is normally only interpreted by the - ticket-granting service. It can be ignored by application servers. - When set, this flag tells the ticket-granting server that it is OK to - issue a new ticket (but not a ticket-granting ticket) with a - different network address based on this ticket. This flag is set by - default. - - This flag allows a client to pass a proxy to a server to perform a - remote request on its behalf, e.g., a print service client can give - the print server a proxy to access the client's files on a particular - file server in order to satisfy a print request. - - In order to complicate the use of stolen credentials, Kerberos - tickets are usually valid from only those network addresses - specifically included in the ticket (It is permissible to request or - issue tickets with no network addresses specified, but we do not - recommend it). For this reason, a client wishing to grant a proxy - must request a new ticket valid for the network address of the - service to be granted the proxy. - - The PROXY flag is set in a ticket by the TGS when it issues a - proxy ticket. Application servers may check this flag and require - additional authentication from the agent presenting the proxy in - order to provide an audit trail. - - - - - -Kohl & Neuman [Page 14] - -RFC 1510 Kerberos September 1993 - - -2.6. Forwardable tickets - - Authentication forwarding is an instance of the proxy case where the - service is granted complete use of the client's identity. An example - where it might be used is when a user logs in to a remote system and - wants authentication to work from that system as if the login were - local. - - The FORWARDABLE flag in a ticket is normally only interpreted by the - ticket-granting service. It can be ignored by application servers. - The FORWARDABLE flag has an interpretation similar to that of the - PROXIABLE flag, except ticket-granting tickets may also be issued - with different network addresses. This flag is reset by default, but - users may request that it be set by setting the FORWARDABLE option in - the AS request when they request their initial ticket-granting - ticket. - - This flag allows for authentication forwarding without requiring the - user to enter a password again. If the flag is not set, then - authentication forwarding is not permitted, but the same end result - can still be achieved if the user engages in the AS exchange with the - requested network addresses and supplies a password. - - The FORWARDED flag is set by the TGS when a client presents a ticket - with the FORWARDABLE flag set and requests it be set by specifying - the FORWARDED KDC option and supplying a set of addresses for the new - ticket. It is also set in all tickets issued based on tickets with - the FORWARDED flag set. Application servers may wish to process - FORWARDED tickets differently than non-FORWARDED tickets. - -2.7. Other KDC options - - There are two additional options which may be set in a client's - request of the KDC. The RENEWABLE-OK option indicates that the - client will accept a renewable ticket if a ticket with the requested - life cannot otherwise be provided. If a ticket with the requested - life cannot be provided, then the KDC may issue a renewable ticket - with a renew-till equal to the the requested endtime. The value of - the renew-till field may still be adjusted by site-determined limits - or limits imposed by the individual principal or server. - - The ENC-TKT-IN-SKEY option is honored only by the ticket-granting - service. It indicates that the to-be-issued ticket for the end - server is to be encrypted in the session key from the additional - ticket-granting ticket provided with the request. See section 3.3.3 - for specific details. - - - - - -Kohl & Neuman [Page 15] - -RFC 1510 Kerberos September 1993 - - -3. Message Exchanges - - The following sections describe the interactions between network - clients and servers and the messages involved in those exchanges. - -3.1. The Authentication Service Exchange - - Summary - - Message direction Message type Section - 1. Client to Kerberos KRB_AS_REQ 5.4.1 - 2. Kerberos to client KRB_AS_REP or 5.4.2 - KRB_ERROR 5.9.1 - - The Authentication Service (AS) Exchange between the client and the - Kerberos Authentication Server is usually initiated by a client when - it wishes to obtain authentication credentials for a given server but - currently holds no credentials. The client's secret key is used for - encryption and decryption. This exchange is typically used at the - initiation of a login session, to obtain credentials for a Ticket- - Granting Server, which will subsequently be used to obtain - credentials for other servers (see section 3.3) without requiring - further use of the client's secret key. This exchange is also used - to request credentials for services which must not be mediated - through the Ticket-Granting Service, but rather require a principal's - secret key, such as the password-changing service. (The password- - changing request must not be honored unless the requester can provide - the old password (the user's current secret key). Otherwise, it - would be possible for someone to walk up to an unattended session and - change another user's password.) This exchange does not by itself - provide any assurance of the the identity of the user. (To - authenticate a user logging on to a local system, the credentials - obtained in the AS exchange may first be used in a TGS exchange to - obtain credentials for a local server. Those credentials must then - be verified by the local server through successful completion of the - Client/Server exchange.) - - The exchange consists of two messages: KRB_AS_REQ from the client to - Kerberos, and KRB_AS_REP or KRB_ERROR in reply. The formats for these - messages are described in sections 5.4.1, 5.4.2, and 5.9.1. - - In the request, the client sends (in cleartext) its own identity and - the identity of the server for which it is requesting credentials. - The response, KRB_AS_REP, contains a ticket for the client to present - to the server, and a session key that will be shared by the client - and the server. The session key and additional information are - encrypted in the client's secret key. The KRB_AS_REP message - contains information which can be used to detect replays, and to - - - -Kohl & Neuman [Page 16] - -RFC 1510 Kerberos September 1993 - - - associate it with the message to which it replies. Various errors - can occur; these are indicated by an error response (KRB_ERROR) - instead of the KRB_AS_REP response. The error message is not - encrypted. The KRB_ERROR message also contains information which can - be used to associate it with the message to which it replies. The - lack of encryption in the KRB_ERROR message precludes the ability to - detect replays or fabrications of such messages. - - In the normal case the authentication server does not know whether - the client is actually the principal named in the request. It simply - sends a reply without knowing or caring whether they are the same. - This is acceptable because nobody but the principal whose identity - was given in the request will be able to use the reply. Its critical - information is encrypted in that principal's key. The initial - request supports an optional field that can be used to pass - additional information that might be needed for the initial exchange. - This field may be used for preauthentication if desired, but the - mechanism is not currently specified. - -3.1.1. Generation of KRB_AS_REQ message - - The client may specify a number of options in the initial request. - Among these options are whether preauthentication is to be performed; - whether the requested ticket is to be renewable, proxiable, or - forwardable; whether it should be postdated or allow postdating of - derivative tickets; and whether a renewable ticket will be accepted - in lieu of a non-renewable ticket if the requested ticket expiration - date cannot be satisfied by a nonrenewable ticket (due to - configuration constraints; see section 4). See section A.1 for - pseudocode. - - The client prepares the KRB_AS_REQ message and sends it to the KDC. - -3.1.2. Receipt of KRB_AS_REQ message - - If all goes well, processing the KRB_AS_REQ message will result in - the creation of a ticket for the client to present to the server. - The format for the ticket is described in section 5.3.1. The - contents of the ticket are determined as follows. - -3.1.3. Generation of KRB_AS_REP message - - The authentication server looks up the client and server principals - named in the KRB_AS_REQ in its database, extracting their respective - keys. If required, the server pre-authenticates the request, and if - the pre-authentication check fails, an error message with the code - KDC_ERR_PREAUTH_FAILED is returned. If the server cannot accommodate - the requested encryption type, an error message with code - - - -Kohl & Neuman [Page 17] - -RFC 1510 Kerberos September 1993 - - - KDC_ERR_ETYPE_NOSUPP is returned. Otherwise it generates a "random" - session key ("Random" means that, among other things, it should be - impossible to guess the next session key based on knowledge of past - session keys. This can only be achieved in a pseudo-random number - generator if it is based on cryptographic principles. It would be - more desirable to use a truly random number generator, such as one - based on measurements of random physical phenomena.). - - If the requested start time is absent or indicates a time in the - past, then the start time of the ticket is set to the authentication - server's current time. If it indicates a time in the future, but the - POSTDATED option has not been specified, then the error - KDC_ERR_CANNOT_POSTDATE is returned. Otherwise the requested start - time is checked against the policy of the local realm (the - administrator might decide to prohibit certain types or ranges of - postdated tickets), and if acceptable, the ticket's start time is set - as requested and the INVALID flag is set in the new ticket. The - postdated ticket must be validated before use by presenting it to the - KDC after the start time has been reached. - - The expiration time of the ticket will be set to the minimum of the - following: - - +The expiration time (endtime) requested in the KRB_AS_REQ - message. - - +The ticket's start time plus the maximum allowable lifetime - associated with the client principal (the authentication - server's database includes a maximum ticket lifetime field - in each principal's record; see section 4). - - +The ticket's start time plus the maximum allowable lifetime - associated with the server principal. - - +The ticket's start time plus the maximum lifetime set by - the policy of the local realm. - - If the requested expiration time minus the start time (as determined - above) is less than a site-determined minimum lifetime, an error - message with code KDC_ERR_NEVER_VALID is returned. If the requested - expiration time for the ticket exceeds what was determined as above, - and if the "RENEWABLE-OK" option was requested, then the "RENEWABLE" - flag is set in the new ticket, and the renew-till value is set as if - the "RENEWABLE" option were requested (the field and option names are - described fully in section 5.4.1). If the RENEWABLE option has been - requested or if the RENEWABLE-OK option has been set and a renewable - ticket is to be issued, then the renew-till field is set to the - minimum of: - - - -Kohl & Neuman [Page 18] - -RFC 1510 Kerberos September 1993 - - - +Its requested value. - - +The start time of the ticket plus the minimum of the two - maximum renewable lifetimes associated with the principals' - database entries. - - +The start time of the ticket plus the maximum renewable - lifetime set by the policy of the local realm. - - The flags field of the new ticket will have the following options set - if they have been requested and if the policy of the local realm - allows: FORWARDABLE, MAY-POSTDATE, POSTDATED, PROXIABLE, RENEWABLE. - If the new ticket is postdated (the start time is in the future), its - INVALID flag will also be set. - - If all of the above succeed, the server formats a KRB_AS_REP message - (see section 5.4.2), copying the addresses in the request into the - caddr of the response, placing any required pre-authentication data - into the padata of the response, and encrypts the ciphertext part in - the client's key using the requested encryption method, and sends it - to the client. See section A.2 for pseudocode. - -3.1.4. Generation of KRB_ERROR message - - Several errors can occur, and the Authentication Server responds by - returning an error message, KRB_ERROR, to the client, with the - error-code and e-text fields set to appropriate values. The error - message contents and details are described in Section 5.9.1. - -3.1.5. Receipt of KRB_AS_REP message - - If the reply message type is KRB_AS_REP, then the client verifies - that the cname and crealm fields in the cleartext portion of the - reply match what it requested. If any padata fields are present, - they may be used to derive the proper secret key to decrypt the - message. The client decrypts the encrypted part of the response - using its secret key, verifies that the nonce in the encrypted part - matches the nonce it supplied in its request (to detect replays). It - also verifies that the sname and srealm in the response match those - in the request, and that the host address field is also correct. It - then stores the ticket, session key, start and expiration times, and - other information for later use. The key-expiration field from the - encrypted part of the response may be checked to notify the user of - impending key expiration (the client program could then suggest - remedial action, such as a password change). See section A.3 for - pseudocode. - - Proper decryption of the KRB_AS_REP message is not sufficient to - - - -Kohl & Neuman [Page 19] - -RFC 1510 Kerberos September 1993 - - - verify the identity of the user; the user and an attacker could - cooperate to generate a KRB_AS_REP format message which decrypts - properly but is not from the proper KDC. If the host wishes to - verify the identity of the user, it must require the user to present - application credentials which can be verified using a securely-stored - secret key. If those credentials can be verified, then the identity - of the user can be assured. - -3.1.6. Receipt of KRB_ERROR message - - If the reply message type is KRB_ERROR, then the client interprets it - as an error and performs whatever application-specific tasks are - necessary to recover. - -3.2. The Client/Server Authentication Exchange - - Summary - - Message direction Message type Section - Client to Application server KRB_AP_REQ 5.5.1 - [optional] Application server to client KRB_AP_REP or 5.5.2 - KRB_ERROR 5.9.1 - - The client/server authentication (CS) exchange is used by network - applications to authenticate the client to the server and vice versa. - The client must have already acquired credentials for the server - using the AS or TGS exchange. - -3.2.1. The KRB_AP_REQ message - - The KRB_AP_REQ contains authentication information which should be - part of the first message in an authenticated transaction. It - contains a ticket, an authenticator, and some additional bookkeeping - information (see section 5.5.1 for the exact format). The ticket by - itself is insufficient to authenticate a client, since tickets are - passed across the network in cleartext(Tickets contain both an - encrypted and unencrypted portion, so cleartext here refers to the - entire unit, which can be copied from one message and replayed in - another without any cryptographic skill.), so the authenticator is - used to prevent invalid replay of tickets by proving to the server - that the client knows the session key of the ticket and thus is - entitled to use it. The KRB_AP_REQ message is referred to elsewhere - as the "authentication header." - -3.2.2. Generation of a KRB_AP_REQ message - - When a client wishes to initiate authentication to a server, it - obtains (either through a credentials cache, the AS exchange, or the - - - -Kohl & Neuman [Page 20] - -RFC 1510 Kerberos September 1993 - - - TGS exchange) a ticket and session key for the desired service. The - client may re-use any tickets it holds until they expire. The client - then constructs a new Authenticator from the the system time, its - name, and optionally an application specific checksum, an initial - sequence number to be used in KRB_SAFE or KRB_PRIV messages, and/or a - session subkey to be used in negotiations for a session key unique to - this particular session. Authenticators may not be re-used and will - be rejected if replayed to a server (Note that this can make - applications based on unreliable transports difficult to code - correctly, if the transport might deliver duplicated messages. In - such cases, a new authenticator must be generated for each retry.). - If a sequence number is to be included, it should be randomly chosen - so that even after many messages have been exchanged it is not likely - to collide with other sequence numbers in use. - - The client may indicate a requirement of mutual authentication or the - use of a session-key based ticket by setting the appropriate flag(s) - in the ap-options field of the message. - - The Authenticator is encrypted in the session key and combined with - the ticket to form the KRB_AP_REQ message which is then sent to the - end server along with any additional application-specific - information. See section A.9 for pseudocode. - -3.2.3. Receipt of KRB_AP_REQ message - - Authentication is based on the server's current time of day (clocks - must be loosely synchronized), the authenticator, and the ticket. - Several errors are possible. If an error occurs, the server is - expected to reply to the client with a KRB_ERROR message. This - message may be encapsulated in the application protocol if its "raw" - form is not acceptable to the protocol. The format of error messages - is described in section 5.9.1. - - The algorithm for verifying authentication information is as follows. - If the message type is not KRB_AP_REQ, the server returns the - KRB_AP_ERR_MSG_TYPE error. If the key version indicated by the Ticket - in the KRB_AP_REQ is not one the server can use (e.g., it indicates - an old key, and the server no longer possesses a copy of the old - key), the KRB_AP_ERR_BADKEYVER error is returned. If the USE- - SESSION-KEY flag is set in the ap-options field, it indicates to the - server that the ticket is encrypted in the session key from the - server's ticket-granting ticket rather than its secret key (This is - used for user-to-user authentication as described in [6]). Since it - is possible for the server to be registered in multiple realms, with - different keys in each, the srealm field in the unencrypted portion - of the ticket in the KRB_AP_REQ is used to specify which secret key - the server should use to decrypt that ticket. The KRB_AP_ERR_NOKEY - - - -Kohl & Neuman [Page 21] - -RFC 1510 Kerberos September 1993 - - - error code is returned if the server doesn't have the proper key to - decipher the ticket. - - The ticket is decrypted using the version of the server's key - specified by the ticket. If the decryption routines detect a - modification of the ticket (each encryption system must provide - safeguards to detect modified ciphertext; see section 6), the - KRB_AP_ERR_BAD_INTEGRITY error is returned (chances are good that - different keys were used to encrypt and decrypt). - - The authenticator is decrypted using the session key extracted from - the decrypted ticket. If decryption shows it to have been modified, - the KRB_AP_ERR_BAD_INTEGRITY error is returned. The name and realm - of the client from the ticket are compared against the same fields in - the authenticator. If they don't match, the KRB_AP_ERR_BADMATCH - error is returned (they might not match, for example, if the wrong - session key was used to encrypt the authenticator). The addresses in - the ticket (if any) are then searched for an address matching the - operating-system reported address of the client. If no match is - found or the server insists on ticket addresses but none are present - in the ticket, the KRB_AP_ERR_BADADDR error is returned. - - If the local (server) time and the client time in the authenticator - differ by more than the allowable clock skew (e.g., 5 minutes), the - KRB_AP_ERR_SKEW error is returned. If the server name, along with - the client name, time and microsecond fields from the Authenticator - match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is - returned (Note that the rejection here is restricted to - authenticators from the same principal to the same server. Other - client principals communicating with the same server principal should - not be have their authenticators rejected if the time and microsecond - fields happen to match some other client's authenticator.). The - server must remember any authenticator presented within the allowable - clock skew, so that a replay attempt is guaranteed to fail. If a - server loses track of any authenticator presented within the - allowable clock skew, it must reject all requests until the clock - skew interval has passed. This assures that any lost or re-played - authenticators will fall outside the allowable clock skew and can no - longer be successfully replayed (If this is not done, an attacker - could conceivably record the ticket and authenticator sent over the - network to a server, then disable the client's host, pose as the - disabled host, and replay the ticket and authenticator to subvert the - authentication.). If a sequence number is provided in the - authenticator, the server saves it for later use in processing - KRB_SAFE and/or KRB_PRIV messages. If a subkey is present, the - server either saves it for later use or uses it to help generate its - own choice for a subkey to be returned in a KRB_AP_REP message. - - - - -Kohl & Neuman [Page 22] - -RFC 1510 Kerberos September 1993 - - - The server computes the age of the ticket: local (server) time minus - the start time inside the Ticket. If the start time is later than - the current time by more than the allowable clock skew or if the - INVALID flag is set in the ticket, the KRB_AP_ERR_TKT_NYV error is - returned. Otherwise, if the current time is later than end time by - more than the allowable clock skew, the KRB_AP_ERR_TKT_EXPIRED error - is returned. - - If all these checks succeed without an error, the server is assured - that the client possesses the credentials of the principal named in - the ticket and thus, the client has been authenticated to the server. - See section A.10 for pseudocode. - -3.2.4. Generation of a KRB_AP_REP message - - Typically, a client's request will include both the authentication - information and its initial request in the same message, and the - server need not explicitly reply to the KRB_AP_REQ. However, if - mutual authentication (not only authenticating the client to the - server, but also the server to the client) is being performed, the - KRB_AP_REQ message will have MUTUAL-REQUIRED set in its ap-options - field, and a KRB_AP_REP message is required in response. As with the - error message, this message may be encapsulated in the application - protocol if its "raw" form is not acceptable to the application's - protocol. The timestamp and microsecond field used in the reply must - be the client's timestamp and microsecond field (as provided in the - authenticator). [Note: In the Kerberos version 4 protocol, the - timestamp in the reply was the client's timestamp plus one. This is - not necessary in version 5 because version 5 messages are formatted - in such a way that it is not possible to create the reply by - judicious message surgery (even in encrypted form) without knowledge - of the appropriate encryption keys.] If a sequence number is to be - included, it should be randomly chosen as described above for the - authenticator. A subkey may be included if the server desires to - negotiate a different subkey. The KRB_AP_REP message is encrypted in - the session key extracted from the ticket. See section A.11 for - pseudocode. - -3.2.5. Receipt of KRB_AP_REP message - - If a KRB_AP_REP message is returned, the client uses the session key - from the credentials obtained for the server (Note that for - encrypting the KRB_AP_REP message, the sub-session key is not used, - even if present in the Authenticator.) to decrypt the message, and - verifies that the timestamp and microsecond fields match those in the - Authenticator it sent to the server. If they match, then the client - is assured that the server is genuine. The sequence number and subkey - (if present) are retained for later use. See section A.12 for - - - -Kohl & Neuman [Page 23] - -RFC 1510 Kerberos September 1993 - - - pseudocode. - -3.2.6. Using the encryption key - - After the KRB_AP_REQ/KRB_AP_REP exchange has occurred, the client and - server share an encryption key which can be used by the application. - The "true session key" to be used for KRB_PRIV, KRB_SAFE, or other - application-specific uses may be chosen by the application based on - the subkeys in the KRB_AP_REP message and the authenticator - (Implementations of the protocol may wish to provide routines to - choose subkeys based on session keys and random numbers and to - orchestrate a negotiated key to be returned in the KRB_AP_REP - message.). In some cases, the use of this session key will be - implicit in the protocol; in others the method of use must be chosen - from a several alternatives. We leave the protocol negotiations of - how to use the key (e.g., selecting an encryption or checksum type) - to the application programmer; the Kerberos protocol does not - constrain the implementation options. - - With both the one-way and mutual authentication exchanges, the peers - should take care not to send sensitive information to each other - without proper assurances. In particular, applications that require - privacy or integrity should use the KRB_AP_REP or KRB_ERROR responses - from the server to client to assure both client and server of their - peer's identity. If an application protocol requires privacy of its - messages, it can use the KRB_PRIV message (section 3.5). The KRB_SAFE - message (section 3.4) can be used to assure integrity. - -3.3. The Ticket-Granting Service (TGS) Exchange - - Summary - - Message direction Message type Section - 1. Client to Kerberos KRB_TGS_REQ 5.4.1 - 2. Kerberos to client KRB_TGS_REP or 5.4.2 - KRB_ERROR 5.9.1 - - The TGS exchange between a client and the Kerberos Ticket-Granting - Server is initiated by a client when it wishes to obtain - authentication credentials for a given server (which might be - registered in a remote realm), when it wishes to renew or validate an - existing ticket, or when it wishes to obtain a proxy ticket. In the - first case, the client must already have acquired a ticket for the - Ticket-Granting Service using the AS exchange (the ticket-granting - ticket is usually obtained when a client initially authenticates to - the system, such as when a user logs in). The message format for the - TGS exchange is almost identical to that for the AS exchange. The - primary difference is that encryption and decryption in the TGS - - - -Kohl & Neuman [Page 24] - -RFC 1510 Kerberos September 1993 - - - exchange does not take place under the client's key. Instead, the - session key from the ticket-granting ticket or renewable ticket, or - sub-session key from an Authenticator is used. As is the case for - all application servers, expired tickets are not accepted by the TGS, - so once a renewable or ticket-granting ticket expires, the client - must use a separate exchange to obtain valid tickets. - - The TGS exchange consists of two messages: A request (KRB_TGS_REQ) - from the client to the Kerberos Ticket-Granting Server, and a reply - (KRB_TGS_REP or KRB_ERROR). The KRB_TGS_REQ message includes - information authenticating the client plus a request for credentials. - The authentication information consists of the authentication header - (KRB_AP_REQ) which includes the client's previously obtained ticket- - granting, renewable, or invalid ticket. In the ticket-granting - ticket and proxy cases, the request may include one or more of: a - list of network addresses, a collection of typed authorization data - to be sealed in the ticket for authorization use by the application - server, or additional tickets (the use of which are described later). - The TGS reply (KRB_TGS_REP) contains the requested credentials, - encrypted in the session key from the ticket-granting ticket or - renewable ticket, or if present, in the subsession key from the - Authenticator (part of the authentication header). The KRB_ERROR - message contains an error code and text explaining what went wrong. - The KRB_ERROR message is not encrypted. The KRB_TGS_REP message - contains information which can be used to detect replays, and to - associate it with the message to which it replies. The KRB_ERROR - message also contains information which can be used to associate it - with the message to which it replies, but the lack of encryption in - the KRB_ERROR message precludes the ability to detect replays or - fabrications of such messages. - -3.3.1. Generation of KRB_TGS_REQ message - - Before sending a request to the ticket-granting service, the client - must determine in which realm the application server is registered - [Note: This can be accomplished in several ways. It might be known - beforehand (since the realm is part of the principal identifier), or - it might be stored in a nameserver. Presently, however, this - information is obtained from a configuration file. If the realm to - be used is obtained from a nameserver, there is a danger of being - spoofed if the nameservice providing the realm name is not - authenticated. This might result in the use of a realm which has - been compromised, and would result in an attacker's ability to - compromise the authentication of the application server to the - client.]. If the client does not already possess a ticket-granting - ticket for the appropriate realm, then one must be obtained. This is - first attempted by requesting a ticket-granting ticket for the - destination realm from the local Kerberos server (using the - - - -Kohl & Neuman [Page 25] - -RFC 1510 Kerberos September 1993 - - - KRB_TGS_REQ message recursively). The Kerberos server may return a - TGT for the desired realm in which case one can proceed. - Alternatively, the Kerberos server may return a TGT for a realm which - is "closer" to the desired realm (further along the standard - hierarchical path), in which case this step must be repeated with a - Kerberos server in the realm specified in the returned TGT. If - neither are returned, then the request must be retried with a - Kerberos server for a realm higher in the hierarchy. This request - will itself require a ticket-granting ticket for the higher realm - which must be obtained by recursively applying these directions. - - Once the client obtains a ticket-granting ticket for the appropriate - realm, it determines which Kerberos servers serve that realm, and - contacts one. The list might be obtained through a configuration file - or network service; as long as the secret keys exchanged by realms - are kept secret, only denial of service results from a false Kerberos - server. - - As in the AS exchange, the client may specify a number of options in - the KRB_TGS_REQ message. The client prepares the KRB_TGS_REQ - message, providing an authentication header as an element of the - padata field, and including the same fields as used in the KRB_AS_REQ - message along with several optional fields: the enc-authorization- - data field for application server use and additional tickets required - by some options. - - In preparing the authentication header, the client can select a sub- - session key under which the response from the Kerberos server will be - encrypted (If the client selects a sub-session key, care must be - taken to ensure the randomness of the selected subsession key. One - approach would be to generate a random number and XOR it with the - session key from the ticket-granting ticket.). If the sub-session key - is not specified, the session key from the ticket-granting ticket - will be used. If the enc-authorization-data is present, it must be - encrypted in the sub-session key, if present, from the authenticator - portion of the authentication header, or if not present in the - session key from the ticket-granting ticket. - - Once prepared, the message is sent to a Kerberos server for the - destination realm. See section A.5 for pseudocode. - -3.3.2. Receipt of KRB_TGS_REQ message - - The KRB_TGS_REQ message is processed in a manner similar to the - KRB_AS_REQ message, but there are many additional checks to be - performed. First, the Kerberos server must determine which server - the accompanying ticket is for and it must select the appropriate key - to decrypt it. For a normal KRB_TGS_REQ message, it will be for the - - - -Kohl & Neuman [Page 26] - -RFC 1510 Kerberos September 1993 - - - ticket granting service, and the TGS's key will be used. If the TGT - was issued by another realm, then the appropriate inter-realm key - must be used. If the accompanying ticket is not a ticket granting - ticket for the current realm, but is for an application server in the - current realm, the RENEW, VALIDATE, or PROXY options are specified in - the request, and the server for which a ticket is requested is the - server named in the accompanying ticket, then the KDC will decrypt - the ticket in the authentication header using the key of the server - for which it was issued. If no ticket can be found in the padata - field, the KDC_ERR_PADATA_TYPE_NOSUPP error is returned. - - Once the accompanying ticket has been decrypted, the user-supplied - checksum in the Authenticator must be verified against the contents - of the request, and the message rejected if the checksums do not - match (with an error code of KRB_AP_ERR_MODIFIED) or if the checksum - is not keyed or not collision-proof (with an error code of - KRB_AP_ERR_INAPP_CKSUM). If the checksum type is not supported, the - KDC_ERR_SUMTYPE_NOSUPP error is returned. If the authorization-data - are present, they are decrypted using the sub-session key from the - Authenticator. - - If any of the decryptions indicate failed integrity checks, the - KRB_AP_ERR_BAD_INTEGRITY error is returned. - -3.3.3. Generation of KRB_TGS_REP message - - The KRB_TGS_REP message shares its format with the KRB_AS_REP - (KRB_KDC_REP), but with its type field set to KRB_TGS_REP. The - detailed specification is in section 5.4.2. - - The response will include a ticket for the requested server. The - Kerberos database is queried to retrieve the record for the requested - server (including the key with which the ticket will be encrypted). - If the request is for a ticket granting ticket for a remote realm, - and if no key is shared with the requested realm, then the Kerberos - server will select the realm "closest" to the requested realm with - which it does share a key, and use that realm instead. This is the - only case where the response from the KDC will be for a different - server than that requested by the client. - - By default, the address field, the client's name and realm, the list - of transited realms, the time of initial authentication, the - expiration time, and the authorization data of the newly-issued - ticket will be copied from the ticket-granting ticket (TGT) or - renewable ticket. If the transited field needs to be updated, but - the transited type is not supported, the KDC_ERR_TRTYPE_NOSUPP error - is returned. - - - - -Kohl & Neuman [Page 27] - -RFC 1510 Kerberos September 1993 - - - If the request specifies an endtime, then the endtime of the new - ticket is set to the minimum of (a) that request, (b) the endtime - from the TGT, and (c) the starttime of the TGT plus the minimum of - the maximum life for the application server and the maximum life for - the local realm (the maximum life for the requesting principal was - already applied when the TGT was issued). If the new ticket is to be - a renewal, then the endtime above is replaced by the minimum of (a) - the value of the renew_till field of the ticket and (b) the starttime - for the new ticket plus the life (endtimestarttime) of the old - ticket. - - If the FORWARDED option has been requested, then the resulting ticket - will contain the addresses specified by the client. This option will - only be honored if the FORWARDABLE flag is set in the TGT. The PROXY - option is similar; the resulting ticket will contain the addresses - specified by the client. It will be honored only if the PROXIABLE - flag in the TGT is set. The PROXY option will not be honored on - requests for additional ticket-granting tickets. - - If the requested start time is absent or indicates a time in the - past, then the start time of the ticket is set to the authentication - server's current time. If it indicates a time in the future, but the - POSTDATED option has not been specified or the MAY-POSTDATE flag is - not set in the TGT, then the error KDC_ERR_CANNOT_POSTDATE is - returned. Otherwise, if the ticket-granting ticket has the - MAYPOSTDATE flag set, then the resulting ticket will be postdated and - the requested starttime is checked against the policy of the local - realm. If acceptable, the ticket's start time is set as requested, - and the INVALID flag is set. The postdated ticket must be validated - before use by presenting it to the KDC after the starttime has been - reached. However, in no case may the starttime, endtime, or renew- - till time of a newly-issued postdated ticket extend beyond the - renew-till time of the ticket-granting ticket. - - If the ENC-TKT-IN-SKEY option has been specified and an additional - ticket has been included in the request, the KDC will decrypt the - additional ticket using the key for the server to which the - additional ticket was issued and verify that it is a ticket-granting - ticket. If the name of the requested server is missing from the - request, the name of the client in the additional ticket will be - used. Otherwise the name of the requested server will be compared to - the name of the client in the additional ticket and if different, the - request will be rejected. If the request succeeds, the session key - from the additional ticket will be used to encrypt the new ticket - that is issued instead of using the key of the server for which the - new ticket will be used (This allows easy implementation of user-to- - user authentication [6], which uses ticket-granting ticket session - keys in lieu of secret server keys in situations where such secret - - - -Kohl & Neuman [Page 28] - -RFC 1510 Kerberos September 1993 - - - keys could be easily compromised.). - - If the name of the server in the ticket that is presented to the KDC - as part of the authentication header is not that of the ticket- - granting server itself, and the server is registered in the realm of - the KDC, If the RENEW option is requested, then the KDC will verify - that the RENEWABLE flag is set in the ticket and that the renew_till - time is still in the future. If the VALIDATE option is rqeuested, - the KDC will check that the starttime has passed and the INVALID flag - is set. If the PROXY option is requested, then the KDC will check - that the PROXIABLE flag is set in the ticket. If the tests succeed, - the KDC will issue the appropriate new ticket. - - Whenever a request is made to the ticket-granting server, the - presented ticket(s) is(are) checked against a hot-list of tickets - which have been canceled. This hot-list might be implemented by - storing a range of issue dates for "suspect tickets"; if a presented - ticket had an authtime in that range, it would be rejected. In this - way, a stolen ticket-granting ticket or renewable ticket cannot be - used to gain additional tickets (renewals or otherwise) once the - theft has been reported. Any normal ticket obtained before it was - reported stolen will still be valid (because they require no - interaction with the KDC), but only until their normal expiration - time. - - The ciphertext part of the response in the KRB_TGS_REP message is - encrypted in the sub-session key from the Authenticator, if present, - or the session key key from the ticket-granting ticket. It is not - encrypted using the client's secret key. Furthermore, the client's - key's expiration date and the key version number fields are left out - since these values are stored along with the client's database - record, and that record is not needed to satisfy a request based on a - ticket-granting ticket. See section A.6 for pseudocode. - -3.3.3.1. Encoding the transited field - - If the identity of the server in the TGT that is presented to the KDC - as part of the authentication header is that of the ticket-granting - service, but the TGT was issued from another realm, the KDC will look - up the inter-realm key shared with that realm and use that key to - decrypt the ticket. If the ticket is valid, then the KDC will honor - the request, subject to the constraints outlined above in the section - describing the AS exchange. The realm part of the client's identity - will be taken from the ticket-granting ticket. The name of the realm - that issued the ticket-granting ticket will be added to the transited - field of the ticket to be issued. This is accomplished by reading - the transited field from the ticket-granting ticket (which is treated - as an unordered set of realm names), adding the new realm to the set, - - - -Kohl & Neuman [Page 29] - -RFC 1510 Kerberos September 1993 - - - then constructing and writing out its encoded (shorthand) form (this - may involve a rearrangement of the existing encoding). - - Note that the ticket-granting service does not add the name of its - own realm. Instead, its responsibility is to add the name of the - previous realm. This prevents a malicious Kerberos server from - intentionally leaving out its own name (it could, however, omit other - realms' names). - - The names of neither the local realm nor the principal's realm are to - be included in the transited field. They appear elsewhere in the - ticket and both are known to have taken part in authenticating the - principal. Since the endpoints are not included, both local and - single-hop inter-realm authentication result in a transited field - that is empty. - - Because the name of each realm transited is added to this field, - it might potentially be very long. To decrease the length of this - field, its contents are encoded. The initially supported encoding is - optimized for the normal case of inter-realm communication: a - hierarchical arrangement of realms using either domain or X.500 style - realm names. This encoding (called DOMAIN-X500-COMPRESS) is now - described. - - Realm names in the transited field are separated by a ",". The ",", - "\", trailing "."s, and leading spaces (" ") are special characters, - and if they are part of a realm name, they must be quoted in the - transited field by preceding them with a "\". - - A realm name ending with a "." is interpreted as being prepended to - the previous realm. For example, we can encode traversal of EDU, - MIT.EDU, ATHENA.MIT.EDU, WASHINGTON.EDU, and CS.WASHINGTON.EDU as: - - "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.". - - Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were endpoints, - that they would not be included in this field, and we would have: - - "EDU,MIT.,WASHINGTON.EDU" - - A realm name beginning with a "/" is interpreted as being appended to - the previous realm (For the purpose of appending, the realm preceding - the first listed realm is considered to be the null realm ("")). If - it is to stand by itself, then it should be preceded by a space (" - "). For example, we can encode traversal of /COM/HP/APOLLO, /COM/HP, - /COM, and /COM/DEC as: - - "/COM,/HP,/APOLLO, /COM/DEC". - - - -Kohl & Neuman [Page 30] - -RFC 1510 Kerberos September 1993 - - - Like the example above, if /COM/HP/APOLLO and /COM/DEC are endpoints, - they they would not be included in this field, and we would have: - - "/COM,/HP" - - A null subfield preceding or following a "," indicates that all - realms between the previous realm and the next realm have been - traversed (For the purpose of interpreting null subfields, the - client's realm is considered to precede those in the transited field, - and the server's realm is considered to follow them.). Thus, "," - means that all realms along the path between the client and the - server have been traversed. ",EDU, /COM," means that that all realms - from the client's realm up to EDU (in a domain style hierarchy) have - been traversed, and that everything from /COM down to the server's - realm in an X.500 style has also been traversed. This could occur if - the EDU realm in one hierarchy shares an inter-realm key directly - with the /COM realm in another hierarchy. - -3.3.4. Receipt of KRB_TGS_REP message - - When the KRB_TGS_REP is received by the client, it is processed in - the same manner as the KRB_AS_REP processing described above. The - primary difference is that the ciphertext part of the response must - be decrypted using the session key from the ticket-granting ticket - rather than the client's secret key. See section A.7 for pseudocode. - -3.4. The KRB_SAFE Exchange - - The KRB_SAFE message may be used by clients requiring the ability to - detect modifications of messages they exchange. It achieves this by - including a keyed collisionproof checksum of the user data and some - control information. The checksum is keyed with an encryption key - (usually the last key negotiated via subkeys, or the session key if - no negotiation has occured). - -3.4.1. Generation of a KRB_SAFE message - - When an application wishes to send a KRB_SAFE message, it collects - its data and the appropriate control information and computes a - checksum over them. The checksum algorithm should be some sort of - keyed one-way hash function (such as the RSA-MD5-DES checksum - algorithm specified in section 6.4.5, or the DES MAC), generated - using the sub-session key if present, or the session key. Different - algorithms may be selected by changing the checksum type in the - message. Unkeyed or non-collision-proof checksums are not suitable - for this use. - - The control information for the KRB_SAFE message includes both a - - - -Kohl & Neuman [Page 31] - -RFC 1510 Kerberos September 1993 - - - timestamp and a sequence number. The designer of an application - using the KRB_SAFE message must choose at least one of the two - mechanisms. This choice should be based on the needs of the - application protocol. - - Sequence numbers are useful when all messages sent will be received - by one's peer. Connection state is presently required to maintain - the session key, so maintaining the next sequence number should not - present an additional problem. - - If the application protocol is expected to tolerate lost messages - without them being resent, the use of the timestamp is the - appropriate replay detection mechanism. Using timestamps is also the - appropriate mechanism for multi-cast protocols where all of one's - peers share a common sub-session key, but some messages will be sent - to a subset of one's peers. - - After computing the checksum, the client then transmits the - information and checksum to the recipient in the message format - specified in section 5.6.1. - -3.4.2. Receipt of KRB_SAFE message - - When an application receives a KRB_SAFE message, it verifies it as - follows. If any error occurs, an error code is reported for use by - the application. - - The message is first checked by verifying that the protocol version - and type fields match the current version and KRB_SAFE, respectively. - A mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE - error. The application verifies that the checksum used is a - collisionproof keyed checksum, and if it is not, a - KRB_AP_ERR_INAPP_CKSUM error is generated. The recipient verifies - that the operating system's report of the sender's address matches - the sender's address in the message, and (if a recipient address is - specified or the recipient requires an address) that one of the - recipient's addresses appears as the recipient's address in the - message. A failed match for either case generates a - KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the - sequence number fields are checked. If timestamp and usec are - expected and not present, or they are present but not current, the - KRB_AP_ERR_SKEW error is generated. If the server name, along with - the client name, time and microsecond fields from the Authenticator - match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is - generated. If an incorrect sequence number is included, or a - sequence number is expected but not present, the KRB_AP_ERR_BADORDER - error is generated. If neither a timestamp and usec or a sequence - number is present, a KRB_AP_ERR_MODIFIED error is generated. - - - -Kohl & Neuman [Page 32] - -RFC 1510 Kerberos September 1993 - - - Finally, the checksum is computed over the data and control - information, and if it doesn't match the received checksum, a - KRB_AP_ERR_MODIFIED error is generated. - - If all the checks succeed, the application is assured that the - message was generated by its peer and was not modified in transit. - -3.5. The KRB_PRIV Exchange - - The KRB_PRIV message may be used by clients requiring confidentiality - and the ability to detect modifications of exchanged messages. It - achieves this by encrypting the messages and adding control - information. - -3.5.1. Generation of a KRB_PRIV message - - When an application wishes to send a KRB_PRIV message, it collects - its data and the appropriate control information (specified in - section 5.7.1) and encrypts them under an encryption key (usually the - last key negotiated via subkeys, or the session key if no negotiation - has occured). As part of the control information, the client must - choose to use either a timestamp or a sequence number (or both); see - the discussion in section 3.4.1 for guidelines on which to use. - After the user data and control information are encrypted, the client - transmits the ciphertext and some "envelope" information to the - recipient. - -3.5.2. Receipt of KRB_PRIV message - - When an application receives a KRB_PRIV message, it verifies it as - follows. If any error occurs, an error code is reported for use by - the application. - - The message is first checked by verifying that the protocol version - and type fields match the current version and KRB_PRIV, respectively. - A mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE - error. The application then decrypts the ciphertext and processes - the resultant plaintext. If decryption shows the data to have been - modified, a KRB_AP_ERR_BAD_INTEGRITY error is generated. The - recipient verifies that the operating system's report of the sender's - address matches the sender's address in the message, and (if a - recipient address is specified or the recipient requires an address) - that one of the recipient's addresses appears as the recipient's - address in the message. A failed match for either case generates a - KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the - sequence number fields are checked. If timestamp and usec are - expected and not present, or they are present but not current, the - KRB_AP_ERR_SKEW error is generated. If the server name, along with - - - -Kohl & Neuman [Page 33] - -RFC 1510 Kerberos September 1993 - - - the client name, time and microsecond fields from the Authenticator - match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is - generated. If an incorrect sequence number is included, or a - sequence number is expected but not present, the KRB_AP_ERR_BADORDER - error is generated. If neither a timestamp and usec or a sequence - number is present, a KRB_AP_ERR_MODIFIED error is generated. - - If all the checks succeed, the application can assume the message was - generated by its peer, and was securely transmitted (without - intruders able to see the unencrypted contents). - -3.6. The KRB_CRED Exchange - - The KRB_CRED message may be used by clients requiring the ability to - send Kerberos credentials from one host to another. It achieves this - by sending the tickets together with encrypted data containing the - session keys and other information associated with the tickets. - -3.6.1. Generation of a KRB_CRED message - - When an application wishes to send a KRB_CRED message it first (using - the KRB_TGS exchange) obtains credentials to be sent to the remote - host. It then constructs a KRB_CRED message using the ticket or - tickets so obtained, placing the session key needed to use each - ticket in the key field of the corresponding KrbCredInfo sequence of - the encrypted part of the the KRB_CRED message. - - Other information associated with each ticket and obtained during the - KRB_TGS exchange is also placed in the corresponding KrbCredInfo - sequence in the encrypted part of the KRB_CRED message. The current - time and, if specifically required by the application the nonce, s- - address, and raddress fields, are placed in the encrypted part of the - KRB_CRED message which is then encrypted under an encryption key - previosuly exchanged in the KRB_AP exchange (usually the last key - negotiated via subkeys, or the session key if no negotiation has - occured). - -3.6.2. Receipt of KRB_CRED message - - When an application receives a KRB_CRED message, it verifies it. If - any error occurs, an error code is reported for use by the - application. The message is verified by checking that the protocol - version and type fields match the current version and KRB_CRED, - respectively. A mismatch generates a KRB_AP_ERR_BADVERSION or - KRB_AP_ERR_MSG_TYPE error. The application then decrypts the - ciphertext and processes the resultant plaintext. If decryption shows - the data to have been modified, a KRB_AP_ERR_BAD_INTEGRITY error is - generated. - - - -Kohl & Neuman [Page 34] - -RFC 1510 Kerberos September 1993 - - - If present or required, the recipient verifies that the operating - system's report of the sender's address matches the sender's address - in the message, and that one of the recipient's addresses appears as - the recipient's address in the message. A failed match for either - case generates a KRB_AP_ERR_BADADDR error. The timestamp and usec - fields (and the nonce field if required) are checked next. If the - timestamp and usec are not present, or they are present but not - current, the KRB_AP_ERR_SKEW error is generated. - - If all the checks succeed, the application stores each of the new - tickets in its ticket cache together with the session key and other - information in the corresponding KrbCredInfo sequence from the - encrypted part of the KRB_CRED message. - -4. The Kerberos Database - - The Kerberos server must have access to a database containing the - principal identifiers and secret keys of principals to be - authenticated (The implementation of the Kerberos server need not - combine the database and the server on the same machine; it is - feasible to store the principal database in, say, a network name - service, as long as the entries stored therein are protected from - disclosure to and modification by unauthorized parties. However, we - recommend against such strategies, as they can make system management - and threat analysis quite complex.). - -4.1. Database contents - - A database entry should contain at least the following fields: - - Field Value - - name Principal's identifier - key Principal's secret key - p_kvno Principal's key version - max_life Maximum lifetime for Tickets - max_renewable_life Maximum total lifetime for renewable - Tickets - - The name field is an encoding of the principal's identifier. The key - field contains an encryption key. This key is the principal's secret - key. (The key can be encrypted before storage under a Kerberos - "master key" to protect it in case the database is compromised but - the master key is not. In that case, an extra field must be added to - indicate the master key version used, see below.) The p_kvno field is - the key version number of the principal's secret key. The max_life - field contains the maximum allowable lifetime (endtime - starttime) - for any Ticket issued for this principal. The max_renewable_life - - - -Kohl & Neuman [Page 35] - -RFC 1510 Kerberos September 1993 - - - field contains the maximum allowable total lifetime for any renewable - Ticket issued for this principal. (See section 3.1 for a description - of how these lifetimes are used in determining the lifetime of a - given Ticket.) - - A server may provide KDC service to several realms, as long as the - database representation provides a mechanism to distinguish between - principal records with identifiers which differ only in the realm - name. - - When an application server's key changes, if the change is routine - (i.e., not the result of disclosure of the old key), the old key - should be retained by the server until all tickets that had been - issued using that key have expired. Because of this, it is possible - for several keys to be active for a single principal. Ciphertext - encrypted in a principal's key is always tagged with the version of - the key that was used for encryption, to help the recipient find the - proper key for decryption. - - When more than one key is active for a particular principal, the - principal will have more than one record in the Kerberos database. - The keys and key version numbers will differ between the records (the - rest of the fields may or may not be the same). Whenever Kerberos - issues a ticket, or responds to a request for initial authentication, - the most recent key (known by the Kerberos server) will be used for - encryption. This is the key with the highest key version number. - -4.2. Additional fields - - Project Athena's KDC implementation uses additional fields in its - database: - - Field Value - - K_kvno Kerberos' key version - expiration Expiration date for entry - attributes Bit field of attributes - mod_date Timestamp of last modification - mod_name Modifying principal's identifier - - The K_kvno field indicates the key version of the Kerberos master key - under which the principal's secret key is encrypted. - - After an entry's expiration date has passed, the KDC will return an - error to any client attempting to gain tickets as or for the - principal. (A database may want to maintain two expiration dates: - one for the principal, and one for the principal's current key. This - allows password aging to work independently of the principal's - - - -Kohl & Neuman [Page 36] - -RFC 1510 Kerberos September 1993 - - - expiration date. However, due to the limited space in the responses, - the KDC must combine the key expiration and principal expiration date - into a single value called "key_exp", which is used as a hint to the - user to take administrative action.) - - The attributes field is a bitfield used to govern the operations - involving the principal. This field might be useful in conjunction - with user registration procedures, for site-specific policy - implementations (Project Athena currently uses it for their user - registration process controlled by the system-wide database service, - Moira [7]), or to identify the "string to key" conversion algorithm - used for a principal's key. (See the discussion of the padata field - in section 5.4.2 for details on why this can be useful.) Other bits - are used to indicate that certain ticket options should not be - allowed in tickets encrypted under a principal's key (one bit each): - Disallow issuing postdated tickets, disallow issuing forwardable - tickets, disallow issuing tickets based on TGT authentication, - disallow issuing renewable tickets, disallow issuing proxiable - tickets, and disallow issuing tickets for which the principal is the - server. - - The mod_date field contains the time of last modification of the - entry, and the mod_name field contains the name of the principal - which last modified the entry. - -4.3. Frequently Changing Fields - - Some KDC implementations may wish to maintain the last time that a - request was made by a particular principal. Information that might - be maintained includes the time of the last request, the time of the - last request for a ticket-granting ticket, the time of the last use - of a ticket-granting ticket, or other times. This information can - then be returned to the user in the last-req field (see section 5.2). - - Other frequently changing information that can be maintained is the - latest expiration time for any tickets that have been issued using - each key. This field would be used to indicate how long old keys - must remain valid to allow the continued use of outstanding tickets. - -4.4. Site Constants - - The KDC implementation should have the following configurable - constants or options, to allow an administrator to make and enforce - policy decisions: - - + The minimum supported lifetime (used to determine whether the - KDC_ERR_NEVER_VALID error should be returned). This constant - should reflect reasonable expectations of round-trip time to the - - - -Kohl & Neuman [Page 37] - -RFC 1510 Kerberos September 1993 - - - KDC, encryption/decryption time, and processing time by the client - and target server, and it should allow for a minimum "useful" - lifetime. - - + The maximum allowable total (renewable) lifetime of a ticket - (renew_till - starttime). - - + The maximum allowable lifetime of a ticket (endtime - starttime). - - + Whether to allow the issue of tickets with empty address fields - (including the ability to specify that such tickets may only be - issued if the request specifies some authorization_data). - - + Whether proxiable, forwardable, renewable or post-datable tickets - are to be issued. - -5. Message Specifications - - The following sections describe the exact contents and encoding of - protocol messages and objects. The ASN.1 base definitions are - presented in the first subsection. The remaining subsections specify - the protocol objects (tickets and authenticators) and messages. - Specification of encryption and checksum techniques, and the fields - related to them, appear in section 6. - -5.1. ASN.1 Distinguished Encoding Representation - - All uses of ASN.1 in Kerberos shall use the Distinguished Encoding - Representation of the data elements as described in the X.509 - specification, section 8.7 [8]. - -5.2. ASN.1 Base Definitions - - The following ASN.1 base definitions are used in the rest of this - section. Note that since the underscore character (_) is not - permitted in ASN.1 names, the hyphen (-) is used in its place for the - purposes of ASN.1 names. - - Realm ::= GeneralString - PrincipalName ::= SEQUENCE { - name-type[0] INTEGER, - name-string[1] SEQUENCE OF GeneralString - } - - Kerberos realms are encoded as GeneralStrings. Realms shall not - contain a character with the code 0 (the ASCII NUL). Most realms - will usually consist of several components separated by periods (.), - in the style of Internet Domain Names, or separated by slashes (/) in - - - -Kohl & Neuman [Page 38] - -RFC 1510 Kerberos September 1993 - - - the style of X.500 names. Acceptable forms for realm names are - specified in section 7. A PrincipalName is a typed sequence of - components consisting of the following sub-fields: - - name-type This field specifies the type of name that follows. - Pre-defined values for this field are - specified in section 7.2. The name-type should be - treated as a hint. Ignoring the name type, no two - names can be the same (i.e., at least one of the - components, or the realm, must be different). - This constraint may be eliminated in the future. - - name-string This field encodes a sequence of components that - form a name, each component encoded as a General - String. Taken together, a PrincipalName and a Realm - form a principal identifier. Most PrincipalNames - will have only a few components (typically one or two). - - KerberosTime ::= GeneralizedTime - -- Specifying UTC time zone (Z) - - The timestamps used in Kerberos are encoded as GeneralizedTimes. An - encoding shall specify the UTC time zone (Z) and shall not include - any fractional portions of the seconds. It further shall not include - any separators. Example: The only valid format for UTC time 6 - minutes, 27 seconds after 9 pm on 6 November 1985 is 19851106210627Z. - - HostAddress ::= SEQUENCE { - addr-type[0] INTEGER, - address[1] OCTET STRING - } - - HostAddresses ::= SEQUENCE OF SEQUENCE { - addr-type[0] INTEGER, - address[1] OCTET STRING - } - - - The host adddress encodings consists of two fields: - - addr-type This field specifies the type of address that - follows. Pre-defined values for this field are - specified in section 8.1. - - - address This field encodes a single address of type addr-type. - - The two forms differ slightly. HostAddress contains exactly one - - - -Kohl & Neuman [Page 39] - -RFC 1510 Kerberos September 1993 - - - address; HostAddresses contains a sequence of possibly many - addresses. - - AuthorizationData ::= SEQUENCE OF SEQUENCE { - ad-type[0] INTEGER, - ad-data[1] OCTET STRING - } - - - ad-data This field contains authorization data to be - interpreted according to the value of the - corresponding ad-type field. - - ad-type This field specifies the format for the ad-data - subfield. All negative values are reserved for - local use. Non-negative values are reserved for - registered use. - - APOptions ::= BIT STRING { - reserved(0), - use-session-key(1), - mutual-required(2) - } - - - TicketFlags ::= BIT STRING { - reserved(0), - forwardable(1), - forwarded(2), - proxiable(3), - proxy(4), - may-postdate(5), - postdated(6), - invalid(7), - renewable(8), - initial(9), - pre-authent(10), - hw-authent(11) - } - - KDCOptions ::= BIT STRING { - reserved(0), - forwardable(1), - forwarded(2), - proxiable(3), - proxy(4), - allow-postdate(5), - postdated(6), - - - -Kohl & Neuman [Page 40] - -RFC 1510 Kerberos September 1993 - - - unused7(7), - renewable(8), - unused9(9), - unused10(10), - unused11(11), - renewable-ok(27), - enc-tkt-in-skey(28), - renew(30), - validate(31) - } - - - LastReq ::= SEQUENCE OF SEQUENCE { - lr-type[0] INTEGER, - lr-value[1] KerberosTime - } - - lr-type This field indicates how the following lr-value - field is to be interpreted. Negative values indicate - that the information pertains only to the - responding server. Non-negative values pertain to - all servers for the realm. - - If the lr-type field is zero (0), then no information - is conveyed by the lr-value subfield. If the - absolute value of the lr-type field is one (1), - then the lr-value subfield is the time of last - initial request for a TGT. If it is two (2), then - the lr-value subfield is the time of last initial - request. If it is three (3), then the lr-value - subfield is the time of issue for the newest - ticket-granting ticket used. If it is four (4), - then the lr-value subfield is the time of the last - renewal. If it is five (5), then the lr-value - subfield is the time of last request (of any - type). - - lr-value This field contains the time of the last request. - The time must be interpreted according to the contents - of the accompanying lr-type subfield. - - See section 6 for the definitions of Checksum, ChecksumType, - EncryptedData, EncryptionKey, EncryptionType, and KeyType. - - - - - - - - -Kohl & Neuman [Page 41] - -RFC 1510 Kerberos September 1993 - - -5.3. Tickets and Authenticators - - This section describes the format and encryption parameters for - tickets and authenticators. When a ticket or authenticator is - included in a protocol message it is treated as an opaque object. - -5.3.1. Tickets - - A ticket is a record that helps a client authenticate to a service. - A Ticket contains the following information: - -Ticket ::= [APPLICATION 1] SEQUENCE { - tkt-vno[0] INTEGER, - realm[1] Realm, - sname[2] PrincipalName, - enc-part[3] EncryptedData -} --- Encrypted part of ticket -EncTicketPart ::= [APPLICATION 3] SEQUENCE { - flags[0] TicketFlags, - key[1] EncryptionKey, - crealm[2] Realm, - cname[3] PrincipalName, - transited[4] TransitedEncoding, - authtime[5] KerberosTime, - starttime[6] KerberosTime OPTIONAL, - endtime[7] KerberosTime, - renew-till[8] KerberosTime OPTIONAL, - caddr[9] HostAddresses OPTIONAL, - authorization-data[10] AuthorizationData OPTIONAL -} --- encoded Transited field -TransitedEncoding ::= SEQUENCE { - tr-type[0] INTEGER, -- must be registered - contents[1] OCTET STRING -} - - The encoding of EncTicketPart is encrypted in the key shared by - Kerberos and the end server (the server's secret key). See section 6 - for the format of the ciphertext. - - tkt-vno This field specifies the version number for the ticket - format. This document describes version number 5. - - realm This field specifies the realm that issued a ticket. It - also serves to identify the realm part of the server's - principal identifier. Since a Kerberos server can only - issue tickets for servers within its realm, the two will - - - -Kohl & Neuman [Page 42] - -RFC 1510 Kerberos September 1993 - - - always be identical. - - sname This field specifies the name part of the server's - identity. - - enc-part This field holds the encrypted encoding of the - EncTicketPart sequence. - - flags This field indicates which of various options were used or - requested when the ticket was issued. It is a bit-field, - where the selected options are indicated by the bit being - set (1), and the unselected options and reserved fields - being reset (0). Bit 0 is the most significant bit. The - encoding of the bits is specified in section 5.2. The - flags are described in more detail above in section 2. The - meanings of the flags are: - - Bit(s) Name Description - - 0 RESERVED Reserved for future expansion of this - field. - - 1 FORWARDABLE The FORWARDABLE flag is normally only - interpreted by the TGS, and can be - ignored by end servers. When set, - this flag tells the ticket-granting - server that it is OK to issue a new - ticket- granting ticket with a - different network address based on - the presented ticket. - - 2 FORWARDED When set, this flag indicates that - the ticket has either been forwarded - or was issued based on authentication - involving a forwarded ticket-granting - ticket. - - 3 PROXIABLE The PROXIABLE flag is normally only - interpreted by the TGS, and can be - ignored by end servers. The PROXIABLE - flag has an interpretation identical - to that of the FORWARDABLE flag, - except that the PROXIABLE flag tells - the ticket-granting server that only - non- ticket-granting tickets may be - issued with different network - addresses. - - - - -Kohl & Neuman [Page 43] - -RFC 1510 Kerberos September 1993 - - - 4 PROXY When set, this flag indicates that a - ticket is a proxy. - - 5 MAY-POSTDATE The MAY-POSTDATE flag is normally - only interpreted by the TGS, and can - be ignored by end servers. This flag - tells the ticket-granting server that - a post- dated ticket may be issued - based on this ticket-granting ticket. - - 6 POSTDATED This flag indicates that this ticket - has been postdated. The end-service - can check the authtime field to see - when the original authentication - occurred. - - 7 INVALID This flag indicates that a ticket is - invalid, and it must be validated by - the KDC before use. Application - servers must reject tickets which - have this flag set. - - 8 RENEWABLE The RENEWABLE flag is normally only - interpreted by the TGS, and can - usually be ignored by end servers - (some particularly careful servers - may wish to disallow renewable - tickets). A renewable ticket can be - used to obtain a replacement ticket - that expires at a later date. - - 9 INITIAL This flag indicates that this ticket - was issued using the AS protocol, and - not issued based on a ticket-granting - ticket. - - 10 PRE-AUTHENT This flag indicates that during - initial authentication, the client - was authenticated by the KDC before a - ticket was issued. The strength of - the preauthentication method is not - indicated, but is acceptable to the - KDC. - - 11 HW-AUTHENT This flag indicates that the protocol - employed for initial authentication - required the use of hardware expected - to be possessed solely by the named - - - -Kohl & Neuman [Page 44] - -RFC 1510 Kerberos September 1993 - - - client. The hardware authentication - method is selected by the KDC and the - strength of the method is not - indicated. - - 12-31 RESERVED Reserved for future use. - - key This field exists in the ticket and the KDC response and is - used to pass the session key from Kerberos to the - application server and the client. The field's encoding is - described in section 6.2. - - crealm This field contains the name of the realm in which the - client is registered and in which initial authentication - took place. - - cname This field contains the name part of the client's principal - identifier. - - transited This field lists the names of the Kerberos realms that took - part in authenticating the user to whom this ticket was - issued. It does not specify the order in which the realms - were transited. See section 3.3.3.1 for details on how - this field encodes the traversed realms. - - authtime This field indicates the time of initial authentication for - the named principal. It is the time of issue for the - original ticket on which this ticket is based. It is - included in the ticket to provide additional information to - the end service, and to provide the necessary information - for implementation of a `hot list' service at the KDC. An - end service that is particularly paranoid could refuse to - accept tickets for which the initial authentication - occurred "too far" in the past. - - This field is also returned as part of the response from - the KDC. When returned as part of the response to initial - authentication (KRB_AS_REP), this is the current time on - the Kerberos server (It is NOT recommended that this time - value be used to adjust the workstation's clock since the - workstation cannot reliably determine that such a - KRB_AS_REP actually came from the proper KDC in a timely - manner.). - - starttime This field in the ticket specifies the time after which the - ticket is valid. Together with endtime, this field - specifies the life of the ticket. If it is absent from - the ticket, its value should be treated as that of the - - - -Kohl & Neuman [Page 45] - -RFC 1510 Kerberos September 1993 - - - authtime field. - - endtime This field contains the time after which the ticket will - not be honored (its expiration time). Note that individual - services may place their own limits on the life of a ticket - and may reject tickets which have not yet expired. As - such, this is really an upper bound on the expiration time - for the ticket. - - renew-till This field is only present in tickets that have the - RENEWABLE flag set in the flags field. It indicates the - maximum endtime that may be included in a renewal. It can - be thought of as the absolute expiration time for the - ticket, including all renewals. - - caddr This field in a ticket contains zero (if omitted) or more - (if present) host addresses. These are the addresses from - which the ticket can be used. If there are no addresses, - the ticket can be used from any location. The decision - by the KDC to issue or by the end server to accept zero- - address tickets is a policy decision and is left to the - Kerberos and end-service administrators; they may refuse to - issue or accept such tickets. The suggested and default - policy, however, is that such tickets will only be issued - or accepted when additional information that can be used to - restrict the use of the ticket is included in the - authorization_data field. Such a ticket is a capability. - - Network addresses are included in the ticket to make it - harder for an attacker to use stolen credentials. Because - the session key is not sent over the network in cleartext, - credentials can't be stolen simply by listening to the - network; an attacker has to gain access to the session key - (perhaps through operating system security breaches or a - careless user's unattended session) to make use of stolen - tickets. - - It is important to note that the network address from which - a connection is received cannot be reliably determined. - Even if it could be, an attacker who has compromised the - client's workstation could use the credentials from there. - Including the network addresses only makes it more - difficult, not impossible, for an attacker to walk off with - stolen credentials and then use them from a "safe" - location. - - - - - - -Kohl & Neuman [Page 46] - -RFC 1510 Kerberos September 1993 - - - authorization-data The authorization-data field is used to pass - authorization data from the principal on whose behalf a - ticket was issued to the application service. If no - authorization data is included, this field will be left - out. The data in this field are specific to the end - service. It is expected that the field will contain the - names of service specific objects, and the rights to those - objects. The format for this field is described in section - 5.2. Although Kerberos is not concerned with the format of - the contents of the subfields, it does carry type - information (ad-type). - - By using the authorization_data field, a principal is able - to issue a proxy that is valid for a specific purpose. For - example, a client wishing to print a file can obtain a file - server proxy to be passed to the print server. By - specifying the name of the file in the authorization_data - field, the file server knows that the print server can only - use the client's rights when accessing the particular file - to be printed. - - It is interesting to note that if one specifies the - authorization-data field of a proxy and leaves the host - addresses blank, the resulting ticket and session key can - be treated as a capability. See [9] for some suggested - uses of this field. - - The authorization-data field is optional and does not have - to be included in a ticket. - -5.3.2. Authenticators - - An authenticator is a record sent with a ticket to a server to - certify the client's knowledge of the encryption key in the ticket, - to help the server detect replays, and to help choose a "true session - key" to use with the particular session. The encoding is encrypted - in the ticket's session key shared by the client and the server: - --- Unencrypted authenticator -Authenticator ::= [APPLICATION 2] SEQUENCE { - authenticator-vno[0] INTEGER, - crealm[1] Realm, - cname[2] PrincipalName, - cksum[3] Checksum OPTIONAL, - cusec[4] INTEGER, - ctime[5] KerberosTime, - subkey[6] EncryptionKey OPTIONAL, - seq-number[7] INTEGER OPTIONAL, - - - -Kohl & Neuman [Page 47] - -RFC 1510 Kerberos September 1993 - - - authorization-data[8] AuthorizationData OPTIONAL - } - - authenticator-vno This field specifies the version number for the - format of the authenticator. This document specifies - version 5. - - crealm and cname These fields are the same as those described for the - ticket in section 5.3.1. - - cksum This field contains a checksum of the the application data - that accompanies the KRB_AP_REQ. - - cusec This field contains the microsecond part of the client's - timestamp. Its value (before encryption) ranges from 0 to - 999999. It often appears along with ctime. The two fields - are used together to specify a reasonably accurate - timestamp. - - ctime This field contains the current time on the client's host. - - subkey This field contains the client's choice for an encryption - key which is to be used to protect this specific - application session. Unless an application specifies - otherwise, if this field is left out the session key from - the ticket will be used. - - seq-number This optional field includes the initial sequence number - to be used by the KRB_PRIV or KRB_SAFE messages when - sequence numbers are used to detect replays (It may also be - used by application specific messages). When included in - the authenticator this field specifies the initial sequence - number for messages from the client to the server. When - included in the AP-REP message, the initial sequence number - is that for messages from the server to the client. When - used in KRB_PRIV or KRB_SAFE messages, it is incremented by - one after each message is sent. - - For sequence numbers to adequately support the detection of - replays they should be non-repeating, even across - connection boundaries. The initial sequence number should - be random and uniformly distributed across the full space - of possible sequence numbers, so that it cannot be guessed - by an attacker and so that it and the successive sequence - numbers do not repeat other sequences. - - - - - - -Kohl & Neuman [Page 48] - -RFC 1510 Kerberos September 1993 - - - authorization-data This field is the same as described for the ticket - in section 5.3.1. It is optional and will only appear when - additional restrictions are to be placed on the use of a - ticket, beyond those carried in the ticket itself. - -5.4. Specifications for the AS and TGS exchanges - - This section specifies the format of the messages used in exchange - between the client and the Kerberos server. The format of possible - error messages appears in section 5.9.1. - -5.4.1. KRB_KDC_REQ definition - - The KRB_KDC_REQ message has no type of its own. Instead, its type is - one of KRB_AS_REQ or KRB_TGS_REQ depending on whether the request is - for an initial ticket or an additional ticket. In either case, the - message is sent from the client to the Authentication Server to - request credentials for a service. - -The message fields are: - -AS-REQ ::= [APPLICATION 10] KDC-REQ -TGS-REQ ::= [APPLICATION 12] KDC-REQ - -KDC-REQ ::= SEQUENCE { - pvno[1] INTEGER, - msg-type[2] INTEGER, - padata[3] SEQUENCE OF PA-DATA OPTIONAL, - req-body[4] KDC-REQ-BODY -} - -PA-DATA ::= SEQUENCE { - padata-type[1] INTEGER, - padata-value[2] OCTET STRING, - -- might be encoded AP-REQ -} - -KDC-REQ-BODY ::= SEQUENCE { - kdc-options[0] KDCOptions, - cname[1] PrincipalName OPTIONAL, - -- Used only in AS-REQ - realm[2] Realm, -- Server's realm - -- Also client's in AS-REQ - sname[3] PrincipalName OPTIONAL, - from[4] KerberosTime OPTIONAL, - till[5] KerberosTime, - rtime[6] KerberosTime OPTIONAL, - nonce[7] INTEGER, - - - -Kohl & Neuman [Page 49] - -RFC 1510 Kerberos September 1993 - - - etype[8] SEQUENCE OF INTEGER, -- EncryptionType, - -- in preference order - addresses[9] HostAddresses OPTIONAL, - enc-authorization-data[10] EncryptedData OPTIONAL, - -- Encrypted AuthorizationData encoding - additional-tickets[11] SEQUENCE OF Ticket OPTIONAL -} - - The fields in this message are: - - pvno This field is included in each message, and specifies the - protocol version number. This document specifies protocol - version 5. - - msg-type This field indicates the type of a protocol message. It - will almost always be the same as the application - identifier associated with a message. It is included to - make the identifier more readily accessible to the - application. For the KDC-REQ message, this type will be - KRB_AS_REQ or KRB_TGS_REQ. - - padata The padata (pre-authentication data) field contains a of - authentication information which may be needed before - credentials can be issued or decrypted. In the case of - requests for additional tickets (KRB_TGS_REQ), this field - will include an element with padata-type of PA-TGS-REQ and - data of an authentication header (ticket-granting ticket - and authenticator). The checksum in the authenticator - (which must be collisionproof) is to be computed over the - KDC-REQ-BODY encoding. In most requests for initial - authentication (KRB_AS_REQ) and most replies (KDC-REP), the - padata field will be left out. - - This field may also contain information needed by certain - extensions to the Kerberos protocol. For example, it might - be used to initially verify the identity of a client before - any response is returned. This is accomplished with a - padata field with padata-type equal to PA-ENC-TIMESTAMP and - padata-value defined as follows: - - padata-type ::= PA-ENC-TIMESTAMP - padata-value ::= EncryptedData -- PA-ENC-TS-ENC - - PA-ENC-TS-ENC ::= SEQUENCE { - patimestamp[0] KerberosTime, -- client's time - pausec[1] INTEGER OPTIONAL - } - - - - -Kohl & Neuman [Page 50] - -RFC 1510 Kerberos September 1993 - - - with patimestamp containing the client's time and pausec - containing the microseconds which may be omitted if a - client will not generate more than one request per second. - The ciphertext (padata-value) consists of the PA-ENC-TS-ENC - sequence, encrypted using the client's secret key. - - The padata field can also contain information needed to - help the KDC or the client select the key needed for - generating or decrypting the response. This form of the - padata is useful for supporting the use of certain - "smartcards" with Kerberos. The details of such extensions - are beyond the scope of this specification. See [10] for - additional uses of this field. - - padata-type The padata-type element of the padata field indicates the - way that the padata-value element is to be interpreted. - Negative values of padata-type are reserved for - unregistered use; non-negative values are used for a - registered interpretation of the element type. - - req-body This field is a placeholder delimiting the extent of the - remaining fields. If a checksum is to be calculated over - the request, it is calculated over an encoding of the KDC- - REQ-BODY sequence which is enclosed within the req-body - field. - - kdc-options This field appears in the KRB_AS_REQ and KRB_TGS_REQ - requests to the KDC and indicates the flags that the client - wants set on the tickets as well as other information that - is to modify the behavior of the KDC. Where appropriate, - the name of an option may be the same as the flag that is - set by that option. Although in most case, the bit in the - options field will be the same as that in the flags field, - this is not guaranteed, so it is not acceptable to simply - copy the options field to the flags field. There are - various checks that must be made before honoring an option - anyway. - - The kdc_options field is a bit-field, where the selected - options are indicated by the bit being set (1), and the - unselected options and reserved fields being reset (0). - The encoding of the bits is specified in section 5.2. The - options are described in more detail above in section 2. - The meanings of the options are: - - - - - - - -Kohl & Neuman [Page 51] - -RFC 1510 Kerberos September 1993 - - - Bit(s) Name Description - - 0 RESERVED Reserved for future expansion of this - field. - - 1 FORWARDABLE The FORWARDABLE option indicates that - the ticket to be issued is to have its - forwardable flag set. It may only be - set on the initial request, or in a - subsequent request if the ticket- - granting ticket on which it is based - is also forwardable. - - 2 FORWARDED The FORWARDED option is only specified - in a request to the ticket-granting - server and will only be honored if the - ticket-granting ticket in the request - has its FORWARDABLE bit set. This - option indicates that this is a - request for forwarding. The - address(es) of the host from which the - resulting ticket is to be valid are - included in the addresses field of the - request. - - - 3 PROXIABLE The PROXIABLE option indicates that - the ticket to be issued is to have its - proxiable flag set. It may only be set - on the initial request, or in a - subsequent request if the ticket- - granting ticket on which it is based - is also proxiable. - - 4 PROXY The PROXY option indicates that this - is a request for a proxy. This option - will only be honored if the ticket- - granting ticket in the request has its - PROXIABLE bit set. The address(es) of - the host from which the resulting - ticket is to be valid are included in - the addresses field of the request. - - 5 ALLOW-POSTDATE The ALLOW-POSTDATE option indicates - that the ticket to be issued is to - have its MAY-POSTDATE flag set. It - may only be set on the initial - request, or in a subsequent request if - - - -Kohl & Neuman [Page 52] - -RFC 1510 Kerberos September 1993 - - - the ticket-granting ticket on which it - is based also has its MAY-POSTDATE - flag set. - - 6 POSTDATED The POSTDATED option indicates that - this is a request for a postdated - ticket. This option will only be - honored if the ticket-granting ticket - on which it is based has its MAY- - POSTDATE flag set. The resulting - ticket will also have its INVALID flag - set, and that flag may be reset by a - subsequent request to the KDC after - the starttime in the ticket has been - reached. - - 7 UNUSED This option is presently unused. - - 8 RENEWABLE The RENEWABLE option indicates that - the ticket to be issued is to have its - RENEWABLE flag set. It may only be - set on the initial request, or when - the ticket-granting ticket on which - the request is based is also - renewable. If this option is - requested, then the rtime field in the - request contains the desired absolute - expiration time for the ticket. - - 9-26 RESERVED Reserved for future use. - - 27 RENEWABLE-OK The RENEWABLE-OK option indicates that - a renewable ticket will be acceptable - if a ticket with the requested life - cannot otherwise be provided. If a - ticket with the requested life cannot - be provided, then a renewable ticket - may be issued with a renew-till equal - to the the requested endtime. The - value of the renew-till field may - still be limited by local limits, or - limits selected by the individual - principal or server. - - 28 ENC-TKT-IN-SKEY This option is used only by the - ticket-granting service. The ENC- - TKT-IN-SKEY option indicates that the - ticket for the end server is to be - - - -Kohl & Neuman [Page 53] - -RFC 1510 Kerberos September 1993 - - - encrypted in the session key from the - additional ticket-granting ticket - provided. - - 29 RESERVED Reserved for future use. - - 30 RENEW This option is used only by the - ticket-granting service. The RENEW - option indicates that the present - request is for a renewal. The ticket - provided is encrypted in the secret - key for the server on which it is - valid. This option will only be - honored if the ticket to be renewed - has its RENEWABLE flag set and if the - time in its renew till field has not - passed. The ticket to be renewed is - passed in the padata field as part of - the authentication header. - - 31 VALIDATE This option is used only by the - ticket-granting service. The VALIDATE - option indicates that the request is - to validate a postdated ticket. It - will only be honored if the ticket - presented is postdated, presently has - its INVALID flag set, and would be - otherwise usable at this time. A - ticket cannot be validated before its - starttime. The ticket presented for - validation is encrypted in the key of - the server for which it is valid and - is passed in the padata field as part - of the authentication header. - - cname and sname These fields are the same as those described for the - ticket in section 5.3.1. sname may only be absent when the - ENC-TKT-IN-SKEY option is specified. If absent, the name - of the server is taken from the name of the client in the - ticket passed as additional-tickets. - - enc-authorization-data The enc-authorization-data, if present (and it - can only be present in the TGS_REQ form), is an encoding of - the desired authorization-data encrypted under the sub- - session key if present in the Authenticator, or - alternatively from the session key in the ticket-granting - ticket, both from the padata field in the KRB_AP_REQ. - - - - -Kohl & Neuman [Page 54] - -RFC 1510 Kerberos September 1993 - - - realm This field specifies the realm part of the server's - principal identifier. In the AS exchange, this is also the - realm part of the client's principal identifier. - - from This field is included in the KRB_AS_REQ and KRB_TGS_REQ - ticket requests when the requested ticket is to be - postdated. It specifies the desired start time for the - requested ticket. - - till This field contains the expiration date requested by the - client in a ticket request. - - rtime This field is the requested renew-till time sent from a - client to the KDC in a ticket request. It is optional. - - nonce This field is part of the KDC request and response. It it - intended to hold a random number generated by the client. - If the same number is included in the encrypted response - from the KDC, it provides evidence that the response is - fresh and has not been replayed by an attacker. Nonces - must never be re-used. Ideally, it should be gen erated - randomly, but if the correct time is known, it may suffice - (Note, however, that if the time is used as the nonce, one - must make sure that the workstation time is monotonically - increasing. If the time is ever reset backwards, there is - a small, but finite, probability that a nonce will be - reused.). - - etype This field specifies the desired encryption algorithm to be - used in the response. - - addresses This field is included in the initial request for tickets, - and optionally included in requests for additional tickets - from the ticket-granting server. It specifies the - addresses from which the requested ticket is to be valid. - Normally it includes the addresses for the client's host. - If a proxy is requested, this field will contain other - addresses. The contents of this field are usually copied - by the KDC into the caddr field of the resulting ticket. - - additional-tickets Additional tickets may be optionally included in a - request to the ticket-granting server. If the ENC-TKT-IN- - SKEY option has been specified, then the session key from - the additional ticket will be used in place of the server's - key to encrypt the new ticket. If more than one option - which requires additional tickets has been specified, then - the additional tickets are used in the order specified by - the ordering of the options bits (see kdc-options, above). - - - -Kohl & Neuman [Page 55] - -RFC 1510 Kerberos September 1993 - - - The application code will be either ten (10) or twelve (12) depending - on whether the request is for an initial ticket (AS-REQ) or for an - additional ticket (TGS-REQ). - - The optional fields (addresses, authorization-data and additional- - tickets) are only included if necessary to perform the operation - specified in the kdc-options field. - - It should be noted that in KRB_TGS_REQ, the protocol version number - appears twice and two different message types appear: the KRB_TGS_REQ - message contains these fields as does the authentication header - (KRB_AP_REQ) that is passed in the padata field. - -5.4.2. KRB_KDC_REP definition - - The KRB_KDC_REP message format is used for the reply from the KDC for - either an initial (AS) request or a subsequent (TGS) request. There - is no message type for KRB_KDC_REP. Instead, the type will be either - KRB_AS_REP or KRB_TGS_REP. The key used to encrypt the ciphertext - part of the reply depends on the message type. For KRB_AS_REP, the - ciphertext is encrypted in the client's secret key, and the client's - key version number is included in the key version number for the - encrypted data. For KRB_TGS_REP, the ciphertext is encrypted in the - sub-session key from the Authenticator, or if absent, the session key - from the ticket-granting ticket used in the request. In that case, - no version number will be present in the EncryptedData sequence. - - The KRB_KDC_REP message contains the following fields: - - AS-REP ::= [APPLICATION 11] KDC-REP - TGS-REP ::= [APPLICATION 13] KDC-REP - - KDC-REP ::= SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - padata[2] SEQUENCE OF PA-DATA OPTIONAL, - crealm[3] Realm, - cname[4] PrincipalName, - ticket[5] Ticket, - enc-part[6] EncryptedData - } - - EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart - EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart - - EncKDCRepPart ::= SEQUENCE { - key[0] EncryptionKey, - last-req[1] LastReq, - - - -Kohl & Neuman [Page 56] - -RFC 1510 Kerberos September 1993 - - - nonce[2] INTEGER, - key-expiration[3] KerberosTime OPTIONAL, - flags[4] TicketFlags, - authtime[5] KerberosTime, - starttime[6] KerberosTime OPTIONAL, - endtime[7] KerberosTime, - renew-till[8] KerberosTime OPTIONAL, - srealm[9] Realm, - sname[10] PrincipalName, - caddr[11] HostAddresses OPTIONAL - } - - NOTE: In EncASRepPart, the application code in the encrypted - part of a message provides an additional check that - the message was decrypted properly. - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is either KRB_AS_REP or KRB_TGS_REP. - - padata This field is described in detail in section 5.4.1. One - possible use for this field is to encode an alternate - "mix-in" string to be used with a string-to-key algorithm - (such as is described in section 6.3.2). This ability is - useful to ease transitions if a realm name needs to change - (e.g., when a company is acquired); in such a case all - existing password-derived entries in the KDC database would - be flagged as needing a special mix-in string until the - next password change. - - crealm, cname, srealm and sname These fields are the same as those - described for the ticket in section 5.3.1. - - ticket The newly-issued ticket, from section 5.3.1. - - enc-part This field is a place holder for the ciphertext and related - information that forms the encrypted part of a message. - The description of the encrypted part of the message - follows each appearance of this field. The encrypted part - is encoded as described in section 6.1. - - key This field is the same as described for the ticket in - section 5.3.1. - - last-req This field is returned by the KDC and specifies the time(s) - of the last request by a principal. Depending on what - information is available, this might be the last time that - a request for a ticket-granting ticket was made, or the - last time that a request based on a ticket-granting ticket - - - -Kohl & Neuman [Page 57] - -RFC 1510 Kerberos September 1993 - - - was successful. It also might cover all servers for a - realm, or just the particular server. Some implementations - may display this information to the user to aid in - discovering unauthorized use of one's identity. It is - similar in spirit to the last login time displayed when - logging into timesharing systems. - - nonce This field is described above in section 5.4.1. - - key-expiration The key-expiration field is part of the response from - the KDC and specifies the time that the client's secret key - is due to expire. The expiration might be the result of - password aging or an account expiration. This field will - usually be left out of the TGS reply since the response to - the TGS request is encrypted in a session key and no client - information need be retrieved from the KDC database. It is - up to the application client (usually the login program) to - take appropriate action (such as notifying the user) if the - expira tion time is imminent. - - flags, authtime, starttime, endtime, renew-till and caddr These - fields are duplicates of those found in the encrypted - portion of the attached ticket (see section 5.3.1), - provided so the client may verify they match the intended - request and to assist in proper ticket caching. If the - message is of type KRB_TGS_REP, the caddr field will only - be filled in if the request was for a proxy or forwarded - ticket, or if the user is substituting a subset of the - addresses from the ticket granting ticket. If the client- - requested addresses are not present or not used, then the - addresses contained in the ticket will be the same as those - included in the ticket-granting ticket. - -5.5. Client/Server (CS) message specifications - - This section specifies the format of the messages used for the - authentication of the client to the application server. - -5.5.1. KRB_AP_REQ definition - - The KRB_AP_REQ message contains the Kerberos protocol version number, - the message type KRB_AP_REQ, an options field to indicate any options - in use, and the ticket and authenticator themselves. The KRB_AP_REQ - message is often referred to as the "authentication header". - - AP-REQ ::= [APPLICATION 14] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - - - -Kohl & Neuman [Page 58] - -RFC 1510 Kerberos September 1993 - - - ap-options[2] APOptions, - ticket[3] Ticket, - authenticator[4] EncryptedData - } - - APOptions ::= BIT STRING { - reserved(0), - use-session-key(1), - mutual-required(2) - } - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_AP_REQ. - - ap-options This field appears in the application request (KRB_AP_REQ) - and affects the way the request is processed. It is a - bit-field, where the selected options are indicated by the - bit being set (1), and the unselected options and reserved - fields being reset (0). The encoding of the bits is - specified in section 5.2. The meanings of the options are: - - Bit(s) Name Description - - 0 RESERVED Reserved for future expansion of - this field. - - 1 USE-SESSION-KEYThe USE-SESSION-KEY option indicates - that the ticket the client is - presenting to a server is encrypted in - the session key from the server's - ticket-granting ticket. When this - option is not specified, the ticket is - encrypted in the server's secret key. - - 2 MUTUAL-REQUIREDThe MUTUAL-REQUIRED option tells the - server that the client requires mutual - authentication, and that it must - respond with a KRB_AP_REP message. - - 3-31 RESERVED Reserved for future use. - - ticket This field is a ticket authenticating the client to the - server. - - authenticator This contains the authenticator, which includes the - client's choice of a subkey. Its encoding is described in - section 5.3.2. - - - - -Kohl & Neuman [Page 59] - -RFC 1510 Kerberos September 1993 - - -5.5.2. KRB_AP_REP definition - - The KRB_AP_REP message contains the Kerberos protocol version number, - the message type, and an encrypted timestamp. The message is sent in - in response to an application request (KRB_AP_REQ) where the mutual - authentication option has been selected in the ap-options field. - - AP-REP ::= [APPLICATION 15] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - enc-part[2] EncryptedData - } - - EncAPRepPart ::= [APPLICATION 27] SEQUENCE { - ctime[0] KerberosTime, - cusec[1] INTEGER, - subkey[2] EncryptionKey OPTIONAL, - seq-number[3] INTEGER OPTIONAL - } - - NOTE: in EncAPRepPart, the application code in the encrypted part of - a message provides an additional check that the message was decrypted - properly. - - The encoded EncAPRepPart is encrypted in the shared session key of - the ticket. The optional subkey field can be used in an - application-arranged negotiation to choose a per association session - key. - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_AP_REP. - - enc-part This field is described above in section 5.4.2. - - ctime This field contains the current time on the client's host. - - cusec This field contains the microsecond part of the client's - timestamp. - - subkey This field contains an encryption key which is to be used - to protect this specific application session. See section - 3.2.6 for specifics on how this field is used to negotiate - a key. Unless an application specifies otherwise, if this - field is left out, the sub-session key from the - authenticator, or if also left out, the session key from - the ticket will be used. - - - - - -Kohl & Neuman [Page 60] - -RFC 1510 Kerberos September 1993 - - -5.5.3. Error message reply - - If an error occurs while processing the application request, the - KRB_ERROR message will be sent in response. See section 5.9.1 for - the format of the error message. The cname and crealm fields may be - left out if the server cannot determine their appropriate values from - the corresponding KRB_AP_REQ message. If the authenticator was - decipherable, the ctime and cusec fields will contain the values from - it. - -5.6. KRB_SAFE message specification - - This section specifies the format of a message that can be used by - either side (client or server) of an application to send a tamper- - proof message to its peer. It presumes that a session key has - previously been exchanged (for example, by using the - KRB_AP_REQ/KRB_AP_REP messages). - -5.6.1. KRB_SAFE definition - - The KRB_SAFE message contains user data along with a collision-proof - checksum keyed with the session key. The message fields are: - - KRB-SAFE ::= [APPLICATION 20] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - safe-body[2] KRB-SAFE-BODY, - cksum[3] Checksum - } - - KRB-SAFE-BODY ::= SEQUENCE { - user-data[0] OCTET STRING, - timestamp[1] KerberosTime OPTIONAL, - usec[2] INTEGER OPTIONAL, - seq-number[3] INTEGER OPTIONAL, - s-address[4] HostAddress, - r-address[5] HostAddress OPTIONAL - } - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_SAFE. - - safe-body This field is a placeholder for the body of the KRB-SAFE - message. It is to be encoded separately and then have the - checksum computed over it, for use in the cksum field. - - cksum This field contains the checksum of the application data. - Checksum details are described in section 6.4. The - - - -Kohl & Neuman [Page 61] - -RFC 1510 Kerberos September 1993 - - - checksum is computed over the encoding of the KRB-SAFE-BODY - sequence. - - user-data This field is part of the KRB_SAFE and KRB_PRIV messages - and contain the application specific data that is being - passed from the sender to the recipient. - - timestamp This field is part of the KRB_SAFE and KRB_PRIV messages. - Its contents are the current time as known by the sender of - the message. By checking the timestamp, the recipient of - the message is able to make sure that it was recently - generated, and is not a replay. - - usec This field is part of the KRB_SAFE and KRB_PRIV headers. - It contains the microsecond part of the timestamp. - - seq-number This field is described above in section 5.3.2. - - s-address This field specifies the address in use by the sender of - the message. - - r-address This field specifies the address in use by the recipient of - the message. It may be omitted for some uses (such as - broadcast protocols), but the recipient may arbitrarily - reject such messages. This field along with s-address can - be used to help detect messages which have been incorrectly - or maliciously delivered to the wrong recipient. - -5.7. KRB_PRIV message specification - - This section specifies the format of a message that can be used by - either side (client or server) of an application to securely and - privately send a message to its peer. It presumes that a session key - has previously been exchanged (for example, by using the - KRB_AP_REQ/KRB_AP_REP messages). - -5.7.1. KRB_PRIV definition - - The KRB_PRIV message contains user data encrypted in the Session Key. - The message fields are: - - KRB-PRIV ::= [APPLICATION 21] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - enc-part[3] EncryptedData - } - - - - - -Kohl & Neuman [Page 62] - -RFC 1510 Kerberos September 1993 - - - EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { - user-data[0] OCTET STRING, - timestamp[1] KerberosTime OPTIONAL, - usec[2] INTEGER OPTIONAL, - seq-number[3] INTEGER OPTIONAL, - s-address[4] HostAddress, -- sender's addr - r-address[5] HostAddress OPTIONAL - -- recip's addr - } - - NOTE: In EncKrbPrivPart, the application code in the encrypted part - of a message provides an additional check that the message was - decrypted properly. - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_PRIV. - - enc-part This field holds an encoding of the EncKrbPrivPart sequence - encrypted under the session key (If supported by the - encryption method in use, an initialization vector may be - passed to the encryption procedure, in order to achieve - proper cipher chaining. The initialization vector might - come from the last block of the ciphertext from the - previous KRB_PRIV message, but it is the application's - choice whether or not to use such an initialization vector. - If left out, the default initialization vector for the - encryption algorithm will be used.). This encrypted - encoding is used for the enc-part field of the KRB-PRIV - message. See section 6 for the format of the ciphertext. - - user-data, timestamp, usec, s-address and r-address These fields are - described above in section 5.6.1. - - seq-number This field is described above in section 5.3.2. - -5.8. KRB_CRED message specification - - This section specifies the format of a message that can be used to - send Kerberos credentials from one principal to another. It is - presented here to encourage a common mechanism to be used by - applications when forwarding tickets or providing proxies to - subordinate servers. It presumes that a session key has already been - exchanged perhaps by using the KRB_AP_REQ/KRB_AP_REP messages. - -5.8.1. KRB_CRED definition - - The KRB_CRED message contains a sequence of tickets to be sent and - information needed to use the tickets, including the session key from - - - -Kohl & Neuman [Page 63] - -RFC 1510 Kerberos September 1993 - - - each. The information needed to use the tickets is encryped under an - encryption key previously exchanged. The message fields are: - - KRB-CRED ::= [APPLICATION 22] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, -- KRB_CRED - tickets[2] SEQUENCE OF Ticket, - enc-part[3] EncryptedData - } - - EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { - ticket-info[0] SEQUENCE OF KrbCredInfo, - nonce[1] INTEGER OPTIONAL, - timestamp[2] KerberosTime OPTIONAL, - usec[3] INTEGER OPTIONAL, - s-address[4] HostAddress OPTIONAL, - r-address[5] HostAddress OPTIONAL - } - - KrbCredInfo ::= SEQUENCE { - key[0] EncryptionKey, - prealm[1] Realm OPTIONAL, - pname[2] PrincipalName OPTIONAL, - flags[3] TicketFlags OPTIONAL, - authtime[4] KerberosTime OPTIONAL, - starttime[5] KerberosTime OPTIONAL, - endtime[6] KerberosTime OPTIONAL - renew-till[7] KerberosTime OPTIONAL, - srealm[8] Realm OPTIONAL, - sname[9] PrincipalName OPTIONAL, - caddr[10] HostAddresses OPTIONAL - } - - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_CRED. - - tickets - These are the tickets obtained from the KDC specifically - for use by the intended recipient. Successive tickets are - paired with the corresponding KrbCredInfo sequence from the - enc-part of the KRB-CRED message. - - enc-part This field holds an encoding of the EncKrbCredPart sequence - encrypted under the session key shared between the sender - and the intended recipient. This encrypted encoding is - used for the enc-part field of the KRB-CRED message. See - section 6 for the format of the ciphertext. - - - -Kohl & Neuman [Page 64] - -RFC 1510 Kerberos September 1993 - - - nonce If practical, an application may require the inclusion of a - nonce generated by the recipient of the message. If the - same value is included as the nonce in the message, it - provides evidence that the message is fresh and has not - been replayed by an attacker. A nonce must never be re- - used; it should be generated randomly by the recipient of - the message and provided to the sender of the mes sage in - an application specific manner. - - timestamp and usec These fields specify the time that the KRB-CRED - message was generated. The time is used to provide - assurance that the message is fresh. - - s-address and r-address These fields are described above in section - 5.6.1. They are used optionally to provide additional - assurance of the integrity of the KRB-CRED message. - - key This field exists in the corresponding ticket passed by the - KRB-CRED message and is used to pass the session key from - the sender to the intended recipient. The field's encoding - is described in section 6.2. - - The following fields are optional. If present, they can be - associated with the credentials in the remote ticket file. If left - out, then it is assumed that the recipient of the credentials already - knows their value. - - prealm and pname The name and realm of the delegated principal - identity. - - flags, authtime, starttime, endtime, renew-till, srealm, sname, - and caddr These fields contain the values of the - corresponding fields from the ticket found in the ticket - field. Descriptions of the fields are identical to the - descriptions in the KDC-REP message. - -5.9. Error message specification - - This section specifies the format for the KRB_ERROR message. The - fields included in the message are intended to return as much - information as possible about an error. It is not expected that all - the information required by the fields will be available for all - types of errors. If the appropriate information is not available - when the message is composed, the corresponding field will be left - out of the message. - - Note that since the KRB_ERROR message is not protected by any - encryption, it is quite possible for an intruder to synthesize or - - - -Kohl & Neuman [Page 65] - -RFC 1510 Kerberos September 1993 - - - modify such a message. In particular, this means that the client - should not use any fields in this message for security-critical - purposes, such as setting a system clock or generating a fresh - authenticator. The message can be useful, however, for advising a - user on the reason for some failure. - -5.9.1. KRB_ERROR definition - - The KRB_ERROR message consists of the following fields: - - KRB-ERROR ::= [APPLICATION 30] SEQUENCE { - pvno[0] INTEGER, - msg-type[1] INTEGER, - ctime[2] KerberosTime OPTIONAL, - cusec[3] INTEGER OPTIONAL, - stime[4] KerberosTime, - susec[5] INTEGER, - error-code[6] INTEGER, - crealm[7] Realm OPTIONAL, - cname[8] PrincipalName OPTIONAL, - realm[9] Realm, -- Correct realm - sname[10] PrincipalName, -- Correct name - e-text[11] GeneralString OPTIONAL, - e-data[12] OCTET STRING OPTIONAL - } - - pvno and msg-type These fields are described above in section 5.4.1. - msg-type is KRB_ERROR. - - ctime This field is described above in section 5.4.1. - - cusec This field is described above in section 5.5.2. - - stime This field contains the current time on the server. It is - of type KerberosTime. - - susec This field contains the microsecond part of the server's - timestamp. Its value ranges from 0 to 999. It appears - along with stime. The two fields are used in conjunction to - specify a reasonably accurate timestamp. - - error-code This field contains the error code returned by Kerberos or - the server when a request fails. To interpret the value of - this field see the list of error codes in section 8. - Implementations are encouraged to provide for national - language support in the display of error messages. - - crealm, cname, srealm and sname These fields are described above in - - - -Kohl & Neuman [Page 66] - -RFC 1510 Kerberos September 1993 - - - section 5.3.1. - - e-text This field contains additional text to help explain the - error code associated with the failed request (for example, - it might include a principal name which was unknown). - - e-data This field contains additional data about the error for use - by the application to help it recover from or handle the - error. If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then - the e-data field will contain an encoding of a sequence of - padata fields, each corresponding to an acceptable pre- - authentication method and optionally containing data for - the method: - - METHOD-DATA ::= SEQUENCE of PA-DATA - - If the error-code is KRB_AP_ERR_METHOD, then the e-data field will - contain an encoding of the following sequence: - - METHOD-DATA ::= SEQUENCE { - method-type[0] INTEGER, - method-data[1] OCTET STRING OPTIONAL - } - - method-type will indicate the required alternate method; method-data - will contain any required additional information. - -6. Encryption and Checksum Specifications - - The Kerberos protocols described in this document are designed to use - stream encryption ciphers, which can be simulated using commonly - available block encryption ciphers, such as the Data Encryption - Standard [11], in conjunction with block chaining and checksum - methods [12]. Encryption is used to prove the identities of the - network entities participating in message exchanges. The Key - Distribution Center for each realm is trusted by all principals - registered in that realm to store a secret key in confidence. Proof - of knowledge of this secret key is used to verify the authenticity of - a principal. - - The KDC uses the principal's secret key (in the AS exchange) or a - shared session key (in the TGS exchange) to encrypt responses to - ticket requests; the ability to obtain the secret key or session key - implies the knowledge of the appropriate keys and the identity of the - KDC. The ability of a principal to decrypt the KDC response and - present a Ticket and a properly formed Authenticator (generated with - the session key from the KDC response) to a service verifies the - identity of the principal; likewise the ability of the service to - - - -Kohl & Neuman [Page 67] - -RFC 1510 Kerberos September 1993 - - - extract the session key from the Ticket and prove its knowledge - thereof in a response verifies the identity of the service. - - The Kerberos protocols generally assume that the encryption used is - secure from cryptanalysis; however, in some cases, the order of - fields in the encrypted portions of messages are arranged to minimize - the effects of poorly chosen keys. It is still important to choose - good keys. If keys are derived from user-typed passwords, those - passwords need to be well chosen to make brute force attacks more - difficult. Poorly chosen keys still make easy targets for intruders. - - The following sections specify the encryption and checksum mechanisms - currently defined for Kerberos. The encodings, chaining, and padding - requirements for each are described. For encryption methods, it is - often desirable to place random information (often referred to as a - confounder) at the start of the message. The requirements for a - confounder are specified with each encryption mechanism. - - Some encryption systems use a block-chaining method to improve the - the security characteristics of the ciphertext. However, these - chaining methods often don't provide an integrity check upon - decryption. Such systems (such as DES in CBC mode) must be augmented - with a checksum of the plaintext which can be verified at decryption - and used to detect any tampering or damage. Such checksums should be - good at detecting burst errors in the input. If any damage is - detected, the decryption routine is expected to return an error - indicating the failure of an integrity check. Each encryption type is - expected to provide and verify an appropriate checksum. The - specification of each encryption method sets out its checksum - requirements. - - Finally, where a key is to be derived from a user's password, an - algorithm for converting the password to a key of the appropriate - type is included. It is desirable for the string to key function to - be one-way, and for the mapping to be different in different realms. - This is important because users who are registered in more than one - realm will often use the same password in each, and it is desirable - that an attacker compromising the Kerberos server in one realm not - obtain or derive the user's key in another. - - For a discussion of the integrity characteristics of the candidate - encryption and checksum methods considered for Kerberos, the the - reader is referred to [13]. - -6.1. Encryption Specifications - - The following ASN.1 definition describes all encrypted messages. The - enc-part field which appears in the unencrypted part of messages in - - - -Kohl & Neuman [Page 68] - -RFC 1510 Kerberos September 1993 - - - section 5 is a sequence consisting of an encryption type, an optional - key version number, and the ciphertext. - - EncryptedData ::= SEQUENCE { - etype[0] INTEGER, -- EncryptionType - kvno[1] INTEGER OPTIONAL, - cipher[2] OCTET STRING -- ciphertext - } - - etype This field identifies which encryption algorithm was used - to encipher the cipher. Detailed specifications for - selected encryption types appear later in this section. - - kvno This field contains the version number of the key under - which data is encrypted. It is only present in messages - encrypted under long lasting keys, such as principals' - secret keys. - - cipher This field contains the enciphered text, encoded as an - OCTET STRING. - - The cipher field is generated by applying the specified encryption - algorithm to data composed of the message and algorithm-specific - inputs. Encryption mechanisms defined for use with Kerberos must - take sufficient measures to guarantee the integrity of the plaintext, - and we recommend they also take measures to protect against - precomputed dictionary attacks. If the encryption algorithm is not - itself capable of doing so, the protections can often be enhanced by - adding a checksum and a confounder. - - The suggested format for the data to be encrypted includes a - confounder, a checksum, the encoded plaintext, and any necessary - padding. The msg-seq field contains the part of the protocol message - described in section 5 which is to be encrypted. The confounder, - checksum, and padding are all untagged and untyped, and their length - is exactly sufficient to hold the appropriate item. The type and - length is implicit and specified by the particular encryption type - being used (etype). The format for the data to be encrypted is - described in the following diagram: - - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - The format cannot be described in ASN.1, but for those who prefer an - ASN.1-like notation: - - - - - -Kohl & Neuman [Page 69] - -RFC 1510 Kerberos September 1993 - - -CipherText ::= ENCRYPTED SEQUENCE { - confounder[0] UNTAGGED OCTET STRING(conf_length) OPTIONAL, - check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL, - msg-seq[2] MsgSequence, - pad UNTAGGED OCTET STRING(pad_length) OPTIONAL -} - - In the above specification, UNTAGGED OCTET STRING(length) is the - notation for an octet string with its tag and length removed. It is - not a valid ASN.1 type. The tag bits and length must be removed from - the confounder since the purpose of the confounder is so that the - message starts with random data, but the tag and its length are - fixed. For other fields, the length and tag would be redundant if - they were included because they are specified by the encryption type. - - One generates a random confounder of the appropriate length, placing - it in confounder; zeroes out check; calculates the appropriate - checksum over confounder, check, and msg-seq, placing the result in - check; adds the necessary padding; then encrypts using the specified - encryption type and the appropriate key. - - Unless otherwise specified, a definition of an encryption algorithm - that specifies a checksum, a length for the confounder field, or an - octet boundary for padding uses this ciphertext format (The ordering - of the fields in the CipherText is important. Additionally, messages - encoded in this format must include a length as part of the msg-seq - field. This allows the recipient to verify that the message has not - been truncated. Without a length, an attacker could use a chosen - plaintext attack to generate a message which could be truncated, - while leaving the checksum intact. Note that if the msg-seq is an - encoding of an ASN.1 SEQUENCE or OCTET STRING, then the length is - part of that encoding.). Those fields which are not specified will be - omitted. - - In the interest of allowing all implementations using a particular - encryption type to communicate with all others using that type, the - specification of an encryption type defines any checksum that is - needed as part of the encryption process. If an alternative checksum - is to be used, a new encryption type must be defined. - - Some cryptosystems require additional information beyond the key and - the data to be encrypted. For example, DES, when used in cipher- - block-chaining mode, requires an initialization vector. If required, - the description for each encryption type must specify the source of - such additional information. - - - - - - -Kohl & Neuman [Page 70] - -RFC 1510 Kerberos September 1993 - - -6.2. Encryption Keys - - The sequence below shows the encoding of an encryption key: - - EncryptionKey ::= SEQUENCE { - keytype[0] INTEGER, - keyvalue[1] OCTET STRING - } - - keytype This field specifies the type of encryption key that - follows in the keyvalue field. It will almost always - correspond to the encryption algorithm used to generate the - EncryptedData, though more than one algorithm may use the - same type of key (the mapping is many to one). This might - happen, for example, if the encryption algorithm uses an - alternate checksum algorithm for an integrity check, or a - different chaining mechanism. - - keyvalue This field contains the key itself, encoded as an octet - string. - - All negative values for the encryption key type are reserved for - local use. All non-negative values are reserved for officially - assigned type fields and interpretations. - -6.3. Encryption Systems - -6.3.1. The NULL Encryption System (null) - - If no encryption is in use, the encryption system is said to be the - NULL encryption system. In the NULL encryption system there is no - checksum, confounder or padding. The ciphertext is simply the - plaintext. The NULL Key is used by the null encryption system and is - zero octets in length, with keytype zero (0). - -6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc) - - The des-cbc-crc encryption mode encrypts information under the Data - Encryption Standard [11] using the cipher block chaining mode [12]. - A CRC-32 checksum (described in ISO 3309 [14]) is applied to the - confounder and message sequence (msg-seq) and placed in the cksum - field. DES blocks are 8 bytes. As a result, the data to be - encrypted (the concatenation of confounder, checksum, and message) - must be padded to an 8 byte boundary before encryption. The details - of the encryption of this data are identical to those for the des- - cbc-md5 encryption mode. - - Note that, since the CRC-32 checksum is not collisionproof, an - - - -Kohl & Neuman [Page 71] - -RFC 1510 Kerberos September 1993 - - - attacker could use a probabilistic chosenplaintext attack to generate - a valid message even if a confounder is used [13]. The use of - collision-proof checksums is recommended for environments where such - attacks represent a significant threat. The use of the CRC-32 as the - checksum for ticket or authenticator is no longer mandated as an - interoperability requirement for Kerberos Version 5 Specification 1 - (See section 9.1 for specific details). - -6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4) - - The des-cbc-md4 encryption mode encrypts information under the Data - Encryption Standard [11] using the cipher block chaining mode [12]. - An MD4 checksum (described in [15]) is applied to the confounder and - message sequence (msg-seq) and placed in the cksum field. DES blocks - are 8 bytes. As a result, the data to be encrypted (the - concatenation of confounder, checksum, and message) must be padded to - an 8 byte boundary before encryption. The details of the encryption - of this data are identical to those for the descbc-md5 encryption - mode. - -6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5) - - The des-cbc-md5 encryption mode encrypts information under the Data - Encryption Standard [11] using the cipher block chaining mode [12]. - An MD5 checksum (described in [16]) is applied to the confounder and - message sequence (msg-seq) and placed in the cksum field. DES blocks - are 8 bytes. As a result, the data to be encrypted (the - concatenation of confounder, checksum, and message) must be padded to - an 8 byte boundary before encryption. - - Plaintext and DES ciphtertext are encoded as 8-octet blocks which are - concatenated to make the 64-bit inputs for the DES algorithms. The - first octet supplies the 8 most significant bits (with the octet's - MSbit used as the DES input block's MSbit, etc.), the second octet - the next 8 bits, ..., and the eighth octet supplies the 8 least - significant bits. - - Encryption under DES using cipher block chaining requires an - additional input in the form of an initialization vector. Unless - otherwise specified, zero should be used as the initialization - vector. Kerberos' use of DES requires an 8-octet confounder. - - The DES specifications identify some "weak" and "semiweak" keys; - those keys shall not be used for encrypting messages for use in - Kerberos. Additionally, because of the way that keys are derived for - the encryption of checksums, keys shall not be used that yield "weak" - or "semi-weak" keys when eXclusive-ORed with the constant - F0F0F0F0F0F0F0F0. - - - -Kohl & Neuman [Page 72] - -RFC 1510 Kerberos September 1993 - - - A DES key is 8 octets of data, with keytype one (1). This consists - of 56 bits of key, and 8 parity bits (one per octet). The key is - encoded as a series of 8 octets written in MSB-first order. The bits - within the key are also encoded in MSB order. For example, if the - encryption key is: - (B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where - B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the - parity bits, the first octet of the key would be B1,B2,...,B7,P1 - (with B1 as the MSbit). [See the FIPS 81 introduction for - reference.] - - To generate a DES key from a text string (password), the text string - normally must have the realm and each component of the principal's - name appended(In some cases, it may be necessary to use a different - "mix-in" string for compatibility reasons; see the discussion of - padata in section 5.4.2.), then padded with ASCII nulls to an 8 byte - boundary. This string is then fan-folded and eXclusive-ORed with - itself to form an 8 byte DES key. The parity is corrected on the - key, and it is used to generate a DES CBC checksum on the initial - string (with the realm and name appended). Next, parity is corrected - on the CBC checksum. If the result matches a "weak" or "semiweak" - key as described in the DES specification, it is eXclusive-ORed with - the constant 00000000000000F0. Finally, the result is returned as - the key. Pseudocode follows: - - string_to_key(string,realm,name) { - odd = 1; - s = string + realm; - for(each component in name) { - s = s + component; - } - tempkey = NULL; - pad(s); /* with nulls to 8 byte boundary */ - for(8byteblock in s) { - if(odd == 0) { - odd = 1; - reverse(8byteblock) - } - else odd = 0; - tempkey = tempkey XOR 8byteblock; - } - fixparity(tempkey); - key = DES-CBC-check(s,tempkey); - fixparity(key); - if(is_weak_key_key(key)) - key = key XOR 0xF0; - return(key); - } - - - -Kohl & Neuman [Page 73] - -RFC 1510 Kerberos September 1993 - - -6.4. Checksums - - The following is the ASN.1 definition used for a checksum: - - Checksum ::= SEQUENCE { - cksumtype[0] INTEGER, - checksum[1] OCTET STRING - } - - cksumtype This field indicates the algorithm used to generate the - accompanying checksum. - - checksum This field contains the checksum itself, encoded - as an octet string. - - Detailed specification of selected checksum types appear later in - this section. Negative values for the checksum type are reserved for - local use. All non-negative values are reserved for officially - assigned type fields and interpretations. - - Checksums used by Kerberos can be classified by two properties: - whether they are collision-proof, and whether they are keyed. It is - infeasible to find two plaintexts which generate the same checksum - value for a collision-proof checksum. A key is required to perturb - or initialize the algorithm in a keyed checksum. To prevent - message-stream modification by an active attacker, unkeyed checksums - should only be used when the checksum and message will be - subsequently encrypted (e.g., the checksums defined as part of the - encryption algorithms covered earlier in this section). Collision- - proof checksums can be made tamper-proof as well if the checksum - value is encrypted before inclusion in a message. In such cases, the - composition of the checksum and the encryption algorithm must be - considered a separate checksum algorithm (e.g., RSA-MD5 encrypted - using DES is a new checksum algorithm of type RSA-MD5-DES). For most - keyed checksums, as well as for the encrypted forms of collisionproof - checksums, Kerberos prepends a confounder before the checksum is - calculated. - -6.4.1. The CRC-32 Checksum (crc32) - - The CRC-32 checksum calculates a checksum based on a cyclic - redundancy check as described in ISO 3309 [14]. The resulting - checksum is four (4) octets in length. The CRC-32 is neither keyed - nor collision-proof. The use of this checksum is not recommended. - An attacker using a probabilistic chosen-plaintext attack as - described in [13] might be able to generate an alternative message - that satisfies the checksum. The use of collision-proof checksums is - recommended for environments where such attacks represent a - - - -Kohl & Neuman [Page 74] - -RFC 1510 Kerberos September 1993 - - - significant threat. - -6.4.2. The RSA MD4 Checksum (rsa-md4) - - The RSA-MD4 checksum calculates a checksum using the RSA MD4 - algorithm [15]. The algorithm takes as input an input message of - arbitrary length and produces as output a 128-bit (16 octet) - checksum. RSA-MD4 is believed to be collision-proof. - -6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4des) - - The RSA-MD4-DES checksum calculates a keyed collisionproof checksum - by prepending an 8 octet confounder before the text, applying the RSA - MD4 checksum algorithm, and encrypting the confounder and the - checksum using DES in cipher-block-chaining (CBC) mode using a - variant of the key, where the variant is computed by eXclusive-ORing - the key with the constant F0F0F0F0F0F0F0F0 (A variant of the key is - used to limit the use of a key to a particular function, separating - the functions of generating a checksum from other encryption - performed using the session key. The constant F0F0F0F0F0F0F0F0 was - chosen because it maintains key parity. The properties of DES - precluded the use of the complement. The same constant is used for - similar purpose in the Message Integrity Check in the Privacy - Enhanced Mail standard.). The initialization vector should be zero. - The resulting checksum is 24 octets long (8 octets of which are - redundant). This checksum is tamper-proof and believed to be - collision-proof. - - The DES specifications identify some "weak keys"; those keys shall - not be used for generating RSA-MD4 checksums for use in Kerberos. - - The format for the checksum is described in the following diagram: - - +--+--+--+--+--+--+--+-- - | des-cbc(confounder - +--+--+--+--+--+--+--+-- - - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - rsa-md4(confounder+msg),key=var(key),iv=0) | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - - The format cannot be described in ASN.1, but for those who prefer an - ASN.1-like notation: - - rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE { - confounder[0] UNTAGGED OCTET STRING(8), - check[1] UNTAGGED OCTET STRING(16) - } - - - -Kohl & Neuman [Page 75] - -RFC 1510 Kerberos September 1993 - - -6.4.4. The RSA MD5 Checksum (rsa-md5) - - The RSA-MD5 checksum calculates a checksum using the RSA MD5 - algorithm [16]. The algorithm takes as input an input message of - arbitrary length and produces as output a 128-bit (16 octet) - checksum. RSA-MD5 is believed to be collision-proof. - -6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5des) - - The RSA-MD5-DES checksum calculates a keyed collisionproof checksum - by prepending an 8 octet confounder before the text, applying the RSA - MD5 checksum algorithm, and encrypting the confounder and the - checksum using DES in cipher-block-chaining (CBC) mode using a - variant of the key, where the variant is computed by eXclusive-ORing - the key with the constant F0F0F0F0F0F0F0F0. The initialization - vector should be zero. The resulting checksum is 24 octets long (8 - octets of which are redundant). This checksum is tamper-proof and - believed to be collision-proof. - - The DES specifications identify some "weak keys"; those keys shall - not be used for encrypting RSA-MD5 checksums for use in Kerberos. - - The format for the checksum is described in the following diagram: - - +--+--+--+--+--+--+--+-- - | des-cbc(confounder - +--+--+--+--+--+--+--+-- - - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - rsa-md5(confounder+msg),key=var(key),iv=0) | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - - The format cannot be described in ASN.1, but for those who prefer an - ASN.1-like notation: - - rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE { - confounder[0] UNTAGGED OCTET STRING(8), - check[1] UNTAGGED OCTET STRING(16) - } - -6.4.6. DES cipher-block chained checksum (des-mac) - - The DES-MAC checksum is computed by prepending an 8 octet confounder - to the plaintext, performing a DES CBC-mode encryption on the result - using the key and an initialization vector of zero, taking the last - block of the ciphertext, prepending the same confounder and - encrypting the pair using DES in cipher-block-chaining (CBC) mode - using a a variant of the key, where the variant is computed by - - - -Kohl & Neuman [Page 76] - -RFC 1510 Kerberos September 1993 - - - eXclusive-ORing the key with the constant F0F0F0F0F0F0F0F0. The - initialization vector should be zero. The resulting checksum is 128 - bits (16 octets) long, 64 bits of which are redundant. This checksum - is tamper-proof and collision-proof. - - The format for the checksum is described in the following diagram: - - +--+--+--+--+--+--+--+-- - | des-cbc(confounder - +--+--+--+--+--+--+--+-- - - +-----+-----+-----+-----+-----+-----+-----+-----+ - des-mac(conf+msg,iv=0,key),key=var(key),iv=0) | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - The format cannot be described in ASN.1, but for those who prefer an - ASN.1-like notation: - - des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE { - confounder[0] UNTAGGED OCTET STRING(8), - check[1] UNTAGGED OCTET STRING(8) - } - - The DES specifications identify some "weak" and "semiweak" keys; - those keys shall not be used for generating DES-MAC checksums for use - in Kerberos, nor shall a key be used whose veriant is "weak" or - "semi-weak". - -6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative - (rsa-md4-des-k) - - The RSA-MD4-DES-K checksum calculates a keyed collision-proof - checksum by applying the RSA MD4 checksum algorithm and encrypting - the results using DES in cipherblock-chaining (CBC) mode using a DES - key as both key and initialization vector. The resulting checksum is - 16 octets long. This checksum is tamper-proof and believed to be - collision-proof. Note that this checksum type is the old method for - encoding the RSA-MD4-DES checksum and it is no longer recommended. - -6.4.8. DES cipher-block chained checksum alternative (desmac-k) - - The DES-MAC-K checksum is computed by performing a DES CBC-mode - encryption of the plaintext, and using the last block of the - ciphertext as the checksum value. It is keyed with an encryption key - and an initialization vector; any uses which do not specify an - additional initialization vector will use the key as both key and - initialization vector. The resulting checksum is 64 bits (8 octets) - long. This checksum is tamper-proof and collision-proof. Note that - - - -Kohl & Neuman [Page 77] - -RFC 1510 Kerberos September 1993 - - - this checksum type is the old method for encoding the DESMAC checksum - and it is no longer recommended. - - The DES specifications identify some "weak keys"; those keys shall - not be used for generating DES-MAC checksums for use in Kerberos. - -7. Naming Constraints - -7.1. Realm Names - - Although realm names are encoded as GeneralStrings and although a - realm can technically select any name it chooses, interoperability - across realm boundaries requires agreement on how realm names are to - be assigned, and what information they imply. - - To enforce these conventions, each realm must conform to the - conventions itself, and it must require that any realms with which - inter-realm keys are shared also conform to the conventions and - require the same from its neighbors. - - There are presently four styles of realm names: domain, X500, other, - and reserved. Examples of each style follow: - - domain: host.subdomain.domain (example) - X500: C=US/O=OSF (example) - other: NAMETYPE:rest/of.name=without-restrictions (example) - reserved: reserved, but will not conflict with above - - Domain names must look like domain names: they consist of components - separated by periods (.) and they contain neither colons (:) nor - slashes (/). - - X.500 names contain an equal (=) and cannot contain a colon (:) - before the equal. The realm names for X.500 names will be string - representations of the names with components separated by slashes. - Leading and trailing slashes will not be included. - - Names that fall into the other category must begin with a prefix that - contains no equal (=) or period (.) and the prefix must be followed - by a colon (:) and the rest of the name. All prefixes must be - assigned before they may be used. Presently none are assigned. - - The reserved category includes strings which do not fall into the - first three categories. All names in this category are reserved. It - is unlikely that names will be assigned to this category unless there - is a very strong argument for not using the "other" category. - - These rules guarantee that there will be no conflicts between the - - - -Kohl & Neuman [Page 78] - -RFC 1510 Kerberos September 1993 - - - various name styles. The following additional constraints apply to - the assignment of realm names in the domain and X.500 categories: the - name of a realm for the domain or X.500 formats must either be used - by the organization owning (to whom it was assigned) an Internet - domain name or X.500 name, or in the case that no such names are - registered, authority to use a realm name may be derived from the - authority of the parent realm. For example, if there is no domain - name for E40.MIT.EDU, then the administrator of the MIT.EDU realm can - authorize the creation of a realm with that name. - - This is acceptable because the organization to which the parent is - assigned is presumably the organization authorized to assign names to - its children in the X.500 and domain name systems as well. If the - parent assigns a realm name without also registering it in the domain - name or X.500 hierarchy, it is the parent's responsibility to make - sure that there will not in the future exists a name identical to the - realm name of the child unless it is assigned to the same entity as - the realm name. - -7.2. Principal Names - - As was the case for realm names, conventions are needed to ensure - that all agree on what information is implied by a principal name. - The name-type field that is part of the principal name indicates the - kind of information implied by the name. The name-type should be - treated as a hint. Ignoring the name type, no two names can be the - same (i.e., at least one of the components, or the realm, must be - different). This constraint may be eliminated in the future. The - following name types are defined: - - name-type value meaning - NT-UNKNOWN 0 Name type not known - NT-PRINCIPAL 1 Just the name of the principal as in - DCE, or for users - NT-SRV-INST 2 Service and other unique instance (krbtgt) - NT-SRV-HST 3 Service with host name as instance - (telnet, rcommands) - NT-SRV-XHST 4 Service with host as remaining components - NT-UID 5 Unique ID - - When a name implies no information other than its uniqueness at a - particular time the name type PRINCIPAL should be used. The - principal name type should be used for users, and it might also be - used for a unique server. If the name is a unique machine generated - ID that is guaranteed never to be reassigned then the name type of - UID should be used (note that it is generally a bad idea to reassign - names of any type since stale entries might remain in access control - lists). - - - -Kohl & Neuman [Page 79] - -RFC 1510 Kerberos September 1993 - - - If the first component of a name identifies a service and the - remaining components identify an instance of the service in a server - specified manner, then the name type of SRV-INST should be used. An - example of this name type is the Kerberos ticket-granting ticket - which has a first component of krbtgt and a second component - identifying the realm for which the ticket is valid. - - If instance is a single component following the service name and the - instance identifies the host on which the server is running, then the - name type SRV-HST should be used. This type is typically used for - Internet services such as telnet and the Berkeley R commands. If the - separate components of the host name appear as successive components - following the name of the service, then the name type SRVXHST should - be used. This type might be used to identify servers on hosts with - X.500 names where the slash (/) might otherwise be ambiguous. - - A name type of UNKNOWN should be used when the form of the name is - not known. When comparing names, a name of type UNKNOWN will match - principals authenticated with names of any type. A principal - authenticated with a name of type UNKNOWN, however, will only match - other names of type UNKNOWN. - - Names of any type with an initial component of "krbtgt" are reserved - for the Kerberos ticket granting service. See section 8.2.3 for the - form of such names. - -7.2.1. Name of server principals - - The principal identifier for a server on a host will generally be - composed of two parts: (1) the realm of the KDC with which the server - is registered, and (2) a two-component name of type NT-SRV-HST if the - host name is an Internet domain name or a multi-component name of - type NT-SRV-XHST if the name of the host is of a form such as X.500 - that allows slash (/) separators. The first component of the two- or - multi-component name will identify the service and the latter - components will identify the host. Where the name of the host is not - case sensitive (for example, with Internet domain names) the name of - the host must be lower case. For services such as telnet and the - Berkeley R commands which run with system privileges, the first - component will be the string "host" instead of a service specific - identifier. - -8. Constants and other defined values - -8.1. Host address types - - All negative values for the host address type are reserved for local - use. All non-negative values are reserved for officially assigned - - - -Kohl & Neuman [Page 80] - -RFC 1510 Kerberos September 1993 - - - type fields and interpretations. - - The values of the types for the following addresses are chosen to - match the defined address family constants in the Berkeley Standard - Distributions of Unix. They can be found in with - symbolic names AF_xxx (where xxx is an abbreviation of the address - family name). - - - Internet addresses - - Internet addresses are 32-bit (4-octet) quantities, encoded in MSB - order. The type of internet addresses is two (2). - - CHAOSnet addresses - - CHAOSnet addresses are 16-bit (2-octet) quantities, encoded in MSB - order. The type of CHAOSnet addresses is five (5). - - ISO addresses - - ISO addresses are variable-length. The type of ISO addresses is - seven (7). - - Xerox Network Services (XNS) addresses - - XNS addresses are 48-bit (6-octet) quantities, encoded in MSB - order. The type of XNS addresses is six (6). - - AppleTalk Datagram Delivery Protocol (DDP) addresses - - AppleTalk DDP addresses consist of an 8-bit node number and a 16- - bit network number. The first octet of the address is the node - number; the remaining two octets encode the network number in MSB - order. The type of AppleTalk DDP addresses is sixteen (16). - - DECnet Phase IV addresses - - DECnet Phase IV addresses are 16-bit addresses, encoded in LSB - order. The type of DECnet Phase IV addresses is twelve (12). - -8.2. KDC messages - -8.2.1. IP transport - - When contacting a Kerberos server (KDC) for a KRB_KDC_REQ request - using IP transport, the client shall send a UDP datagram containing - only an encoding of the request to port 88 (decimal) at the KDC's IP - - - -Kohl & Neuman [Page 81] - -RFC 1510 Kerberos September 1993 - - - address; the KDC will respond with a reply datagram containing only - an encoding of the reply message (either a KRB_ERROR or a - KRB_KDC_REP) to the sending port at the sender's IP address. - -8.2.2. OSI transport - - During authentication of an OSI client to and OSI server, the mutual - authentication of an OSI server to an OSI client, the transfer of - credentials from an OSI client to an OSI server, or during exchange - of private or integrity checked messages, Kerberos protocol messages - may be treated as opaque objects and the type of the authentication - mechanism will be: - - OBJECT IDENTIFIER ::= {iso (1), org(3), dod(5),internet(1), - security(5), kerberosv5(2)} - - Depending on the situation, the opaque object will be an - authentication header (KRB_AP_REQ), an authentication reply - (KRB_AP_REP), a safe message (KRB_SAFE), a private message - (KRB_PRIV), or a credentials message (KRB_CRED). The opaque data - contains an application code as specified in the ASN.1 description - for each message. The application code may be used by Kerberos to - determine the message type. - -8.2.3. Name of the TGS - - The principal identifier of the ticket-granting service shall be - composed of three parts: (1) the realm of the KDC issuing the TGS - ticket (2) a two-part name of type NT-SRVINST, with the first part - "krbtgt" and the second part the name of the realm which will accept - the ticket-granting ticket. For example, a ticket-granting ticket - issued by the ATHENA.MIT.EDU realm to be used to get tickets from the - ATHENA.MIT.EDU KDC has a principal identifier of "ATHENA.MIT.EDU" - (realm), ("krbtgt", "ATHENA.MIT.EDU") (name). A ticket-granting - ticket issued by the ATHENA.MIT.EDU realm to be used to get tickets - from the MIT.EDU realm has a principal identifier of "ATHENA.MIT.EDU" - (realm), ("krbtgt", "MIT.EDU") (name). - -8.3. Protocol constants and associated values - - The following tables list constants used in the protocol and defines - their meanings. - - - - - - - - - -Kohl & Neuman [Page 82] - -RFC 1510 Kerberos September 1993 - - ----------------+-----------+----------+----------------+--------------- -Encryption type|etype value|block size|minimum pad size|confounder size ----------------+-----------+----------+----------------+--------------- -NULL 0 1 0 0 -des-cbc-crc 1 8 4 8 -des-cbc-md4 2 8 0 8 -des-cbc-md5 3 8 0 8 - --------------------------------+-------------------+------------- -Checksum type |sumtype value |checksum size --------------------------------+-------------------+------------- -CRC32 1 4 -rsa-md4 2 16 -rsa-md4-des 3 24 -des-mac 4 16 -des-mac-k 5 8 -rsa-md4-des-k 6 16 -rsa-md5 7 16 -rsa-md5-des 8 24 - --------------------------------+----------------- -padata type |padata-type value --------------------------------+----------------- -PA-TGS-REQ 1 -PA-ENC-TIMESTAMP 2 -PA-PW-SALT 3 - --------------------------------+------------- -authorization data type |ad-type value --------------------------------+------------- -reserved values 0-63 -OSF-DCE 64 -SESAME 65 - --------------------------------+----------------- -alternate authentication type |method-type value --------------------------------+----------------- -reserved values 0-63 -ATT-CHALLENGE-RESPONSE 64 - --------------------------------+------------- -transited encoding type |tr-type value --------------------------------+------------- -DOMAIN-X500-COMPRESS 1 -reserved values all others - - - - - - -Kohl & Neuman [Page 83] - -RFC 1510 Kerberos September 1993 - - ---------------+-------+----------------------------------------- -Label |Value |Meaning or MIT code ---------------+-------+----------------------------------------- - -pvno 5 current Kerberos protocol version number - -message types - -KRB_AS_REQ 10 Request for initial authentication -KRB_AS_REP 11 Response to KRB_AS_REQ request -KRB_TGS_REQ 12 Request for authentication based on TGT -KRB_TGS_REP 13 Response to KRB_TGS_REQ request -KRB_AP_REQ 14 application request to server -KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL -KRB_SAFE 20 Safe (checksummed) application message -KRB_PRIV 21 Private (encrypted) application message -KRB_CRED 22 Private (encrypted) message to forward - credentials -KRB_ERROR 30 Error response - -name types - -KRB_NT_UNKNOWN 0 Name type not known -KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or - for users -KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt) -KRB_NT_SRV_HST 3 Service with host name as instance (telnet, - rcommands) -KRB_NT_SRV_XHST 4 Service with host as remaining components -KRB_NT_UID 5 Unique ID - -error codes - -KDC_ERR_NONE 0 No error -KDC_ERR_NAME_EXP 1 Client's entry in database has - expired -KDC_ERR_SERVICE_EXP 2 Server's entry in database has - expired -KDC_ERR_BAD_PVNO 3 Requested protocol version number - not supported -KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old - master key -KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old - master key -KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database -KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database -KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in - database - - - -Kohl & Neuman [Page 84] - -RFC 1510 Kerberos September 1993 - - -KDC_ERR_NULL_KEY 9 The client or server has a null key -KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating -KDC_ERR_NEVER_VALID 11 Requested start time is later than - end time -KDC_ERR_POLICY 12 KDC policy rejects request -KDC_ERR_BADOPTION 13 KDC cannot accommodate requested - option -KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption - type -KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type -KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type -KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type -KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked -KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been - revoked -KDC_ERR_TGT_REVOKED 20 TGT has been revoked -KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again - later -KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again - later -KDC_ERR_KEY_EXPIRED 23 Password has expired - change - password to reset -KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information - was invalid -KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authentication - required* -KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field - failed -KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired -KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid -KRB_AP_ERR_REPEAT 34 Request is a replay -KRB_AP_ERR_NOT_US 35 The ticket isn't for us -KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match -KRB_AP_ERR_SKEW 37 Clock skew too great -KRB_AP_ERR_BADADDR 38 Incorrect net address -KRB_AP_ERR_BADVERSION 39 Protocol version mismatch -KRB_AP_ERR_MSG_TYPE 40 Invalid msg type -KRB_AP_ERR_MODIFIED 41 Message stream modified -KRB_AP_ERR_BADORDER 42 Message out of order -KRB_AP_ERR_BADKEYVER 44 Specified version of key is not - available -KRB_AP_ERR_NOKEY 45 Service key not available -KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed -KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction -KRB_AP_ERR_METHOD 48 Alternative authentication method - required* -KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message -KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in - - - -Kohl & Neuman [Page 85] - -RFC 1510 Kerberos September 1993 - - - message -KRB_ERR_GENERIC 60 Generic error (description in e-text) -KRB_ERR_FIELD_TOOLONG 61 Field is too long for this - implementation - - *This error carries additional information in the e-data field. The - contents of the e-data field for this message is described in section - 5.9.1. - -9. Interoperability requirements - - Version 5 of the Kerberos protocol supports a myriad of options. - Among these are multiple encryption and checksum types, alternative - encoding schemes for the transited field, optional mechanisms for - pre-authentication, the handling of tickets with no addresses, - options for mutual authentication, user to user authentication, - support for proxies, forwarding, postdating, and renewing tickets, - the format of realm names, and the handling of authorization data. - - In order to ensure the interoperability of realms, it is necessary to - define a minimal configuration which must be supported by all - implementations. This minimal configuration is subject to change as - technology does. For example, if at some later date it is discovered - that one of the required encryption or checksum algorithms is not - secure, it will be replaced. - -9.1. Specification 1 - - This section defines the first specification of these options. - Implementations which are configured in this way can be said to - support Kerberos Version 5 Specification 1 (5.1). - - Encryption and checksum methods - - The following encryption and checksum mechanisms must be supported. - Implementations may support other mechanisms as well, but the - additional mechanisms may only be used when communicating with - principals known to also support them: Encryption: DES-CBC-MD5 - Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5 - - Realm Names - - All implementations must understand hierarchical realms in both the - Internet Domain and the X.500 style. When a ticket granting ticket - for an unknown realm is requested, the KDC must be able to determine - the names of the intermediate realms between the KDCs realm and the - requested realm. - - - - -Kohl & Neuman [Page 86] - -RFC 1510 Kerberos September 1993 - - - Transited field encoding - - DOMAIN-X500-COMPRESS (described in section 3.3.3.1) must be - supported. Alternative encodings may be supported, but they may be - used only when that encoding is supported by ALL intermediate realms. - - Pre-authentication methods - - The TGS-REQ method must be supported. The TGS-REQ method is not used - on the initial request. The PA-ENC-TIMESTAMP method must be supported - by clients but whether it is enabled by default may be determined on - a realm by realm basis. If not used in the initial request and the - error KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENCTIMESTAMP - as an acceptable method, the client should retry the initial request - using the PA-ENC-TIMESTAMP preauthentication method. Servers need not - support the PAENC-TIMESTAMP method, but if not supported the server - should ignore the presence of PA-ENC-TIMESTAMP pre-authentication in - a request. - - Mutual authentication - - Mutual authentication (via the KRB_AP_REP message) must be supported. - - Ticket addresses and flags - - All KDC's must pass on tickets that carry no addresses (i.e., if a - TGT contains no addresses, the KDC will return derivative tickets), - but each realm may set its own policy for issuing such tickets, and - each application server will set its own policy with respect to - accepting them. By default, servers should not accept them. - - Proxies and forwarded tickets must be supported. Individual realms - and application servers can set their own policy on when such tickets - will be accepted. - - All implementations must recognize renewable and postdated tickets, - but need not actually implement them. If these options are not - supported, the starttime and endtime in the ticket shall specify a - ticket's entire useful life. When a postdated ticket is decoded by a - server, all implementations shall make the presence of the postdated - flag visible to the calling server. - - User-to-user authentication - - Support for user to user authentication (via the ENC-TKTIN-SKEY KDC - option) must be provided by implementations, but individual realms - may decide as a matter of policy to reject such requests on a per- - principal or realm-wide basis. - - - -Kohl & Neuman [Page 87] - -RFC 1510 Kerberos September 1993 - - - Authorization data - - Implementations must pass all authorization data subfields from - ticket-granting tickets to any derivative tickets unless directed to - suppress a subfield as part of the definition of that registered - subfield type (it is never incorrect to pass on a subfield, and no - registered subfield types presently specify suppression at the KDC). - - Implementations must make the contents of any authorization data - subfields available to the server when a ticket is used. - Implementations are not required to allow clients to specify the - contents of the authorization data fields. - -9.2. Recommended KDC values - - Following is a list of recommended values for a KDC implementation, - based on the list of suggested configuration constants (see section - 4.4). - - minimum lifetime 5 minutes - - maximum renewable lifetime 1 week - - maximum ticket lifetime 1 day - - empty addresses only when suitable restrictions appear - in authorization data - - proxiable, etc. Allowed. - -10. Acknowledgments - - Early versions of this document, describing version 4 of the - protocol, were written by Jennifer Steiner (formerly at Project - Athena); these drafts provided an excellent starting point for this - current version 5 specification. Many people in the Internet - community have contributed ideas and suggested protocol changes for - version 5. Notable contributions came from Ted Anderson, Steve - Bellovin and Michael Merritt [17], Daniel Bernstein, Mike Burrows, - Donald Davis, Ravi Ganesan, Morrie Gasser, Virgil Gligor, Bill - Griffeth, Mark Lillibridge, Mark Lomas, Steve Lunt, Piers McMahon, - Joe Pato, William Sommerfeld, Stuart Stubblebine, Ralph Swick, Ted - T'so, and Stanley Zanarotti. Many others commented and helped shape - this specification into its current form. - - - - - - - -Kohl & Neuman [Page 88] - -RFC 1510 Kerberos September 1993 - - -11. References - - [1] Miller, S., Neuman, C., Schiller, J., and J. Saltzer, "Section - E.2.1: Kerberos Authentication and Authorization System", - M.I.T. Project Athena, Cambridge, Massachusetts, December 21, - 1987. - - [2] Steiner, J., Neuman, C., and J. Schiller, "Kerberos: An - Authentication Service for Open Network Systems", pp. 191-202 in - Usenix Conference Proceedings, Dallas, Texas, February, 1988. - - [3] Needham, R., and M. Schroeder, "Using Encryption for - Authentication in Large Networks of Computers", Communications - of the ACM, Vol. 21 (12), pp. 993-999, December 1978. - - [4] Denning, D., and G. Sacco, "Time stamps in Key Distribution - Protocols", Communications of the ACM, Vol. 24 (8), pp. 533-536, - August 1981. - - [5] Kohl, J., Neuman, C., and T. Ts'o, "The Evolution of the - Kerberos Authentication Service", in an IEEE Computer Society - Text soon to be published, June 1992. - - [6] Davis, D., and R. Swick, "Workstation Services and Kerberos - Authentication at Project Athena", Technical Memorandum TM-424, - MIT Laboratory for Computer Science, February 1990. - - [7] Levine, P., Gretzinger, M, Diaz, J., Sommerfeld, W., and K. - Raeburn, "Section E.1: Service Management System, M.I.T. - Project Athena, Cambridge, Mas sachusetts (1987). - - [8] CCITT, Recommendation X.509: The Directory Authentication - Framework, December 1988. - - [9] Neuman, C., "Proxy-Based Authorization and Accounting for - Distributed Systems," in Proceedings of the 13th International - Conference on Distributed Computing Systems", Pittsburgh, PA, - May 1993. - - [10] Pato, J., "Using Pre-Authentication to Avoid Password Guessing - Attacks", Open Software Foundation DCE Request for Comments 26, - December 1992. - - [11] National Bureau of Standards, U.S. Department of Commerce, "Data - Encryption Standard", Federal Information Processing Standards - Publication 46, Washington, DC (1977). - - - - - -Kohl & Neuman [Page 89] - -RFC 1510 Kerberos September 1993 - - - [12] National Bureau of Standards, U.S. Department of Commerce, "DES - Modes of Operation", Federal Information Processing Standards - Publication 81, Springfield, VA, December 1980. - - [13] Stubblebine S., and V. Gligor, "On Message Integrity in - Cryptographic Protocols", in Proceedings of the IEEE Symposium - on Research in Security and Privacy, Oakland, California, May - 1992. - - [14] International Organization for Standardization, "ISO Information - Processing Systems - Data Communication High-Level Data Link - Control Procedure - Frame Structure", IS 3309, October 1984, 3rd - Edition. - - [15] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT - Laboratory for Computer Science, April 1992. - - [16] Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321, MIT - Laboratory for Computer Science, April 1992. - - [17] Bellovin S., and M. Merritt, "Limitations of the Kerberos - Authentication System", Computer Communications Review, Vol. - 20(5), pp. 119-132, October 1990. - -12. Security Considerations - - Security issues are discussed throughout this memo. - -13. Authors' Addresses - - John Kohl - Digital Equipment Corporation - 110 Spit Brook Road, M/S ZKO3-3/U14 - Nashua, NH 03062 - - Phone: 603-881-2481 - EMail: jtkohl@zk3.dec.com - - - B. Clifford Neuman - USC/Information Sciences Institute - 4676 Admiralty Way #1001 - Marina del Rey, CA 90292-6695 - - Phone: 310-822-1511 - EMail: bcn@isi.edu - - - - - -Kohl & Neuman [Page 90] - -RFC 1510 Kerberos September 1993 - - -A. Pseudo-code for protocol processing - - This appendix provides pseudo-code describing how the messages are to - be constructed and interpreted by clients and servers. - -A.1. KRB_AS_REQ generation - request.pvno := protocol version; /* pvno = 5 */ - request.msg-type := message type; /* type = KRB_AS_REQ */ - - if(pa_enc_timestamp_required) then - request.padata.padata-type = PA-ENC-TIMESTAMP; - get system_time; - padata-body.patimestamp,pausec = system_time; - encrypt padata-body into request.padata.padata-value - using client.key; /* derived from password */ - endif - - body.kdc-options := users's preferences; - body.cname := user's name; - body.realm := user's realm; - body.sname := service's name; /* usually "krbtgt", - "localrealm" */ - if (body.kdc-options.POSTDATED is set) then - body.from := requested starting time; - else - omit body.from; - endif - body.till := requested end time; - if (body.kdc-options.RENEWABLE is set) then - body.rtime := requested final renewal time; - endif - body.nonce := random_nonce(); - body.etype := requested etypes; - if (user supplied addresses) then - body.addresses := user's addresses; - else - omit body.addresses; - endif - omit body.enc-authorization-data; - request.req-body := body; - - kerberos := lookup(name of local kerberos server (or servers)); - send(packet,kerberos); - - wait(for response); - if (timed_out) then - retry or use alternate server; - endif - - - -Kohl & Neuman [Page 91] - -RFC 1510 Kerberos September 1993 - - -A.2. KRB_AS_REQ verification and KRB_AS_REP generation - decode message into req; - - client := lookup(req.cname,req.realm); - server := lookup(req.sname,req.realm); - get system_time; - kdc_time := system_time.seconds; - - if (!client) then - /* no client in Database */ - error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN); - endif - if (!server) then - /* no server in Database */ - error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN); - endif - - if(client.pa_enc_timestamp_required and - pa_enc_timestamp not present) then - error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)); - endif - - if(pa_enc_timestamp present) then - decrypt req.padata-value into decrypted_enc_timestamp - using client.key; - using auth_hdr.authenticator.subkey; - if (decrypt_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - if(decrypted_enc_timestamp is not within allowable - skew) then error_out(KDC_ERR_PREAUTH_FAILED); - endif - if(decrypted_enc_timestamp and usec is replay) - error_out(KDC_ERR_PREAUTH_FAILED); - endif - add decrypted_enc_timestamp and usec to replay cache; - endif - - use_etype := first supported etype in req.etypes; - - if (no support for req.etypes) then - error_out(KDC_ERR_ETYPE_NOSUPP); - endif - - new_tkt.vno := ticket version; /* = 5 */ - new_tkt.sname := req.sname; - new_tkt.srealm := req.srealm; - reset all flags in new_tkt.flags; - - - - -Kohl & Neuman [Page 92] - -RFC 1510 Kerberos September 1993 - - - /* It should be noted that local policy may affect the */ - /* processing of any of these flags. For example, some */ - /* realms may refuse to issue renewable tickets */ - - if (req.kdc-options.FORWARDABLE is set) then - set new_tkt.flags.FORWARDABLE; - endif - if (req.kdc-options.PROXIABLE is set) then - set new_tkt.flags.PROXIABLE; - endif - if (req.kdc-options.ALLOW-POSTDATE is set) then - set new_tkt.flags.ALLOW-POSTDATE; - endif - if ((req.kdc-options.RENEW is set) or - (req.kdc-options.VALIDATE is set) or - (req.kdc-options.PROXY is set) or - (req.kdc-options.FORWARDED is set) or - (req.kdc-options.ENC-TKT-IN-SKEY is set)) then - error_out(KDC_ERR_BADOPTION); - endif - - new_tkt.session := random_session_key(); - new_tkt.cname := req.cname; - new_tkt.crealm := req.crealm; - new_tkt.transited := empty_transited_field(); - - new_tkt.authtime := kdc_time; - - if (req.kdc-options.POSTDATED is set) then - if (against_postdate_policy(req.from)) then - error_out(KDC_ERR_POLICY); - endif - set new_tkt.flags.INVALID; - new_tkt.starttime := req.from; - else - omit new_tkt.starttime; /* treated as authtime when - omitted */ - endif - if (req.till = 0) then - till := infinity; - else - till := req.till; - endif - - new_tkt.endtime := min(till, - new_tkt.starttime+client.max_life, - new_tkt.starttime+server.max_life, - new_tkt.starttime+max_life_for_realm); - - - -Kohl & Neuman [Page 93] - -RFC 1510 Kerberos September 1993 - - - if ((req.kdc-options.RENEWABLE-OK is set) and - (new_tkt.endtime < req.till)) then - /* we set the RENEWABLE option for later processing */ - set req.kdc-options.RENEWABLE; - req.rtime := req.till; - endif - - if (req.rtime = 0) then - rtime := infinity; - else - rtime := req.rtime; - endif - - if (req.kdc-options.RENEWABLE is set) then - set new_tkt.flags.RENEWABLE; - new_tkt.renew-till := min(rtime, - new_tkt.starttime+client.max_rlife, - new_tkt.starttime+server.max_rlife, - new_tkt.starttime+max_rlife_for_realm); - else - omit new_tkt.renew-till; /* only present if RENEWABLE */ - endif - - if (req.addresses) then - new_tkt.caddr := req.addresses; - else - omit new_tkt.caddr; - endif - - new_tkt.authorization_data := empty_authorization_data(); - - encode to-be-encrypted part of ticket into OCTET STRING; - new_tkt.enc-part := encrypt OCTET STRING - using etype_for_key(server.key), server.key, server.p_kvno; - - - /* Start processing the response */ - - resp.pvno := 5; - resp.msg-type := KRB_AS_REP; - resp.cname := req.cname; - resp.crealm := req.realm; - resp.ticket := new_tkt; - - resp.key := new_tkt.session; - resp.last-req := fetch_last_request_info(client); - resp.nonce := req.nonce; - resp.key-expiration := client.expiration; - - - -Kohl & Neuman [Page 94] - -RFC 1510 Kerberos September 1993 - - - resp.flags := new_tkt.flags; - - resp.authtime := new_tkt.authtime; - resp.starttime := new_tkt.starttime; - resp.endtime := new_tkt.endtime; - - if (new_tkt.flags.RENEWABLE) then - resp.renew-till := new_tkt.renew-till; - endif - - resp.realm := new_tkt.realm; - resp.sname := new_tkt.sname; - - resp.caddr := new_tkt.caddr; - - encode body of reply into OCTET STRING; - - resp.enc-part := encrypt OCTET STRING - using use_etype, client.key, client.p_kvno; - send(resp); - -A.3. KRB_AS_REP verification - decode response into resp; - - if (resp.msg-type = KRB_ERROR) then - if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)) - then set pa_enc_timestamp_required; - goto KRB_AS_REQ; - endif - process_error(resp); - return; - endif - - /* On error, discard the response, and zero the session key */ - /* from the response immediately */ - - key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype, - resp.padata); - unencrypted part of resp := decode of decrypt of resp.enc-part - using resp.enc-part.etype and key; - zero(key); - - if (common_as_rep_tgs_rep_checks fail) then - destroy resp.key; - return error; - endif - - if near(resp.princ_exp) then - - - -Kohl & Neuman [Page 95] - -RFC 1510 Kerberos September 1993 - - - print(warning message); - endif - save_for_later(ticket,session,client,server,times,flags); - -A.4. KRB_AS_REP and KRB_TGS_REP common checks - if (decryption_error() or - (req.cname != resp.cname) or - (req.realm != resp.crealm) or - (req.sname != resp.sname) or - (req.realm != resp.realm) or - (req.nonce != resp.nonce) or - (req.addresses != resp.caddr)) then - destroy resp.key; - return KRB_AP_ERR_MODIFIED; - endif - - /* make sure no flags are set that shouldn't be, and that */ - /* all that should be are set */ - if (!check_flags_for_compatability(req.kdc-options,resp.flags)) - then destroy resp.key; - return KRB_AP_ERR_MODIFIED; - endif - - if ((req.from = 0) and - (resp.starttime is not within allowable skew)) then - destroy resp.key; - return KRB_AP_ERR_SKEW; - endif - if ((req.from != 0) and (req.from != resp.starttime)) then - destroy resp.key; - return KRB_AP_ERR_MODIFIED; - endif - if ((req.till != 0) and (resp.endtime > req.till)) then - destroy resp.key; - return KRB_AP_ERR_MODIFIED; - endif - - if ((req.kdc-options.RENEWABLE is set) and - (req.rtime != 0) and (resp.renew-till > req.rtime)) then - destroy resp.key; - return KRB_AP_ERR_MODIFIED; - endif - if ((req.kdc-options.RENEWABLE-OK is set) and - (resp.flags.RENEWABLE) and - (req.till != 0) and - (resp.renew-till > req.till)) then - destroy resp.key; - return KRB_AP_ERR_MODIFIED; - - - -Kohl & Neuman [Page 96] - -RFC 1510 Kerberos September 1993 - - - endif - -A.5. KRB_TGS_REQ generation - /* Note that make_application_request might have to */ - /* recursivly call this routine to get the appropriate */ - /* ticket-granting ticket */ - - request.pvno := protocol version; /* pvno = 5 */ - request.msg-type := message type; /* type = KRB_TGS_REQ */ - - body.kdc-options := users's preferences; - /* If the TGT is not for the realm of the end-server */ - /* then the sname will be for a TGT for the end-realm */ - /* and the realm of the requested ticket (body.realm) */ - /* will be that of the TGS to which the TGT we are */ - /* sending applies */ - body.sname := service's name; - body.realm := service's realm; - - if (body.kdc-options.POSTDATED is set) then - body.from := requested starting time; - else - omit body.from; - endif - body.till := requested end time; - if (body.kdc-options.RENEWABLE is set) then - body.rtime := requested final renewal time; - endif - body.nonce := random_nonce(); - body.etype := requested etypes; - if (user supplied addresses) then - body.addresses := user's addresses; - else - omit body.addresses; - endif - - body.enc-authorization-data := user-supplied data; - if (body.kdc-options.ENC-TKT-IN-SKEY) then - body.additional-tickets_ticket := second TGT; - endif - - request.req-body := body; - check := generate_checksum (req.body,checksumtype); - - request.padata[0].padata-type := PA-TGS-REQ; - request.padata[0].padata-value := create a KRB_AP_REQ using - the TGT and checksum - - - - -Kohl & Neuman [Page 97] - -RFC 1510 Kerberos September 1993 - - - /* add in any other padata as required/supplied */ - - kerberos := lookup(name of local kerberose server (or servers)); - send(packet,kerberos); - - wait(for response); - if (timed_out) then - retry or use alternate server; - endif - -A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation - /* note that reading the application request requires first - determining the server for which a ticket was issued, and - choosing the correct key for decryption. The name of the - server appears in the plaintext part of the ticket. */ - - if (no KRB_AP_REQ in req.padata) then - error_out(KDC_ERR_PADATA_TYPE_NOSUPP); - endif - verify KRB_AP_REQ in req.padata; - - /* Note that the realm in which the Kerberos server is - operating is determined by the instance from the - ticket-granting ticket. The realm in the ticket-granting - ticket is the realm under which the ticket granting ticket was - issued. It is possible for a single Kerberos server to - support more than one realm. */ - - auth_hdr := KRB_AP_REQ; - tgt := auth_hdr.ticket; - - if (tgt.sname is not a TGT for local realm and is not - req.sname) then error_out(KRB_AP_ERR_NOT_US); - - realm := realm_tgt_is_for(tgt); - - decode remainder of request; - - if (auth_hdr.authenticator.cksum is missing) then - error_out(KRB_AP_ERR_INAPP_CKSUM); - endif - if (auth_hdr.authenticator.cksum type is not supported) then - error_out(KDC_ERR_SUMTYPE_NOSUPP); - endif - if (auth_hdr.authenticator.cksum is not both collision-proof - and keyed) then - error_out(KRB_AP_ERR_INAPP_CKSUM); - endif - - - -Kohl & Neuman [Page 98] - -RFC 1510 Kerberos September 1993 - - - set computed_checksum := checksum(req); - if (computed_checksum != auth_hdr.authenticatory.cksum) then - error_out(KRB_AP_ERR_MODIFIED); - endif - - server := lookup(req.sname,realm); - - if (!server) then - if (is_foreign_tgt_name(server)) then - server := best_intermediate_tgs(server); - else - /* no server in Database */ - error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN); - endif - endif - - session := generate_random_session_key(); - - - use_etype := first supported etype in req.etypes; - - if (no support for req.etypes) then - error_out(KDC_ERR_ETYPE_NOSUPP); - endif - - new_tkt.vno := ticket version; /* = 5 */ - new_tkt.sname := req.sname; - new_tkt.srealm := realm; - reset all flags in new_tkt.flags; - - /* It should be noted that local policy may affect the */ - /* processing of any of these flags. For example, some */ - /* realms may refuse to issue renewable tickets */ - - new_tkt.caddr := tgt.caddr; - resp.caddr := NULL; /* We only include this if they change */ - if (req.kdc-options.FORWARDABLE is set) then - if (tgt.flags.FORWARDABLE is reset) then - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.FORWARDABLE; - endif - if (req.kdc-options.FORWARDED is set) then - if (tgt.flags.FORWARDABLE is reset) then - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.FORWARDED; - new_tkt.caddr := req.addresses; - - - -Kohl & Neuman [Page 99] - -RFC 1510 Kerberos September 1993 - - - resp.caddr := req.addresses; - endif - if (tgt.flags.FORWARDED is set) then - set new_tkt.flags.FORWARDED; - endif - - if (req.kdc-options.PROXIABLE is set) then - if (tgt.flags.PROXIABLE is reset) - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.PROXIABLE; - endif - if (req.kdc-options.PROXY is set) then - if (tgt.flags.PROXIABLE is reset) then - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.PROXY; - new_tkt.caddr := req.addresses; - resp.caddr := req.addresses; - endif - - if (req.kdc-options.POSTDATE is set) then - if (tgt.flags.POSTDATE is reset) - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.POSTDATE; - endif - if (req.kdc-options.POSTDATED is set) then - if (tgt.flags.POSTDATE is reset) then - error_out(KDC_ERR_BADOPTION); - endif - set new_tkt.flags.POSTDATED; - set new_tkt.flags.INVALID; - if (against_postdate_policy(req.from)) then - error_out(KDC_ERR_POLICY); - endif - new_tkt.starttime := req.from; - endif - - - if (req.kdc-options.VALIDATE is set) then - if (tgt.flags.INVALID is reset) then - error_out(KDC_ERR_POLICY); - endif - if (tgt.starttime > kdc_time) then - error_out(KRB_AP_ERR_NYV); - endif - if (check_hot_list(tgt)) then - - - -Kohl & Neuman [Page 100] - -RFC 1510 Kerberos September 1993 - - - error_out(KRB_AP_ERR_REPEAT); - endif - tkt := tgt; - reset new_tkt.flags.INVALID; - endif - - if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW, - and those already processed) is set) then - error_out(KDC_ERR_BADOPTION); - endif - - new_tkt.authtime := tgt.authtime; - - if (req.kdc-options.RENEW is set) then - /* Note that if the endtime has already passed, the ticket */ - /* would have been rejected in the initial authentication */ - /* stage, so there is no need to check again here */ - if (tgt.flags.RENEWABLE is reset) then - error_out(KDC_ERR_BADOPTION); - endif - if (tgt.renew-till >= kdc_time) then - error_out(KRB_AP_ERR_TKT_EXPIRED); - endif - tkt := tgt; - new_tkt.starttime := kdc_time; - old_life := tgt.endttime - tgt.starttime; - new_tkt.endtime := min(tgt.renew-till, - new_tkt.starttime + old_life); - else - new_tkt.starttime := kdc_time; - if (req.till = 0) then - till := infinity; - else - till := req.till; - endif - new_tkt.endtime := min(till, - new_tkt.starttime+client.max_life, - new_tkt.starttime+server.max_life, - new_tkt.starttime+max_life_for_realm, - tgt.endtime); - - if ((req.kdc-options.RENEWABLE-OK is set) and - (new_tkt.endtime < req.till) and - (tgt.flags.RENEWABLE is set) then - /* we set the RENEWABLE option for later */ - /* processing */ - set req.kdc-options.RENEWABLE; - req.rtime := min(req.till, tgt.renew-till); - - - -Kohl & Neuman [Page 101] - -RFC 1510 Kerberos September 1993 - - - endif - endif - - if (req.rtime = 0) then - rtime := infinity; - else - rtime := req.rtime; - endif - - if ((req.kdc-options.RENEWABLE is set) and - (tgt.flags.RENEWABLE is set)) then - set new_tkt.flags.RENEWABLE; - new_tkt.renew-till := min(rtime, - new_tkt.starttime+client.max_rlife, - new_tkt.starttime+server.max_rlife, - new_tkt.starttime+max_rlife_for_realm, - tgt.renew-till); - else - new_tkt.renew-till := OMIT; - /* leave the renew-till field out */ - endif - if (req.enc-authorization-data is present) then - decrypt req.enc-authorization-data - into decrypted_authorization_data - using auth_hdr.authenticator.subkey; - if (decrypt_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - endif - new_tkt.authorization_data := - req.auth_hdr.ticket.authorization_data + - decrypted_authorization_data; - - new_tkt.key := session; - new_tkt.crealm := tgt.crealm; - new_tkt.cname := req.auth_hdr.ticket.cname; - - if (realm_tgt_is_for(tgt) := tgt.realm) then - /* tgt issued by local realm */ - new_tkt.transited := tgt.transited; - else - /* was issued for this realm by some other realm */ - if (tgt.transited.tr-type not supported) then - error_out(KDC_ERR_TRTYPE_NOSUPP); - endif - new_tkt.transited - := compress_transited(tgt.transited + tgt.realm) - endif - - - -Kohl & Neuman [Page 102] - -RFC 1510 Kerberos September 1993 - - - encode encrypted part of new_tkt into OCTET STRING; - if (req.kdc-options.ENC-TKT-IN-SKEY is set) then - if (server not specified) then - server = req.second_ticket.client; - endif - if ((req.second_ticket is not a TGT) or - (req.second_ticket.client != server)) then - error_out(KDC_ERR_POLICY); - endif - - new_tkt.enc-part := encrypt OCTET STRING using - using etype_for_key(second-ticket.key), - second-ticket.key; - else - new_tkt.enc-part := encrypt OCTET STRING - using etype_for_key(server.key), server.key, - server.p_kvno; - endif - - resp.pvno := 5; - resp.msg-type := KRB_TGS_REP; - resp.crealm := tgt.crealm; - resp.cname := tgt.cname; - resp.ticket := new_tkt; - - resp.key := session; - resp.nonce := req.nonce; - resp.last-req := fetch_last_request_info(client); - resp.flags := new_tkt.flags; - - resp.authtime := new_tkt.authtime; - resp.starttime := new_tkt.starttime; - resp.endtime := new_tkt.endtime; - - omit resp.key-expiration; - - resp.sname := new_tkt.sname; - resp.realm := new_tkt.realm; - - if (new_tkt.flags.RENEWABLE) then - resp.renew-till := new_tkt.renew-till; - endif - - - encode body of reply into OCTET STRING; - - if (req.padata.authenticator.subkey) - resp.enc-part := encrypt OCTET STRING using use_etype, - - - -Kohl & Neuman [Page 103] - -RFC 1510 Kerberos September 1993 - - - req.padata.authenticator.subkey; - else resp.enc-part := encrypt OCTET STRING - using use_etype, tgt.key; - - send(resp); - -A.7. KRB_TGS_REP verification - decode response into resp; - - if (resp.msg-type = KRB_ERROR) then - process_error(resp); - return; - endif - - /* On error, discard the response, and zero the session key from - the response immediately */ - - if (req.padata.authenticator.subkey) - unencrypted part of resp := - decode of decrypt of resp.enc-part - using resp.enc-part.etype and subkey; - else unencrypted part of resp := - decode of decrypt of resp.enc-part - using resp.enc-part.etype and tgt's session key; - if (common_as_rep_tgs_rep_checks fail) then - destroy resp.key; - return error; - endif - - check authorization_data as necessary; - save_for_later(ticket,session,client,server,times,flags); - -A.8. Authenticator generation - body.authenticator-vno := authenticator vno; /* = 5 */ - body.cname, body.crealm := client name; - if (supplying checksum) then - body.cksum := checksum; - endif - get system_time; - body.ctime, body.cusec := system_time; - if (selecting sub-session key) then - select sub-session key; - body.subkey := sub-session key; - endif - if (using sequence numbers) then - select initial sequence number; - body.seq-number := initial sequence; - endif - - - -Kohl & Neuman [Page 104] - -RFC 1510 Kerberos September 1993 - - -A.9. KRB_AP_REQ generation - obtain ticket and session_key from cache; - - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_AP_REQ */ - - if (desired(MUTUAL_AUTHENTICATION)) then - set packet.ap-options.MUTUAL-REQUIRED; - else - reset packet.ap-options.MUTUAL-REQUIRED; - endif - if (using session key for ticket) then - set packet.ap-options.USE-SESSION-KEY; - else - reset packet.ap-options.USE-SESSION-KEY; - endif - packet.ticket := ticket; /* ticket */ - generate authenticator; - encode authenticator into OCTET STRING; - encrypt OCTET STRING into packet.authenticator - using session_key; - -A.10. KRB_AP_REQ verification - receive packet; - if (packet.pvno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.msg-type != KRB_AP_REQ) then - error_out(KRB_AP_ERR_MSG_TYPE); - endif - if (packet.ticket.tkt_vno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.ap_options.USE-SESSION-KEY is set) then - retrieve session key from ticket-granting ticket for - packet.ticket.{sname,srealm,enc-part.etype}; - else - retrieve service key for - packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno}; - endif - if (no_key_available) then - if (cannot_find_specified_skvno) then - error_out(KRB_AP_ERR_BADKEYVER); - else - error_out(KRB_AP_ERR_NOKEY); - endif - - - -Kohl & Neuman [Page 105] - -RFC 1510 Kerberos September 1993 - - - endif - decrypt packet.ticket.enc-part into decr_ticket - using retrieved key; - if (decryption_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - decrypt packet.authenticator into decr_authenticator - using decr_ticket.key; - if (decryption_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - if (decr_authenticator.{cname,crealm} != - decr_ticket.{cname,crealm}) then - error_out(KRB_AP_ERR_BADMATCH); - endif - if (decr_ticket.caddr is present) then - if (sender_address(packet) is not in decr_ticket.caddr) - then error_out(KRB_AP_ERR_BADADDR); - endif - elseif (application requires addresses) then - error_out(KRB_AP_ERR_BADADDR); - endif - if (not in_clock_skew(decr_authenticator.ctime, - decr_authenticator.cusec)) then - error_out(KRB_AP_ERR_SKEW); - endif - if (repeated(decr_authenticator.{ctime,cusec,cname,crealm})) - then error_out(KRB_AP_ERR_REPEAT); - endif - save_identifier(decr_authenticator.{ctime,cusec,cname,crealm}); - get system_time; - if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or - (decr_ticket.flags.INVALID is set)) then - /* it hasn't yet become valid */ - error_out(KRB_AP_ERR_TKT_NYV); - endif - if (system_time-decr_ticket.endtime > CLOCK_SKEW) then - error_out(KRB_AP_ERR_TKT_EXPIRED); - endif - /* caller must check decr_ticket.flags for any pertinent */ - /* details */ - return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED); - -A.11. KRB_AP_REP generation - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_AP_REP */ - body.ctime := packet.ctime; - body.cusec := packet.cusec; - - - -Kohl & Neuman [Page 106] - -RFC 1510 Kerberos September 1993 - - - if (selecting sub-session key) then - select sub-session key; - body.subkey := sub-session key; - endif - if (using sequence numbers) then - select initial sequence number; - body.seq-number := initial sequence; - endif - - encode body into OCTET STRING; - - select encryption type; - encrypt OCTET STRING into packet.enc-part; - -A.12. KRB_AP_REP verification - receive packet; - if (packet.pvno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.msg-type != KRB_AP_REP) then - error_out(KRB_AP_ERR_MSG_TYPE); - endif - cleartext := decrypt(packet.enc-part) - using ticket's session key; - if (decryption_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - if (cleartext.ctime != authenticator.ctime) then - error_out(KRB_AP_ERR_MUT_FAIL); - endif - if (cleartext.cusec != authenticator.cusec) then - error_out(KRB_AP_ERR_MUT_FAIL); - endif - if (cleartext.subkey is present) then - save cleartext.subkey for future use; - endif - if (cleartext.seq-number is present) then - save cleartext.seq-number for future verifications; - endif - return(AUTHENTICATION_SUCCEEDED); - -A.13. KRB_SAFE generation - collect user data in buffer; - - /* assemble packet: */ - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_SAFE */ - - - -Kohl & Neuman [Page 107] - -RFC 1510 Kerberos September 1993 - - - body.user-data := buffer; /* DATA */ - if (using timestamp) then - get system_time; - body.timestamp, body.usec := system_time; - endif - if (using sequence numbers) then - body.seq-number := sequence number; - endif - body.s-address := sender host addresses; - if (only one recipient) then - body.r-address := recipient host address; - endif - checksum.cksumtype := checksum type; - compute checksum over body; - checksum.checksum := checksum value; /* checksum.checksum */ - packet.cksum := checksum; - packet.safe-body := body; - -A.14. KRB_SAFE verification - receive packet; - if (packet.pvno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.msg-type != KRB_SAFE) then - error_out(KRB_AP_ERR_MSG_TYPE); - endif - if (packet.checksum.cksumtype is not both collision-proof - and keyed) then - error_out(KRB_AP_ERR_INAPP_CKSUM); - endif - if (safe_priv_common_checks_ok(packet)) then - set computed_checksum := checksum(packet.body); - if (computed_checksum != packet.checksum) then - error_out(KRB_AP_ERR_MODIFIED); - endif - return (packet, PACKET_IS_GENUINE); - else - return common_checks_error; - endif - -A.15. KRB_SAFE and KRB_PRIV common checks - if (packet.s-address != O/S_sender(packet)) then - /* O/S report of sender not who claims to have sent it */ - error_out(KRB_AP_ERR_BADADDR); - endif - if ((packet.r-address is present) and - (packet.r-address != local_host_address)) then - - - -Kohl & Neuman [Page 108] - -RFC 1510 Kerberos September 1993 - - - /* was not sent to proper place */ - error_out(KRB_AP_ERR_BADADDR); - endif - if (((packet.timestamp is present) and - (not in_clock_skew(packet.timestamp,packet.usec))) or - (packet.timestamp is not present and timestamp expected)) - then error_out(KRB_AP_ERR_SKEW); - endif - if (repeated(packet.timestamp,packet.usec,packet.s-address)) - then error_out(KRB_AP_ERR_REPEAT); - endif - if (((packet.seq-number is present) and - ((not in_sequence(packet.seq-number)))) or - (packet.seq-number is not present and sequence expected)) - then error_out(KRB_AP_ERR_BADORDER); - endif - if (packet.timestamp not present and - packet.seq-number not present) then - error_out(KRB_AP_ERR_MODIFIED); - endif - - save_identifier(packet.{timestamp,usec,s-address}, - sender_principal(packet)); - - return PACKET_IS_OK; - -A.16. KRB_PRIV generation - collect user data in buffer; - - /* assemble packet: */ - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_PRIV */ - - packet.enc-part.etype := encryption type; - - body.user-data := buffer; - if (using timestamp) then - get system_time; - body.timestamp, body.usec := system_time; - endif - if (using sequence numbers) then - body.seq-number := sequence number; - endif - body.s-address := sender host addresses; - if (only one recipient) then - body.r-address := recipient host address; - endif - - - - -Kohl & Neuman [Page 109] - -RFC 1510 Kerberos September 1993 - - - encode body into OCTET STRING; - - select encryption type; - encrypt OCTET STRING into packet.enc-part.cipher; - -A.17. KRB_PRIV verification - receive packet; - if (packet.pvno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.msg-type != KRB_PRIV) then - error_out(KRB_AP_ERR_MSG_TYPE); - endif - - cleartext := decrypt(packet.enc-part) using negotiated key; - if (decryption_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - - if (safe_priv_common_checks_ok(cleartext)) then - return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED); - else - return common_checks_error; - endif - -A.18. KRB_CRED generation - invoke KRB_TGS; /* obtain tickets to be provided to peer */ - - /* assemble packet: */ - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_CRED */ - - for (tickets[n] in tickets to be forwarded) do - packet.tickets[n] = tickets[n].ticket; - done - - packet.enc-part.etype := encryption type; - - for (ticket[n] in tickets to be forwarded) do - body.ticket-info[n].key = tickets[n].session; - body.ticket-info[n].prealm = tickets[n].crealm; - body.ticket-info[n].pname = tickets[n].cname; - body.ticket-info[n].flags = tickets[n].flags; - body.ticket-info[n].authtime = tickets[n].authtime; - body.ticket-info[n].starttime = tickets[n].starttime; - body.ticket-info[n].endtime = tickets[n].endtime; - body.ticket-info[n].renew-till = tickets[n].renew-till; - - - -Kohl & Neuman [Page 110] - -RFC 1510 Kerberos September 1993 - - - body.ticket-info[n].srealm = tickets[n].srealm; - body.ticket-info[n].sname = tickets[n].sname; - body.ticket-info[n].caddr = tickets[n].caddr; - done - - get system_time; - body.timestamp, body.usec := system_time; - - if (using nonce) then - body.nonce := nonce; - endif - - if (using s-address) then - body.s-address := sender host addresses; - endif - if (limited recipients) then - body.r-address := recipient host address; - endif - - encode body into OCTET STRING; - - select encryption type; - encrypt OCTET STRING into packet.enc-part.cipher - using negotiated encryption key; - -A.19. KRB_CRED verification - receive packet; - if (packet.pvno != 5) then - either process using other protocol spec - or error_out(KRB_AP_ERR_BADVERSION); - endif - if (packet.msg-type != KRB_CRED) then - error_out(KRB_AP_ERR_MSG_TYPE); - endif - - cleartext := decrypt(packet.enc-part) using negotiated key; - if (decryption_error()) then - error_out(KRB_AP_ERR_BAD_INTEGRITY); - endif - if ((packet.r-address is present or required) and - (packet.s-address != O/S_sender(packet)) then - /* O/S report of sender not who claims to have sent it */ - error_out(KRB_AP_ERR_BADADDR); - endif - if ((packet.r-address is present) and - (packet.r-address != local_host_address)) then - /* was not sent to proper place */ - error_out(KRB_AP_ERR_BADADDR); - - - -Kohl & Neuman [Page 111] - -RFC 1510 Kerberos September 1993 - - - endif - if (not in_clock_skew(packet.timestamp,packet.usec)) then - error_out(KRB_AP_ERR_SKEW); - endif - if (repeated(packet.timestamp,packet.usec,packet.s-address)) - then error_out(KRB_AP_ERR_REPEAT); - endif - if (packet.nonce is required or present) and - (packet.nonce != expected-nonce) then - error_out(KRB_AP_ERR_MODIFIED); - endif - - for (ticket[n] in tickets that were forwarded) do - save_for_later(ticket[n],key[n],principal[n], - server[n],times[n],flags[n]); - return - -A.20. KRB_ERROR generation - - /* assemble packet: */ - packet.pvno := protocol version; /* 5 */ - packet.msg-type := message type; /* KRB_ERROR */ - - get system_time; - packet.stime, packet.susec := system_time; - packet.realm, packet.sname := server name; - - if (client time available) then - packet.ctime, packet.cusec := client_time; - endif - packet.error-code := error code; - if (client name available) then - packet.cname, packet.crealm := client name; - endif - if (error text available) then - packet.e-text := error text; - endif - if (error data available) then - packet.e-data := error data; - endif - - - - - - - - - - - -Kohl & Neuman [Page 112] - \ No newline at end of file diff --git a/doc/krb5conf.texinfo b/doc/krb5conf.texinfo deleted file mode 100644 index 09825524f..000000000 --- a/doc/krb5conf.texinfo +++ /dev/null @@ -1,83 +0,0 @@ -The @code{krb5.conf} file contains Kerberos configuration information, -including the locations of KDCs and admin servers for the Kerberos -realms of interest, defaults for the current realm and for Kerberos -applications, and mappings of hostnames onto Kerberos realms. Normally, -you should install your @code{krb5.conf} file in the directory -@code{/etc}. You can override the default location by setting the -environment variable @samp{KRB5_CONFIG}. - -The @code{krb5.conf} file is set up in the style of a Windows INI file. -Sections are headed by the section name, in square brackets. Each -section may contain zero or more relations, of the form: - -@smallexample -foo = bar -@end smallexample - -@noindent -or - -@smallexample -@group -fubar = @{ - foo = bar - baz = quux -@} -@end group -@end smallexample - -Placing a `*' at the end of a line indicates that this is the -@dfn{final} value for the tag. This means that neither the remainder -of this configuration file nor any other configuration file will be -checked for any other values for this tag. - -For example, if you have the following lines: - -@smallexample -foo = bar* -foo = baz -@end smallexample - -then the second value of foo (baz) would never be read. - -The @code{krb5.conf} file may contain any or all of the following -sections: - -@table @b -@itemx libdefaults -Contains default values used by the Kerberos V5 library. - -@itemx login -Contains default values used by the Kerberos V5 login program. - -@itemx appdefaults -Contains default values that can be used by Kerberos V5 applications. - -@itemx realms -Contains subsections keyed by Kerberos realm names. Each subsection -describes realm-specific information, including where to find the -Kerberos servers for that realm. - -@itemx domain_realm -Contains relations which map domain names and subdomains onto Kerberos -realm names. This is used by programs to determine what realm a host -should be in, given its fully qualified domain name. - -@itemx logging -Contains relations which determine how Kerberos programs are to perform -logging. - -@itemx capaths -Contains the authentication paths used with direct (nonhierarchical) -cross-realm authentication. Entries in this section are used by the -client to determine the intermediate realms which may be used in -cross-realm authentication. It is also used by the end-service when -checking the transited field for trusted intermediate realms. - -@ignore -this doesn't seem to be used -@itemx kdc -For a KDC, may contain the location of the kdc.conf file. -@end ignore - -@end table diff --git a/doc/man2html b/doc/man2html deleted file mode 100644 index ea45686b8..000000000 --- a/doc/man2html +++ /dev/null @@ -1,608 +0,0 @@ -#!/usr/athena/bin/perl -#!/usr/local/bin/perl -##---------------------------------------------------------------------------## -## File: -## @(#) man2html 1.2 97/08/12 12:57:30 @(#) -## Author: -## Earl Hood, ehood@medusa.acs.uci.edu -## Description: -## man2html is a Perl program to convert formatted nroff output -## to HTML. -## -## Recommend command-line options based on platform: -## -## Platform Options -## --------------------------------------------------------------------- -## c2mp -## hp9000s700/800 -leftm 1 -topm 8 -## sun4 -sun -## --------------------------------------------------------------------- -## -##---------------------------------------------------------------------------## -## Copyright (C) 1995-1997 Earl Hood, ehood@medusa.acs.uci.edu -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -## 02111-1307, USA -##---------------------------------------------------------------------------## - -package Man2Html; - -use Getopt::Long; - -($PROG = $0) =~ s/.*\///; -$VERSION = "3.0.1"; - -## Input and outputs filehandles -$InFH = \*STDIN unless $InFH; -$OutFH = \*STDOUT unless $OutFH; - -## Backspace character: Used in overstriking detection -*bs = \"\b"; - -## Hash of section titles and their HTML tag wrapper. -## This list allows customization of what HTML tag is used for -## a given section head. -## -## The section title can be a regular expression. Therefore, one must -## be careful about quoting special characters. -## -%SectionHead = ( - - '\S.*OPTIONS.*' => '

', - 'AUTHORS?' => '

', - 'BUGS' => '

', - 'COMPATIBILITY' => '

', - 'DEPENDENCIES' => '

', - 'DESCRIPTION' => '

', - 'DIAGNOSTICS' => '

', - 'ENVIRONMENT' => '

', - 'ERRORS' => '

', - 'EXAMPLES' => '

', - 'EXTERNAL INFLUENCES' => '

', - 'FILES' => '

', - 'LIMITATIONS' => '

', - 'NAME' => '

', - 'NOTES?' => '

', - 'OPTIONS' => '

', - 'REFERENCES' => '

', - 'RETURN VALUE' => '

', - 'SECTION.*:' => '

', - 'SEE ALSO' => '

', - 'STANDARDS CONFORMANCE' => '

', - 'STYLE CONVENTION' => '

', - 'SYNOPSIS' => '

', - 'SYNTAX' => '

', - 'WARNINGS' => '

', - '\s+Section.*:' => '

', - -); - -## Fallback tag if above is not found -$HeadFallback = '

'; - -## Other gobals - -$Bare = 0; # Skip printing HTML head/foot flag -$BTag = 'B'; # Overstrike tag -$CgiUrl = ''; # CGI URL expression -$Compress = 0; # Do blank line compression flag -$K = 0; # Do keyword search processing flag -$NoDepage = 0; # Do not strip page information -$NoHeads = 0; # Do no header detection flag -$SeeAlso = 0; # Do only SEE ALSO xrefs flag -$Solaris = 0; # Solaris keyword search processing flag -$Sun = 0; # Headers not overstriken flag -$Title = ''; # Title -$UTag = 'I'; # Underline tag -$ftsz = 7; # Bottome margin size -$hdsz = 7; # Top margin size -$leftm = ''; # Left margin pad -$leftmsz = 0; # Left margin size -$pgsz = 66; # Size of page size -$txsz = 52; # Text body length size - -############################################################################# -## Main Block -############################################################################# -{ - if (get_cli_opts()) { - if ($K) { - man_k(); - } else { - do_it(); - } - } else { - usage(); - } -} - -############################################################################# -## Subroutines -############################################################################# - -sub do_it { - - ## Define while loop and then eval it when used. The reason - ## is to avoid the regular expression reevaulation in the - ## section head detection code. - - $doitcode =<<'EndOfDoItCode'; - - my($line, $tmp, $i, $head, $preindent, $see_also, $do); - - $see_also = !$SeeAlso; - print $OutFH "\n"; - LOOP: while(!eof($InFH)) { - $blank = 0; - for ($i=0; $i < $hdsz; $i++) { - last LOOP unless defined($_ = <$InFH>); - } - for ($i=0; $i < $txsz; $i++) { - last LOOP unless defined($_ = <$InFH>); - - ## Check if compress consecutive blank lines - if ($Compress and !/\S/) { - if ($blank) { next; } else { $blank = 1; } - } else { - $blank = 0; - } - - ## Try to check if line space is needed at page boundaries ## - if (!$NoDepage && ($i==0 || $i==($txsz-1)) && !/^\s*$/) { - /^(\s*)/; $tmp = length($1); - if ($do) { - if ($tmp < $preindent) { print $OutFH "\n"; } - } else { - $do = 1; - } - $preindent = $tmp; - } else { - $do = 0; $preindent = 0; - } - - ## Interpret line - $line = $_; - entitize(\$_); # Convert [$<>] to entity references - - ## Check for 'SEE ALSO' link only - if (!$see_also && $CgiUrl && $SeeAlso) { - ($tmp = $line) =~ s/.\010//go; - if ($tmp =~ /^\s*SEE\s+ALSO\s*$/o) { $see_also = 1; } - else { $see_also = 0; } - } - - ## Create anchor links for manpage references - s/((((.\010)+)?[\+_\.\w-])+\(((.\010)+)? - \d((.\010)+)?\w?\)) - /make_xref($1) - /geox if $see_also; - - ## Emphasize underlined words - # s/((_\010[^_])+[\.\(\)_]?(_\010[^_])+\)?)/emphasize($1)/oge; - # s/((_\010[^_])+([\.\(\)_]?(_\010[^_])+)?)/emphasize($1)/oge; - # - # The previous expressions were trying to be clever about - # detecting underlined text which contain non-alphanumeric - # characters. nroff will not underline non-alphanumeric - # characters in an underlined phrase, and the above was trying - # to detect that. It does not work all the time, and it - # screws up other text, so a simplified expression is used. - - s/((_\010[^_])+)/emphasize($1)/oge; - - $secth = 0; - ## Check for strong text and headings - if ($Sun || /.\010./o) { - if (!$NoHeads) { - $line =~ s/.\010//go; - $tmp = $HeadFallback; -EndOfDoItCode - - ## Create switch statement for detecting a heading - ## - $doitcode .= "HEADSW: {\n"; - foreach $head (keys %SectionHead) { - $doitcode .= join("", "\$tmp = '$SectionHead{$head}', ", - "\$secth = 1, last HEADSW ", - "if \$line =~ /^$leftm$head/o;\n"); - } - $doitcode .= "}\n"; - - ## Rest of routine - ## - $doitcode .=<<'EndOfDoItCode'; - if ($secth || $line =~ /^$leftm\S/o) { - chop $line; - $_ = $tmp . $line . $tmp; - s%<([^>]*)>$%%; - $_ = "\n\n" . $_ . "
\n";
-		    } else {
-			s/(((.\010)+.)+)/strongize($1)/oge;
-		    }
-		} else {
-		    s/(((.\010)+.)+)/strongize($1)/oge;
-		}
-	    }
-	    print $OutFH $_;
-	}
-
-	for ($i=0; $i < $ftsz; $i++) {
-	    last LOOP  unless defined($_ = <$InFH>);
-	}
-    }
-EndOfDoItCode
-
-
-    ##	Perform processing.
-
-    printhead()  unless $Bare;
-    print $OutFH "
\n";
-    eval $doitcode;			# $doitcode defined above
-    print $OutFH "
\n"; - printtail() unless $Bare; -} - -##--------------------------------------------------------------------------- -## -sub get_cli_opts { - return 0 unless - GetOptions( - "bare", # Leave out HTML, HEAD, BODY tags. - "belem=s", # HTML Element for overstriked text (def: "B") - "botm=i", # Number of lines for bottom margin (def: 7) - "cgiurl=s", # CGI URL for linking to other manpages - "cgiurlexp=s", # CGI URL Perl expr for linking to other manpages - "compress", # Compress consecutive blank lines - "headmap=s", # Filename of user section head map file - "k", # Process input from 'man -k' output. - "leftm=i", # Character width of left margin (def: 0) - "nodepage", # Do not remove pagination lines - "noheads", # Do not detect for section heads - "pgsize=i", # Number of lines in a page (def: 66) - "seealso", # Link to other manpages only in the SEE ALSO section - "solaris", # Parse 'man -k' output from a solaris system - "sun", # Section heads are not overstriked in input - "title=s", # Title of manpage (def: Not defined) - "topm=i", # Number of lines for top margin (def: 7) - "uelem=s", # HTML Element for underlined text (def: "I") - - "help" # Short usage message - ); - return 0 if defined($opt_help); - - $pgsz = $opt_pgsize || $pgsz; - if (defined($opt_nodepage)) { - $hdsz = 0; - $ftsz = 0; - } else { - $hdsz = $opt_topm if defined($opt_topm); - $ftsz = $opt_botm if defined($opt_botm); - } - $txsz = $pgsz - ($hdsz + $ftsz); - $leftmsz = $opt_leftm if defined($opt_leftm); - $leftm = ' ' x $leftmsz; - - $Bare = defined($opt_bare); - $Compress = defined($opt_compress); - $K = defined($opt_k); - $NoDepage = defined($opt_nodepage); - $NoHeads = defined($opt_noheads); - $SeeAlso = defined($opt_seealso); - $Solaris = defined($opt_solaris); - $Sun = defined($opt_sun); - - $Title = $opt_title || $Title; - $CgiUrl = $opt_cgiurlexp || - ($opt_cgiurl ? qq{return "$opt_cgiurl"} : ''); - - $BTag = $opt_belem || $BTag; - $UTag = $opt_uelem || $UTag; - $BTag =~ s/[<>]//g; - $UTag =~ s/[<>]//g; - - if (defined($opt_headmap)) { - require $opt_headmap or warn "Unable to read $opt_headmap\n"; - } - 1; -} - -##--------------------------------------------------------------------------- -sub printhead { - print $OutFH "\n"; - print $OutFH "\n", - "$Title\n", - "\n" if $Title; - print $OutFH "\n"; - print $OutFH "

$Title

\n", - "
\n" if $Title; -} - -##--------------------------------------------------------------------------- -sub printtail { - print $OutFH < -
-Man(1) output converted with -man2html -
- - -EndOfRef -} - -##--------------------------------------------------------------------------- -sub emphasize { - my($txt) = shift; - $txt =~ s/.\010//go; - $txt = "<$UTag>$txt"; - $txt; -} - -##--------------------------------------------------------------------------- -sub strongize { - my($txt) = shift; - $txt =~ s/.\010//go; - $txt = "<$BTag>$txt"; - $txt; -} - -##--------------------------------------------------------------------------- -sub entitize { - my($txt) = shift; - - ## Check for special characters in overstrike text ## - $$txt =~ s/_\010\&/strike('_', '&')/geo; - $$txt =~ s/_\010/strike('_', '>')/geo; - - $$txt =~ s/(\&\010)+\&/strike('&', '&')/geo; - $$txt =~ s/(<\010)+\010)+>/strike('>', '>')/geo; - - ## Check for special characters in regular text. Must be careful - ## to check before/after character in expression because it might be - ## a special character. - $$txt =~ s/([^\010]\&[^\010])/htmlize2($1)/geo; - $$txt =~ s/([^\010]<[^\010])/htmlize2($1)/geo; - $$txt =~ s/([^\010]>[^\010])/htmlize2($1)/geo; -} - -##--------------------------------------------------------------------------- -## escape special characters in a string, in-place -## -sub htmlize { - my($str) = shift; - $$str =~ s/&/\&/g; - $$str =~ s//\>/g; - $$str; -} - -##--------------------------------------------------------------------------- -## htmlize2() is used by entitize. -## -sub htmlize2 { - my($str) = shift; - $str =~ s/&/\&/g; - $str =~ s//\>/g; - $str; -} - -##--------------------------------------------------------------------------- -## strike converts HTML special characters in overstriked text -## into entity references. The entities are overstriked so -## strongize() and emphasize() will recognize the entity to be -## wrapped in tags. -## -sub strike { - my($w, $char) = @_; - my($ret); - if ($w eq '_') { - if ($char eq '&') { - $ret = "_$bs\&_${bs}a_${bs}m_${bs}p_${bs};"; - } elsif ($char eq '<') { - $ret = "_$bs\&_${bs}l_${bs}t_${bs};"; - } elsif ($char eq '>') { - $ret = "_$bs\&_${bs}g_${bs}t_${bs};"; - } else { - warn qq|Unrecognized character, "$char", passed to strike()\n|; - } - } else { - if ($char eq '&') { - $ret = "\&$bs\&a${bs}am${bs}mp${bs}p;${bs};"; - } elsif ($char eq '<') { - $ret = "\&$bs\&l${bs}lt${bs}t;${bs};"; - } elsif ($char eq '>') { - $ret = "\&$bs\&g${bs}gt${bs}t;${bs};"; - } else { - warn qq|Unrecognized character, "$char", passed to strike()\n|; - } - } - $ret; -} - -##--------------------------------------------------------------------------- -## make_xref() converts a manpage crossreference into a hyperlink. -## -sub make_xref { - my $str = shift; - $str =~ s/.\010//go; # Remove overstriking - - if ($CgiUrl) { - my($title,$section,$subsection) = - ($str =~ /([\+_\.\w-]+)\((\d)(\w?)\)/); - - $title =~ s/\+/%2B/g; - my($href) = (eval $CgiUrl); - qq|$str|; - } else { - qq|$str|; - } -} - -##--------------------------------------------------------------------------- -## man_k() process a keyword search. The problem we have is there -## is no standard for keyword search results from man. Solaris -## systems have a different enough format to warrent dealing -## with it as a special case. For other cases, we try our best. -## Unfortunately, there are some lines of results that may be -## skipped. -## -sub man_k { - my($line,$refs,$section,$subsection,$desc,$i, - %Sec1, %Sec1sub, %Sec2, %Sec2sub, %Sec3, %Sec3sub, - %Sec4, %Sec4sub, %Sec5, %Sec5sub, %Sec6, %Sec6sub, - %Sec7, %Sec7sub, %Sec8, %Sec8sub, %Sec9, %Sec9sub, - %SecN, %SecNsub, %SecNsec); - - printhead() unless $Bare; - print $OutFH "\n"; - - while ($line = <$InFH>) { - next if $line !~ /\(\d\w?\)\s+-\s/; # check if line can be handled - ($refs,$section,$subsection,$desc) = - $line =~ /^\s*(.*)\((\d)(\w?)\)\s*-\s*(.*)$/; - - if ($Solaris) { - $refs =~ s/^\s*([\+_\.\w-]+)\s+([\+_\.\w-]+)\s*$/$1/; - # - } else { - $refs =~ s/\s(and|or)\s/,/gi; # Convert and/or to commas - $refs =~ s/^[^:\s]:\s*//; # Remove prefixed whatis path - } - $refs =~ s/\s//g; # Remove all whitespace - $refs =~ s/,/, /g; # Put space after comma - htmlize(\$desc); # Check for special chars in desc - $desc =~ s/^(.)/\U$1/; # Uppercase first letter in desc - - if ($section eq '1') { - $Sec1{$refs} = $desc; $Sec1sub{$refs} = $subsection; - } elsif ($section eq '2') { - $Sec2{$refs} = $desc; $Sec2sub{$refs} = $subsection; - } elsif ($section eq '3') { - $Sec3{$refs} = $desc; $Sec3sub{$refs} = $subsection; - } elsif ($section eq '4') { - $Sec4{$refs} = $desc; $Sec4sub{$refs} = $subsection; - } elsif ($section eq '5') { - $Sec5{$refs} = $desc; $Sec5sub{$refs} = $subsection; - } elsif ($section eq '6') { - $Sec6{$refs} = $desc; $Sec6sub{$refs} = $subsection; - } elsif ($section eq '7') { - $Sec7{$refs} = $desc; $Sec7sub{$refs} = $subsection; - } elsif ($section eq '8') { - $Sec8{$refs} = $desc; $Sec8sub{$refs} = $subsection; - } elsif ($section eq '9') { - $Sec9{$refs} = $desc; $Sec9sub{$refs} = $subsection; - } else { # Catch all - $SecN{$refs} = $desc; $SecNsec{$refs} = $section; - $SecNsub{$refs} = $subsection; - } - } - print_mank_sec(\%Sec1, 1, \%Sec1sub); - print_mank_sec(\%Sec2, 2, \%Sec2sub); - print_mank_sec(\%Sec3, 3, \%Sec3sub); - print_mank_sec(\%Sec4, 4, \%Sec4sub); - print_mank_sec(\%Sec5, 5, \%Sec5sub); - print_mank_sec(\%Sec6, 6, \%Sec6sub); - print_mank_sec(\%Sec7, 7, \%Sec7sub); - print_mank_sec(\%Sec8, 8, \%Sec8sub); - print_mank_sec(\%Sec9, 9, \%Sec9sub); - print_mank_sec(\%SecN, 'N', \%SecNsub, \%SecNsec); - - printtail() unless $Bare; -} -##--------------------------------------------------------------------------- -## print_mank_sec() prints out manpage cross-refs of a specific section. -## -sub print_mank_sec { - my($sec, $sect, $secsub, $secsec) = @_; - my(@array, @refs, $href, $item, $title, $subsection, $i, $section, - $xref); - $section = $sect; - - @array = sort keys %$sec; - if ($#array >= 0) { - print $OutFH "

Section $section

\n", - "
\n"; - foreach $item (@array) { - @refs = split(/,/, $item); - $section = $secsec->{$item} if $sect eq 'N'; - $subsection = $secsub->{$item}; - if ($CgiUrl) { - ($title = $refs[0]) =~ s/\(\)//g; # watch out for extra ()'s - $xref = eval $CgiUrl; - } - print $OutFH "
\n"; - $i = 0; - foreach (@refs) { - if ($CgiUrl) { - print $OutFH qq|$_|; - } else { - print $OutFH $_; - } - print $OutFH ", " if $i < $#refs; - $i++; - } - print $OutFH " ($section$subsection)\n", - "
\n", - $sec->{$item}, "
\n"; - } - print $OutFH "
\n"; - } -} - -##--------------------------------------------------------------------------- -## -sub usage { - print $OutFH < outfile -Options: - -bare : Do not put in HTML, HEAD, BODY tags - -belem : HTML Element for overstriked text (def: "B") - -botm <#> : Number of lines for bottom margin (def: 7) - -cgiurl : URL for linking to other manpages - -cgiurlexp : Perl expression URL for linking to other manpages - -compress : Compress consective blank lines - -headmap : Filename of user section head map file - -help : This message - -k : Process a keyword search result - -leftm <#> : Character width of left margin (def: 0) - -nodepage : Do not remove pagination lines - -noheads : Turn off section head detection - -pgsize <#> : Number of lines in a page (def: 66) - -seealso : Link to other manpages only in the SEE ALSO section - -solaris : Process keyword search result in Solaris format - -sun : Section heads are not overstriked in input - -title : Title of manpage (def: Not defined) - -topm <#> : Number of lines for top margin (def: 7) - -uelem : HTML Element for underlined text (def: "I") - -Description: - $PROG takes formatted manpages from STDIN and converts it to HTML sent - to STDOUT. The -topm and -botm arguments are the number of lines to the - main body text and NOT to the running headers/footers. - -Version: - $VERSION - Copyright (C) 1995-1997 Earl Hood, ehood\@medusa.acs.uci.edu - $PROG comes with ABSOLUTELY NO WARRANTY and $PROG may be copied only - under the terms of the GNU General Public License, which may be found in - the $PROG distribution. - -EndOfUsage - exit 0; -} diff --git a/doc/man2html.M b/doc/man2html.M deleted file mode 100644 index 537d6073b..000000000 --- a/doc/man2html.M +++ /dev/null @@ -1,761 +0,0 @@ -.\" sccsid = "@(#) man2html.1 1.2 08/12/97" -.\" -.\" ================================================ -.\" ARGUMENT MACRO: .Ar "arg" [B] -.de Ar -.ie \\$2B \%\fB\\$1\fR -.el \%\fI\\$1\fR -.. -.\" ================================================ -.\" BRACKETED ARGUMENT MACRO: .Br "arg" [B] -.de Br -.ie \\$2B \%[\|\fB\\$1\fR\|] -.el \%[\|\fI\\$1\fR\|] -.. -.\" ================================================ -.\" OPTION FLAG MACRO .Of -x [arg] -.de Of -.ie \\n(.$==1 \%[\|\fB\\$1\fR\|] -.el .if \\n(.$==2 \%[\|\fB\\$1\fR\0\fI\fI\\$2\fR\|] -.. -.\" ================================================ -.\" SYNOPSIS START MACRO -.de Ss .Ss name -.na -.nr aA \w\\$1\\0u -.in +\\n(aAu -'ti -\\n(aAu -.ta \\n(aAu -\&\fB\\$1\fR\t\c -.. -.\" ================================================ -.\" SYNOPSIS END MACRO -.de Se .Se -.ad -.in -.. -.\" ================================================ -.\" -.\" -.TH MAN2HTML 1 "97/08/12" -.SH NAME -.na -man2html \- convert UNIX nroff(1) manual pages to HTML format -.SH SYNOPSIS -.na -.Ss man2html -.Of -bare -.Of -belem name -.Of -botm lines -.Of -cgiurl string -.Of -cgiurlexp expr -.Of -compress -.Of -headmap mapfile -.Of -help -.Of -k -.Of -leftm chars -.Of -nodepage -.Of -noheads -.Of -pgsize lines -.Of -seealso -.Of -solaris -.Of -sun -.Of -title string -.Of -topm lines -.Of -uelem name -.Se -.sp 2 -Typical Usage: -.sp -.Ss man2html -.Of -options -.BI "\0<\0" infile -.BI "\0\0>\0" outfile -.Se -.sp -.B man -.I topic -.B | man2html -.Of -options -.BI "\0>\0" outfile -.\" -.SH DESCRIPTION -.na -The -.B man2html -filter reads formatted nroff text from standard input -.RI ( stdin ) -and writes a \s-1HTML\s+1 document to standard output -.RI ( stdout ). -.LP -The formatted nroff output is surrounded with -.B \s-1
\s+1
-tags with the following exceptions/additions:
-.RS 4n
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	Section heads are wrapped in \s-1HTML\s+1
-.I header
-tags.
-See the
-.B "\s-1SECTION\ HEAD\ MAP\ FILE\s+1"
-section below for additional information.
-The
-.B \%-noheads
-option can be used to disable this feature.
-.ad
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	Bold words designated by a \%""
-sequences are wrapped in
-.B \s-1\s+1
-tags (or the element specified via the
-.B \%-belem
-option).
-.ad
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	Underlined words designated by a \%"_"
-sequences are wrapped in
-.B \s-1\s+1
-tags (or the element specified via the
-.B \%-uelem
-option).
-.ad
-.RE
-.SH OPTIONS
-.na
-.TP 0.5i
-.B -bare
-This option will eliminate \s-1HTML\s+1
-.B \s-1\s+1
-and
-.B \s-1\s+1
-tags from the output.
-This is useful when you wish to incorporate the output into another
-\s-1HTML\s+1 document.
-.TP 0.5i 
-.BI -belem\0 name
-Use
-.I name
-as the name of the element to wrap overstriken characters.
-The default is \fBB\fR.
-.TP 0.5i 
-.BI -botm\0 lines
-The
-.I lines
-argument specifies the number of lines representing the bottom
-margin of the formatted nroff input.
-The line count includes any running footers.
-The default value is 7.
-.TP 0.5i
-.BI -cgiurl\0 string
-The
-.I string
-argument specifies a template \s-1URL\s+1 for creating links to other manpages.
-See the
-.B "\s-1LINKING\ TO\ OTHER\ MANPAGES\s+1"
-section below for additional information.
-.TP 0.5i
-.BI -cgiurlexp\0 expr
-The
-.I expr
-argument specifies a Perl expression evaluting to a \s-1URL\s+1 for
-creating links to other manpages.
-See the
-.B "\s-1LINKING\ TO\ OTHER\ MANPAGES\s+1"
-section below for additional information.
-.TP 0.5i
-.B -compress
-Compress consecutive blank lines into a single line.
-.TP 0.5i
-.BI -headmap\0 mapfile
-The
-.I mapfile
-argument is read to determine which \s-1HTML\s+1
-header tags are to be used for various section heading in the manpage.
-See the
-.B "\s-1SECTION\ HEAD\ MAP\ FILE\s+1"
-section below for information on the format of the map file.
-.TP 0.5i
-.B -help
-Print out a short usage message and then exit immediately.
-.TP 0.5i
-.B -k
-Process input resulting from a manpage keyword search
-.RB ( "man\ -k" ).
-See the
-.B "\s-1KEYWORD\ SEARCH\s+1"
-section below for additional information.
-.TP 0.5i
-.BI -leftm\0 chars
-The
-.I chars
-argument specifies the width of the number of characters making
-up the left margin of the formatted nroff input.
-The default value is 0.
-.TP 0.5i
-.B -nodepage
-By default,
-.B man2html
-merges multi-page formatted nroff into a single page.
-This option may be used to disable depagination, causing
-running headers and footers in the formatted nroff input
-to be carried over into the \s-1HTML\s+1 output.
-.TP 0.5i
-.B -noheads
-By default,
-.B man2html
-wraps section heads in \s-1HTML\s+1
-header tags.
-See the
-.B "\s-1SECTION\ HEAD\ MAP\ FILE\s+1"
-section below for additional information.
-This option may be specified to disabled this feature.
-.TP 0.5i
-.BI -pgsize\0 lines
-The
-.I lines
-argument specifies the number of lines making up the page size (length)
-of the formatted nroff input.
-The default value is 66.
-.TP 0.5i
-.B -seealso
-If the
-.B -cgiurl
-option has been specified, then this option restricts the
-creation of links to other manual pages to the
-.B "\%\s-1SEE\ ALSO\s+1"
-section only.
-.TP 0.5i
-.B -solaris
-If the
-.B -k
-option has been specified, then this option modifies its operation
-to process the alternate manual page keyword search format produced
-by the
-.BR man (1)
-utility on systems running
-.IR Solaris .
-See the
-.B "\s-1KEYWORD\ SEARCH\s+1"
-section below for additional information.
-.TP 0.5i
-.B -sun
-Do not require a section head to have bold overstriking in the
-formatted nroff input.
-The option is called
-.B \%sun
-because it was on a Sun workstation that section heads in
-manpages were found to not be overstruck.
-.TP 0.5i
-.BI -title\0 string
-By default,
-.B man2html
-does not generate a \s-1HTML\s+1 title
-.RB ( \s-1\s+1 ).
-This option sets the title of the \s-1HTML\s+1 output to the specified
-.IR string .
-.TP 0.5i
-.BI -topm\0 lines
-The
-.I lines
-argument specifies number number of lines representing the
-top margin of the formatted nroff input.
-The line count includes any running headers.
-The default value is 7.
-.TP 0.5i 
-.BI -uelem\0 name
-Use
-.I name
-as the name of the element to wrap underscored characters.
-The default is \fBI\fR.
-.\"
-.SH "SECTION HEAD MAP FILE"
-.na
-.LP
-The
-.B \%-headmap
-option may be used to customize which \s-1HTML\s+1 header tags,
-.BR "\s-1<H1>\s+1 ... \s-1<H6>\s+1" ,
-are used in manpage section headings.
-Normally,
-.B man2html
-treats lines that are flush to the left margin
-.RB ( -leftm ),
-and contain overstriking (overstrike check is canceled with the
-.B -sun
-option), as section heads.
-However, you can augment/override what \s-1HTML\s+1 header tags are used for
-any given section head.
-.LP
-In order to write a section head map file, you will need to know about
-.BR perl (1)
-associative arrays.
-You do not need to be an expert in
-.B perl
-to write a map file, however, having knowledge of
-.B perl
-allows you to be more clever.
-.\"
-.SS "Augmenting the Default Map" 
-.LP
-To add to the default mapping defined by
-.BR man2html ,
-your map file will contain lines with the following syntax:
-.sp
-.if t .RS 4n
-.B "$SectionHead{'<section head text>'} = '<html header tag>';"
-.if t .RE
-.sp
-where
-.IP "\fB\%<section\ head\ text>\fR"
-is the text of the manpage section head.
-For example:
-.B  \s-1SYNOPSIS\s+1
-or
-.BR \s-1DESCRIPTION\s+1 .
-.IP "\fB\%<html\ header\ tag>\fR"
-is the \s-1HTML\s+1 header tag to wrap the section head in.
-Legal values are:
-.BR \s-1<H1>\s+1 ,
-.BR \s-1<H2>\s+1 ,
-.BR \s-1<H3>\s+1 ,
-.BR \s-1<H4>\s+1 ,
-.BR \s-1<H5>\s+1 ,
-.BR \s-1<H6>\s+1 .
-.SS "Overriding the Default Map"
-To override the default mapping with your own, then your map file will
-have the following syntax:
-.sp
-.RS 4n
-.ft B
-.nf
-.ne 6v
-%SectionHead = (
-         \&'<section head text>', '<html header tag>',
-         \&'<section head text>', '<html header tag>',
-         \&# ... More section head/tag pairs
-         \&'<section head text>', '<html header tag>',
-);
-.fi
-.ft
-.RE
-.SS "The Default Map"
-.LP
-As of this writing, this is the default map used by
-.BR man2html :
-.RS 4n
-.sp
-.ft C
-.nf
-.ne 29v
-%SectionHead = (
-.ps -1
-    \&'\\S.*OPTIONS.*'             => '<H2>',
-    \&'AUTHORS?'                  => '<H2>',
-    \&'BUGS'                      => '<H2>',
-    \&'COMPATIBILITY'             => '<H2>',
-    \&'DEPENDENCIES'              => '<H2>',
-    \&'DESCRIPTION'               => '<H2>',
-    \&'DIAGNOSTICS'               => '<H2>',
-    \&'ENVIRONMENT'               => '<H2>',
-    \&'ERRORS'                    => '<H2>',
-    \&'EXAMPLES'                  => '<H2>',
-    \&'EXTERNAL INFLUENCES'       => '<H2>',
-    \&'FILES'                     => '<H2>',
-    \&'LIMITATIONS'               => '<H2>',
-    \&'NAME'                      => '<H2>',
-    \&'NOTES?'                    => '<H2>',
-    \&'OPTIONS'                   => '<H2>',
-    \&'REFERENCES'                => '<H2>',
-    \&'RETURN VALUE'              => '<H2>',
-    \&'SECTION.*:'                => '<H2>',
-    \&'SEE ALSO'                  => '<H2>',
-    \&'STANDARDS CONFORMANCE'     => '<H2>',
-    \&'STYLE CONVENTION'          => '<H2>',
-    \&'SYNOPSIS'                  => '<H2>',
-    \&'SYNTAX'                    => '<H2>',
-    \&'WARNINGS'                  => '<H2>',
-    \&'\\s+Section.*:'             => '<H3>',
-.ps +1
-);
-$HeadFallback = '\s-1<H2>\s+1';  # Fallback tag if above is not found.
-.fi
-.ft
-.RE
-.LP
-Check the
-.B perl
-source code of
-.B man2html
-for the latest default mapping.
-.LP 
-You can reassign the
-.B \%$HeadFallback
-variable to a different value if you choose.
-This value is used as the header tag of a section head if
-no matches are found in the \%\fB%SectionHead\fR map.
-.SS "Using Regular Expressions in the Map File"
-.LP
-You may have noticed unusual characters in the default map file, like
-"\\s" or "*".
-The
-.B man2html
-utility actual treats the
-.B "\%<section\ head\ text>"
-as a
-.B perl
-regular expression.
-If you are comfortable with
-.B perl
-regular expressions, then you have their full power to use
-in your map file.
-.LP
-.I Caution:
-The
-.B man2html
-utility already anchors the regular expression to the beginning of the
-line with left margin spacing specified by the
-.B \%-leftm
-option.
-Therefore, do not use the `\fB\fR^' character to anchor your regular
-expression to the beginning.
-However, you may end your expression with a `\fB$\fR' to anchor it to
-the end of the line.
-.LP 
-Since the
-.B "\%<section\ head\ text>"
-is actually a regular expression, you will have to be careful of
-special characters if you want them to be treated literally.
-Any of the characters
-.RB ` "[ ] ( ) . ^ { } $ * ? + \\ |" '
-should be escaped by prefixing them by the
-\&`\fB\\\fR' character if you want
-.B perl
-to treat them "as is".
-.LP
-.I Caution:
-One should use single quotes instead of double quotes to delimit
-.BR "\%<section\ head\ text>" .
-This will preserve any `\fB\\\fR' characters for character escaping
-or when the `\fB\\\fR' is used for special
-.B perl
-character matching sequences (e.g.,  \fB\\s\fR, \fB\\w\fR, \fB\\S\fR).
-.SS "Other Tid-bits on the Map File"
-.LP
-Comments can be inserted in the map file by using the '\fB#\fR'
-character.
-Anything after, and including, the '\fB#\fR' character is ignored,
-up to the end of line.
-.LP 
-You might be thinking that the above is quite-a-bit-of-stuff just for
-doing manpage section heads.
-However, you will be surprised how much better the \s-1HTML\s+1 output looks
-with header tags, even though, everything else is in a
-.B \s-1<PRE>\s+1
-tag.
-.\"
-.SH "LINKING TO OTHER MANPAGES"
-.na
-.LP 
-The
-.B man2html
-utility allows the ability to link to other manpage references.
-If the
-.B \%-cgiurl
-option is specified,
-.B man2html
-will create anchors that link to other manpages.
-.LP 
-The \s-1URL\s+1 entered with the
-.B \%-cgiurl
-option is actually a template that determines the actual \s-1URL\s+1 used to
-link to other manpages.
-The following variables are defined during run time that may be used in
-the template string:
-.sp
-.RS 4n
-.IP \fB$title\fR
-The title of the manual page referenced.
-.IP \fB$section\fR
-The section number of the manual page referenced.
-.IP \fB$subsection\fR
-The subsection of the manual page referenced.
-.RE
-.LP
-Any other text in the template is preserved "as is".
-.LP
-.I Caution:
-The
-.B man2html
-utility evaluates the template string as a
-.B perl
-string expression.
-Therefore, one might need to surround the variable names with
-\&'\fB{\|}\fR' (e.g.,
-.BR ${\|title\|}\| )
-so that
-.B man2html
-properly recognizes the variable.
-.LP
-.I Note:
-If a \s-1CGI\s+1 program calling
-.B man2html
-is actually a shell script or a
-.B perl
-program, make sure to properly escape the '\fB$\fR' character
-in the \s-1URL\s+1 template to avoid variable interpolation by the \s-1CGI\s+1
-program.
-.LP
-Normally, the \s-1URL\s+1 calls a \s-1CGI\s+1 program (hence the option name),
-but the \s-1URL\s+1 can easily link to statically converted documents.
-.SS "Example1:"
-.LP 
-The following template string is specified to call a \s-1CGI\s+1 program to
-retrieve the appropriate manpage linked to:
-.LP
-.nf
-.B "/cgi-bin/man.cgi?section=${section}${subsection}&topic=${title}"
-.fi
-.LP 
-If the
-.BR ls (1)
-manpage is referenced in the
-.B "SEE ALSO"
-section, the above template will translate to the following \s-1URL\s+1:
-.LP
-.B "/cgi-bin/man.cgi?section=1&topic=ls"
-.LP 
-The actual \s-1HTML\s+1 markup will look like the following:
-.LP
-\fB<A\ HREF="/cgi-bin/man.cgi?section=1&topic=ls">ls(1)</A>\fR
-.SS "Example2:"
-.LP 
-The following template string is specified to retrieve pre-converted
-manpages:
-.LP
-.B "http://foo.org/man$section/$title.$section$subsection.html"
-.LP 
-If the
-.BR mount (1M)
-manpage is referenced, the above template will translate to the
-following \s-1URL\s+1:
-.LP
-.B "http://foo.org/man1/mount.1M.html"
-.LP 
-The actual \s-1HTML\s+1 markup will look like the following:
-.LP
-\fB<A HREF="http://foo.org/man1/mount.1M.html">mount(1M)</A>\fR
-.SS "-cgiurlexp"
-The option
-.B \%-cgiurlexp
-is a more general form of the
-.B \%-cgiurl
-option.
-.B \%-cgiurlexp
-allows one to specify a general Perl expression.  For example:
-.LP
-\fB$title=~/^db_/i?"$title.html":"/cgi-bin/man?$title+$section"\fR
-.LP
-A
-.B \%-cgiurl
-.I string
-can be expressed as follows with \fB-cgiurlexp\fR:
-.LP
-\fBreturn "\fIstring\fB"\fR
-.\"
-.SH "KEYWORD SEARCH"
-.na
-.LP
-The
-.B man2html
-utility has the ability to process keyword search output generated
-by the \%\fBman\ -k\fR or \%\fBapropos\fR commands, through the
-use of the
-.B -k
-option.
-The
-.B man2html
-utility will generate an \s-1HTML\s+1 document of the keyword search input
-having the following format:
-.RS 4n 
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	All manpage references are listed by section.
-.ad
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	Within each section listing, the manpage references
-are sorted alphabetically (case-sensitive) in a
-.B \s-1<DL>\s+1
-tag.
-The manpage references are listed in the
-.B \s-1<DT>\s+1
-section, and the summary text is listed in the
-.B \s-1<DD>\s+1
-section.
-.ad
-.LP
-.na
-'ti -2n
-'ta  2n
-\(bu	Each manpage reference listed is a hyperlink to the
-actual manpage as specified by the
-.B \%-cgiurl
-option.
-.ad
-.RE
-.LP 
-.na
-This ability to process keyword searches gives nice added functionality
-to a \s-1WWW\s+1 forms interface to
-.BR man (1).
-Even if you have statically converted manpages to \s-1HTML\s+1 via another
-man->\s-1HTML\s+1 program, you can use
-.B man2html
-and "\fBman\ -k\fR" to provide keyword search capabilities easily for
-your \s-1HTML\s+1 manpages.
-.SS "Processing Keyword Search Results"
-.na
-.LP 
-Unfortunately, there is no standard controlling the format of keyword
-search results.
-The
-.B man2html
-utility tries it best to handle all the variations.
-However, the keyword search results generated by the
-.I Solaris
-operating system is different enough from other systems that a
-special command-line option
-.RB ( -solaris )
-must be specified to handle its output.
-.SS "Example of raw Solaris-type keyword search results:"
-.LP
-.ft C
-.nf
-.ne 10v
-strcpy        strcpy (9f)  - copy a string from one location to another.
-strcpy        string (3c)  - string operations
-strncpy       strcpy (9f)  - copy a string from one location to another.
-strncpy       string (3c)  - string operations
-.fi
-.ft
-.LP 
-If keyword search results on your systems appear in the following format:
-.LP
-.RS 4n
-.B "<topic>  <actual_manpage> (#) - Description"
-.RE
-.LP
-then you need to specify the
-.B \%-solaris
-option in addition to the
-.B -k
-option.
-.SH "ADDITIONAL NOTES"
-.na
-.LP
-Different systems format manpages differently.
-Here is a list of recommended command-line options for certain systems:
-.RS 4n
-.LP
-.ta 1i
-.nf
-.ne 3v
-\fBConvex\fR:	<defaults should be okay>
-\fBHP\fR:	\fB-leftm 1 -topm 8\fR
-\fBSun\fR:	\fB-sun\fR (and \fB-solaris\fR when using \fB-k\fR)
-.fi
-.RE
-.LP
-Some line spacing gets lost in the formatted nroff since the
-spacing would occur in the middle of a page break.
-This can cause text to be merged that shouldn't be merged when
-.B man2html
-depaginates the text.
-To avoid this problem,
-.B man2html
-keeps track of the margin indent right before and after a page break.
-If the margin width of the line after the page break is less than the
-line before the page break, then
-.B man2html
-inserts a blank line in the \s-1HTML\s+1 output.
-.LP 
-A manpage cross-reference is detected by the following pseudo expression:
-\%\fB[A-z.-+_]+([0-9][A-z]?)\fR
-.LP
-The
-.B man2html
-utility only recognizes lines with "\fB - \fR" (the normal separator
-between manpage references and summary text) while in keyword
-search mode.
-.LP 
-The
-.B man2html
-utility can be hooked in a \s-1CGI\s+1 script/program to convert manpages
-on the fly.
-This is the reason for the
-.B \%-cgiurl
-option.
-.SH LIMITATIONS
-.na
-.LP 
-The order that section head mapping is searched is not defined.
-Therefore, if two or more
-.B "\%<section\ head\ text>"
-can match a give manpage section, there is no way to determine
-which map tag is chosen.
-.LP 
-If
-.B \%-seealso
-is specified, all xrefs are detected after the
-.B "\%SEE\ ALSO"
-heading.
-In other words, sections after
-.B "\%SEE\ ALSO"
-may contain hyperlinked xrefs.
-.SH BUGS
-.na
-.LP 
-Text that is flush to the left margin, but is not actually a
-section head, can be mistaken for a section head.
-This mistake is more likely when the
-.B \%-sun
-option is in affect.
-.SH VERSION
-.na
-This documentation describes
-.B man2html
-version 3.0.1
-.SH "SEE ALSO"
-.na
-.BR man (1),
-.BR nroff (1),
-.BR perl (1)
-.LP
-.I http://www.oac.uci.edu/indiv/ehood/man2html.html
-.SH AUTHOR
-.LP
-.B Earl Hood
-.br
-.I ehood@medusa.acs.uci.edu
-.\"
-.SH "ERRORS AND OMISSIONS"
-.na
-Troff version of this document initially created for version 2.1.0
-by C. Jeffery Small
-.RI ( jeff@cjsa.com )
-by copying, reformatting, rearranging and partially rewriting
-the contents of the ascii text file
-.BR doc/man2html.txt .
diff --git a/doc/man2ps b/doc/man2ps
deleted file mode 100644
index 06240e07c..000000000
--- a/doc/man2ps
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-com=`basename $0`
-files=$*
-ROFF=groff
-ROFF_FLAGS="-C -man -Tps"
-CSPLIT=
-
-IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}:"
-for i in $PATH; do
-  if [ -f $i/gcsplit ]; then
-	CSPLIT=$i/gcsplit
-	break
-  fi
-  if [ -f $i/csplit ]; then
-	CSPLIT=$i/csplit
-	break
-  fi
-done
-IFS="$save_ifs"
-
-if [ "$files" = "" ]; then
-    echo "Usage: $com file [file2 ...]"
-    exit 1
-fi
-
-for file in $files
-do
-    filename=`basename $file | awk -F. '{print $1}'`
-    eval $ROFF $ROFF_FLAGS $file > $filename.ps
-
-    pages=`grep '%%Pages\:' $filename.ps | awk '{print $2}'`
-    pp=`expr $pages - 1`
-
-    echo $filename': '$pages' pages'
-
-    if [ "$CSPLIT"x != x ]; then
-        $CSPLIT -k $filename.ps /Page:/ \{$pp\} > /dev/null
-
-        counter=0
-
-        for number in `ls xx*`
-        do
-            cat xx00 > $filename$counter.ps
-            echo '0.85 dup scale' >> $filename$counter.ps
-            cat $number >> $filename$counter.ps
-            if [ $counter != $pages ];
-                then
-                echo '%%Trailer' >> $filename$counter.ps
-                echo 'end' >> $filename$counter.ps
-                echo '%%EOF' >> $filename$counter.ps
-            fi
-            counter=`expr $counter + 1`
-        done
-
-        rm $filename.ps $filename'0.ps' xx*
-    else
-        echo "Can't find the csplit command.  You'll have to split $filename.ps manually."
-    fi
-done
diff --git a/doc/man2ps.M b/doc/man2ps.M
deleted file mode 100644
index d9c79032b..000000000
--- a/doc/man2ps.M
+++ /dev/null
@@ -1,50 +0,0 @@
-.TH MAN2PS 1
-.SH NAME
-man2ps \- create individual PostScript files for each page of a man page
-.SH SYNOPSIS
-.B man2ps
-.I file
-[\fIfile2\fP [\fI...\fP]]
-.SH DESCRIPTION
-.B man2ps
-is a bourne shell script that turns a man page into a set of PostScript
-files, for inclusion in a document.
-.B man2ps
-converts the man page to a PostScript file using
-.IR groff (1), 
-and then uses the
-.IR csplit (1)
-command to split the file into individual pages.
-.B man2ps
-inserts the PostScript command:
-.sp
-.nf
-.in +.5i
-\&0.85 dup scale
-.in -.5i
-.fi
-.sp
-at the beginning of each page, so that the pages will fit onto an
-8.5"x11" page.
-.PP
-The files created by
-.B man2ps
-have the same name as the command, with a sequential number and the
-string ".ps" appended.  For example, running
-.B man2ps
-on the file "kinit.M" would produce the PostScript files "kinit1.ps",
-"kinit2.ps", ...
-.SH SEE ALSO
-troff(1), csplit(1)
-.SH BUGS
-.B man2ps
-requires the user to have
-.I groff
-and either
-.I csplit
-or
-.I gcsplit
-in her path.
-.SH AUTHORS
-.B man2ps
-was written by Jeff Bigler at Cygnus Support and Theodore Ts'o at MIT.
diff --git a/doc/old-V4-docs/.Sanitize b/doc/old-V4-docs/.Sanitize
deleted file mode 100644
index d36248c95..000000000
--- a/doc/old-V4-docs/.Sanitize
+++ /dev/null
@@ -1,36 +0,0 @@
-# Sanitize.in for Kerberos V5
-
-# Each directory to survive it's way into a release will need a file
-# like this one called "./.Sanitize".  All keyword lines must exist,
-# and must exist in the order specified by this file.  Each directory
-# in the tree will be processed, top down, in the following order.
-
-# Hash started lines like this one are comments and will be deleted
-# before anything else is done.  Blank lines will also be squashed
-# out.
-
-# The lines between the "Do-first:" line and the "Things-to-keep:"
-# line are executed as a /bin/sh shell script before anything else is
-# done in this 
-
-Do-first:
-
-# All files listed between the "Things-to-keep:" line and the
-# "Files-to-sed:" line will be kept.  All other files will be removed.
-# Directories listed in this section will have their own Sanitize
-# called.  Directories not listed will be removed in their entirety
-# with rm -rf.
-
-Things-to-keep:
-
-README
-installation.PS
-installation.mss
-operation.PS
-operation.mss
-
-Things-to-lose:
-
-Do-last:
-
-# End of file.
diff --git a/doc/old-V4-docs/README b/doc/old-V4-docs/README
deleted file mode 100644
index 8858655cb..000000000
--- a/doc/old-V4-docs/README
+++ /dev/null
@@ -1,4 +0,0 @@
-These documentation files are old --- and refer to the Kerberos V4 
-implementation.  They are included because the equivalent V5 documentation
-set have not been written yet, and the concepts contained in these documents
-may be helpful.
diff --git a/doc/old-V4-docs/installation.PS b/doc/old-V4-docs/installation.PS
deleted file mode 100644
index 7609d4e64..000000000
--- a/doc/old-V4-docs/installation.PS
+++ /dev/null
@@ -1,2338 +0,0 @@
-%!PS-Adobe-2.0
-%%Title: installation.mss
-%%DocumentFonts: (atend)
-%%Creator: John T Kohl,,E40-351M,31510,6176432831 and Scribe 7(1700)
-%%CreationDate: 4 January 1990 11:56
-%%Pages: (atend)
-%%EndComments
-% PostScript Prelude for Scribe.
-/BS {/SV save def 0.0 792.0 translate .01 -.01 scale} bind def
-/ES {showpage SV restore} bind def
-/SC {setrgbcolor} bind def
-/FMTX matrix def
-/RDF {WFT SLT 0.0 eq 
-  {SSZ 0.0 0.0 SSZ neg 0.0 0.0 FMTX astore}
-  {SSZ 0.0 SLT neg sin SLT cos div SSZ mul SSZ neg 0.0 0.0 FMTX astore}
-  ifelse makefont setfont} bind def
-/SLT 0.0 def
-/SI { /SLT exch cvr def RDF} bind def
-/WFT /Courier findfont def
-/SF { /WFT exch findfont def RDF} bind def
-/SSZ 1000.0 def
-/SS { /SSZ exch 100.0 mul def RDF} bind def
-/AF { /WFT exch findfont def /SSZ exch 100.0 mul def RDF} bind def
-/MT /moveto load def
-/XM {currentpoint exch pop moveto} bind def
-/UL {gsave newpath moveto dup 2.0 div 0.0 exch rmoveto
-   setlinewidth 0.0 rlineto stroke grestore} bind def
-/LH {gsave newpath moveto setlinewidth
-   0.0 rlineto
-   gsave stroke grestore} bind def
-/LV {gsave newpath moveto setlinewidth
-   0.0 exch rlineto
-   gsave stroke grestore} bind def
-/BX {gsave newpath moveto setlinewidth
-   exch
-   dup 0.0 rlineto
-   exch 0.0 exch neg rlineto
-   neg 0.0 rlineto
-   closepath
-   gsave stroke grestore} bind def
-/BX1 {grestore} bind def
-/BX2 {setlinewidth 1 setgray stroke grestore} bind def
-/PB {/PV save def newpath translate
-    100.0 -100.0 scale pop /showpage {} def} bind def
-/PE {PV restore} bind def
-/GB {/PV save def newpath translate rotate
-    div dup scale 100.0 -100.0 scale /showpage {} def} bind def
-/GE {PV restore} bind def
-/FB {dict dup /FontMapDict exch def begin} bind def
-/FM {cvn exch cvn exch def} bind def
-/FE {end /original-findfont /findfont load def  /findfont
-   {dup FontMapDict exch known{FontMapDict exch get} if
-   original-findfont} def} bind def
-/BC {gsave moveto dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath clip} bind def
-/EC /grestore load def
-/SH /show load def
-/MX {exch show 0.0 rmoveto} bind def
-/W {0 32 4 -1 roll widthshow} bind def
-/WX {0 32 5 -1 roll widthshow 0.0 rmoveto} bind def
-/RC {100.0 -100.0 scale
-612.0 0.0 translate
--90.0 rotate
-.01 -.01 scale} bind def
-/URC {100.0 -100.0 scale
-90.0 rotate
--612.0 0.0 translate
-.01 -.01 scale} bind def
-/RCC {100.0 -100.0 scale
-0.0 -792.0 translate 90.0 rotate
-.01 -.01 scale} bind def
-/URCC {100.0 -100.0 scale
--90.0 rotate 0.0 792.0 translate
-.01 -.01 scale} bind def
-%%EndProlog
-%%Page: 0 1
-BS
-0 SI
-20 /Times-Bold AF
-18823 13788 MT
-(Kerberos Installation Notes)SH
-27156 15798 MT
-(DRAFT)SH
-16 /Times-Roman AF
-27021 23502 MT
-(Bill Bryant)SH
-25557 25150 MT
-(Jennifer Steiner)SH
-27289 26798 MT
-(John Kohl)SH
-23957 30444 MT
-(Project Athena, MIT)SH
-/Times-Bold SF
-19489 36042 MT
-(Initial Release, January 24, 1989)SH
-/Times-Italic SF
-17558 37690 MT
-(\050plus later patches through patchlevel 7\051)SH
-11 /Times-Roman AF
-7200 45644 MT
-(The release consists of three parts.)SH
-7200 47942 MT
-(The first part consists of the core Kerberos system, which was developed at MIT and does not require)SH
-7200 49138 MT
-(additional licenses for us to distribute.  Included in this part are the Kerberos authentication server, the)SH
-7200 50334 MT
-(Kerberos library, the)SH
-/Times-Italic SF
-16606 XM
-(ndbm)SH
-/Times-Roman SF
-19325 XM
-(database interface library, user programs, administration programs, manual)SH
-7200 51530 MT
-(pages, some applications which use Kerberos for authentication, and some utilities.)SH
-7200 53828 MT
-(The second part is the Data Encryption Standard \050DES\051 library, which we are distributing only within the)SH
-7200 55024 MT
-(United States.)SH
-7200 57322 MT
-(The third part contains Kerberos modifications to Sun's NFS, which we distribute as ``context diffs'' to)SH
-7200 58518 MT
-(the Sun NFS source code.  Its distribution is controlled to provide an accounting of who has retrieved the)SH
-7200 59714 MT
-(patches, so that Project Athena can comply with its agreements with Sun regarding distribution of these)SH
-7200 60910 MT
-(changes.)SH
-ES
-%%Page: 1 2
-BS
-0 SI
-16 /Times-Bold AF
-7200 8272 MT
-(1. Organization)
-400 W( of the Source Directory)SH
-11 /Times-Roman AF
-7200 10467 MT
-(The Kerberos building and installation process, as described in this document, builds the binaries and)SH
-7200 11663 MT
-(executables from the files contained in the Kerberos source tree, and deposits them in a separate object)SH
-7200 12859 MT
-(tree. This)
-275 W( is intended to easily support several different build trees from a single source tree \050this is useful)SH
-7200 14055 MT
-(if you support several machine architectures\051.  We suggest that you copy the Kerberos sources into a)SH
-/Times-Italic SF
-7200 15251 MT
-(/mit/kerberos/src)SH
-/Times-Roman SF
-14991 XM
-(directory, and create as well a)SH
-/Times-Italic SF
-28396 XM
-(/mit/kerberos/obj)SH
-/Times-Roman SF
-36249 XM
-(directory in which to hold the)SH
-7200 16447 MT
-(executables. In)
-275 W( the rest of this document, we'll refer to the Kerberos source and object directories as)SH
-7200 17643 MT
-([SOURCE_DIR] and [OBJ_DIR], respectively.)SH
-7200 19941 MT
-(Below is a brief overview of the organization of the complete source directory.  More detailed)SH
-7200 21137 MT
-(descriptions follow.)SH
-/Times-Bold SF
-7200 23088 MT
-(admin)SH
-/Times-Roman SF
-18200 XM
-(utilities for the Kerberos administrator)SH
-/Times-Bold SF
-7200 24783 MT
-(appl)SH
-/Times-Roman SF
-18200 XM
-(applications that use Kerberos)SH
-/Times-Bold SF
-7200 26478 MT
-(appl/bsd)SH
-/Times-Roman SF
-18200 XM
-(Berkeley's rsh/rlogin suite, using Kerberos)SH
-/Times-Bold SF
-7200 28173 MT
-(appl/knetd)SH
-/Times-Roman SF
-18200 XM
-(\050old\051 software for inetd-like multiplexing of a single TCP listening port)SH
-/Times-Bold SF
-7200 29868 MT
-(appl/sample)SH
-/Times-Roman SF
-18200 XM
-(sample application servers and clients)SH
-/Times-Bold SF
-7200 31563 MT
-(appl/tftp)SH
-/Times-Roman SF
-18200 XM
-(Trivial File Transfer Protocol, using Kerberos)SH
-/Times-Bold SF
-7200 33258 MT
-(include)SH
-/Times-Roman SF
-18200 XM
-(include files)SH
-/Times-Bold SF
-7200 34953 MT
-(kadmin)SH
-/Times-Roman SF
-18200 XM
-(remote administrative interface to the Kerberos master database)SH
-/Times-Bold SF
-7200 36648 MT
-(kuser)SH
-/Times-Roman SF
-18200 XM
-(assorted user programs)SH
-/Times-Bold SF
-7200 38343 MT
-(lib)SH
-/Times-Roman SF
-18200 XM
-(libraries for use with/by Kerberos)SH
-/Times-Bold SF
-7200 40038 MT
-(lib/acl)SH
-/Times-Roman SF
-18200 XM
-(Access Control List library)SH
-/Times-Bold SF
-7200 41733 MT
-(lib/des)SH
-/Times-Roman SF
-18200 XM
-(Data Encryption Standard library \050US only\051)SH
-/Times-Bold SF
-7200 43428 MT
-(lib/kadm)SH
-/Times-Roman SF
-18200 XM
-(administrative interface library)SH
-/Times-Bold SF
-7200 45123 MT
-(lib/kdb)SH
-/Times-Roman SF
-18200 XM
-(Kerberos server library interface to)SH
-/Times-Italic SF
-33925 XM
-(ndbm)SH
-/Times-Bold SF
-7200 46818 MT
-(lib/knet)SH
-/Times-Roman SF
-18200 XM
-(\050old\051 library for use with)SH
-/Times-Bold SF
-29349 XM
-(knetd)SH
-7200 48513 MT
-(lib/krb)SH
-/Times-Roman SF
-18200 XM
-(Kerberos library)SH
-/Times-Bold SF
-7200 50208 MT
-(man)SH
-/Times-Roman SF
-18200 XM
-(manual pages)SH
-/Times-Bold SF
-7200 51903 MT
-(prototypes)SH
-/Times-Roman SF
-18200 XM
-(sample configuration files)SH
-/Times-Bold SF
-7200 53598 MT
-(server)SH
-/Times-Roman SF
-18200 XM
-(the authentication server)SH
-/Times-Bold SF
-7200 55293 MT
-(slave)SH
-/Times-Roman SF
-18200 XM
-(Kerberos slave database propagation software)SH
-/Times-Bold SF
-7200 56988 MT
-(tools)SH
-/Times-Roman SF
-18200 XM
-(shell scripts for maintaining the source tree)SH
-/Times-Bold SF
-7200 58683 MT
-(util)SH
-/Times-Roman SF
-18200 XM
-(utilities)SH
-/Times-Bold SF
-7200 60378 MT
-(util/imake)SH
-/Times-Roman SF
-18200 XM
-(Imakefile-to-Makefile ``compilation'' tool)SH
-/Times-Bold SF
-7200 62073 MT
-(util/ss)SH
-/Times-Roman SF
-18200 XM
-(Sub-system library \050for command line subsystems\051)SH
-/Times-Bold SF
-7200 63768 MT
-(util/et)SH
-/Times-Roman SF
-18200 XM
-(Error-table library \050for independent, unique error codes\051)SH
-/Times-Bold SF
-7200 65463 MT
-(util/makedepend)SH
-/Times-Roman SF
-18200 XM
-(Makefile dependency generator tool)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(1)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 2 3
-BS
-0 SI
-14 /Times-Bold AF
-7200 8167 MT
-(1.1 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(admin)SH
-/Times-Bold SF
-16340 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 10362 MT
-(This directory contains source for the Kerberos master database administration tools.)SH
-/Times-Bold SF
-7200 12313 MT
-(kdb_init)SH
-/Times-Roman SF
-18200 XM
-(This program creates and initializes the Kerberos master database.  It prompts)SH
-18200 13509 MT
-(for a Kerberos realmname, and the Kerberos master password.)SH
-/Times-Bold SF
-7200 15204 MT
-(kstash)SH
-/Times-Roman SF
-18200 XM
-(This program ``stashes'' the master password in the file)SH
-/Times-Italic SF
-43033 XM
-(/.k)SH
-/Times-Roman SF
-44377 XM
-(so that the master)SH
-18200 16400 MT
-(server machine can restart the Kerberos server automatically after an unattended)SH
-18200 17596 MT
-(reboot. The)
-275 W( hidden password is also available to administrative programs that)SH
-18200 18792 MT
-(have been set to run automatically.)SH
-/Times-Bold SF
-7200 20487 MT
-(kdb_edit)SH
-/Times-Roman SF
-18200 XM
-(This program is a low-level tool for editing the master database.)SH
-/Times-Bold SF
-7200 22182 MT
-(kdb_destroy)SH
-/Times-Roman SF
-18200 XM
-(This program deletes the master database.)SH
-/Times-Bold SF
-7200 23877 MT
-(kdb_util)SH
-/Times-Roman SF
-18200 XM
-(This program can be used to dump the master database into an ascii file, and can)SH
-18200 25073 MT
-(also be used to load the ascii file into the master database.)SH
-/Times-Bold SF
-7200 26768 MT
-(ext_srvtab)SH
-/Times-Roman SF
-18200 XM
-(This program extracts information from the master database and creates a host-)SH
-18200 27964 MT
-(dependent)SH
-/Times-Italic SF
-22995 XM
-(srvtab)SH
-/Times-Roman SF
-26020 XM
-(file. This)
-275 W( file contains the Kerberos keys for the host's)SH
-18200 29160 MT
-(``Kerberized'' services.  These services look up their keys in the)SH
-/Times-Italic SF
-46846 XM
-(srvtab)SH
-/Times-Roman SF
-49871 XM
-(file for)SH
-18200 30356 MT
-(use in the authentication process.)SH
-14 /Times-Bold AF
-7200 34203 MT
-(1.2 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(kuser)SH
-/Times-Bold SF
-15874 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 36398 MT
-(This directory contains the source code for several user-oriented programs.)SH
-/Times-Bold SF
-7200 38349 MT
-(kinit)SH
-/Times-Roman SF
-18200 XM
-(This program prompts users for their usernames and Kerberos passwords, then)SH
-18200 39545 MT
-(furnishes them with Kerberos ticket-granting tickets.)SH
-/Times-Bold SF
-7200 41240 MT
-(kdestroy)SH
-/Times-Roman SF
-18200 XM
-(This program destroys any active tickets.  Users should use)SH
-/Times-Italic SF
-44563 XM
-(kdestroy)SH
-/Times-Roman SF
-48564 XM
-(before they)SH
-18200 42436 MT
-(log off their workstations.)SH
-/Times-Bold SF
-7200 44131 MT
-(klist)SH
-/Times-Roman SF
-18200 XM
-(This program lists a user's active tickets.)SH
-/Times-Bold SF
-7200 45826 MT
-(ksrvtgt)SH
-/Times-Roman SF
-18200 XM
-(This retrieves a ticket-granting ticket with a life time of five minutes, using a)SH
-18200 47022 MT
-(server's secret key in lieu of a password.  It is primarily for use in shell scripts)SH
-18200 48218 MT
-(and other batch facilities.)SH
-/Times-Bold SF
-7200 49913 MT
-(ksu)SH
-/Times-Roman SF
-18200 XM
-(Substitute user id, using Kerberos to mediate attempts to change to ``root''.)SH
-14 /Times-Bold AF
-7200 53760 MT
-(1.3 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(appl)SH
-/Times-Bold SF
-15173 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 55955 MT
-(If your site has the appropriate BSD license, your Kerberos release provides certain Unix utilities The)SH
-7200 57151 MT
-(Berkeley programs that have been modified to use Kerberos authentication are found in the)SH
-/Times-Italic SF
-47640 XM
-(appl/bsd)SH
-/Times-Roman SF
-7200 58347 MT
-(directory. They)
-275 W( include)SH
-/Times-Italic SF
-18043 XM
-(login)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-20855 XM
-(rlogin)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-24095 XM
-(rsh)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-27914 XM
-(rcp)SH
-/Times-Roman SF
-(, as well as the associated daemon programs)SH
-/Times-Italic SF
-49081 XM
-(kshd)SH
-/Times-Roman SF
-51372 XM
-(and)SH
-/Times-Italic SF
-7200 59543 MT
-(klogind)SH
-/Times-Roman SF
-(. The)275 W
-/Times-Italic SF
-13310 XM
-(login)SH
-/Times-Roman SF
-15847 XM
-(program obtains ticket-granting tickets for users upon login; the other utilities provide)SH
-7200 60739 MT
-(authenticated Unix network services.)SH
-7200 63037 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(appl)SH
-/Times-Roman SF
-11416 XM
-(directory also contains samples Kerberos application client and server programs, an)SH
-7200 64233 MT
-(authenticated)SH
-/Times-Italic SF
-13339 XM
-(tftp)SH
-/Times-Roman SF
-15082 XM
-(program,)SH
-/Times-Italic SF
-19358 XM
-(knetd)SH
-/Times-Roman SF
-(, an authenticated inet daemon.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(2)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 3 4
-BS
-0 SI
-14 /Times-Bold AF
-7200 8167 MT
-(1.4 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(server)SH
-/Times-Bold SF
-16185 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 10362 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(server)SH
-/Times-Roman SF
-12208 XM
-(directory contains the Kerberos KDC server, called)SH
-/Times-Italic SF
-35052 XM
-(kerberos)SH
-/Times-Roman SF
-(. This)
-275 W( program manages read-)SH
-7200 11558 MT
-(only requests made to the master database, distributing tickets and encryption keys to clients requesting)SH
-7200 12754 MT
-(authentication service.)SH
-14 /Times-Bold AF
-7200 16601 MT
-(1.5 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(kadmin)SH
-/Times-Bold SF
-17040 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 18796 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(kadmin)SH
-/Times-Roman SF
-12698 XM
-(directory contains the Kerberos administration server and associated client programs.  The)SH
-7200 19992 MT
-(server accepts network requests from the user program)SH
-/Times-Italic SF
-31570 XM
-(kpasswd)SH
-/Times-Roman SF
-35573 XM
-(\050used to change a user's password\051, the)SH
-7200 21188 MT
-(Kerberos administration program)SH
-/Times-Italic SF
-22137 XM
-(kadmin)SH
-/Times-Roman SF
-(, and the srvtab utility program)SH
-/Times-Italic SF
-39276 XM
-(ksrvutil)SH
-/Times-Roman SF
-(. The)
-275 W( administration)SH
-7200 22384 MT
-(server can make modifications to the master database.)SH
-14 /Times-Bold AF
-7200 26231 MT
-(1.6 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(include)SH
-/Times-Bold SF
-16962 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 28426 MT
-(This directory contains the)SH
-/Times-Italic SF
-19236 XM
-(include)SH
-/Times-Roman SF
-22749 XM
-(files needed to build the Kerberos system.)SH
-14 /Times-Bold AF
-7200 32273 MT
-(1.7 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(lib)SH
-/Times-Bold SF
-14162 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 34468 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(lib)SH
-/Times-Roman SF
-10622 XM
-(directory has six subdirectories:)SH
-/Times-Italic SF
-25193 XM
-(acl)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-27087 XM
-(des)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-29103 XM
-(kadm)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-32035 XM
-(kdb)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-34173 XM
-(knet)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-38418 XM
-(krb)SH
-/Times-Roman SF
-(. The)275 W
-/Times-Italic SF
-42694 XM
-(des)SH
-/Times-Roman SF
-44435 XM
-(directory contains)SH
-7200 35664 MT
-(source for the DES encryption library.  The)SH
-/Times-Italic SF
-26595 XM
-(kadm)SH
-/Times-Roman SF
-29252 XM
-(directory contains source for the Kerberos)SH
-7200 36860 MT
-(administration server utility library.  The)SH
-/Times-Italic SF
-25439 XM
-(kdb)SH
-/Times-Roman SF
-27302 XM
-(directory contains source for the Kerberos database routine)SH
-7200 38056 MT
-(library. The)275 W
-/Times-Italic SF
-12942 XM
-(knet)SH
-/Times-Roman SF
-15049 XM
-(directory contains source for a library used by clients of the)SH
-/Times-Italic SF
-41530 XM
-(knetd)SH
-/Times-Roman SF
-44187 XM
-(server. The)275 W
-/Times-Italic SF
-49683 XM
-(krb)SH
-/Times-Roman SF
-7200 39252 MT
-(directory contains source for the)SH
-/Times-Italic SF
-21707 XM
-(libkrb.a)SH
-/Times-Roman SF
-25435 XM
-(library. This)
-275 W( library contains routines that are used by the)SH
-7200 40448 MT
-(Kerberos server program, and by applications programs that require authentication service.)SH
-14 /Times-Bold AF
-7200 44295 MT
-(1.8 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(man)SH
-/Times-Bold SF
-15251 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 46490 MT
-(This directory contains manual pages for Kerberos programs and library routines.)SH
-14 /Times-Bold AF
-7200 50337 MT
-(1.9 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(prototypes)SH
-/Times-Bold SF
-18596 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 52532 MT
-(This directory contains prototype)SH
-/Times-Italic SF
-22108 XM
-(/etc/services)SH
-/Times-Roman SF
-27819 XM
-(and)SH
-/Times-Italic SF
-29682 XM
-(/etc/krb.conf)SH
-/Times-Roman SF
-35486 XM
-(files. New)
-275 W( entries must be added to the)SH
-/Times-Italic SF
-7200 53728 MT
-(/etc/services)SH
-/Times-Roman SF
-12911 XM
-(file for the Kerberos server, and possibly for Kerberized applications \050)SH
-/Times-Italic SF
-(services.append)SH
-/Times-Roman SF
-7200 54924 MT
-(contains the entries used by the Athena-provided servers & applications, and is suitable for appending to)SH
-7200 56120 MT
-(your existing)SH
-/Times-Italic SF
-13250 XM
-(/etc/services)SH
-/Times-Roman SF
-18961 XM
-(file.\051. The)275 W
-/Times-Italic SF
-23878 XM
-(/etc/krb.conf)SH
-/Times-Roman SF
-29682 XM
-(file defines the local Kerberos realm for its host and)SH
-7200 57316 MT
-(lists Kerberos servers for given realms.  The)SH
-/Times-Italic SF
-26961 XM
-(/etc/krb.realms)SH
-/Times-Roman SF
-33865 XM
-(file defines exceptions for mapping machine)SH
-7200 58512 MT
-(names to Kerberos realms.)SH
-14 /Times-Bold AF
-7200 62359 MT
-(1.10 The)350 W
-/Times-BoldItalic SF
-13034 XM
-(tools)SH
-/Times-Bold SF
-16107 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 64554 MT
-(This directory contains a makefile to set up a directory tree for building the software in, and a shell script)SH
-7200 65750 MT
-(to format code in the style we use.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(3)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 4 5
-BS
-0 SI
-14 /Times-Bold AF
-7200 8167 MT
-(1.11 The)350 W
-/Times-BoldItalic SF
-13034 XM
-(util)SH
-/Times-Bold SF
-15329 XM
-(Directory)SH
-11 /Times-Roman AF
-7200 10362 MT
-(This directory contains several utility programs and libraries.  Included are Larry Wall's)SH
-/Times-Italic SF
-46296 XM
-(patch)SH
-/Times-Roman SF
-49015 XM
-(program, a)SH
-/Times-Italic SF
-7200 11558 MT
-(make)SH
-/Times-Roman SF
-9795 XM
-(pre-processor program called)SH
-/Times-Italic SF
-22956 XM
-(imake)SH
-/Times-Roman SF
-(, and a program for generating Makefile dependencies,)SH
-/Times-Italic SF
-7200 12754 MT
-(makedepend)SH
-/Times-Roman SF
-(, as well as the Sub-system library and utilities \050)SH
-/Times-Italic SF
-(ss)SH
-/Times-Roman SF
-(\051, and the Error table library and utilities)SH
-7200 13950 MT
-(\050)SH
-/Times-Italic SF
-(et)SH
-/Times-Roman SF
-(\051.)SH
-16 /Times-Bold AF
-7200 18622 MT
-(2. Preparing)
-400 W( for Installation)SH
-11 /Times-Roman AF
-7200 20817 MT
-(This document assumes that you will build the system on the machine on which you plan to install the)SH
-7200 22013 MT
-(Kerberos master server and its database.  You'll need about 10 megabytes for source and executables.)SH
-7200 24311 MT
-(By default, there must be a)SH
-/Times-Italic SF
-19327 XM
-(/kerberos)SH
-/Times-Roman SF
-23756 XM
-(directory on the master server machine in which to store the)SH
-7200 25507 MT
-(Kerberos database files.  If the master server machine does not have room on its root partition for these)SH
-7200 26703 MT
-(files, create a)SH
-/Times-Italic SF
-13306 XM
-(/kerberos)SH
-/Times-Roman SF
-17735 XM
-(symbolic link to another file system.)SH
-16 /Times-Bold AF
-7200 31375 MT
-(3. Preparing)
-400 W( for the Build)SH
-11 /Times-Roman AF
-7200 33570 MT
-(Before you build the system, you have to choose a)SH
-/Times-Bold SF
-29653 XM
-(realm name)SH
-/Times-Roman SF
-(, the name that specifies the system's)SH
-7200 34766 MT
-(administrative domain.  Project Athena uses the internet domain name ATHENA.MIT.EDU to specify its)SH
-7200 35962 MT
-(Kerberos realm name.  We recommend using a name of this form.)SH
-/Times-Bold SF
-36857 XM
-(NOTE:)SH
-/Times-Roman SF
-40616 XM
-(the realm-name is case)SH
-7200 37158 MT
-(sensitive; by convention, we suggest that you use your internet domain name, in capital letters.)SH
-7200 39456 MT
-(Edit the [SOURCE_DIR]/)SH
-/Times-Italic SF
-(include/krb.h)SH
-/Times-Roman SF
-24860 XM
-(file and look for the following lines of code:)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(4)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 5 6
-BS
-0 SI
-11 /Courier AF
-8520 7886 MT
-(/*)SH
-9180 9000 MT
-(* Kerberos specific definitions)SH
-9180 10114 MT
-(*)SH
-9180 11228 MT
-(* KRBLOG is the log file for the kerberos master server.)SH
-9180 12342 MT
-(* KRB_CONF is the configuration file where different host)SH
-9180 13456 MT
-(* machines running master and slave servers can be found.)SH
-9180 14570 MT
-(* KRB_MASTER is the name of the machine with the master)SH
-9180 15684 MT
-(* database.  The admin_server runs on this machine, and all)SH
-9180 16798 MT
-(* changes to the db \050as opposed to read-only requests, which)SH
-9180 17912 MT
-(* can go to slaves\051 must go to it.)SH
-9180 19026 MT
-(* KRB_HOST is the default machine when looking for a kerberos)SH
-9180 20140 MT
-(* slave server.  Other possibilities are in the KRB_CONF file.)SH
-9180 21254 MT
-(* KRB_REALM is the name of the realm.)SH
-9180 22368 MT
-(*/)SH
-8520 24596 MT
-(#ifdef notdef)SH
-8520 25710 MT
-(this is server-only, does not belong here;)SH
-8520 26824 MT
-(#define KRBLOG)
-3960 W( "/kerberos/kerberos.log")5940 W
-8520 27938 MT
-(are these used anyplace '?';)SH
-8520 29052 MT
-(#define VX_KRB_HSTFILE)
-9240 W( "/etc/krbhst")660 W
-8520 30166 MT
-(#define PC_KRB_HSTFILE)
-9240 W( "\134\134kerberos\134\134krbhst")660 W
-8520 31280 MT
-(#endif)SH
-8520 33508 MT
-(#define KRB_CONF)
-9240 W( "/etc/krb.conf")4620 W
-8520 34622 MT
-(#define KRB_RLM_TRANS)
-9240 W( "/etc/krb.realms")1320 W
-8520 35736 MT
-(#define KRB_MASTER)
-9240 W( "kerberos")3300 W
-8520 36850 MT
-(#define KRB_HOST)
-9240 W( KRB_MASTER)5280 W
-8520 37964 MT
-(#define KRB_REALM)
-9240 W( "ATHENA.MIT.EDU")3960 W
-/Times-Roman SF
-7200 39559 MT
-(Edit the last line as follows:)SH
-9400 41510 MT
-(1.)SH
-10500 XM
-(Change the KRB_REALM definition so that it specifies the realm name you have chosen)SH
-10500 42706 MT
-(for your Kerberos system.  This is a default which is usually overridden by a configuration)SH
-10500 43902 MT
-(file on each machine; however, if that config file is absent, many programs will use this)SH
-10500 45098 MT
-("built-in" realm name.)SH
-14 /Times-Bold AF
-7200 48945 MT
-(3.1 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(/etc/krb.conf)SH
-/Times-Bold SF
-19956 XM
-(File)SH
-11 /Times-Roman AF
-7200 51140 MT
-(Create a)SH
-/Times-Italic SF
-11108 XM
-(/etc/krb.conf)SH
-/Times-Roman SF
-16912 XM
-(file using the following format:)SH
-/Times-BoldItalic SF
-8520 52740 MT
-(realm_name)SH
-8520 53854 MT
-(realm_name master_server_name)1045 W
-/Courier SF
-25594 XM
-(admin server)SH
-/Times-Roman SF
-7200 55449 MT
-(where)SH
-/Times-Italic SF
-10161 XM
-(realm_name)SH
-/Times-Roman SF
-15934 XM
-(specifies the system's realm name, and)SH
-/Times-Italic SF
-33375 XM
-(master_server_name)SH
-/Times-Roman SF
-42874 XM
-(specifies the machine)SH
-7200 56645 MT
-(name on which you will run the master server.  The words 'admin server' must appear next to the name of)SH
-7200 57841 MT
-(the server on which you intend to run the administration server \050which must be a machine with access to)SH
-7200 59037 MT
-(the database\051.)SH
-7200 61335 MT
-(For example, if your realm name is)SH
-/Times-Italic SF
-22962 XM
-(tim.edu)SH
-/Times-Roman SF
-26506 XM
-(and your master server's name is)SH
-/Times-Italic SF
-41288 XM
-(kerberos.tim.edu)SH
-/Times-Roman SF
-(, the file)SH
-7200 62531 MT
-(should have these contents:)SH
-/Courier SF
-8520 64057 MT
-(tim.edu)SH
-8520 65171 MT
-(tim.edu kerberos.tim.edu)
-660 W( admin server)SH
-/Times-Roman SF
-7200 67469 MT
-(See the [SOURCE_DIR]/)SH
-/Times-Italic SF
-(prototypes/etc.krb.conf)SH
-/Times-Roman SF
-28921 XM
-(file for an example)SH
-/Times-Italic SF
-37533 XM
-(/etc/krb.conf)SH
-/Times-Roman SF
-43337 XM
-(file. That)
-275 W( file has)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(5)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 6 7
-BS
-0 SI
-11 /Times-Roman AF
-7200 7955 MT
-(examples of how to provide backup servers for a given realm \050additional lines with the same leading)SH
-7200 9151 MT
-(realm name\051 and how to designate servers for remote realms.)SH
-14 /Times-Bold AF
-7200 12998 MT
-(3.2 The)350 W
-/Times-BoldItalic SF
-12334 XM
-(/etc/krb.realms)SH
-/Times-Bold SF
-21280 XM
-(File)SH
-11 /Times-Roman AF
-7200 15193 MT
-(In many situations, the default realm in which a host operates will be identical to the domain portion its)SH
-7200 16389 MT
-(Internet domain name.)SH
-7200 18687 MT
-(If this is not the case, you will need to establish a translation from host name or domain name to realm)SH
-7200 19883 MT
-(name. This)
-275 W( is accomplished with the)SH
-/Times-Italic SF
-23820 XM
-(/etc/krb.realms)SH
-/Times-Roman SF
-30724 XM
-(file.)SH
-7200 22181 MT
-(Each line of the translation file specifies either a hostname or domain name, and its associated realm:)SH
-/Courier SF
-8520 23707 MT
-(.domain.name kerberos.realm1)SH
-8520 24821 MT
-(host.name kerberos.realm2)SH
-/Times-Roman SF
-7200 26416 MT
-(For example, to map all hosts in the domain LSC.TIM.EDU to KRB.REALM1 but the host)SH
-7200 27612 MT
-(FILMS.LSC.TIM.EDU to KRB.REALM2 your file would read:)SH
-/Courier SF
-8520 29138 MT
-(.LSC.TIM.EDU KRB.REALM1)SH
-8520 30252 MT
-(FILMS.LSC.TIM.EDU KRB.REALM2)SH
-/Times-Roman SF
-7200 31847 MT
-(If a particular host matches both a domain and a host entry, the host entry takes precedence.)SH
-16 /Times-Bold AF
-7200 36519 MT
-(4. Building)
-400 W( the Software)SH
-11 /Times-Roman AF
-7200 38714 MT
-(Before you build the software read the)SH
-/Times-Bold SF
-24395 XM
-(README)SH
-/Times-Roman SF
-29558 XM
-(file in [SOURCE_DIR].  What follows is a more)SH
-7200 39910 MT
-(detailed description of the instructions listed in README.)SH
-9400 41861 MT
-(1.)SH
-10500 XM
-(Create an [OBJ_DIR] directory to hold the tree of Kerberos object files you are about to)SH
-10500 43057 MT
-(build, for example,)SH
-/Times-Italic SF
-19145 XM
-(/mit/kerberos/obj)SH
-/Times-Roman SF
-(.)SH
-9400 44951 MT
-(2.)SH
-10500 XM
-(Change directory to [OBJ_DIR].  The following command creates directories under)SH
-10500 46147 MT
-([OBJ_DIR] and installs Makefiles for the final build.)SH
-/Courier SF
-11820 47724 MT
-(host%)SH
-/Times-Bold SF
-15780 XM
-(make -f [SOURCE_DIR]/tools/makeconfig SRCDIR=[SOURCE_DIR])275 W
-/Times-Roman SF
-9400 49618 MT
-(3.)SH
-10500 XM
-(Change directory to util/imake.includes.  Read through config.Imakefile, turning on)SH
-10500 50814 MT
-(appropriate flags for your installation.  Change SRCTOP so that it is set to the top level of)SH
-10500 52010 MT
-(your source directory.)SH
-9400 53904 MT
-(4.)SH
-10500 XM
-(Check that your machine type has a definition in include/osconf.h & related files in the)SH
-10500 55100 MT
-(source tree \050if it doesn't, then you may need to create your own; if you get successful)SH
-10500 56296 MT
-(results, please post to kerberos@athena.mit.edu\051)SH
-9400 58190 MT
-(5.)SH
-10500 XM
-(Change directory to [OBJ_DIR].  The next command generates new Makefiles based on the)SH
-10500 59386 MT
-(configuration you selected in config.Imakefile, then adds dependency information to the)SH
-10500 60582 MT
-(Makefiles, and finally builds the system:)SH
-/Courier SF
-11820 62159 MT
-(host%)SH
-/Times-Bold SF
-15780 XM
-(make world)275 W
-/Times-Roman SF
-10500 63754 MT
-(This command takes a while to complete; you may wish to redirect the output onto a file)SH
-10500 64950 MT
-(and put the job in the background:)SH
-/Courier SF
-11820 66527 MT
-(host%)SH
-/Times-Bold SF
-15780 XM
-(make world)
-275 W( >&WORLDLOG_891201 &)SH
-/Times-Roman SF
-10500 68122 MT
-(If you need to rebuild the Kerberos programs and libraries after making a change, you can)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(6)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 7 8
-BS
-0 SI
-11 /Times-Roman AF
-10500 7955 MT
-(usually just type:)SH
-/Courier SF
-11820 9532 MT
-(host%)SH
-/Times-Bold SF
-15780 XM
-(make all)275 W
-/Times-Roman SF
-10500 11127 MT
-(However, if you changed the configuration in config.Imakefile or modified the Imakefiles)SH
-10500 12323 MT
-(or Makefiles, you should run)SH
-/Times-Italic SF
-23514 XM
-(make world)SH
-/Times-Roman SF
-28952 XM
-(to re-build all the Makefiles and dependency lists.)SH
-14 /Times-Bold AF
-7200 16141 MT
-(4.1 Testing)
-350 W( the DES Library)SH
-11 /Times-Roman AF
-7200 18336 MT
-(Use the)SH
-/Times-Italic SF
-10804 XM
-(verify)SH
-/Times-Roman SF
-13583 XM
-(command to test the DES library implementation:)SH
-/Courier SF
-8520 19913 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([OBJ_DIR]/lib/des/verify)SH
-/Times-Roman SF
-7200 21508 MT
-(The command should display the following:)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(7)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 8 9
-BS
-0 SI
-11 /Courier AF
-8520 7886 MT
-(Examples per FIPS publication 81, keys ivs and cipher)SH
-8520 9000 MT
-(in hex.  These are the correct answers, see below for)SH
-8520 10114 MT
-(the actual answers.)SH
-8520 12342 MT
-(Examples per Davies and Price.)SH
-8520 14570 MT
-(EXAMPLE ECB)
-SH( key)
-2640 W( = 08192a3b4c5d6e7f)SH
-13800 15684 MT
-(clear = 0)SH
-13800 16798 MT
-(cipher = 25 dd ac 3e 96 17 64 67)SH
-8520 17912 MT
-(ACTUAL ECB)SH
-13800 19026 MT
-(clear "")SH
-13800 20140 MT
-(cipher =)
-660 W( \050low to high bytes\051)SH
-19080 21254 MT
-(25 dd ac 3e 96 17 64 67)SH
-8520 23482 MT
-(EXAMPLE ECB)
-SH( key)
-2640 W( = 0123456789abcdef)SH
-13800 24596 MT
-(clear = "Now is the time for all ")SH
-13800 25710 MT
-(cipher = 3f a4 0e 8a 98 4d 48 15 ...)SH
-8520 26824 MT
-(ACTUAL ECB)SH
-13800 27938 MT
-(clear "Now is the time for all ")SH
-13800 29052 MT
-(cipher =)
-660 W( \050low to high bytes\051)SH
-19080 30166 MT
-(3f a4 0e 8a 98 4d 48 15)SH
-8520 32394 MT
-(EXAMPLE CBC)
-SH( key)
-2640 W( = 0123456789abcdef  iv = 1234567890abcdef)SH
-13800 33508 MT
-(clear = "Now is the time for all ")SH
-13800 34622 MT
-(cipher =)
-SH( e5)
-4620 W( c7 cd de 87 2b f2 7c)SH
-24360 35736 MT
-(43 e9 34 00 8c 38 9c 0f)SH
-24360 36850 MT
-(68 37 88 49 9a 7c 05 f6)SH
-8520 37964 MT
-(ACTUAL CBC)SH
-13800 39078 MT
-(clear "Now is the time for all ")SH
-13800 40192 MT
-(ciphertext = \050low to high bytes\051)SH
-19080 41306 MT
-(e5 c7 cd de 87 2b f2 7c)SH
-19080 42420 MT
-(43 e9 34 00 8c 38 9c 0f)SH
-19080 43534 MT
-(68 37 88 49 9a 7c 05 f6)SH
-19080 44648 MT
-(00 00 00 00 00 00 00 00)SH
-19080 45762 MT
-(00 00 00 00 00 00 00 00)SH
-19080 46876 MT
-(00 00 00 00 00 00 00 00)SH
-19080 47990 MT
-(00 00 00 00 00 00 00 00)SH
-19080 49104 MT
-(00 00 00 00 00 00 00 00)SH
-13800 50218 MT
-(decrypted clear_text = "Now is the time for all ")SH
-8520 51332 MT
-(EXAMPLE CBC checksum)
-SH( key)
-1980 W( =  0123456789abcdef iv =  1234567890abcdef)SH
-13800 52446 MT
-(clear =)
-SH( "7654321)
-5280 W( Now is the time for ")SH
-13800 53560 MT
-(checksum 58)
-4620 W( d2 e7 7e 86 06 27 33  or some part thereof)SH
-8520 54674 MT
-(ACTUAL CBC checksum)SH
-19080 55788 MT
-(encrypted cksum = \050low to high bytes\051)SH
-19080 56902 MT
-(58 d2 e7 7e 86 06 27 33)SH
-/Times-Roman SF
-7200 59200 MT
-(If the)SH
-/Times-Italic SF
-9826 XM
-(verify)SH
-/Times-Roman SF
-12605 XM
-(command fails to display this information as specified above, the implementation of DES for)SH
-7200 60396 MT
-(your hardware needs to be adjusted.  Your Kerberos system cannot work properly if your DES library)SH
-7200 61592 MT
-(fails this test.)SH
-7200 63890 MT
-(When you have finished building the software, you will find the executables in the object tree as follows:)SH
-/Times-Bold SF
-7200 65841 MT
-([OBJ_DIR]/admin)SH
-/Times-Italic SF
-18200 XM
-(ext_srvtab)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-23332 XM
-(kdb_destroy)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-29258 XM
-(kdb_edit)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-33596 XM
-(kdb_init)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-37752 XM
-(kdb_util)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-43771 XM
-(kstash)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 67536 MT
-([OBJ_DIR]/kuser)SH
-/Times-Italic SF
-18200 XM
-(kdestroy)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-22476 XM
-(kinit)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-24982 XM
-(klist)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-27366 XM
-(ksrvtgt)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-32773 XM
-(ksu)SH
-/Times-Roman SF
-(.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(8)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 9 10
-BS
-0 SI
-11 /Times-Bold AF
-7200 7955 MT
-([OBJ_DIR]/server)SH
-/Times-Italic SF
-18200 XM
-(kerberos)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 9650 MT
-([OBJ_DIR]/appl/bsd)SH
-/Times-Italic SF
-18200 XM
-(klogind)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-22050 XM
-(kshd)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-24616 XM
-(login.krb)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-29169 XM
-(rcp)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-31185 XM
-(rlogin)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-36288 XM
-(rsh)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 11345 MT
-([OBJ_DIR]/appl/knetd)SH
-/Times-Italic SF
-18200 XM
-(knetd)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 13040 MT
-([OBJ_DIR]/appl/sample)SH
-/Times-Italic SF
-18200 14236 MT
-(sample_server)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-25164 XM
-(sample_client)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-31824 XM
-(simple_server)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-40407 XM
-(simple_client)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 15931 MT
-([OBJ_DIR]/appl/tftp)SH
-/Times-Italic SF
-18200 XM
-(tcom)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-20888 XM
-(tftpd)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-25319 XM
-(tftp)SH
-/Times-Roman SF
-(.)SH
-/Times-Bold SF
-7200 17626 MT
-([OBJ_DIR]/slave)SH
-/Times-Italic SF
-18200 XM
-(kprop)SH
-/Times-Roman SF
-21041 XM
-(and)SH
-/Times-Italic SF
-22904 XM
-(kpropd)SH
-/Times-Roman SF
-(.)SH
-16 /Times-Bold AF
-7200 22298 MT
-(5. Installing)
-400 W( the Software)SH
-11 /Times-Roman AF
-7200 24493 MT
-(To install the software, issue the)SH
-/Times-Italic SF
-21711 XM
-(make install)SH
-/Times-Roman SF
-27333 XM
-(command from the [OBJ_DIR] \050you need to be a privileged)SH
-7200 25689 MT
-(user in order to properly install the programs\051.  Programs can either be installed in default directories, or)SH
-7200 26885 MT
-(under a given root directory, as described below.)SH
-14 /Times-Bold AF
-7200 30703 MT
-(5.1 The)
-350 W( ``Standard'' Places)SH
-11 /Times-Roman AF
-7200 32898 MT
-(If you use the)SH
-/Times-Italic SF
-13492 XM
-(make)SH
-/Times-Roman SF
-16087 XM
-(command as follows:)SH
-/Courier SF
-8520 34475 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(make install)275 W
-/Times-Roman SF
-7200 36070 MT
-(the installation process will try to install the various parts of the system in ``standard'' directories.  This)SH
-7200 37266 MT
-(process creates the ``standard'' directories as needed.)SH
-7200 39564 MT
-(The standard installation process copies things as follows:)SH
-/Symbol SF
-9169 41640 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The)SH
-/Times-Italic SF
-11935 XM
-(include)SH
-/Times-Roman SF
-15448 XM
-(files)SH
-/Times-Italic SF
-17617 XM
-(krb.h)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-20458 XM
-(des.h)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-23299 XM
-(mit-copyright.h)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-30662 XM
-(kadm.h)SH
-/Times-Roman SF
-34144 XM
-(and)SH
-/Times-Italic SF
-36007 XM
-(kadm_err.h)SH
-/Times-Roman SF
-41383 XM
-(get copied to the)SH
-/Times-Italic SF
-9950 42836 MT
-(/usr/include)SH
-/Times-Roman SF
-15481 XM
-(directory.)SH
-/Symbol SF
-9169 44730 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos libraries)SH
-/Times-Italic SF
-20119 XM
-(libdes.a)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-24122 XM
-(libkrb.a)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-28125 XM
-(libkdb.a)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-32250 XM
-(libkadm.a)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-37169 XM
-(libknet.a)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-43401 XM
-(libacl.a)SH
-/Times-Roman SF
-47007 XM
-(get)SH
-9950 45926 MT
-(copied to the)SH
-/Times-Italic SF
-15907 XM
-(/usr/athena/lib)SH
-/Times-Roman SF
-22662 XM
-(\050or wherever you pointed LIBDIR in config.Imakefile\051)SH
-9950 47122 MT
-(directory.)SH
-/Symbol SF
-9169 49016 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos master database utilities)SH
-/Times-Italic SF
-27085 XM
-(kdb_init)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-31241 XM
-(kdb_destroy)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-37167 XM
-(kdb_edit)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-41505 XM
-(kdb_util)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-45661 XM
-(kstash)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-9950 50212 MT
-(ext_srvtab)SH
-/Times-Roman SF
-14807 XM
-(get copied to the)SH
-/Times-Italic SF
-22383 XM
-(/usr/etc)SH
-/Times-Roman SF
-25958 XM
-(\050DAEMDIR\051 directory.)SH
-/Symbol SF
-9169 52106 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos user utilities)SH
-/Times-Italic SF
-21924 XM
-(kinit)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-24430 XM
-(kdestroy)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-28706 XM
-(klist)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-31090 XM
-(ksrvtgt)SH
-/Times-Roman SF
-34359 XM
-(and)SH
-/Times-Italic SF
-36222 XM
-(ksu)SH
-/Times-Roman SF
-37963 XM
-(get copied to the)SH
-/Times-Italic SF
-45539 XM
-(/usr/athena)SH
-/Times-Roman SF
-9950 53302 MT
-(\050PROGDIR\051 directory.)SH
-/Symbol SF
-9169 55196 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The modified Berkeley utilities)SH
-/Times-Italic SF
-24004 XM
-(rsh)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-25960 XM
-(rlogin)SH
-/Times-Roman SF
-28925 XM
-(get copied to the)SH
-/Times-Italic SF
-36501 XM
-(/usr/ucb)SH
-/Times-Roman SF
-40382 XM
-(\050UCBDIR\051 directory;)SH
-/Times-Italic SF
-9950 56392 MT
-(rcp)SH
-/Times-Roman SF
-11691 XM
-(gets copied to the)SH
-/Times-Italic SF
-19695 XM
-(/bin)SH
-/Times-Roman SF
-21682 XM
-(\050SLASHBINDIR\051 directory; and)SH
-/Times-Italic SF
-36375 XM
-(rlogind)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-40165 XM
-(rshd)SH
-/Times-Roman SF
-(, and)SH
-/Times-Italic SF
-44534 XM
-(login.krb)SH
-/Times-Roman SF
-48812 XM
-(get)SH
-9950 57588 MT
-(copied to the)SH
-/Times-Italic SF
-15907 XM
-(/usr/etc)SH
-/Times-Roman SF
-19482 XM
-(\050DAEMDIR\051 directory.  The old copies of the user programs are)SH
-9950 58784 MT
-(renamed)SH
-/Times-Italic SF
-14011 XM
-(rsh.ucb)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-17830 XM
-(rlogin.ucb)SH
-/Times-Roman SF
-22658 XM
-(and)SH
-/Times-Italic SF
-24521 XM
-(rcp.ucb)SH
-/Times-Roman SF
-(, respectively.  The Kerberos versions of these)SH
-9950 59980 MT
-(programs are designed to fall back and execute the original versions if something prevents)SH
-9950 61176 MT
-(the Kerberos versions from succeeding.)SH
-/Symbol SF
-9169 63070 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos version of)SH
-/Times-Italic SF
-20944 XM
-(tftp)SH
-/Times-Roman SF
-22687 XM
-(and)SH
-/Times-Italic SF
-24550 XM
-(tcom)SH
-/Times-Roman SF
-26963 XM
-(get copied to the)SH
-/Times-Italic SF
-34539 XM
-(/usr/athena)SH
-/Times-Roman SF
-39826 XM
-(\050PROGDIR\051 directory;)SH
-/Times-Italic SF
-9950 64266 MT
-(tftpd)SH
-/Times-Roman SF
-12243 XM
-(gets copied to the)SH
-/Times-Italic SF
-20247 XM
-(/etc)SH
-/Times-Roman SF
-22110 XM
-(\050ETCDIR\051 directory.)SH
-/Times-Italic SF
-31884 XM
-(tftp)SH
-/Times-Roman SF
-33627 XM
-(and)SH
-/Times-Italic SF
-35490 XM
-(tftpd)SH
-/Times-Roman SF
-37783 XM
-(are installed set-uid to an)SH
-9950 65462 MT
-(unprivileged user \050user id of DEF_UID\051.)SH
-/Symbol SF
-9169 67356 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The)SH
-/Times-Italic SF
-11935 XM
-(knetd)SH
-/Times-Roman SF
-14592 XM
-(daemon gets copied to the)SH
-/Times-Italic SF
-26353 XM
-(/usr/etc)SH
-/Times-Roman SF
-29928 XM
-(\050DAEMDIR\051 directory.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(9)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 10 11
-BS
-0 SI
-11 /Symbol AF
-9169 8080 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos server)SH
-/Times-Italic SF
-19201 XM
-(kerberos)SH
-/Times-Roman SF
-(, the slave propagation software)SH
-/Times-Italic SF
-37343 XM
-(kprop)SH
-/Times-Roman SF
-40184 XM
-(and)SH
-/Times-Italic SF
-42047 XM
-(kpropd)SH
-/Times-Roman SF
-(, and the)SH
-9950 9276 MT
-(administration server)SH
-/Times-Italic SF
-19542 XM
-(kadmind)SH
-/Times-Roman SF
-23605 XM
-(get copied to the)SH
-/Times-Italic SF
-31181 XM
-(/usr/etc)SH
-/Times-Roman SF
-34756 XM
-(\050SVRDIR, SVRDIR, and)SH
-9950 10472 MT
-(DAEMDIR\051 directory.)SH
-/Symbol SF
-9169 12366 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The remote administration tools)SH
-/Times-Italic SF
-24310 XM
-(kpasswd)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-28588 XM
-(ksrvutil)SH
-/Times-Roman SF
-32163 XM
-(and)SH
-/Times-Italic SF
-34026 XM
-(kadmin)SH
-/Times-Roman SF
-37539 XM
-(get copied to the)SH
-/Times-Italic SF
-45115 XM
-(/usr/athena)SH
-/Times-Roman SF
-9950 13562 MT
-(\050PROGDIR\051 directory.)SH
-/Symbol SF
-9169 15456 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The Kerberos manual pages get installed in the appropriate)SH
-/Times-Italic SF
-36187 XM
-(/usr/man)SH
-/Times-Roman SF
-40374 XM
-(directories. Don't)275 W
-9950 16652 MT
-(forget to run)SH
-/Times-Italic SF
-15723 XM
-(makewhatis)SH
-/Times-Roman SF
-21192 XM
-(after installing the manual pages.)SH
-14 /Times-Bold AF
-7200 20470 MT
-(5.2 ``Non-Standard'')
-350 W( Installation)SH
-11 /Times-Roman AF
-7200 22665 MT
-(If you'd rather install the software in a different location, you can use the)SH
-/Times-Italic SF
-39667 XM
-(make)SH
-/Times-Roman SF
-42262 XM
-(command as follows,)SH
-7200 23861 MT
-(where [DEST_DIR] specifies an alternate destination directory which will be used as the root for the)SH
-7200 25057 MT
-(installed programs, i.e. programs that would normally be installed in /usr/athena would be installed in)SH
-7200 26253 MT
-([DEST_DIR]/usr/athena.)SH
-/Courier SF
-8520 27830 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(make install DESTDIR=[DEST_DIR])275 W
-16 SS 
-7200 32502 MT
-(6. Conclusion)400 W
-11 /Times-Roman AF
-7200 34697 MT
-(Now that you have built and installed your Kerberos system, use the accompanying Kerberos Operation)SH
-4030 50 44224 34897 UL
-4398 50 48529 34897 UL
-7200 35893 MT
-(Notes to create a Kerberos Master database, install authenticated services, and start the Kerberos server.)SH
-2566 50 7200 36093 UL
-16 /Times-Bold AF
-7200 40565 MT
-(7. Acknowledgements)400 W
-11 /Times-Roman AF
-7200 42760 MT
-(We'd like to thank Henry Mensch and Jon Rochlis for helping us debug this document.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30100 XM
-(10)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: i 12
-BS
-0 SI
-14 /Times-Bold AF
-25272 8138 MT
-(Table of Contents)SH
-13 SS 
-7200 9781 MT
-(1. Organization)
-325 W( of the Source Directory)SH
-53350 XM
-(1)SH
-12 /Times-Roman AF
-9000 11136 MT
-(1.1 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(admin)SH
-/Times-Roman SF
-16701 XM
-(Directory)SH
-53400 XM
-(2)SH
-9000 12491 MT
-(1.2 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(kuser)SH
-/Times-Roman SF
-16300 XM
-(Directory)SH
-53400 XM
-(2)SH
-9000 13846 MT
-(1.3 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(appl)SH
-/Times-Roman SF
-15700 XM
-(Directory)SH
-53400 XM
-(2)SH
-9000 15201 MT
-(1.4 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(server)SH
-/Times-Roman SF
-16566 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 16556 MT
-(1.5 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(kadmin)SH
-/Times-Roman SF
-17301 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 17911 MT
-(1.6 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(include)SH
-/Times-Roman SF
-17234 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 19266 MT
-(1.7 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(lib)SH
-/Times-Roman SF
-14834 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 20621 MT
-(1.8 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(man)SH
-/Times-Roman SF
-15767 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 21976 MT
-(1.9 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(prototypes)SH
-/Times-Roman SF
-18634 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 23331 MT
-(1.10 The)300 W
-/Times-BoldItalic SF
-13866 XM
-(tools)SH
-/Times-Roman SF
-16501 XM
-(Directory)SH
-53400 XM
-(3)SH
-9000 24686 MT
-(1.11 The)300 W
-/Times-BoldItalic SF
-13866 XM
-(util)SH
-/Times-Roman SF
-15835 XM
-(Directory)SH
-53400 XM
-(4)SH
-13 /Times-Bold AF
-7200 26329 MT
-(2. Preparing)
-325 W( for Installation)SH
-53350 XM
-(4)SH
-7200 27972 MT
-(3. Preparing)
-325 W( for the Build)SH
-53350 XM
-(4)SH
-12 /Times-Roman AF
-9000 29327 MT
-(3.1 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(/etc/krb.conf)SH
-/Times-Roman SF
-19801 XM
-(File)SH
-53400 XM
-(5)SH
-9000 30682 MT
-(3.2 The)300 W
-/Times-BoldItalic SF
-13266 XM
-(/etc/krb.realms)SH
-/Times-Roman SF
-20936 XM
-(File)SH
-53400 XM
-(6)SH
-13 /Times-Bold AF
-7200 32325 MT
-(4. Building)
-325 W( the Software)SH
-53350 XM
-(6)SH
-12 /Times-Roman AF
-9000 33674 MT
-(4.1 Testing)
-300 W( the DES Library)SH
-53400 XM
-(7)SH
-13 /Times-Bold AF
-7200 35317 MT
-(5. Installing)
-325 W( the Software)SH
-53350 XM
-(9)SH
-12 /Times-Roman AF
-9000 36666 MT
-(5.1 The)
-300 W( ``Standard'' Places)SH
-53400 XM
-(9)SH
-9000 38015 MT
-(5.2 ``Non-Standard'')
-300 W( Installation)SH
-52800 XM
-(10)SH
-13 /Times-Bold AF
-7200 39658 MT
-(6. Conclusion)325 W
-52700 XM
-(10)SH
-7200 41301 MT
-(7. Acknowledgements)325 W
-52700 XM
-(10)SH
-10 /Times-Roman AF
-7200 75600 MT
-(MIT Project Athena)SH
-30461 XM
-(i)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Trailer
-%%Pages: 12
-%%DocumentFonts: Times-Roman Times-Bold Times-Italic Times-BoldItalic Courier Symbol
diff --git a/doc/old-V4-docs/installation.mss b/doc/old-V4-docs/installation.mss
deleted file mode 100644
index 0a2ae7595..000000000
--- a/doc/old-V4-docs/installation.mss
+++ /dev/null
@@ -1,681 +0,0 @@
-@Comment[	$Source$]
-@Comment[	$Author$]
-@Comment[	$Id$]
-@Comment[]
-@device[postscript]
-@make[report]
-@comment[
-@DefineFont(HeadingFont,
-      P=<RawFont "NewCenturySchlbkBoldItalic">,
-      B=<RawFont "NewCenturySchlbkBold">,
-      I=<RawFont "NewCenturySchlbkBoldItalic">,
-      R=<RawFont "NewCenturySchlbkRoman">)
-]
-@DefineFont(HeadingFont,
-      P=<RawFont "TimesBoldItalic">,
-      B=<RawFont "TimesBold">,
-      I=<RawFont "TimesItalic">,
-      R=<RawFont "TimesRoman">)
-@Counter(MajorPart,TitleEnv HD0,ContentsEnv tc0,Numbered [@I],
-          IncrementedBy Use,Announced)
-@Counter(Chapter,TitleEnv HD1,ContentsEnv tc1,Numbered [@1. ],
-          IncrementedBy Use,Referenced [@1],Announced)
-@Counter(Appendix,TitleEnv HD1,ContentsEnv tc1,Numbered [@A. ],
-          IncrementedBy,Referenced [@A],Announced,Alias Chapter)
-@Counter(UnNumbered,TitleEnv HD1,ContentsEnv tc1,Announced,Alias 
-           Chapter)
-@Counter(Section,Within Chapter,TitleEnv HD2,ContentsEnv tc2,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy
-          Use,Announced)
-@Counter(AppendixSection,Within Appendix,TitleEnv HD2,
-          ContentsEnv tc2,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy 
-          Use,Announced)
-@Counter(SubSection,Within Section,TitleEnv HD3,ContentsEnv tc3,
-          Numbered [@#@:.@1 ],IncrementedBy Use,
-          Referenced [@#@:.@1 ])
-@Counter(AppendixSubSection,Within AppendixSection,TitleEnv HD3,
-          ContentsEnv tc3,
-          Numbered [@#@:.@1 ],IncrementedBy Use,
-          Referenced [@#@:.@1 ])
-@Counter(Paragraph,Within SubSection,TitleEnv HD4,ContentsEnv tc4,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],
-          IncrementedBy Use)
-@modify(CopyrightNotice, Fixed -1 inch, Flushright)
-@Modify(Titlebox, Fixed 3.0 inches)
-@Modify(hd1, below .2 inch, facecode B, size 16, spaces kept, pagebreak off)
-@Modify(hd2, below .2 inch, facecode B, size 14, spaces kept)
-@Modify(hd3, below .2 inch, facecode B, size 12, spaces kept)
-@Modify(Description, Leftmargin +20, Indent -20,below 1 line, above 1 line)
-@Modify(Tc1, Above .5,  Facecode B)
-@Modify(Tc2, Above .25, Below .25, Facecode R)
-@Modify(Tc3,Facecode R)
-@Modify(Tc4,Facecode R)
-@Modify(Itemize,Above 1line,Below 1line)
-@Modify(Insert,LeftMargin +2, RightMargin +2)
-@libraryfile[stable]
-@comment[@Style(Font NewCenturySchoolBook, size 11)]
-@Style(Font TimesRoman, size 11)
-@Style(Spacing 1.1, indent 0)
-@Style(leftmargin 1.0inch)
-@Style(justification no)
-@Style(BottomMargin 1.5inch)
-@Style(ChangeBarLocation Right)
-@Style(ChangeBars=off)
-@pageheading[immediate]
-@pagefooting[immediate, left = "MIT Project Athena", center = "@value(page)",
-right = "@value(date)"]
-@set[page = 0]
-@blankspace[.5 inches]
-@begin[group, size 20]
-@begin(center)
-@b[Kerberos Installation Notes]
-@b[DRAFT]
-@end[center]
-@end(group)
-@blankspace[.5 inches]
-@begin[group, size 16]
-@begin(center)
-Bill Bryant
-Jennifer Steiner
-John Kohl
-@blankspace[1 line]
-Project Athena, MIT
-@blankspace[.5 inches]
-@b[Initial Release, January 24, 1989]
-@i[(plus later patches through patchlevel 7)]
-@end[center]
-@end(group)
-@begin[group, size 10]
-@end[group]
-@blankspace[.75 inches]
-
-
-The release consists of three parts.
-
-The first part consists of the core Kerberos system, which was developed
-at MIT and does not require additional licenses for us to distribute.
-Included in this part are the Kerberos authentication server, the
-Kerberos library, the
-@i[ndbm]
-database interface library, user programs, administration programs,
-manual pages, some applications which use Kerberos for authentication,
-and some utilities.
-
-The second part is the Data Encryption Standard (DES) library, which we
-are distributing only within the United States.
-
-The third part contains Kerberos modifications to Sun's NFS, which we
-distribute as ``context diffs'' to the Sun NFS source code.  Its
-distribution is controlled to provide an accounting of who has retrieved
-the patches, so that Project Athena can comply with its agreements with
-Sun regarding distribution of these changes.
-
-@newpage()
-@chapter[Organization of the Source Directory]
-
-The Kerberos building and installation process,
-as described in this document,
-builds the binaries and executables from the files contained in the Kerberos
-source tree, and deposits them in a separate object tree.
-This is intended to easily support several different build trees from a
-single source tree (this is useful if you support several machine
-architectures).
-We suggest that you copy the Kerberos sources into a
-@i[/mit/kerberos/src] directory,
-and create as well a @i[/mit/kerberos/obj] directory in which
-to hold the executables.
-In the rest of this document, we'll refer to the Kerberos
-source and object directories as [SOURCE_DIR]
-and [OBJ_DIR], respectively.
-
-Below is a brief overview of the organization of the complete
-source directory.
-More detailed descriptions follow.
-
-@begin[description]
-
-@b[admin]@\utilities for the Kerberos administrator
-
-@b[appl]@\applications that use Kerberos
-
-@b[appl/bsd]@\Berkeley's rsh/rlogin suite, using Kerberos
-
-@b[appl/knetd]@\(old) software for inetd-like multiplexing of a single
-TCP listening port
-
-@b[appl/sample]@\sample application servers and clients
-
-@b[appl/tftp]@\Trivial File Transfer Protocol, using Kerberos
-
-@b[include]@\include files
-
-@b[kadmin]@\remote administrative interface to the Kerberos master database
-
-@b[kuser]@\assorted user programs
-
-@b[lib]@\libraries for use with/by Kerberos
-
-@b[lib/acl]@\Access Control List library
-
-@b[lib/des]@\Data Encryption Standard library (US only)
-
-@b[lib/kadm]@\administrative interface library
-
-@b[lib/kdb]@\Kerberos server library interface to @i[ndbm]
-
-@b[lib/knet]@\(old) library for use with @b[knetd]
-
-@b[lib/krb]@\Kerberos library
-
-@b[man]@\manual pages
-
-@b[prototypes]@\sample configuration files
-
-@b[server]@\the authentication server
-
-@b[slave]@\Kerberos slave database propagation software
-
-@b[tools]@\shell scripts for maintaining the source tree
-
-@b[util]@\utilities
-
-@b[util/imake]@\Imakefile-to-Makefile ``compilation'' tool
-
-@b[util/ss]@\Sub-system library (for command line subsystems)
-
-@b[util/et]@\Error-table library (for independent, unique error codes)
-
-@b[util/makedepend]@\Makefile dependency generator tool
-
-@end[description]
-
-@section[The @p(admin) Directory]
-
-This directory contains source for
-the Kerberos master database administration tools.
-@begin[description]
-@b[kdb_init]@\This program creates and initializes the
-Kerberos master database.
-It prompts for a Kerberos realmname, and the Kerberos master password.
-
-@b[kstash]@\This program ``stashes'' the master password in the file
-@i[/.k] so that the master server machine can restart the Kerberos
-server automatically after an unattended reboot.
-The hidden password is also available to administrative programs
-that have been set to run automatically.
-
-@b[kdb_edit]@\This program is a low-level tool for editing
-the master database.
-
-@b[kdb_destroy]@\This program deletes the master database.
-
-@b[kdb_util]@\This program can be used to dump the master database
-into an ascii file, and can also be used to load the ascii file
-into the master database.
-
-@b[ext_srvtab]@\This program extracts information from the master
-database and creates a host-dependent @i[srvtab] file.
-This file contains the Kerberos keys for the host's
-``Kerberized'' services.
-These services look up their keys in the @i[srvtab] file
-for use in the authentication process.
-@end[description]
-
-@section[The @p(kuser) Directory]
-
-This directory contains the source code for several user-oriented
-programs.
-@begin[description]
-@b[kinit]@\This program prompts users for their usernames and
-Kerberos passwords, then furnishes them with Kerberos ticket-granting
-tickets.
-
-@b[kdestroy]@\This program destroys any active tickets.
-Users should use @i[kdestroy] before they log off their workstations.
-
-@b[klist]@\This program lists a user's active tickets.
-
-@b[ksrvtgt]@\This retrieves a ticket-granting ticket with a life time
-of five minutes, using a server's secret key in lieu of a password.  It
-is primarily for use in shell scripts and other batch facilities.
-
-@b[ksu]@\Substitute user id, using Kerberos to mediate attempts to
-change to ``root''.
-@end[description]
-
-@section[The @p(appl) Directory]
-
-If your site has the appropriate BSD license,
-your Kerberos release provides certain Unix utilities
-The Berkeley programs that have been modified to use Kerberos
-authentication are found in the @i[appl/bsd] directory.
-They include @i[login], @i[rlogin], @i[rsh], and @i[rcp], as well as the
-associated daemon programs @i[kshd] and @i[klogind].
-The @i[login] program obtains ticket-granting tickets for users
-upon login; the other utilities provide authenticated
-Unix network services.
-
-The @i[appl] directory also contains samples Kerberos application
-client and server programs, an authenticated @i[tftp] program,
-@i[knetd], an authenticated inet daemon.
-
-@section[The @p(server) Directory]
-
-The @i[server] directory contains the Kerberos KDC server, called
-@i[kerberos].
-This program manages read-only requests made to the
-master database,
-distributing tickets and encryption keys to clients requesting
-authentication service.
-
-@section[The @p(kadmin) Directory]
-
-The @i[kadmin] directory contains the Kerberos administration server and
-associated client programs.
-The server accepts network requests from the
-user program @i[kpasswd] (used to change a user's password), the
-Kerberos administration program @i(kadmin), and the srvtab utility
-program @i[ksrvutil].
-The administration server can make modifications to the master database.
-
-@section[The @p(include) Directory]
-
-This directory contains the @i[include] files needed to
-build the Kerberos system.
-
-@section[The @p(lib) Directory]
-
-The @i[lib] directory has six subdirectories:
-@i[acl], @i[des], @i[kadm], @i[kdb], @i[knet], and @i[krb].
-The @i[des] directory contains source for the DES encryption library.
-The @i[kadm] directory contains source for the Kerberos administration
-server utility library.
-The @i[kdb] directory contains source for the Kerberos database
-routine library.
-The @i[knet] directory contains source for a library used by clients of
-the @i[knetd] server.
-The @i[krb] directory contains source for the @i[libkrb.a]
-library.
-This library contains routines that are used by the Kerberos server program,
-and by applications programs that require authentication service.
-
-@section[The @p(man) Directory]
-
-This directory contains manual pages for Kerberos programs and
-library routines.
-
-@section[The @p(prototypes) Directory]
-
-This directory contains prototype
-@i[/etc/services] and @i[/etc/krb.conf] files.
-New entries must be added to the @i[/etc/services] file for
-the Kerberos server, and possibly for Kerberized applications
-(@i[services.append] contains the entries used by the Athena-provided
-servers & applications, and is suitable for appending to your existing
-@i[/etc/services] file.).
-The @i[/etc/krb.conf] file defines the local Kerberos realm
-for its host and lists Kerberos servers for given realms.
-The @i[/etc/krb.realms] file defines exceptions for mapping machine
-names to Kerberos realms.
-
-@section[The @p(tools) Directory]
-
-This directory contains
-a makefile to set up a directory tree
-for building the software in, and
-a shell script to format code in the
-style we use.
-
-
-@section[The @p(util) Directory]
-
-This directory contains several utility programs and libraries.
-Included are Larry Wall's @i[patch] program, a @i[make] pre-processor
-program called
-@i[imake], and a program for generating Makefile dependencies,
-@i[makedepend], as well as the Sub-system library and
-utilities (@i[ss]), and the Error table library and utilities (@i[et]).
-
-@chapter[Preparing for Installation]
-
-This document assumes that you will build the system
-on the machine on which you plan to install
-the Kerberos master server and its database.
-You'll need about 10 megabytes for source and executables.
-
-By default, there must be
-a @i[/kerberos] directory on the master server machine
-in which to store the Kerberos
-database files.
-If the master server machine does not have room on its root partition
-for these files,
-create a @i[/kerberos] symbolic link to another file system.
-
-@chapter[Preparing for the Build]
-
-Before you build the system,
-you have to choose a @b[realm name],
-the name that specifies the system's administrative domain.
-Project Athena uses the internet domain name ATHENA.MIT.EDU
-to specify its Kerberos realm name.
-We recommend using a name of this form.
-@b[NOTE:] the realm-name is case sensitive; by convention, we suggest
-that you use your internet domain name, in capital letters.
-
-Edit the [SOURCE_DIR]/@i[include/krb.h] file and look for the following
-lines of code:
-@begin[example]
-/*
- * Kerberos specific definitions
- *
- * KRBLOG is the log file for the kerberos master server.
- * KRB_CONF is the configuration file where different host
- * machines running master and slave servers can be found.
- * KRB_MASTER is the name of the machine with the master
- * database.  The admin_server runs on this machine, and all
- * changes to the db (as opposed to read-only requests, which
- * can go to slaves) must go to it.
- * KRB_HOST is the default machine when looking for a kerberos
- * slave server.  Other possibilities are in the KRB_CONF file.
- * KRB_REALM is the name of the realm.
- */
-
-#ifdef notdef
-this is server-only, does not belong here;
-#define       KRBLOG          "/kerberos/kerberos.log"
-are these used anyplace '?';
-#define               VX_KRB_HSTFILE  "/etc/krbhst"
-#define               PC_KRB_HSTFILE  "\\kerberos\\krbhst"
-#endif
-
-#define               KRB_CONF        "/etc/krb.conf"
-#define               KRB_RLM_TRANS   "/etc/krb.realms"
-#define               KRB_MASTER      "kerberos"
-#define               KRB_HOST         KRB_MASTER
-#define               KRB_REALM       "ATHENA.MIT.EDU"
-@end[example]
-Edit the last line as follows:
-@begin[enumerate]
-Change the KRB_REALM definition so that it specifies the realm name
-you have chosen for your Kerberos system.  This is a default which is
-usually overridden by a configuration file on each machine; however, if
-that config file is absent, many programs will use this "built-in" realm
-name.
-@end[enumerate]
-
-@section[The @p(/etc/krb.conf) File]
-
-Create a @i[/etc/krb.conf] file using the following format:
-@begin[example]
-@p[realm_name]
-@p[realm_name]  @p[master_server_name] admin server
-@end[example]
-where @i[realm_name] specifies the system's realm name,
-and @i[master_server_name] specifies the machine name on
-which you will run the master server.  The words 'admin server' must
-appear next to the name of the server on which you intend to run the
-administration server (which must be a machine with access to the database).
-
-For example,
-if your realm name is @i[tim.edu] and your master server's name is
-@i[kerberos.tim.edu], the file should have these contents:
-@begin[example]
-tim.edu
-tim.edu  kerberos.tim.edu admin server
-@end[example]
-
-See the [SOURCE_DIR]/@i[prototypes/etc.krb.conf] file for an
-example @i[/etc/krb.conf] file.  That file has examples of how to
-provide backup servers for a given realm (additional lines with the same
-leading realm name) and how to designate servers for remote realms.
-
-@section[The @p(/etc/krb.realms) File]
-
-In many situations, the default realm in which a host operates will be
-identical to the domain portion its Internet domain name.
-
-If this is not the case, you will need to establish a translation from
-host name or domain name to realm name.  This is accomplished with the
-@i(/etc/krb.realms) file.
-
-Each line of the translation file specifies either a hostname or domain
-name, and its associated realm:
-@begin[example]
-.domain.name kerberos.realm1
-host.name kerberos.realm2
-@end[example]
-For example, to map all hosts in the domain LSC.TIM.EDU to KRB.REALM1
-but the host FILMS.LSC.TIM.EDU to KRB.REALM2 your file would read:
-@begin[example]
-.LSC.TIM.EDU KRB.REALM1
-FILMS.LSC.TIM.EDU KRB.REALM2
-@end[example]
-If a particular host matches both a domain and a host entry, the host
-entry takes precedence.
-
-@chapter[Building the Software]
-
-Before you build the software
-read the @b[README] file in [SOURCE_DIR].
-What follows is a more detailed description of the instructions
-listed in README.
-@begin[enumerate]
-Create an [OBJ_DIR] directory to hold the tree of Kerberos object files you
-are about to build, for example,
-@i[/mit/kerberos/obj].
-
-Change directory to [OBJ_DIR].
-The following command creates directories under [OBJ_DIR]
-and installs Makefiles for the final build.
-@begin[example, rightmargin -7]
-host% @b(make  -f  [SOURCE_DIR]/tools/makeconfig  SRCDIR=[SOURCE_DIR])
-@end[example]
-
-
-
-Change directory to util/imake.includes.  Read through config.Imakefile,
-turning on appropriate flags for your installation.  Change SRCTOP so
-that it is set to the top level of your source directory.
-
-Check that your machine type has a definition in include/osconf.h &
-related files in the source tree (if it doesn't, then you may need to
-create your own; if you get successful results, please post to
-kerberos@@athena.mit.edu)
-
-Change directory to [OBJ_DIR].  The next command generates new Makefiles
-based on the configuration you selected in config.Imakefile, then adds
-dependency information to the Makefiles, and finally builds the system:
-@begin[example, rightmargin -7]
-host% @b(make  world)
-@end[example]
-This command takes a while to complete; you may wish to redirect the
-output onto a file and put the job in the background:
-@begin[example, rightmargin -7]
-host% @b(make  world >&WORLDLOG_891201 &)
-@end[example]
-If you need to rebuild the Kerberos programs and libraries after making
-a change, you can usually just type:
-@begin[example, rightmargin -7]
-host% @b(make  all)
-@end[example]
-However, if you changed the configuration in config.Imakefile or modified
-the Imakefiles or Makefiles, you should run @i[make world] to re-build
-all the Makefiles and dependency lists.
-@end(enumerate)
-
-@section[Testing the DES Library]
-
-Use the @i[verify] command to test the DES library
-implementation:
-@begin[example]
-host% @b([OBJ_DIR]/lib/des/verify)
-@end[example]
-The command should display the following:
-@begin[example, rightmargin -10]
-Examples per FIPS publication 81, keys ivs and cipher
-in hex.  These are the correct answers, see below for
-the actual answers.
-
-Examples per Davies and Price.
-
-EXAMPLE ECB     key = 08192a3b4c5d6e7f
-        clear = 0
-        cipher = 25 dd ac 3e 96 17 64 67
-ACTUAL ECB
-        clear ""
-        cipher  = (low to high bytes)
-                25 dd ac 3e 96 17 64 67 
-
-EXAMPLE ECB     key = 0123456789abcdef
-        clear = "Now is the time for all "
-        cipher = 3f a4 0e 8a 98 4d 48 15 ...
-ACTUAL ECB
-        clear "Now is the time for all "
-        cipher  = (low to high bytes)
-                3f a4 0e 8a 98 4d 48 15 
-
-EXAMPLE CBC     key = 0123456789abcdef  iv = 1234567890abcdef
-        clear = "Now is the time for all "
-        cipher =        e5 c7 cd de 87 2b f2 7c
-                        43 e9 34 00 8c 38 9c 0f
-                        68 37 88 49 9a 7c 05 f6
-ACTUAL CBC
-        clear "Now is the time for all "
-        ciphertext = (low to high bytes)
-                e5 c7 cd de 87 2b f2 7c 
-                43 e9 34 00 8c 38 9c 0f 
-                68 37 88 49 9a 7c 05 f6 
-                00 00 00 00 00 00 00 00 
-                00 00 00 00 00 00 00 00 
-                00 00 00 00 00 00 00 00 
-                00 00 00 00 00 00 00 00 
-                00 00 00 00 00 00 00 00 
-        decrypted clear_text = "Now is the time for all "
-EXAMPLE CBC checksum    key =  0123456789abcdef iv =  1234567890abcdef
-        clear =         "7654321 Now is the time for "
-        checksum        58 d2 e7 7e 86 06 27 33  or some part thereof
-ACTUAL CBC checksum
-                encrypted cksum = (low to high bytes)
-                58 d2 e7 7e 86 06 27 33
-@end[example]
-
-If the @i[verify] command fails to display this information as specified
-above, the implementation of DES for your hardware needs to
-be adjusted.
-Your Kerberos system cannot work properly if your DES library
-fails this test.
-
-When you have finished building the software,
-you will find the executables in the object tree as follows:
-@begin[description]
-@b([OBJ_DIR]/admin)@\@i[ext_srvtab], @i[kdb_destroy],
-@i[kdb_edit], @i[kdb_init], @i[kdb_util], and @i[kstash].
-
-@b([OBJ_DIR]/kuser)@\@i[kdestroy], @i[kinit], @i[klist], @i[ksrvtgt],
-and @i[ksu].
-
-@b([OBJ_DIR]/server)@\@i[kerberos].
-
-@b([OBJ_DIR]/appl/bsd)@\@i[klogind], @i[kshd], @i[login.krb], @i[rcp],
-@i[rlogin], and @i[rsh].
-
-@b([OBJ_DIR]/appl/knetd)@\@i[knetd].
-
-@b([OBJ_DIR]/appl/sample)@\@i[sample_server], @i[sample_client],
-@i[simple_server], and @i[simple_client].
-
-@b([OBJ_DIR]/appl/tftp)@\@i[tcom], @i[tftpd], and @i[tftp].
-
-@b([OBJ_DIR]/slave)@\@i[kprop] and @i[kpropd].
-@end[description]
-
-@chapter[Installing the Software]
-
-To install the software, issue the @i[make install] command from
-the [OBJ_DIR] (you need to be a privileged user in order to
-properly install the programs).
-Programs can either be installed in default directories, or under
-a given root directory, as described below.
-
-@section[The ``Standard'' Places]
-
-If you use the @i[make] command as follows:
-@begin[example]
-host# @b(make  install)
-@end[example]
-the installation process will try to install the various parts of the
-system in ``standard'' directories.
-This process creates the ``standard'' directories as needed.
-
-The standard installation process copies things as follows:
-@begin[itemize]
-The @i[include] files @i[krb.h], @i[des.h], @i[mit-copyright.h],
-@i[kadm.h] and @i[kadm_err.h] get copied to the
-@i[/usr/include] directory.
-
-The Kerberos libraries @i[libdes.a], @i[libkrb.a], @i[libkdb.a],
-@i[libkadm.a], @i[libknet.a], and @i[libacl.a] get copied
-to the @i[/usr/athena/lib] (or wherever you pointed LIBDIR in
-config.Imakefile) directory.
-
-The Kerberos master database utilities @i[kdb_init], @i[kdb_destroy],
-@i[kdb_edit], @i[kdb_util], @i[kstash], and @i[ext_srvtab] get copied to
-the @i[/usr/etc] (DAEMDIR) directory.
-
-The Kerberos user utilities @i[kinit], @i[kdestroy], @i[klist],
-@i[ksrvtgt] and @i[ksu] get copied to the @i[/usr/athena] (PROGDIR)
-directory.
-
-The modified Berkeley utilities @i[rsh], @i[rlogin] get copied to the
-@i[/usr/ucb] (UCBDIR) directory; @i[rcp] gets copied to the @i[/bin]
-(SLASHBINDIR) directory; and @i[rlogind], @i[rshd], and @i[login.krb]
-get copied to the @i[/usr/etc] (DAEMDIR) directory.  The old copies of
-the user programs are renamed @i(rsh.ucb), @i(rlogin.ucb) and
-@i(rcp.ucb), respectively.  The Kerberos versions of these programs are
-designed to fall back and execute the original versions if something
-prevents the Kerberos versions from succeeding.
-
-The Kerberos version of @i[tftp] and @i[tcom] get copied to the
-@i[/usr/athena] (PROGDIR) directory; @i[tftpd] gets copied to the
-@i[/etc] (ETCDIR) directory.  @i[tftp] and @i[tftpd] are installed
-set-uid to an unprivileged user (user id of DEF_UID).
-
-The @i[knetd] daemon gets copied to the @i[/usr/etc] (DAEMDIR) directory.
-
-The Kerberos server @i[kerberos], the slave propagation software
-@i[kprop] and @i[kpropd], and the administration server @i[kadmind] get
-copied to the @i[/usr/etc] (SVRDIR, SVRDIR, and DAEMDIR) directory.
-
-The remote administration tools @i[kpasswd], @i[ksrvutil] and @i[kadmin]
-get copied to the @i[/usr/athena] (PROGDIR) directory.
-
-The Kerberos manual pages get installed in the appropriate
-@i[/usr/man] directories.  Don't forget to run @i[makewhatis]
-after installing the manual pages.
-
-@end[itemize]
-
-@section[``Non-Standard'' Installation]
-
-If you'd rather install the software in a different location,
-you can use the @i[make] command as follows,
-where [DEST_DIR] specifies an alternate destination directory
-which will be used as the root for the installed programs, i.e. programs
-that would normally be installed in /usr/athena would be installed in
-[DEST_DIR]/usr/athena.
-@begin[example]
-host# @b(make  install  DESTDIR=[DEST_DIR])
-@end[example]
-
-@chapter[Conclusion]
-
-Now that you have built and installed your Kerberos system,
-use the accompanying @u[Kerberos Operation Notes]
-to create a Kerberos Master database, install authenticated services,
-and start the Kerberos server.
-
-@chapter [Acknowledgements]
-
-We'd like to thank Henry Mensch and Jon Rochlis for helping us debug
-this document.
diff --git a/doc/old-V4-docs/operation.PS b/doc/old-V4-docs/operation.PS
deleted file mode 100644
index 3afb8cf06..000000000
--- a/doc/old-V4-docs/operation.PS
+++ /dev/null
@@ -1,2669 +0,0 @@
-%!PS-Adobe-2.0
-%%Title: operation.mss
-%%DocumentFonts: (atend)
-%%Creator: John T Kohl,,E40-351M,31510,6176432831 and Scribe 7(1700)
-%%CreationDate: 4 January 1990 11:55
-%%Pages: (atend)
-%%EndComments
-% PostScript Prelude for Scribe.
-/BS {/SV save def 0.0 792.0 translate .01 -.01 scale} bind def
-/ES {showpage SV restore} bind def
-/SC {setrgbcolor} bind def
-/FMTX matrix def
-/RDF {WFT SLT 0.0 eq 
-  {SSZ 0.0 0.0 SSZ neg 0.0 0.0 FMTX astore}
-  {SSZ 0.0 SLT neg sin SLT cos div SSZ mul SSZ neg 0.0 0.0 FMTX astore}
-  ifelse makefont setfont} bind def
-/SLT 0.0 def
-/SI { /SLT exch cvr def RDF} bind def
-/WFT /Courier findfont def
-/SF { /WFT exch findfont def RDF} bind def
-/SSZ 1000.0 def
-/SS { /SSZ exch 100.0 mul def RDF} bind def
-/AF { /WFT exch findfont def /SSZ exch 100.0 mul def RDF} bind def
-/MT /moveto load def
-/XM {currentpoint exch pop moveto} bind def
-/UL {gsave newpath moveto dup 2.0 div 0.0 exch rmoveto
-   setlinewidth 0.0 rlineto stroke grestore} bind def
-/LH {gsave newpath moveto setlinewidth
-   0.0 rlineto
-   gsave stroke grestore} bind def
-/LV {gsave newpath moveto setlinewidth
-   0.0 exch rlineto
-   gsave stroke grestore} bind def
-/BX {gsave newpath moveto setlinewidth
-   exch
-   dup 0.0 rlineto
-   exch 0.0 exch neg rlineto
-   neg 0.0 rlineto
-   closepath
-   gsave stroke grestore} bind def
-/BX1 {grestore} bind def
-/BX2 {setlinewidth 1 setgray stroke grestore} bind def
-/PB {/PV save def newpath translate
-    100.0 -100.0 scale pop /showpage {} def} bind def
-/PE {PV restore} bind def
-/GB {/PV save def newpath translate rotate
-    div dup scale 100.0 -100.0 scale /showpage {} def} bind def
-/GE {PV restore} bind def
-/FB {dict dup /FontMapDict exch def begin} bind def
-/FM {cvn exch cvn exch def} bind def
-/FE {end /original-findfont /findfont load def  /findfont
-   {dup FontMapDict exch known{FontMapDict exch get} if
-   original-findfont} def} bind def
-/BC {gsave moveto dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath clip} bind def
-/EC /grestore load def
-/SH /show load def
-/MX {exch show 0.0 rmoveto} bind def
-/W {0 32 4 -1 roll widthshow} bind def
-/WX {0 32 5 -1 roll widthshow 0.0 rmoveto} bind def
-/RC {100.0 -100.0 scale
-612.0 0.0 translate
--90.0 rotate
-.01 -.01 scale} bind def
-/URC {100.0 -100.0 scale
-90.0 rotate
--612.0 0.0 translate
-.01 -.01 scale} bind def
-/RCC {100.0 -100.0 scale
-0.0 -792.0 translate 90.0 rotate
-.01 -.01 scale} bind def
-/URCC {100.0 -100.0 scale
--90.0 rotate 0.0 792.0 translate
-.01 -.01 scale} bind def
-%%EndProlog
-%%Page: 0 1
-BS
-0 SI
-20 /Times-Bold AF
-19324 13788 MT
-(Kerberos Operation Notes)SH
-27156 15798 MT
-(DRAFT)SH
-16 /Times-Roman AF
-27021 23502 MT
-(Bill Bryant)SH
-27289 25150 MT
-(John Kohl)SH
-23957 26798 MT
-(Project Athena, MIT)SH
-/Times-Bold SF
-19489 32396 MT
-(Initial Release, January 24, 1989)SH
-/Times-Italic SF
-17558 34044 MT
-(\050plus later patches through patchlevel 7\051)SH
-11 /Times-Roman AF
-7200 43798 MT
-(These notes assume that you have used the)SH
-/Times-Italic SF
-26322 XM
-(Kerberos Installation Notes)SH
-/Times-Roman SF
-38821 XM
-(to build and install your Kerberos)SH
-7200 44994 MT
-(system. As)
-275 W( in that document, we refer to the directory that contains the built Kerberos binaries as)SH
-7200 46190 MT
-([OBJ_DIR].)SH
-7200 48488 MT
-(This document assumes that you are a Unix system manager.)SH
-ES
-%%Page: 1 2
-BS
-0 SI
-16 /Times-Bold AF
-7200 8272 MT
-(1. How)
-400 W( Kerberos Works: A Schematic Description)SH
-11 /Times-Roman AF
-7200 10467 MT
-(This section provides a simplified description of a general user's interaction with the Kerberos system.)SH
-7200 11663 MT
-(This interaction happens transparently--users don't need to know and probably don't care about what's)SH
-7200 12859 MT
-(going on--but Kerberos administrators might find a schematic description of the process useful.  The)SH
-7200 14055 MT
-(description glosses over a lot of details; for more information, see)SH
-/Times-Italic SF
-36404 XM
-(Kerberos: An Authentication Service)SH
-7200 15251 MT
-(for Open Network Systems)SH
-/Times-Roman SF
-(, a paper presented at Winter USENIX 1988, in Dallas, Texas.)SH
-14 /Times-Bold AF
-7200 19069 MT
-(1.1 Network)
-350 W( Services and Their Client Programs)SH
-11 /Times-Roman AF
-7200 21264 MT
-(In an environment that provides network services, you use)SH
-/Times-Italic SF
-33164 XM
-(client)SH
-/Times-Roman SF
-35883 XM
-(programs to request service from)SH
-/Times-Italic SF
-50696 XM
-(server)SH
-/Times-Roman SF
-7200 22460 MT
-(programs that are somewhere on the network.  Suppose you have logged in to a workstation and you want)SH
-7200 23656 MT
-(to)SH
-/Times-Italic SF
-8331 XM
-(rlogin)SH
-/Times-Roman SF
-11296 XM
-(to another machine.  You use the local)SH
-/Times-Italic SF
-28493 XM
-(rlogin)SH
-/Times-Roman SF
-31458 XM
-(client program to contact the remote machine's)SH
-/Times-Italic SF
-7200 24852 MT
-(rlogin)SH
-/Times-Roman SF
-10165 XM
-(service daemon.)SH
-14 /Times-Bold AF
-7200 28670 MT
-(1.2 Kerberos)
-350 W( Tickets)SH
-11 /Times-Roman AF
-7200 30865 MT
-(Under Kerberos, the)SH
-/Times-Italic SF
-16422 XM
-(rlogin)SH
-/Times-Roman SF
-19387 XM
-(service program allows a client to login to a remote machine if it can provide)SH
-7200 32061 MT
-(a Kerberos)SH
-/Times-Bold SF
-12268 XM
-(ticket)SH
-/Times-Roman SF
-15169 XM
-(for the request.  This ticket proves the identity of the person who has used the client)SH
-7200 33257 MT
-(program to access the server program.)SH
-14 /Times-Bold AF
-7200 37075 MT
-(1.3 The)
-350 W( Kerberos Master Database)SH
-11 /Times-Roman AF
-7200 39270 MT
-(Kerberos will give you tickets only if you have an entry in the Kerberos server's)SH
-/Times-Bold SF
-42845 XM
-(master database)SH
-/Times-Roman SF
-(. Your)275 W
-7200 40466 MT
-(database entry includes your Kerberos username \050often referred to as your Kerberos)SH
-/Times-Bold SF
-44394 XM
-(principal)SH
-/Times-Roman SF
-48949 XM
-(name\051, and)SH
-7200 41662 MT
-(your Kerberos password.  Every Kerberos user must have an entry in this database.)SH
-14 /Times-Bold AF
-7200 45480 MT
-(1.4 The)
-350 W( Ticket-Granting Ticket)SH
-11 /Times-Roman AF
-7200 47675 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(kinit)SH
-/Times-Roman SF
-11416 XM
-(command prompts for your Kerberos username and password, and if you enter them)SH
-7200 48871 MT
-(successfully, you will obtain a Kerberos)SH
-/Times-Italic SF
-25131 XM
-(ticket-granting ticket)SH
-/Times-Roman SF
-(. As)
-275 W( illustrated below, client programs use)SH
-7200 50067 MT
-(this ticket to get other Kerberos tickets as needed.)SH
-14 /Times-Bold AF
-7200 53885 MT
-(1.5 Network)
-350 W( Services and the Master Database)SH
-11 /Times-Roman AF
-7200 56080 MT
-(The master database also contains entries for all network services that require Kerberos authentication.)SH
-7200 57276 MT
-(Suppose for instance that your site has a machine)SH
-/Times-Italic SF
-29163 XM
-(laughter)SH
-/Times-Roman SF
-33166 XM
-(that requires Kerberos authentication from)SH
-7200 58472 MT
-(anyone who wants to)SH
-/Times-Italic SF
-16792 XM
-(rlogin)SH
-/Times-Roman SF
-19757 XM
-(to it.  This service must be registered in the master database.  Its entry)SH
-7200 59668 MT
-(includes the service's principal name, and its)SH
-/Times-Bold SF
-27238 XM
-(instance)SH
-/Times-Roman SF
-(.)SH
-7200 61966 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(instance)SH
-/Times-Roman SF
-13126 XM
-(is the name of the service's machine; in this case, the service's instance is the name)SH
-/Times-Italic SF
-7200 63162 MT
-(laughter)SH
-/Times-Roman SF
-(. The)
-275 W( instance provides a means for Kerberos to distinguish between machines that provide the)SH
-7200 64358 MT
-(same service.  Your site is likely to have more than one machine that provides)SH
-/Times-Italic SF
-41840 XM
-(rlogin)SH
-/Times-Roman SF
-44805 XM
-(service.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(1)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 2 3
-BS
-0 SI
-14 /Times-Bold AF
-7200 8138 MT
-(1.6 The)
-350 W( User-Kerberos Interaction)SH
-11 /Times-Roman AF
-7200 10333 MT
-(Suppose that you \050in the guise of a general user\051 walk up to a workstation intending to login to it, and)SH
-7200 11529 MT
-(then)SH
-/Times-Italic SF
-9369 XM
-(rlogin)SH
-/Times-Roman SF
-12334 XM
-(to the machine)SH
-/Times-Italic SF
-19085 XM
-(laughter)SH
-/Times-Roman SF
-(. Here's)
-275 W( what happens.)SH
-9400 13480 MT
-(1.)SH
-10500 XM
-(You login to the workstation and use the)SH
-/Times-Italic SF
-28648 XM
-(kinit)SH
-/Times-Roman SF
-30879 XM
-(command to to get a ticket-granting ticket.)SH
-10500 14676 MT
-(This command prompts you for your username \050your Kerberos Principal Name\051, and your)SH
-10500 15872 MT
-(Kerberos password [on some systems which use the new version of)SH
-/Times-Italic SF
-40465 XM
-(/bin/login)SH
-/Times-Roman SF
-(, this may be)SH
-10500 17068 MT
-(done as part of the login process, not requiring the user to run a separate program].)SH
-12762 19019 MT
-(a.)SH
-13800 XM
-(The)SH
-/Times-Italic SF
-15785 XM
-(kinit)SH
-/Times-Roman SF
-18016 XM
-(command sends your request to the Kerberos master server machine.  The)SH
-13800 20215 MT
-(server software looks for your principal name's entry in the Kerberos)SH
-/Times-Bold SF
-44555 XM
-(master)SH
-13800 21411 MT
-(database)SH
-/Times-Roman SF
-(.)SH
-12700 23305 MT
-(b.)SH
-13800 XM
-(If this entry exists, the Kerberos server creates and returns a)SH
-/Times-Italic SF
-40430 XM
-(ticket-granting ticket)SH
-/Times-Roman SF
-(,)SH
-13800 24501 MT
-(encrypted in your password.  If)SH
-/Times-Italic SF
-27819 XM
-(kinit)SH
-/Times-Roman SF
-30050 XM
-(can decrypt the Kerberos reply using the)SH
-13800 25697 MT
-(password you provide, it stores this ticket in a)SH
-/Times-Bold SF
-34270 XM
-(ticket file)SH
-/Times-Roman SF
-38912 XM
-(on your local machine for)SH
-13800 26893 MT
-(later use.  The ticket file to be used can be specified in the)SH
-/Times-Bold SF
-39609 XM
-(KRBTKFILE)SH
-/Times-Roman SF
-13800 28089 MT
-(environment variable.  If this variable is not set, the name of the file will be)SH
-/Times-Italic SF
-13800 29285 MT
-(/tmp/tkt)SH
-/Times-BoldItalic SF
-(uid)SH
-/Times-Roman SF
-(, where)SH
-/Times-BoldItalic SF
-22141 XM
-(uid)SH
-/Times-Roman SF
-23884 XM
-(is the UNIX user-id, represented in decimal.)SH
-9400 31236 MT
-(2.)SH
-10500 XM
-(Now you use the)SH
-/Times-Italic SF
-18198 XM
-(rlogin)SH
-/Times-Roman SF
-21163 XM
-(client to try to access the machine)SH
-/Times-Italic SF
-36344 XM
-(laughter)SH
-/Times-Roman SF
-(.)SH
-/Courier SF
-11820 32813 MT
-(host%)SH
-/Times-Bold SF
-15780 XM
-(rlogin laughter)275 W
-/Times-Roman SF
-12762 34764 MT
-(a.)SH
-13800 XM
-(The)SH
-/Times-Italic SF
-15785 XM
-(rlogin)SH
-/Times-Roman SF
-18750 XM
-(client checks your ticket file to see if you have a ticket for)SH
-/Times-Italic SF
-44559 XM
-(laughter)SH
-/Times-Roman SF
-('s)SH
-/Times-Italic SF
-13800 35960 MT
-(rcmd)SH
-/Times-Roman SF
-16335 XM
-(service \050the rlogin program uses the)SH
-/Times-Italic SF
-32401 XM
-(rcmd)SH
-/Times-Roman SF
-34936 XM
-(service name, mostly for historical)SH
-13800 37156 MT
-(reasons\051. You)
-275 W( don't, so)SH
-/Times-Italic SF
-24583 XM
-(rlogin)SH
-/Times-Roman SF
-27548 XM
-(uses the ticket file's)SH
-/Times-Italic SF
-36590 XM
-(ticket-granting ticket)SH
-/Times-Roman SF
-46060 XM
-(to make a)SH
-13800 38352 MT
-(request to the master server's ticket-granting service.)SH
-12700 40246 MT
-(b.)SH
-13800 XM
-(This ticket-granting service receives the)SH
-/Times-Italic SF
-31667 XM
-(rcmd-laughter)SH
-/Times-Roman SF
-38296 XM
-(request and looks in the)SH
-13800 41442 MT
-(master database for an)SH
-/Times-Italic SF
-23938 XM
-(rcmd-laughter)SH
-/Times-Roman SF
-30567 XM
-(entry. If)
-275 W( that entry exists, the ticket-granting)SH
-13800 42638 MT
-(service issues you a ticket for that service.  That ticket is also cached in your ticket)SH
-13800 43834 MT
-(file.)SH
-12762 45728 MT
-(c.)SH
-13800 XM
-(The)SH
-/Times-Italic SF
-15785 XM
-(rlogin)SH
-/Times-Roman SF
-18750 XM
-(client now uses that ticket to request service from the)SH
-/Times-Italic SF
-42454 XM
-(laughter rlogin)SH
-/Times-Roman SF
-13800 46924 MT
-(service program.  The service program lets you)SH
-/Times-Italic SF
-34843 XM
-(rlogin)SH
-/Times-Roman SF
-37808 XM
-(if the ticket is valid.)SH
-16 /Times-Bold AF
-7200 51596 MT
-(2. Setting)
-400 W( Up and Testing the Kerberos Server)SH
-11 /Times-Roman AF
-7200 53791 MT
-(The procedure for setting up and testing a Kerberos server is as follows:)SH
-9400 55742 MT
-(1.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kdb_init)SH
-/Times-Roman SF
-17985 XM
-(command to create and initialize the master database.)SH
-9400 57636 MT
-(2.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kdb_edit)SH
-/Times-Roman SF
-18167 XM
-(utility to add your username to the master database.)SH
-9400 59530 MT
-(3.)SH
-10500 XM
-(Start the Kerberos server.)SH
-9400 61424 MT
-(4.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kinit)SH
-/Times-Roman SF
-16335 XM
-(command to obtain a Kerberos ticket-granting ticket.)SH
-9400 63318 MT
-(5.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(klist)SH
-/Times-Roman SF
-16213 XM
-(command to verify that the)SH
-/Times-Italic SF
-28402 XM
-(kinit)SH
-/Times-Roman SF
-30633 XM
-(command authenticated you successfully.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(2)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 3 4
-BS
-0 SI
-14 /Times-Bold AF
-7200 8138 MT
-(2.1 Creating)
-350 W( and Initializing the Master Database)SH
-11 /Times-Roman AF
-7200 10333 MT
-(Login to the Kerberos master server machine, and use the)SH
-/Times-Bold SF
-32825 XM
-(su)SH
-/Times-Roman SF
-34140 XM
-(command to become root.  If you installed)SH
-7200 11529 MT
-(the Kerberos administration tools with the)SH
-/Times-Italic SF
-26020 XM
-(make install)SH
-/Times-Roman SF
-31642 XM
-(command and the default pathnames, they should)SH
-7200 12725 MT
-(be in the)SH
-/Times-Italic SF
-11263 XM
-(/usr/etc)SH
-/Times-Roman SF
-14838 XM
-(directory. If)
-275 W( you installed the tools in a different directory, hopefully you know what it)SH
-7200 13921 MT
-(is. From)
-275 W( now on, we will refer to this directory as [ADMIN_DIR].)SH
-7200 16219 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(kdb_init)SH
-/Times-Roman SF
-13066 XM
-(command creates and initializes the master database.  It asks you to enter the system's realm)SH
-7200 17415 MT
-(name and the database's master password.  Do not forget this password.  If you do, the database becomes)SH
-7200 18611 MT
-(useless. \050Your)
-275 W( realm name should be substituted for [REALMNAME] below.\051)SH
-7200 20909 MT
-(Use)SH
-/Times-Italic SF
-9185 XM
-(kdb_init)SH
-/Times-Roman SF
-13066 XM
-(as follows:)SH
-/Courier SF
-8520 22486 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-([ADMIN_DIR]/kdb_init)SH
-/Courier SF
-8520 23600 MT
-(Realm name \050default XXX\051:)SH
-/Times-Bold SF
-25680 XM
-([REALMNAME])SH
-39600 XM
-(<--)SH
-/Times-BoldItalic SF
-41619 XM
-(Enter your system's realm name.)SH
-/Courier SF
-8520 24714 MT
-(You will be prompted for the database Master Password.)SH
-8520 25828 MT
-(It is important that you NOT FORGET this password.)SH
-8520 28056 MT
-(Enter Kerberos master key:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter the master password.)SH
-14 /Times-Bold AF
-7200 32988 MT
-(2.2 Storing)
-350 W( the Master Password)SH
-11 /Times-Roman AF
-7200 35183 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(kstash)SH
-/Times-Roman SF
-12210 XM
-(command ``stashes'' the master password in the file)SH
-/Times-Italic SF
-35424 XM
-(/.k)SH
-/Times-Roman SF
-36768 XM
-(so that the Kerberos server can be)SH
-7200 36379 MT
-(started automatically during an unattended reboot of the master server.  Other administrative programs)SH
-7200 37575 MT
-(use this hidden password so that they can access the master database without someone having to manually)SH
-7200 38771 MT
-(provide the master password.  This command is an optional one; if you'd rather enter the master password)SH
-7200 39967 MT
-(each time you start the Kerberos server, don't use)SH
-/Times-Italic SF
-29312 XM
-(kstash)SH
-/Times-Roman SF
-(.)SH
-7200 42265 MT
-(One the one hand, if you use)SH
-/Times-Italic SF
-20090 XM
-(kstash)SH
-/Times-Roman SF
-(, a copy of the master key will reside on disk which may not be)SH
-7200 43461 MT
-(acceptable; on the other hand, if you don't use)SH
-/Times-Italic SF
-27848 XM
-(kstash)SH
-/Times-Roman SF
-(, the server cannot be started unless someone is)SH
-7200 44657 MT
-(around to type the password in manually.)SH
-7200 46955 MT
-(The command prompts you twice for the master password:)SH
-/Courier SF
-8520 48532 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-([ADMIN_DIR]/kstash)SH
-/Courier SF
-8520 50760 MT
-(Enter Kerberos master key:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter the master password.)SH
-/Courier SF
-8520 51874 MT
-(Current Kerberos master key version is 1.)SH
-8520 54102 MT
-(Master key entered)
-SH( BEWARE!)1320 W
-/Times-Roman SF
-7200 56400 MT
-(A note about the Kerberos database master key:  if your master key is compromised and the database is)SH
-7200 57596 MT
-(obtained, the security of your entire authentication system is compromised.  The master key must be a)SH
-7200 58792 MT
-(carefully kept secret.  If you keep backups, you must guard all the master keys you use, in case someone)SH
-7200 59988 MT
-(has stolen an old backup and wants to attack users' whose passwords haven't changed since the backup)SH
-7200 61184 MT
-(was stolen.  This is why we provide the option not to store it on disk.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(3)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 4 5
-BS
-0 SI
-14 /Times-Bold AF
-7200 8167 MT
-(2.3 Using)350 W
-/Times-BoldItalic SF
-13423 XM
-(kdb_edit)SH
-/Times-Bold SF
-18673 XM
-(to Add Users to the Master Database)SH
-11 /Times-Roman AF
-7200 10362 MT
-(The)SH
-/Times-Italic SF
-9185 XM
-(kdb_edit)SH
-/Times-Roman SF
-13248 XM
-(program is used to add new users and services to the master database, and to modify)SH
-7200 11558 MT
-(existing database information.  The program prompts you to enter a principal's)SH
-/Times-Bold SF
-42177 XM
-(name)SH
-/Times-Roman SF
-45018 XM
-(and)SH
-/Times-Bold SF
-46881 XM
-(instance)SH
-/Times-Roman SF
-(.)SH
-7200 13856 MT
-(A principal name is typically a username or a service program's name.  An instance further qualifies the)SH
-7200 15052 MT
-(principal. If)
-275 W( the principal is a service, the instance is used to specify the name of the machine on which)SH
-7200 16248 MT
-(that service runs.  If the principal is a username that has general user privileges, the instance is usually set)SH
-7200 17444 MT
-(to null.)SH
-7200 19742 MT
-(The following example shows how to use)SH
-/Times-Italic SF
-25805 XM
-(kdb_edit)SH
-/Times-Roman SF
-29868 XM
-(to add the user)SH
-/Times-Italic SF
-36588 XM
-(wave)SH
-/Times-Roman SF
-39123 XM
-(to the Kerberos database.)SH
-/Courier SF
-8520 21319 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-([ADMIN_DIR]/kdb_edit)SH
-/Courier SF
-8520 23547 MT
-(Opening database...)SH
-8520 25775 MT
-(Enter Kerberos master key:)SH
-8520 26889 MT
-(Verifying, please re-enter)SH
-8520 28003 MT
-(Enter Kerberos master key:)SH
-8520 29117 MT
-(Current Kerberos master key version is 1)SH
-8520 31345 MT
-(Master key entered.  BEWARE!)SH
-8520 32459 MT
-(Previous or default values are in [brackets] ,)SH
-8520 33573 MT
-(enter return to leave the same, or new value.)SH
-8520 35801 MT
-(Principal name:)SH
-/Times-Bold SF
-19080 XM
-(wave)SH
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter the username.)SH
-/Courier SF
-8520 36915 MT
-(Instance:)SH
-/Times-BoldItalic SF
-28800 XM
-(<-- Enter a null instance.)SH
-/Courier SF
-8520 39143 MT
-(<Not found>, Create [y] ?)SH
-/Times-Bold SF
-25680 XM
-(y)SH
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(The user-instance does not exist.)SH
-30450 40257 MT
-(Enter y to create the user-instance.)SH
-/Courier SF
-8520 41371 MT
-(Principal: wave  Instance:  m_key_v: 1)SH
-8520 42485 MT
-(New Password:)SH
-/Times-BoldItalic SF
-28800 XM
-(<-- Enter the user-instance's password.)SH
-/Courier SF
-8520 43599 MT
-(Verifying, please re-enter)SH
-8520 44713 MT
-(New Password:)SH
-8520 45827 MT
-(Principal's new key version = 1)SH
-8520 46941 MT
-(Expiration date \050enter dd-mm-yy\051 [ 12/31/99 ] ?)SH
-/Times-Bold SF
-39600 XM
-(<--)SH
-/Times-BoldItalic SF
-41619 XM
-(Enter newlines)SH
-/Courier SF
-8520 48055 MT
-(Max ticket lifetime \050*5 minutes\051 [ 255 ] ?)SH
-/Times-Bold SF
-39600 XM
-(<--)SH
-/Times-BoldItalic SF
-41619 XM
-(to get the)SH
-/Courier SF
-8520 49169 MT
-(Attributes [ 0 ] ?)SH
-/Times-Bold SF
-30120 XM
-(<--)SH
-/Times-BoldItalic SF
-32139 XM
-(default values.)SH
-/Courier SF
-8520 50283 MT
-(Edit O.K.)SH
-8520 52511 MT
-(Principal name:)SH
-/Times-BoldItalic SF
-28800 XM
-(<-- Enter a newline to exit the program.)SH
-/Times-Roman SF
-7200 54809 MT
-(Use the)SH
-/Times-Italic SF
-10804 XM
-(kdb_edit)SH
-/Times-Roman SF
-14867 XM
-(utility to add your username to the master database.)SH
-14 /Times-Bold AF
-7200 58627 MT
-(2.4 Starting)
-350 W( the Kerberos Server)SH
-11 /Times-Roman AF
-7200 60822 MT
-(Change directories to the directory in which you have installed the server program)SH
-/Times-Italic SF
-43701 XM
-(kerberos)SH
-/Times-Roman SF
-47824 XM
-(\050the default)SH
-7200 62018 MT
-(directory is)SH
-/Times-Italic SF
-12454 XM
-(/usr/etc)SH
-/Times-Roman SF
-(\051, and start the program as a background process:)SH
-/Courier SF
-8520 63595 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(./kerberos &)SH
-/Times-Roman SF
-7200 65190 MT
-(If you have used the)SH
-/Times-Italic SF
-16393 XM
-(kstash)SH
-/Times-Roman SF
-19418 XM
-(command to store the master database password, the server will start)SH
-7200 66386 MT
-(automatically. If)
-275 W( you did not use)SH
-/Times-Italic SF
-22048 XM
-(kstash)SH
-/Times-Roman SF
-(, use the following command:)SH
-/Courier SF
-8520 67963 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(./kerberos -m)SH
-10 /Times-Roman AF
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(4)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 5 6
-BS
-0 SI
-11 /Times-Roman AF
-7200 7955 MT
-(The server will prompt you to enter the master password before actually starting itself.)SH
-14 /Times-Bold AF
-7200 11773 MT
-(2.5 Testing)
-350 W( the Kerberos Server)SH
-11 /Times-Roman AF
-7200 13968 MT
-(Exit the root account and use the)SH
-/Times-Italic SF
-21893 XM
-(kinit)SH
-/Times-Roman SF
-24124 XM
-(command obtain a Kerberos ticket-granting ticket.  This command)SH
-7200 15164 MT
-(creates your ticket file and stores the ticket-granting ticket in it.)SH
-7200 17462 MT
-(If you used the default)SH
-/Times-Italic SF
-17371 XM
-(make install)SH
-/Times-Roman SF
-22993 XM
-(command and directories to install the Kerberos user utilities,)SH
-/Times-Italic SF
-50365 XM
-(kinit)SH
-/Times-Roman SF
-7200 18658 MT
-(will be in the)SH
-/Times-Italic SF
-13250 XM
-(/usr/athena)SH
-/Times-Roman SF
-18537 XM
-(directory. From now on, we'll refer to the Kerberos user commands directory as)SH
-7200 19854 MT
-([K_USER].)SH
-7200 22152 MT
-(Use)SH
-/Times-Italic SF
-9185 XM
-(kinit)SH
-/Times-Roman SF
-11416 XM
-(as follows:)SH
-/Courier SF
-8520 23729 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/kinit)SH
-/Courier SF
-8520 24843 MT
-(MIT Project Athena, \050ariadne\051)SH
-8520 25957 MT
-(Kerberos Initialization)SH
-8520 27071 MT
-(Kerberos name:)SH
-/Times-BoldItalic SF
-18420 XM
-(yourusername)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter your Kerberos username.)SH
-/Courier SF
-8520 28185 MT
-(Password:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter your Kerberos password.)SH
-/Times-Roman SF
-7200 30483 MT
-(Use the)SH
-/Times-Italic SF
-10804 XM
-(klist)SH
-/Times-Roman SF
-12913 XM
-(program to list the contents of your ticket file.)SH
-/Courier SF
-8520 32060 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/klist)SH
-/Times-Roman SF
-7200 33655 MT
-(The command should display something like the following:)SH
-/Courier SF
-8520 35181 MT
-(Ticket file:)
-SH( /tmp/tkt5555)1980 W
-8520 36295 MT
-(Principal: yourusername@REALMNAME)3300 W
-9840 38523 MT
-(Issued Expires)
-6600 W( Principal)5940 W
-8520 39637 MT
-(May 6)
-660 W( 10:15:23  May  6 18:15:23  krbtgt.REALMNAME@REALMNAME)SH
-/Times-Roman SF
-7200 41935 MT
-(If you have any problems, you can examine the log file)SH
-/Times-Italic SF
-31758 XM
-(/kerberos/kerberos.log)SH
-/Times-Roman SF
-42022 XM
-(on the Kerberos server)SH
-7200 43131 MT
-(machine to see if there was some sort of error.)SH
-16 /Times-Bold AF
-7200 47803 MT
-(3. Setting)
-400 W( up and testing the Administration server)SH
-11 /Times-Roman AF
-7200 49998 MT
-(The procedure for setting up and testing the Kerberos administration server is as follows:)SH
-9400 51949 MT
-(1.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kdb_edit)SH
-/Times-Roman SF
-18167 XM
-(utility to add your username with an administration instance to the master)SH
-10500 53145 MT
-(database.)SH
-9400 55039 MT
-(2.)SH
-10500 XM
-(Edit the access control lists for the administration server)SH
-9400 56933 MT
-(3.)SH
-10500 XM
-(Start the Kerberos administration server.)SH
-9400 58827 MT
-(4.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kpasswd)SH
-/Times-Roman SF
-18107 XM
-(command to change your password.)SH
-9400 60721 MT
-(5.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kadmin)SH
-/Times-Roman SF
-17617 XM
-(command to add new entries to the database.)SH
-9400 62615 MT
-(6.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(kinit)SH
-/Times-Roman SF
-16335 XM
-(command to verify that the)SH
-/Times-Italic SF
-28524 XM
-(kadmin)SH
-/Times-Roman SF
-32037 XM
-(command correctly added new entries to)SH
-10500 63811 MT
-(the database.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(5)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 6 7
-BS
-0 SI
-14 /Times-Bold AF
-7200 8138 MT
-(3.1 Adding)
-350 W( an administration instance for the administrator)SH
-11 /Times-Roman AF
-7200 10333 MT
-(Login to the Kerberos master server machine, and use the)SH
-/Times-Bold SF
-32825 XM
-(su)SH
-/Times-Roman SF
-34140 XM
-(command to become root.  Use the)SH
-/Times-Italic SF
-49780 XM
-(kdb_edit)SH
-/Times-Roman SF
-7200 11529 MT
-(program to create an entry for each administrator with the instance ``)SH
-/Times-BoldItalic SF
-(admin)SH
-/Times-Roman SF
-(''.)SH
-/Courier SF
-8520 13106 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-([ADMIN_DIR]/kdb_edit)SH
-/Courier SF
-8520 15334 MT
-(Opening database...)SH
-8520 17562 MT
-(Enter Kerberos master key:)SH
-8520 18676 MT
-(Verifying, please re-enter)SH
-8520 19790 MT
-(Enter Kerberos master key:)SH
-8520 20904 MT
-(Current Kerberos master key version is 1)SH
-8520 23132 MT
-(Master key entered.  BEWARE!)SH
-8520 24246 MT
-(Previous or default values are in [brackets] ,)SH
-8520 25360 MT
-(enter return to leave the same, or new value.)SH
-8520 27588 MT
-(Principal name:)SH
-/Times-Bold SF
-19080 XM
-(wave)SH
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter the username.)SH
-/Courier SF
-8520 28702 MT
-(Instance:)SH
-/Times-Bold SF
-(admin)SH
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter ``admin''.)SH
-/Courier SF
-8520 30930 MT
-(<Not found>, Create [y] ?)SH
-/Times-Bold SF
-25680 XM
-(y)SH
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(The user-instance does not exist.)SH
-30450 32044 MT
-(Enter y to create the user-instance.)SH
-/Courier SF
-8520 33158 MT
-(Principal: wave  Instance: admin m_key_v: 1)SH
-8520 34272 MT
-(New Password:)SH
-/Times-BoldItalic SF
-28800 XM
-(<-- Enter the user-instance's password.)SH
-/Courier SF
-8520 35386 MT
-(Verifying, please re-enter)SH
-8520 36500 MT
-(New Password:)SH
-8520 37614 MT
-(Principal's new key version = 1)SH
-8520 38728 MT
-(Expiration date \050enter dd-mm-yy\051 [ 12/31/99 ] ?)SH
-/Times-Bold SF
-39600 XM
-(<--)SH
-/Times-BoldItalic SF
-41619 XM
-(Enter newlines)SH
-/Courier SF
-8520 39842 MT
-(Max ticket lifetime \050*5 minutes\051 [ 255 ] ?)SH
-/Times-Bold SF
-39600 XM
-(<--)SH
-/Times-BoldItalic SF
-41619 XM
-(to get the)SH
-/Courier SF
-8520 40956 MT
-(Attributes [ 0 ] ?)SH
-/Times-Bold SF
-30120 XM
-(<--)SH
-/Times-BoldItalic SF
-32139 XM
-(default values.)SH
-/Courier SF
-8520 42070 MT
-(Edit O.K.)SH
-8520 44298 MT
-(Principal name:)SH
-/Times-BoldItalic SF
-28800 XM
-(<-- Enter a newline to exit the program.)SH
-14 /Times-Bold AF
-7200 48116 MT
-(3.2 The)
-350 W( Access Control Lists)SH
-11 /Times-Roman AF
-7200 50311 MT
-(The Kerberos administration server uses three access control lists to determine who is authorized to make)SH
-7200 51507 MT
-(certain requests.  The access control lists are stored on the master Kerberos server in the same directory as)SH
-7200 52703 MT
-(the principal database,)SH
-/Times-Italic SF
-17340 XM
-(/kerberos)SH
-/Times-Roman SF
-(. The)
-275 W( access control lists are simple ASCII text files, with each line)SH
-7200 53899 MT
-(specifying the name of one principal who is allowed the particular function.  To allow several people to)SH
-7200 55095 MT
-(perform the same function, put their principal names on separate lines in the same file.)SH
-7200 57393 MT
-(The first list,)SH
-/Times-Italic SF
-13128 XM
-(/kerberos/admin_acl.mod)SH
-/Times-Roman SF
-(, is a list of principals which are authorized to change entries in the)SH
-7200 58589 MT
-(database. To)
-275 W( allow the administrator `)SH
-/Times-Bold SF
-(wave)SH
-/Times-Roman SF
-(' to modify entries in the database for the realm `)SH
-/Times-Bold SF
-(TIM.EDU)SH
-/Times-Roman SF
-(',)SH
-7200 59785 MT
-(you would put the following line into the file)SH
-/Times-Italic SF
-27275 XM
-(/kerberos/admin_acl.mod)SH
-/Times-Roman SF
-(:)SH
-/Courier SF
-8520 61311 MT
-(wave.admin@TIM.EDU)SH
-/Times-Roman SF
-7200 63609 MT
-(The second list,)SH
-/Times-Italic SF
-14410 XM
-(/kerberos/admin_acl.get)SH
-/Times-Roman SF
-(, is a list of principals which are authorized to retrieve entries)SH
-7200 64805 MT
-(from the database.)SH
-7200 67103 MT
-(The third list,)SH
-/Times-Italic SF
-13434 XM
-(/kerberos/admin_acl.add)SH
-/Times-Roman SF
-(, is a list of principals which are authorized to add new entries to)SH
-7200 68299 MT
-(the database.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(6)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 7 8
-BS
-0 SI
-14 /Times-Bold AF
-7200 8138 MT
-(3.3 Starting)
-350 W( the administration server)SH
-11 /Times-Roman AF
-7200 10333 MT
-(Change directories to the directory in which you have installed the administration server program)SH
-/Times-Italic SF
-7200 11529 MT
-(kadmind)SH
-/Times-Roman SF
-11263 XM
-(\050the default directory is)SH
-/Times-Italic SF
-21831 XM
-(/usr/etc)SH
-/Times-Roman SF
-(\051, and start the program as a background process:)SH
-/Courier SF
-8520 13106 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(./kadmind -n&)SH
-/Times-Roman SF
-7200 14701 MT
-(If you have used the)SH
-/Times-Italic SF
-16393 XM
-(kstash)SH
-/Times-Roman SF
-19418 XM
-(command to store the master database password, the server will start)SH
-7200 15897 MT
-(automatically. If)
-275 W( you did not use)SH
-/Times-Italic SF
-22048 XM
-(kstash)SH
-/Times-Roman SF
-(, use the following command:)SH
-/Courier SF
-8520 17474 MT
-(host#)SH
-/Times-Bold SF
-12480 XM
-(./kadmind)SH
-/Times-Roman SF
-7200 19069 MT
-(The server will prompt you to enter the master password before actually starting itself; after it starts, you)SH
-7200 20265 MT
-(should suspend it and put it in the background \050usually this is done by typing control-Z and then)SH
-/Times-Bold SF
-49792 XM
-(bg)SH
-/Times-Roman SF
-(\051.)SH
-14 /Times-Bold AF
-7200 24112 MT
-(3.4 Testing)350 W
-/Times-BoldItalic SF
-14434 XM
-(kpasswd)SH
-11 /Times-Roman AF
-7200 26307 MT
-(To test the administration server, you should try changing your password with the)SH
-/Times-Italic SF
-43494 XM
-(kpasswd)SH
-/Times-Roman SF
-47497 XM
-(command, and)SH
-7200 27503 MT
-(you should try adding new users with the)SH
-/Times-Italic SF
-25592 XM
-(kadmin)SH
-/Times-Roman SF
-29105 XM
-(command \050both commands are installed into)SH
-/Times-Italic SF
-48963 XM
-(/usr/athena)SH
-/Times-Roman SF
-7200 28699 MT
-(by default\051.)SH
-7200 30997 MT
-(Before testing, you should exit the root account.)SH
-7200 33295 MT
-(To change your password, run the)SH
-/Times-Italic SF
-22441 XM
-(kpasswd)SH
-/Times-Roman SF
-26444 XM
-(command:)SH
-/Courier SF
-8520 34872 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/kpasswd)SH
-/Courier SF
-8520 35986 MT
-(Old password for wave@TIM.EDU:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-(Enter your password)SH
-/Courier SF
-8520 37100 MT
-(New Password for wave@TIM.EDU:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-(Enter a new password)SH
-/Courier SF
-8520 38214 MT
-(Verifying, please re-enter New Password for wave@TIM.EDU:)SH
-/Times-Bold SF
-28800 39328 MT
-(<--)SH
-/Times-BoldItalic SF
-(Enter new password again)SH
-/Courier SF
-8520 40442 MT
-(Password changed.)SH
-/Times-Roman SF
-7200 42037 MT
-(Once you have changed your password, use the)SH
-/Times-Italic SF
-28365 XM
-(kinit)SH
-/Times-Roman SF
-30596 XM
-(program as shown above to verify that the password)SH
-7200 43233 MT
-(was properly changed.)SH
-14 /Times-Bold AF
-7200 47080 MT
-(3.5 Testing)350 W
-/Times-BoldItalic SF
-14434 XM
-(kadmin)SH
-11 /Times-Roman AF
-7200 49275 MT
-(You should also test the function of the)SH
-/Times-Italic SF
-24798 XM
-(kadmin)SH
-/Times-Roman SF
-28311 XM
-(program, by adding a new user \050here named)SH
-7200 50471 MT
-(``)SH
-/Courier SF
-(username)SH
-/Times-Roman SF
-(''\051:)SH
-/Courier SF
-8520 52048 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/kadmin)SH
-/Courier SF
-8520 53162 MT
-(Welcome to the Kerberos Administration Program, version 2)SH
-8520 54276 MT
-(Type "help" if you need it.)SH
-8520 55390 MT
-(admin:)SH
-/Times-Bold SF
-13800 XM
-(ank username)SH
-/Times-BoldItalic SF
-28800 XM
-(`ank' stands for Add New Key)SH
-/Courier SF
-8520 56504 MT
-(Admin password:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-(enter the password)SH
-28800 57618 MT
-(you chose above for wave.admin)SH
-/Courier SF
-8520 58732 MT
-(Password for username:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-(Enter the user's initial password)SH
-/Courier SF
-8520 59846 MT
-(Verifying, please re-enter Password for username:)SH
-/Times-Bold SF
-40920 XM
-(<--)SH
-/Times-BoldItalic SF
-(enter it again)SH
-/Courier SF
-8520 60960 MT
-(username added to database.)SH
-8520 63188 MT
-(admin: quit)660 W
-8520 64302 MT
-(Cleaning up and exiting.)SH
-10 /Times-Roman AF
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(7)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 8 9
-BS
-0 SI
-14 /Times-Bold AF
-7200 8167 MT
-(3.6 Verifying)
-350 W( with)SH
-/Times-BoldItalic SF
-18671 XM
-(kinit)SH
-11 /Times-Roman AF
-7200 10362 MT
-(Once you've added a new user, you should test to make sure it was added properly by using)SH
-/Times-Italic SF
-47917 XM
-(kinit)SH
-/Times-Roman SF
-(, and)SH
-7200 11558 MT
-(trying to get tickets for that user:)SH
-/Courier SF
-8520 13135 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/kinit username)SH
-/Courier SF
-8520 14249 MT
-(MIT Project Athena \050ariadne\051)SH
-8520 15363 MT
-(Kerberos Initialization for "username@TIM.EDU")SH
-8520 16477 MT
-(Password:)SH
-/Times-Bold SF
-15120 XM
-(<--)SH
-/Times-BoldItalic SF
-(Enter the user's password you used above)SH
-/Courier SF
-8520 17591 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/klist)SH
-/Courier SF
-8520 18705 MT
-(Ticket file:)
-SH( /tmp/tkt_5509_spare1)1980 W
-8520 19819 MT
-(Principal: username@TIM.MIT.EDU)3300 W
-9840 22047 MT
-(Issued Expires)
-6600 W( Principal)5940 W
-8520 23161 MT
-(Nov 20 15:58:52  Nov 20 23:58:52  krbtgt.TIM.EDU@TIM.EDU)SH
-/Times-Roman SF
-7200 25459 MT
-(If you have any problems, you can examine the log files)SH
-/Times-Italic SF
-32186 XM
-(/kerberos/kerberos.log)SH
-/Times-Roman SF
-42450 XM
-(and)SH
-/Times-Italic SF
-7200 26655 MT
-(/kerberos/admin_server.syslog)SH
-/Times-Roman SF
-21008 XM
-(on the Kerberos server machine to see if there was some sort of error.)SH
-16 /Times-Bold AF
-7200 31327 MT
-(4. Setting)
-400 W( up and testing slave server\050s\051)SH
-11 /Times-Roman AF
-7200 33522 MT
-([Unfortunately, this chapter is not yet ready.  Sorry. -ed])SH
-16 /Times-Bold AF
-7200 38194 MT
-(5. A)
-400 W( Sample Application)SH
-11 /Times-Roman AF
-7200 40389 MT
-(This release of Kerberos comes with a sample application server and a corresponding client program.)SH
-7200 41585 MT
-(You will find this software in the [OBJ_DIR])SH
-/Times-Italic SF
-(/appl/sample)SH
-/Times-Roman SF
-33170 XM
-(directory. The)
-275 W( file)SH
-/Times-Italic SF
-41691 XM
-(sample_client)SH
-/Times-Roman SF
-48076 XM
-(contains the)SH
-7200 42781 MT
-(client program's executable code, the file)SH
-/Times-Italic SF
-25677 XM
-(sample_server)SH
-/Times-Roman SF
-32366 XM
-(contains the server's executable.)SH
-7200 45079 MT
-(The programs are rudimentary.  When they have been installed \050the installation procedure is described in)SH
-7200 46275 MT
-(detail later\051, they work as follows:)SH
-/Symbol SF
-9169 48351 MT
-(\267)SH
-/Times-Roman SF
-9950 XM
-(The user starts)SH
-/Times-Italic SF
-16639 XM
-(sample_client)SH
-/Times-Roman SF
-23024 XM
-(and provides as arguments to the command the name of the)SH
-9950 49547 MT
-(server machine and a checksum.  For instance:)SH
-/Courier SF
-11270 51147 MT
-(host%)SH
-/Times-Bold SF
-15230 XM
-(sample_client)SH
-/Times-BoldItalic SF
-22966 XM
-(servername 43)385 W
-/Symbol SF
-9169 53041 MT
-(\267)SH
-/Times-Italic SF
-9950 XM
-(Sample_client)SH
-/Times-Roman SF
-16457 XM
-(contacts the server machine and authenticates the user to)SH
-/Times-Italic SF
-41654 XM
-(sample_server)SH
-/Times-Roman SF
-(.)SH
-/Symbol SF
-9169 54935 MT
-(\267)SH
-/Times-Italic SF
-9950 XM
-(Sample_server)SH
-/Times-Roman SF
-16761 XM
-(authenticates itself to)SH
-/Times-Italic SF
-26384 XM
-(sample_client)SH
-/Times-Roman SF
-(, then returns a message to the client)SH
-9950 56131 MT
-(program. This)
-275 W( message contains diagnostic information that includes the user's username,)SH
-9950 57327 MT
-(the Kerberos realm, and the user's workstation address.)SH
-/Symbol SF
-9169 59221 MT
-(\267)SH
-/Times-Italic SF
-9950 XM
-(Sample_client)SH
-/Times-Roman SF
-16457 XM
-(displays the server's message on the user's terminal screen.)SH
-14 /Times-Bold AF
-7200 63039 MT
-(5.1 The)
-350 W( Installation Process)SH
-11 /Times-Roman AF
-7200 65234 MT
-(In general, you use the following procedure to install a Kerberos-authenticated server-client system.)SH
-9400 67185 MT
-(1.)SH
-10500 XM
-(Add the appropriate entry to the Kerberos database using)SH
-/Times-Italic SF
-35881 XM
-(kdb_edit)SH
-/Times-Roman SF
-39944 XM
-(or)SH
-/Times-Italic SF
-41135 XM
-(kadmin)SH
-/Times-Roman SF
-44648 XM
-(\050described)SH
-10500 68381 MT
-(below\051.)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(8)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 9 10
-BS
-0 SI
-11 /Times-Roman AF
-9400 7955 MT
-(2.)SH
-10500 XM
-(Create a)SH
-/Times-Italic SF
-14408 XM
-(/etc/srvtab)SH
-/Times-Roman SF
-19327 XM
-(file for the server machine.)SH
-9400 9849 MT
-(3.)SH
-10500 XM
-(Install the service program and the)SH
-/Times-Italic SF
-26016 XM
-(/etc/srvtab)SH
-/Times-Roman SF
-30935 XM
-(file on the server machine.)SH
-9400 11743 MT
-(4.)SH
-10500 XM
-(Install the client program on the client machine.)SH
-9400 13637 MT
-(5.)SH
-10500 XM
-(Update the)SH
-/Times-Italic SF
-15570 XM
-(/etc/services)SH
-/Times-Roman SF
-21281 XM
-(file on the client and server machines.)SH
-7200 15935 MT
-(We will use the sample application as an example, although the procedure used to install)SH
-/Times-Italic SF
-46484 XM
-(sample_server)SH
-/Times-Roman SF
-7200 17131 MT
-(differs slightly from the general case because the)SH
-/Times-Italic SF
-29006 XM
-(sample_server)SH
-/Times-Roman SF
-35695 XM
-(takes requests via the)SH
-/Times-Italic SF
-45347 XM
-(inetd)SH
-/Times-Roman SF
-47822 XM
-(program.)SH
-/Times-Italic SF
-7200 18327 MT
-(Inetd)SH
-/Times-Roman SF
-9735 XM
-(starts)SH
-/Times-Italic SF
-12332 XM
-(sample_server)SH
-/Times-Roman SF
-19021 XM
-(each time a client process contacts the server machine.)SH
-/Times-Italic SF
-43606 XM
-(Sample_server)SH
-/Times-Roman SF
-7200 19523 MT
-(processes the request, terminiates, then is restarted when)SH
-/Times-Italic SF
-32368 XM
-(inetd)SH
-/Times-Roman SF
-34843 XM
-(receives another)SH
-/Times-Italic SF
-42293 XM
-(sample_client)SH
-/Times-Roman SF
-48678 XM
-(request.)SH
-7200 20719 MT
-(When you install the program on the server, you must add a)SH
-/Times-Italic SF
-33807 XM
-(sample)SH
-/Times-Roman SF
-37198 XM
-(entry to the server machine's)SH
-/Times-Italic SF
-7200 21915 MT
-(/etc/inetd.conf)SH
-/Times-Roman SF
-13738 XM
-(file.)SH
-7200 24213 MT
-(The following description assumes that you are installing)SH
-/Times-Italic SF
-32680 XM
-(sample_server)SH
-/Times-Roman SF
-39369 XM
-(on the machine)SH
-/Times-Italic SF
-46364 XM
-(ariadne.tim.edu)SH
-/Times-Roman SF
-(.)SH
-7200 25409 MT
-(Here's the process, step by step:)SH
-9400 27360 MT
-(1.)SH
-10500 XM
-(Login as or)SH
-/Times-Italic SF
-15785 XM
-(su)SH
-/Times-Roman SF
-17038 XM
-(to root on the Kerberos server machine.  Use the)SH
-/Times-Italic SF
-38631 XM
-(kdb_edit)SH
-/Times-Roman SF
-42694 XM
-(or)SH
-/Times-Italic SF
-43885 XM
-(kadmin)SH
-/Times-Roman SF
-47398 XM
-(program)SH
-10500 28556 MT
-(to create an entry for)SH
-/Times-Italic SF
-19935 XM
-(sample)SH
-/Times-Roman SF
-23326 XM
-(in the Kerberos database:)SH
-/Courier SF
-11820 30133 MT
-(host#)SH
-/Times-Bold SF
-15780 XM
-([ADMIN_DIR]/kdb_edit)SH
-/Courier SF
-11820 32361 MT
-(Opening database...)SH
-11820 34589 MT
-(Enter Kerberos master key:)SH
-11820 35703 MT
-(Verifying, please re-enter)SH
-11820 36817 MT
-(master key entered.  BEWARE!)SH
-11820 37931 MT
-(Previous or default values are in [brackets] ,)SH
-11820 39045 MT
-(enter return to leave the same, or new value.)SH
-11820 41273 MT
-(Principal name:)SH
-/Times-Bold SF
-22380 XM
-(sample)SH
-26220 XM
-(<--)SH
-/Times-BoldItalic SF
-28239 XM
-(Enter the principal name.)SH
-/Courier SF
-11820 42387 MT
-(Instance:)SH
-/Times-Bold SF
-18420 XM
-(ariadne)SH
-26220 XM
-(<--)SH
-/Times-BoldItalic SF
-28239 XM
-(Instances cannot have periods in them.)SH
-/Courier SF
-11820 44615 MT
-(<Not found>, Create [y] ?)SH
-/Times-Bold SF
-28980 XM
-(y)SH
-/Courier SF
-11820 46843 MT
-(Principal: sample_server  Instance: ariadne m_key_v: 1)SH
-11820 47957 MT
-(New Password:)SH
-/Times-Bold SF
-26220 XM
-(<--)SH
-/Times-BoldItalic SF
-28239 XM
-(Enter ``RANDOM'' to get random password.)SH
-/Courier SF
-11820 49071 MT
-(Verifying, please re-enter)SH
-11820 50185 MT
-(New Password:)SH
-/Times-Bold SF
-26220 XM
-(<--)SH
-/Times-BoldItalic SF
-28239 XM
-(Enter ``RANDOM'' again.)SH
-/Courier SF
-11820 51299 MT
-(Random password [y] ?)SH
-/Times-Bold SF
-26340 XM
-(y)SH
-/Courier SF
-11820 53527 MT
-(Principal's new key version = 1)SH
-11820 54641 MT
-(Expiration date \050enter dd-mm-yy\051 [ 12/31/99 ] ?)SH
-11820 55755 MT
-(Max ticket lifetime \050*5 minutes\051 [ 255 ] ?)SH
-11820 56869 MT
-(Attributes [ 0 ] ?)SH
-11820 57983 MT
-(Edit O.K.)SH
-11820 60211 MT
-(Principal name:)SH
-/Times-Bold SF
-26220 XM
-(<--)SH
-/Times-BoldItalic SF
-28239 XM
-(Enter newline to exit kdb_edit.)SH
-/Times-Roman SF
-9400 62105 MT
-(2.)SH
-10500 XM
-(Use the)SH
-/Times-Italic SF
-14104 XM
-(ext_srvtab)SH
-/Times-Roman SF
-18961 XM
-(program to create a)SH
-/Times-Italic SF
-27755 XM
-(srvtab)SH
-/Times-Roman SF
-30780 XM
-(file for)SH
-/Times-Italic SF
-34078 XM
-(sample_server)SH
-/Times-Roman SF
-('s host machine:)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30350 XM
-(9)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 10 11
-BS
-0 SI
-11 /Courier AF
-11820 7937 MT
-(host#)SH
-/Times-Bold SF
-15780 XM
-([ADMIN_DIR]/ext_srvtab ariadne)275 W
-/Courier SF
-11820 10165 MT
-(Enter Kerberos master key:)SH
-11820 11279 MT
-(Current Kerberos master key version is 1.)SH
-11820 13507 MT
-(Generating 'ariadne-new-srvtab'....)SH
-/Times-Roman SF
-10500 15102 MT
-(Transfer the)SH
-/Times-Italic SF
-16118 XM
-(ariadne-new-srvtab)SH
-/Times-Roman SF
-25069 XM
-(file to)SH
-/Times-Italic SF
-27941 XM
-(ariadne)SH
-/Times-Roman SF
-31638 XM
-(and install it as)SH
-/Times-Italic SF
-38544 XM
-(/etc/srvtab)SH
-/Times-Roman SF
-(. Note)
-275 W( that this)SH
-10500 16298 MT
-(file is equivalent to the service's password and should be treated with care.  For example, it)SH
-10500 17494 MT
-(could be transferred by removable media, but should not be sent over an open network in)SH
-10500 18690 MT
-(the clear.  Once installed, this file should be readable only by root.)SH
-9400 20584 MT
-(3.)SH
-10500 XM
-(Add the following line to the)SH
-/Times-Italic SF
-23516 XM
-(/etc/services)SH
-/Times-Roman SF
-29227 XM
-(file on)SH
-/Times-Italic SF
-32343 XM
-(ariadne)SH
-/Times-Roman SF
-(, and on all machines that will run)SH
-10500 21780 MT
-(the)SH
-/Times-Italic SF
-12119 XM
-(sample_client)SH
-/Times-Roman SF
-18504 XM
-(program:)SH
-/Courier SF
-11820 23306 MT
-(sample 906/tcp)
-2640 W( #)
-3960 W( Kerberos sample app server)SH
-/Times-Roman SF
-9400 25200 MT
-(4.)SH
-10500 XM
-(Add a line similar to the following line to the)SH
-/Times-Italic SF
-30666 XM
-(/etc/inetd.conf)SH
-/Times-Roman SF
-37204 XM
-(file on)SH
-/Times-Italic SF
-40320 XM
-(sample_server)SH
-/Times-Roman SF
-('s)SH
-10500 26396 MT
-(machine:)SH
-/Courier SF
-11820 27922 MT
-(sample stream tcp nowait switched root)1320 W
-14460 29036 MT
-([PATH]/sample_server sample_server)SH
-/Times-Roman SF
-10500 30631 MT
-(where [PATH] should be substituted with the path to the)SH
-/Times-Italic SF
-35674 XM
-(sample_server)SH
-/Times-Roman SF
-42363 XM
-(program. \050This)275 W
-/Times-Italic SF
-10500 31827 MT
-(inetd.conf)SH
-/Times-Roman SF
-15144 XM
-(information should be placed on one line.\051  You should examine existing lines in)SH
-/Times-Italic SF
-10500 33023 MT
-(/etc/inetd.conf)SH
-/Times-Roman SF
-17038 XM
-(and use the same format used by other entries \050e.g. for telnet\051.  Most systems)SH
-10500 34219 MT
-(do not have a column for the `switched' keyword, and some do not have a column for the)SH
-10500 35415 MT
-(username \050usually `root', as above\051.)SH
-9400 37309 MT
-(5.)SH
-10500 XM
-(Restart)SH
-/Times-Italic SF
-13891 XM
-(inetd)SH
-/Times-Roman SF
-16366 XM
-(by sending the current)SH
-/Times-Italic SF
-26446 XM
-(inetd)SH
-/Times-Roman SF
-28921 XM
-(process a hangup signal:)SH
-/Courier SF
-11820 38909 MT
-(host#)SH
-/Times-Bold SF
-15780 XM
-(kill -HUP)275 W
-/Times-BoldItalic SF
-21373 XM
-(process_id_number)SH
-/Times-Roman SF
-9400 40803 MT
-(6.)SH
-10500 XM
-(The)SH
-/Times-Italic SF
-12485 XM
-(sample_server)SH
-/Times-Roman SF
-19174 XM
-(is now ready to take)SH
-/Times-Italic SF
-28307 XM
-(sample_client)SH
-/Times-Roman SF
-34692 XM
-(requests.)SH
-14 /Times-Bold AF
-7200 44621 MT
-(5.2 Testing)
-350 W( the Sample Server)SH
-11 /Times-Roman AF
-7200 46816 MT
-(Assume that you have installed)SH
-/Times-Italic SF
-21223 XM
-(sample_server)SH
-/Times-Roman SF
-27912 XM
-(on)SH
-/Times-Italic SF
-29287 XM
-(ariadne)SH
-/Times-Roman SF
-(.)SH
-7200 49114 MT
-(Login to your workstation and use the)SH
-/Times-Italic SF
-24217 XM
-(kinit)SH
-/Times-Roman SF
-26448 XM
-(command to obtain a Kerberos ticket-granting ticket:)SH
-/Courier SF
-8520 50691 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([K_USER]/kinit)SH
-/Courier SF
-8520 51805 MT
-(MIT Project Athena, \050your_workstation\051)SH
-8520 52919 MT
-(Kerberos Initialization)SH
-8520 54033 MT
-(Kerberos name:)SH
-/Times-BoldItalic SF
-18420 XM
-(yourusername)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter your Kerberos username.)SH
-/Courier SF
-8520 55147 MT
-(Password:)SH
-/Times-Bold SF
-28800 XM
-(<--)SH
-/Times-BoldItalic SF
-30819 XM
-(Enter your Kerberos password.)SH
-/Times-Roman SF
-7200 57445 MT
-(Now use the)SH
-/Times-Italic SF
-12973 XM
-(sample_client)SH
-/Times-Roman SF
-19358 XM
-(program as follows:)SH
-/Courier SF
-8520 59022 MT
-(host%)SH
-/Times-Bold SF
-12480 XM
-([PATH]/sample_client ariadne)275 W
-/Times-Roman SF
-7200 60617 MT
-(The command should display something like the following:)SH
-/Courier SF
-8520 62143 MT
-(The server says:)SH
-8520 63257 MT
-(You are)SH
-/Times-BoldItalic SF
-13800 XM
-(yourusername)SH
-/Courier SF
-(.@REALMNAME \050local name)SH
-/Times-BoldItalic SF
-36180 XM
-(yourusername)SH
-/Courier SF
-(\051,)SH
-9180 64371 MT
-(at address)SH
-/Times-BoldItalic SF
-16440 XM
-(yournetaddress)SH
-/Courier SF
-(, version VERSION9, cksum 997)SH
-10 /Times-Roman AF
-7200 75600 MT
-(MIT Project Athena)SH
-30100 XM
-(10)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: 11 12
-BS
-0 SI
-16 /Times-Bold AF
-7200 8272 MT
-(6. Service)
-400 W( names and other services)SH
-14 SS 
-7200 12090 MT
-(6.1 rlogin,)
-350 W( rsh, rcp, tftp, and others)SH
-11 /Times-Roman AF
-7200 14285 MT
-(Many services use a common principal name for authentication purposes.)SH
-/Times-Italic SF
-40128 XM
-(rlogin)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-43368 XM
-(rsh)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-45324 XM
-(rcp)SH
-/Times-Roman SF
-(,)SH
-/Times-Italic SF
-47340 XM
-(tftp)SH
-/Times-Roman SF
-49083 XM
-(and others)SH
-7200 15481 MT
-(use the principal name ``)SH
-/Courier SF
-(rcmd)SH
-/Times-Roman SF
-(''. For)
-275 W( example, to set up the machine)SH
-/Times-Italic SF
-38033 XM
-(ariadne)SH
-/Times-Roman SF
-41730 XM
-(to support Kerberos rlogin,)SH
-7200 16677 MT
-(it needs to have a service key for principal ``)SH
-/Courier SF
-(rcmd)SH
-/Times-Roman SF
-('', instance ``)SH
-/Courier SF
-(ariadne)SH
-/Times-Roman SF
-(''. You)
-275 W( create this key in the)SH
-7200 17873 MT
-(same way as shown above for the sample service.)SH
-7200 20171 MT
-(After creating this key, you need to run the)SH
-/Times-Italic SF
-26382 XM
-(ext_srvtab)SH
-/Times-Roman SF
-31239 XM
-(program again to generate a new srvtab file for)SH
-7200 21367 MT
-(ariadne.)SH
-14 /Times-Bold AF
-7200 25185 MT
-(6.2 NFS)
-350 W( modifications)SH
-11 /Times-Roman AF
-7200 27380 MT
-(The NFS modifications distributed separately use the service name ``)SH
-/Courier SF
-(rvdsrv)SH
-/Times-Roman SF
-('' with the instance set to)SH
-7200 28576 MT
-(the machine name \050as for the sample server and the rlogin, rsh, rcp and tftp services\051.)SH
-14 /Times-Bold AF
-7200 32394 MT
-(6.3 inetd.conf)
-350 W( entries)SH
-11 /Times-Roman AF
-7200 34589 MT
-(The following are the)SH
-/Times-Italic SF
-16974 XM
-(/etc/inetd.conf)SH
-/Times-Roman SF
-23512 XM
-(entries necessary to support rlogin, encrypted rlogin, rsh, and rcp)SH
-7200 35785 MT
-(services on a server machine.  As above, your)SH
-/Times-Italic SF
-27631 XM
-(inetd.conf)SH
-/Times-Roman SF
-32275 XM
-(may not support all the fields shown here.)SH
-/Courier SF
-8520 37311 MT
-(eklogin stream)
-660 W( tcp nowait unswitched root)1320 W
-11160 38425 MT
-([PATH]/klogind eklogind)1320 W
-8520 39539 MT
-(kshell stream tcp nowait unswitched root)1320 W
-11160 40653 MT
-([PATH]/kshd kshd)1320 W
-8520 41767 MT
-(klogin stream tcp nowait unswitched root)1320 W
-11160 42881 MT
-([PATH]/klogind klogind)1320 W
-10 /Times-Roman AF
-7200 75600 MT
-(MIT Project Athena)SH
-30100 XM
-(11)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Page: i 13
-BS
-0 SI
-14 /Times-Bold AF
-25272 8138 MT
-(Table of Contents)SH
-13 SS 
-7200 9781 MT
-(1. How)
-325 W( Kerberos Works: A Schematic Description)SH
-53350 XM
-(1)SH
-12 /Times-Roman AF
-9000 11130 MT
-(1.1 Network)
-300 W( Services and Their Client Programs)SH
-53400 XM
-(1)SH
-9000 12479 MT
-(1.2 Kerberos)
-300 W( Tickets)SH
-53400 XM
-(1)SH
-9000 13828 MT
-(1.3 The)
-300 W( Kerberos Master Database)SH
-53400 XM
-(1)SH
-9000 15177 MT
-(1.4 The)
-300 W( Ticket-Granting Ticket)SH
-53400 XM
-(1)SH
-9000 16526 MT
-(1.5 Network)
-300 W( Services and the Master Database)SH
-53400 XM
-(1)SH
-9000 17875 MT
-(1.6 The)
-300 W( User-Kerberos Interaction)SH
-53400 XM
-(2)SH
-13 /Times-Bold AF
-7200 19518 MT
-(2. Setting)
-325 W( Up and Testing the Kerberos Server)SH
-53350 XM
-(2)SH
-12 /Times-Roman AF
-9000 20867 MT
-(2.1 Creating)
-300 W( and Initializing the Master Database)SH
-53400 XM
-(3)SH
-9000 22216 MT
-(2.2 Storing)
-300 W( the Master Password)SH
-53400 XM
-(3)SH
-9000 23571 MT
-(2.3 Using)300 W
-/Times-BoldItalic SF
-14267 XM
-(kdb_edit)SH
-/Times-Roman SF
-18768 XM
-(to Add Users to the Master Database)SH
-53400 XM
-(4)SH
-9000 24920 MT
-(2.4 Starting)
-300 W( the Kerberos Server)SH
-53400 XM
-(4)SH
-9000 26269 MT
-(2.5 Testing)
-300 W( the Kerberos Server)SH
-53400 XM
-(5)SH
-13 /Times-Bold AF
-7200 27912 MT
-(3. Setting)
-325 W( up and testing the Administration server)SH
-53350 XM
-(5)SH
-12 /Times-Roman AF
-9000 29261 MT
-(3.1 Adding)
-300 W( an administration instance for the administrator)SH
-53400 XM
-(6)SH
-9000 30610 MT
-(3.2 The)
-300 W( Access Control Lists)SH
-53400 XM
-(6)SH
-9000 31959 MT
-(3.3 Starting)
-300 W( the administration server)SH
-53400 XM
-(7)SH
-9000 33314 MT
-(3.4 Testing)300 W
-/Times-BoldItalic SF
-15001 XM
-(kpasswd)SH
-/Times-Roman SF
-53400 XM
-(7)SH
-9000 34669 MT
-(3.5 Testing)300 W
-/Times-BoldItalic SF
-15001 XM
-(kadmin)SH
-/Times-Roman SF
-53400 XM
-(7)SH
-9000 36024 MT
-(3.6 Verifying)
-300 W( with)SH
-/Times-BoldItalic SF
-18501 XM
-(kinit)SH
-/Times-Roman SF
-53400 XM
-(8)SH
-13 /Times-Bold AF
-7200 37667 MT
-(4. Setting)
-325 W( up and testing slave server\050s\051)SH
-53350 XM
-(8)SH
-7200 39310 MT
-(5. A)
-325 W( Sample Application)SH
-53350 XM
-(8)SH
-12 /Times-Roman AF
-9000 40659 MT
-(5.1 The)
-300 W( Installation Process)SH
-53400 XM
-(8)SH
-9000 42008 MT
-(5.2 Testing)
-300 W( the Sample Server)SH
-52800 XM
-(10)SH
-13 /Times-Bold AF
-7200 43651 MT
-(6. Service)
-325 W( names and other services)SH
-52700 XM
-(11)SH
-12 /Times-Roman AF
-9000 45000 MT
-(6.1 rlogin,)
-300 W( rsh, rcp, tftp, and others)SH
-52800 XM
-(11)SH
-9000 46349 MT
-(6.2 NFS)
-300 W( modifications)SH
-52800 XM
-(11)SH
-9000 47698 MT
-(6.3 inetd.conf)
-300 W( entries)SH
-52800 XM
-(11)SH
-10 SS 
-7200 75600 MT
-(MIT Project Athena)SH
-30461 XM
-(i)SH
-47890 XM
-(4 January 1990)SH
-ES
-%%Trailer
-%%Pages: 13
-%%DocumentFonts: Times-Roman Times-Bold Times-Italic Times-BoldItalic Courier Symbol
diff --git a/doc/old-V4-docs/operation.mss b/doc/old-V4-docs/operation.mss
deleted file mode 100644
index a35bb9f95..000000000
--- a/doc/old-V4-docs/operation.mss
+++ /dev/null
@@ -1,799 +0,0 @@
-@Comment[	$Source$]
-@Comment[	$Author$]
-@Comment[	$Id$]
-@Comment[]
-@device[postscript]
-@make[report]
-@comment[
-@DefineFont(HeadingFont,
-      P=<RawFont "NewCenturySchlbkBoldItalic">,
-      B=<RawFont "NewCenturySchlbkBold">,
-      I=<RawFont "NewCenturySchlbkBoldItalic">,
-      R=<RawFont "NewCenturySchlbkRoman">)
-]
-@DefineFont(HeadingFont,
-      P=<RawFont "TimesBoldItalic">,
-      B=<RawFont "TimesBold">,
-      I=<RawFont "TimesItalic">,
-      R=<RawFont "TimesRoman">)
-@Counter(MajorPart,TitleEnv HD0,ContentsEnv tc0,Numbered [@I],
-          IncrementedBy Use,Announced)
-@Counter(Chapter,TitleEnv HD1,ContentsEnv tc1,Numbered [@1. ],
-          IncrementedBy Use,Referenced [@1],Announced)
-@Counter(Appendix,TitleEnv HD1,ContentsEnv tc1,Numbered [@A. ],
-          IncrementedBy,Referenced [@A],Announced,Alias Chapter)
-@Counter(UnNumbered,TitleEnv HD1,ContentsEnv tc1,Announced,Alias 
-           Chapter)
-@Counter(Section,Within Chapter,TitleEnv HD2,ContentsEnv tc2,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy
-          Use,Announced)
-@Counter(AppendixSection,Within Appendix,TitleEnv HD2,
-          ContentsEnv tc2,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy 
-          Use,Announced)
-@Counter(SubSection,Within Section,TitleEnv HD3,ContentsEnv tc3,
-          Numbered [@#@:.@1 ],IncrementedBy Use,
-          Referenced [@#@:.@1 ])
-@Counter(AppendixSubSection,Within AppendixSection,TitleEnv HD3,
-          ContentsEnv tc3,
-          Numbered [@#@:.@1 ],IncrementedBy Use,
-          Referenced [@#@:.@1 ])
-@Counter(Paragraph,Within SubSection,TitleEnv HD4,ContentsEnv tc4,
-          Numbered [@#@:.@1 ],Referenced [@#@:.@1],
-          IncrementedBy Use)
-@modify(CopyrightNotice, Fixed -1 inch, Flushright)
-@Modify(Titlebox, Fixed 3.0 inches)
-@Modify(hd1, below .2 inch, facecode B, size 16, spaces kept, pagebreak off)
-@Modify(hd2, below .2 inch, facecode B, size 14, spaces kept)
-@Modify(hd3, below .2 inch, facecode B, size 12, spaces kept)
-@Modify(Description, Leftmargin +20, Indent -20,below 1 line, above 1 line)
-@Modify(Tc1, Above .5,  Facecode B)
-@Modify(Tc2, Above .25, Below .25, Facecode R)
-@Modify(Tc3,Facecode R)
-@Modify(Tc4,Facecode R)
-@Modify(Itemize,Above 1line,Below 1line)
-@Modify(Insert,LeftMargin +2, RightMargin +2)
-@libraryfile[stable]
-@comment[@Style(Font NewCenturySchoolBook, size 11)]
-@Style(Font TimesRoman, size 11)
-@Style(Spacing 1.1, indent 0)
-@Style(leftmargin 1.0inch)
-@Style(justification no)
-@Style(BottomMargin 1.5inch)
-@Style(ChangeBarLocation Right)
-@Style(ChangeBars=off)
-@pageheading[immediate]
-@pagefooting[immediate, left = "MIT Project Athena", center = "@value(page)",
-right = "@value(date)"]
-@set[page = 0]
-@blankspace[.5 inches]
-@begin[group, size 20]
-@begin(center)
-@b[Kerberos Operation Notes]
-@b[DRAFT]
-@end[center]
-@blankspace[.5 inches]
-@end(group)
-@begin[group, size 16]
-@begin(center)
-Bill Bryant
-John Kohl
-Project Athena, MIT
-@blankspace[.5 inches]
-@b[Initial Release, January 24, 1989]
-@i[(plus later patches through patchlevel 7)]
-@end[center]
-@end(group)
-@begin[group, size 10]
-@end[group]
-@blankspace[1inches]
-
-These notes assume that you have used the
-@i[Kerberos Installation Notes] to build and install your
-Kerberos system.
-As in that document, we refer to the directory that contains
-the built Kerberos binaries as [OBJ_DIR].
-
-This document assumes that you are a Unix system manager.
-
-@newpage()
-@chapter[How Kerberos Works: A Schematic Description]
-
-This section provides a simplified description of
-a general user's interaction with the Kerberos system.
-This interaction happens transparently--users don't need to know
-and probably don't care about what's going on--but Kerberos administrators
-might find a schematic description of the process useful.
-The description glosses over a lot of details;
-for more information, see @i[Kerberos: An Authentication
-Service for Open Network Systems],
-a paper presented at Winter USENIX 1988, in Dallas, Texas.
-
-@section[Network Services and Their Client Programs]
-
-In an environment that provides network services,
-you use @i[client] programs to request service from
-@i[server] programs that are somewhere on the network.
-Suppose you have logged in to a workstation
-and you want to @i[rlogin] to another machine.
-You use the local @i[rlogin] client program to
-contact the remote machine's @i[rlogin] service daemon.
-
-@section[Kerberos Tickets]
-
-Under Kerberos, the @i[rlogin] service program
-allows a client to login to a remote machine if it
-can provide
-a Kerberos @b[ticket] for the request.
-This ticket proves the identity of the person who has used
-the client program to access the server program.
-
-@section[The Kerberos Master Database]
-
-Kerberos will give you tickets only if you
-have an entry in the Kerberos server's
-@b[master database].
-Your database entry includes your Kerberos username (often referred to
-as your Kerberos @b[principal] name), and your Kerberos password.
-Every Kerberos user must have an entry in this database.
-
-@section[The Ticket-Granting Ticket]
-
-The @i[kinit] command prompts for your Kerberos username and password,
-and if you enter them successfully, you will obtain a Kerberos
-@i[ticket-granting ticket].
-As illustrated below,
-client programs use this ticket to get other Kerberos tickets as
-needed.
-
-@section[Network Services and the Master Database]
-
-The master database also contains entries for all network services that
-require Kerberos authentication.
-Suppose for instance that your site has a machine @i[laughter]
-that requires Kerberos authentication from anyone who wants
-to @i[rlogin] to it.
-This service must be registered in the master database.
-Its entry includes the service's principal name, and its @b[instance].
-
-The @i[instance] is the name of the service's machine;
-in this case, the service's instance is the name @i[laughter].
-The instance provides a means for Kerberos to distinguish between
-machines that provide the same service.
-Your site is likely to have more than one machine that
-provides @i[rlogin] service.
-
-@section[The User-Kerberos Interaction]
-
-Suppose that you (in the guise of a general user) walk up to a workstation
-intending to login to it, and then @i[rlogin] to the machine @i[laughter].
-Here's what happens.
-@begin[enumerate]
-You login to the workstation and use the @i[kinit] command
-to to get a ticket-granting ticket.
-This command prompts you for your username (your Kerberos Principal Name),
-and your Kerberos password [on some systems which use the new version of
-@i{/bin/login}, this may be done as part of the login process, not
-requiring the user to run a separate program].
-@begin[enumerate]
-The @i[kinit] command sends your request to the Kerberos master server
-machine.
-The server software looks for your principal name's entry in the
-Kerberos @b[master database].
-
-If this entry exists, the
-Kerberos server creates and returns a
-@i[ticket-granting ticket], encrypted in your password.
-If @i[kinit] can decrypt the Kerberos reply using the password you
-provide, it stores this ticket in a @b[ticket file] on your
-local machine for later use.
-The ticket file to be used
-can be specified in the @b[KRBTKFILE] environment
-variable.  If this variable is not set, the name of the file will be
-@i[/tmp/tkt@p(uid)], where @p(uid) is the UNIX user-id, represented in decimal.
-@end[enumerate]
-
-Now you use the @i[rlogin] client to try to access the machine @i[laughter].
-@begin[example]
-host% @b[rlogin  laughter]
-@end[example]
-@begin[enumerate]
-The @i[rlogin] client checks your ticket file to see if you
-have a ticket for @i[laughter]'s @i[rcmd] service (the rlogin program
-uses the @i[rcmd] service name, mostly for historical reasons).
-You don't, so @i[rlogin] uses the ticket file's @i[ticket-granting
-ticket] to make a request to the master server's ticket-granting service.
-
-This ticket-granting service receives the @i[rcmd-laughter] request
-and looks in the master database for an @i[rcmd-laughter] entry.
-If that entry exists, the ticket-granting service issues you a ticket
-for that service.
-That ticket is also cached in your ticket file.
-
-The @i[rlogin] client now uses that ticket to request service from
-the @i[laughter] @i[rlogin] service program.
-The service program
-lets you @i[rlogin] if the ticket is valid.
-@end[enumerate]
-@end[enumerate]
-
-@chapter[Setting Up and Testing the Kerberos Server]
-
-The procedure for setting up and testing a Kerberos server
-is as follows:
-@begin[enumerate]
-Use the @i[kdb_init] command to create and initialize the master database.
-
-Use the @i[kdb_edit] utility to add your username to the
-master database.
-
-Start the Kerberos server.
-
-Use the @i[kinit] command to obtain a Kerberos ticket-granting ticket.
-
-Use the @i[klist] command to verify that the @i[kinit] command
-authenticated you successfully.
-@end[enumerate]
-
-@section[Creating and Initializing the Master Database]
-
-Login to the Kerberos master server machine,
-and use the @b[su] command to become root.
-If you installed the Kerberos administration tools
-with the @i[make install] command and the default pathnames,
-they should be in the @i[/usr/etc] directory.
-If you installed the tools in a different directory,
-hopefully you know what it is.
-From now on, we will refer to this directory as [ADMIN_DIR].
-
-The @i[kdb_init] command creates and initializes the master database.
-It asks you to enter the system's
-realm name and the database's master password.
-Do not forget this password.
-If you do, the database becomes useless.
-(Your realm name should be substituted for [REALMNAME] below.)
-
-Use @i[kdb_init] as follows:
-@tabset[3inches, +1.5inches]
-@begin[example, rightmargin -10]
-host# @b([ADMIN_DIR]/kdb_init)
-Realm name (default XXX): @b([REALMNAME])@\@b[<--] @p[Enter your system's realm name.]
-You will be prompted for the database Master Password.
-It is important that you NOT FORGET this password.
-
-Enter Kerberos master key: @\@b[<--] @p[Enter the master password.]
-@comment(this needs to be re-fixed...:
-Verifying, please re-enter
-Enter Kerberos master key: @\@b[<--] @p[Re-enter it.]
-)
-@end[example]
-
-@section[Storing the Master Password]
-
-The @i[kstash] command ``stashes'' the master password in the file @i[/.k]
-so that the Kerberos server can
-be started automatically during an unattended reboot of the
-master server.
-Other administrative programs use this hidden password so that they
-can access the master database without someone having to manually
-provide the master password.
-This command is an optional one;
-if you'd rather enter the master password each time you
-start the Kerberos server, don't use @i[kstash].
-
-One the one hand, if you use @i[kstash], a copy of the master
-key will reside
-on disk which may not be acceptable; on the other hand, if you don't
-use @i[kstash], the server cannot be started unless someone is around to
-type the password in manually.
-
-The command prompts you twice for the master password:
-@begin[example]
-@tabset[3inches]
-host# @b([ADMIN_DIR]/kstash)
-
-Enter Kerberos master key:@\@b[<--] @p[Enter the master password.]
-Current Kerberos master key version is 1.
-
-Master key entered   BEWARE!
-@end[example]
-
-A note about the Kerberos database master key:
-if your master key is compromised and the database is obtained,
-the security of your entire authentication system is compromised.
-The master key must be a carefully kept secret.  If you keep backups,
-you must guard all the master keys you use, in case someone has stolen
-an old backup and wants to attack users' whose passwords haven't changed
-since the backup was stolen.
-This is why we provide the option not to store it on disk.
-
-@section[Using @p(kdb_edit) to Add Users to the Master Database]
-
-The @i[kdb_edit] program is used to add new users and services
-to the master database, and to modify existing database information.
-The program prompts you to enter a principal's @b[name] and @b[instance].
-
-A principal name is typically a username or a service program's name.
-An instance further qualifies the principal.
-If the principal is a service,
-the instance is used to specify the name of the machine on which that
-service runs.
-If the principal is a username that has general user privileges,
-the instance is usually set to null.
-
-The following example shows how to use @i[kdb_edit] to
-add the user @i[wave] to the Kerberos database.
-@begin[example, rightmargin -10]
-@tabset[3inches, +1.5inches]
-host# @b([ADMIN_DIR]/kdb_edit)
-
-Opening database...
-
-Enter Kerberos master key:
-Verifying, please re-enter
-Enter Kerberos master key:
-Current Kerberos master key version is 1
-
-Master key entered.  BEWARE!
-Previous or default values are in [brackets] ,
-enter return to leave the same, or new value.
-
-Principal name: @b[wave]@\@b[<--] @p[Enter the username.]
-Instance:@\@p[<-- Enter a null instance.]
-
-<Not found>, Create [y] ? @b[y]@\@b[<--] @p[The user-instance does not exist.]
-@\@p[      Enter y to create the user-instance.]
-Principal: wave  Instance:  m_key_v: 1
-New Password: @\@p[<-- Enter the user-instance's password.]
-Verifying, please re-enter 
-New Password:
-Principal's new key version = 1
-Expiration date (enter dd-mm-yy) [ 12/31/99 ] ?@\@b[<--] @p[Enter newlines]
-Max ticket lifetime (*5 minutes) [ 255 ] ? @\@b[<--] @p[to get the]
-Attributes [ 0 ] ? @\@\@b[<--] @p[default values.]
-Edit O.K.
-
-Principal name:@\@p[<-- Enter a newline to exit the program.]
-@end[example]
-
-Use the @i[kdb_edit] utility to add your username to the master database.
-
-@section[Starting the Kerberos Server]
-
-Change directories to the directory in which you have installed
-the server program @i[kerberos]
-(the default directory is @i[/usr/etc]),
-and start the program as a background process:
-@begin[example]
-host# @b[./kerberos &]
-@end[example]
-If you have used the @i[kstash] command to store the master database password,
-the server will start automatically.
-If you did not use @i[kstash],
-use the following command:
-@begin[example]
-host# @b[./kerberos -m]
-@end[example]
-The server will prompt you to enter the master password before actually
-starting itself.
-
-@section[Testing the Kerberos Server]
-
-Exit the root account and use the @i[kinit] command obtain a Kerberos
-ticket-granting ticket.
-This command
-creates your ticket file
-and stores the ticket-granting ticket in it.
-
-If you used the default @i[make install] command and directories to
-install the Kerberos user utilities, @i[kinit] will be in the
-@i[/usr/athena] directory. From now on, we'll refer to the Kerberos user
-commands directory as [K_USER].
-
-Use @i[kinit] as follows:
-@begin[example]
-@tabset[3 inches]
-host% @b([K_USER]/kinit)
-MIT Project Athena, (ariadne)
-Kerberos Initialization
-Kerberos name: @p[yourusername]@\@b[<--] @p[Enter your Kerberos username.]
-Password: @\@b[<--] @p[Enter your Kerberos password.]
-@end[example]
-
-Use the @i[klist] program to list the contents of your ticket file.
-@begin[example]
-host% @b([K_USER]/klist)
-@end[example]
-The command should display something like the following:
-@begin[example]
-Ticket file:    /tmp/tkt5555
-Principal:      yourusername@@REALMNAME
-
-  Issued           Expires          Principal
-May  6 10:15:23  May  6 18:15:23  krbtgt.REALMNAME@@REALMNAME
-@end[example]
-
-If you have any problems, you can examine the log file
-@i[/kerberos/kerberos.log] on the Kerberos server machine to see if
-there was some sort of error.
-
-@chapter[Setting up and testing the Administration server]
-
-The procedure for setting up and testing the Kerberos administration server
-is as follows:
-@begin[enumerate]
-Use the @i[kdb_edit] utility to add your username with an administration
-instance to the master database.
-
-Edit the access control lists for the administration server
-
-Start the Kerberos administration server.
-
-Use the @i[kpasswd] command to change your password.
-
-Use the @i[kadmin] command to add new entries to the database.
-
-Use the @i[kinit] command to verify that the @i[kadmin] command
-correctly added new entries to the database.
-@end(enumerate)
-
-@section[Adding an administration instance for the administrator]
-
-Login to the Kerberos master server machine,
-and use the @b[su] command to become root.
-Use the @i[kdb_edit] program to create an entry for each administrator
-with the instance ``@p(admin)''.
-@begin[example]
-@tabset[3inches, +1.5inches]
-host# @b([ADMIN_DIR]/kdb_edit)
-
-Opening database...
-
-Enter Kerberos master key:
-Verifying, please re-enter
-Enter Kerberos master key:
-Current Kerberos master key version is 1
-
-Master key entered.  BEWARE!
-Previous or default values are in [brackets] ,
-enter return to leave the same, or new value.
-
-Principal name: @b[wave]@\@b[<--] @p[Enter the username.]
-Instance:@b[admin]@\@b[<--] @p[Enter ``admin''.]
-
-<Not found>, Create [y] ? @b[y]@\@b[<--] @p[The user-instance does not exist.]
-@\@p[      Enter y to create the user-instance.]
-Principal: wave  Instance: admin m_key_v: 1
-New Password: @\@p[<-- Enter the user-instance's password.]
-Verifying, please re-enter 
-New Password:
-Principal's new key version = 1
-Expiration date (enter dd-mm-yy) [ 12/31/99 ] ?@\@b[<--] @p[Enter newlines]
-Max ticket lifetime (*5 minutes) [ 255 ] ? @\@b[<--] @p[to get the]
-Attributes [ 0 ] ? @\@\@b[<--] @p[default values.]
-Edit O.K.
-
-Principal name:@\@p[<-- Enter a newline to exit the program.]
-@end[example]
-
-@section[The Access Control Lists]
-The Kerberos administration server uses three access control lists to
-determine who is authorized to make certain requests.  The access
-control lists are stored on the master Kerberos server in the same
-directory as the principal database, @i(/kerberos).  The access control
-lists are simple ASCII text files, with each line specifying the name of
-one principal who is allowed the particular function.  To allow several
-people to perform the same function, put their principal names on
-separate lines in the same file.
-
-The first list, @i(/kerberos/admin_acl.mod), is a list of principals
-which are authorized to change entries in the database.  To allow the
-administrator `@b[wave]' to modify entries in the database for the realm
-`@b[TIM.EDU]', you would put the following line into the file
-@i(/kerberos/admin_acl.mod):
-@begin(example)
-wave.admin@@TIM.EDU
-@end(example)
-
-The second list, @i(/kerberos/admin_acl.get), is a list of principals
-which are authorized to retrieve entries from the database.
-
-The third list, @i(/kerberos/admin_acl.add), is a list of principals
-which are authorized to add new entries to the database.
-
-@section(Starting the administration server)
-Change directories to the directory in which you have installed
-the administration server program @i[kadmind]
-(the default directory is @i[/usr/etc]),
-and start the program as a background process:
-@begin[example]
-host# @b[./kadmind -n&]
-@end[example]
-If you have used the @i[kstash] command to store the master database password,
-the server will start automatically.
-If you did not use @i[kstash],
-use the following command:
-@begin[example]
-host# @b[./kadmind]
-@end[example]
-The server will prompt you to enter the master password before actually
-starting itself; after it starts, you should suspend it and put it in
-the background (usually this is done by typing control-Z and then @b(bg)).
-
-@section(Testing @p[kpasswd])
-
-To test the administration server, you should try changing your password
-with the @i[kpasswd] command, and you should try adding new users with
-the @i[kadmin] command (both commands are installed into @i[/usr/athena]
-by default).
-
-Before testing, you should exit the root account.
-
-To change your password, run the @i[kpasswd] command:
-@begin(example)
-@tabset[3inches, +1.5inches]
-host% @b([K_USER]/kpasswd)
-Old password for wave@@TIM.EDU:@\@b[<--]@p[Enter your password]
-New Password for wave@@TIM.EDU:@\@b[<--]@p[Enter a new password]
-Verifying, please re-enter New Password for wave@@TIM.EDU:
-@\@b[<--]@p[Enter new password again]
-Password changed.
-@end(example)
-Once you have changed your password, use the @i[kinit] program as shown
-above to verify that the password was properly changed.
-
-@section(Testing @p[kadmin])
-You should also test the function of the @i[kadmin] program, by adding a
-new user (here named ``@t[username]''):
-@begin(example)
-@tabset[3inches, +1.5inches]
-host% @b([K_USER]/kadmin)
-Welcome to the Kerberos Administration Program, version 2
-Type "help" if you need it.
-admin:  @b(ank username)@\@p[`ank' stands for Add New Key]
-Admin password: @\@b[<--]@p[enter the password 
-@\you chose above for wave.admin]
-Password for username:@\@b[<--]@p[Enter the user's initial password]
-Verifying, please re-enter Password for username:@\@b[<--]@p[enter it again]
-username added to database.
-
-admin:  quit
-Cleaning up and exiting.
-@end[example]
-
-@section(Verifying with @p[kinit])
-Once you've added a new user, you should test to make sure it was added
-properly by using @i[kinit], and trying to get tickets for that user:
-
-@begin[example]
-@tabset[3inches, +1.5inches]
-host% @b([K_USER]/kinit username)
-MIT Project Athena (ariadne)
-Kerberos Initialization for "username@@TIM.EDU"
-Password: @b[<--]@p[Enter the user's password you used above]
-host% @b([K_USER]/klist)
-Ticket file:    /tmp/tkt_5509_spare1
-Principal:      username@@TIM.MIT.EDU
-
-  Issued           Expires          Principal
-Nov 20 15:58:52  Nov 20 23:58:52  krbtgt.TIM.EDU@@TIM.EDU
-@end[example]
-
-If you have any problems, you can examine the log files
-@i[/kerberos/kerberos.log] and @i[/kerberos/admin_server.syslog] on the
-Kerberos server machine to see if there was some sort of error.
-
-@chapter[Setting up and testing slave server(s)]
-
-[Unfortunately, this chapter is not yet ready.  Sorry. -ed]
-
-@chapter[A Sample Application]
-
-This release of Kerberos comes with a sample application
-server and a corresponding client program.
-You will find this software in the [OBJ_DIR]@i[/appl/sample] directory.
-The file @i[sample_client] contains the client program's executable
-code, the file @i[sample_server] contains the server's executable.
-
-The programs are rudimentary.
-When they have been installed (the installation procedure is described
-in detail later), they work as follows:
-@begin[itemize]
-The user starts @i[sample_client] and provides as arguments
-to the command the name of the server machine and a checksum.
-For instance:
-@begin[example]
-host% @b[sample_client]  @p[servername] @p[43]
-@end[example]
-
-@i[Sample_client] contacts the server machine and
-authenticates the user to @i[sample_server].
-
-@i[Sample_server] authenticates itself to @i[sample_client],
-then returns a message to the client program.
-This message contains diagnostic information
-that includes the user's username, the Kerberos realm,
-and the user's workstation address.
-
-@i[Sample_client] displays the server's message on the user's
-terminal screen.
-@end[itemize]
-
-@section[The Installation Process]
-
-In general,
-you use the following procedure to install a Kerberos-authenticated
-server-client system.
-@begin[enumerate]
-Add the appropriate entry to the Kerberos database using @i[kdb_edit] or
-@i[kadmin] (described below).
-
-Create a @i[/etc/srvtab] file for the server machine.
-
-Install the service program and the @i[/etc/srvtab]
-file on the server machine.
-
-Install the client program on the client machine.
-
-Update the @i[/etc/services] file on the client and server machines.
-@end[enumerate]
-
-We will use the sample application as an example, although
-the procedure used to install @i[sample_server] differs slightly
-from the general case because the @i[sample_server]
-takes requests via the
-@i[inetd] program.
-@i[Inetd] starts @i[sample_server] each time
-a client process contacts the server machine.
-@i[Sample_server] processes the request,
-terminiates, then is restarted when @i[inetd] receives another
-@i[sample_client] request.
-When you install the program on the server,
-you must add a @i[sample] entry to the server machine's
-@i[/etc/inetd.conf] file.
-
-The following description assumes that you are installing
-@i[sample_server] on the machine @i[ariadne.tim.edu].
-Here's the process, step by step:
-@begin[enumerate]
-Login as or @i[su] to root on the Kerberos server machine.
-Use the @i[kdb_edit] or @i[kadmin] program to create an entry for
-@i[sample] in the Kerberos database:
-@begin[example, rightmargin -10]
-@tabset[2.0inches, +.5inches]
-host# @b([ADMIN_DIR]/kdb_edit)
-
-Opening database...
-
-Enter Kerberos master key:
-Verifying, please re-enter
-master key entered.  BEWARE!
-Previous or default values are in [brackets] ,
-enter return to leave the same, or new value.
-
-Principal name: @b[sample]@\@b[<--] @p[Enter the principal name.]
-Instance: @b[ariadne]@\@b[<--] @p[Instances cannot have periods in them.]
-
-<Not found>, Create [y] ? @b[y]
-
-Principal: sample_server  Instance: ariadne m_key_v: 1
-New Password:@\@b[<--] @p[Enter ``RANDOM'' to get random password.]
-Verifying, please re-enter 
-New Password:@\@b[<--] @p[Enter ``RANDOM'' again.]
-Random password [y] ? @b[y]
-
-Principal's new key version = 1
-Expiration date (enter dd-mm-yy) [ 12/31/99 ] ? 
-Max ticket lifetime (*5 minutes) [ 255 ] ? 
-Attributes [ 0 ] ? 
-Edit O.K.
-
-Principal name:@\@b[<--] @p[Enter newline to exit kdb_edit.]
-@end[example]
-
-Use the @i[ext_srvtab] program to create a @i[srvtab] file
-for @i[sample_server]'s host machine:
-@begin[example]
-host# @b([ADMIN_DIR]/ext_srvtab  ariadne)
-
-Enter Kerberos master key: 
-Current Kerberos master key version is 1.
-
-Generating 'ariadne-new-srvtab'....
-@end[example]
-Transfer the @i[ariadne-new-srvtab] file to @i[ariadne] and install it as
-@i[/etc/srvtab].
-Note that this file is equivalent to the service's password and should
-be treated with care.
-For example, it could be transferred by removable media, but should
-not be sent over an open network in the clear.
-Once installed, this file should be readable only by root.
-
-Add the following line to the @i[/etc/services] file on
-@i[ariadne], and on all machines that
-will run the @i[sample_client] program:
-@begin[example]
-sample     906/tcp       # Kerberos sample app server
-@end[example]
-
-Add a line similar to the following line to the @i[/etc/inetd.conf]
-file on @i[sample_server]'s machine:
-@begin[example]
-sample   stream   tcp   nowait   switched   root
-    [PATH]/sample_server sample_server
-@end[example]
-where [PATH] should be substituted with
-the path to the @i[sample_server] program.
-(This @i[inetd.conf] information should be placed on one line.)
-You should examine existing lines in @i[/etc/inetd.conf] and use the
-same format used by other entries (e.g. for telnet).  Most systems do
-not have a column for the `switched' keyword, and some do not have a
-column for the username (usually `root', as above).
-
-Restart @i[inetd] by sending the current @i[inetd] process
-a hangup signal:
-@begin[example]
-host# @b[kill  -HUP   @p(process_id_number)]
-@end[example]
-
-The @i[sample_server] is now ready to take @i[sample_client] requests.
-@end[enumerate]
-
-@section[Testing the Sample Server]
-
-Assume that you have installed @i[sample_server] on @i[ariadne].
-
-Login to your workstation and use the @i[kinit] command to
-obtain a Kerberos ticket-granting ticket:
-@begin[example]
-@tabset[3 inches]
-host% @b([K_USER]/kinit)
-MIT Project Athena, (your_workstation)
-Kerberos Initialization
-Kerberos name: @p[yourusername]@\@b[<--] @p[Enter your Kerberos username.]
-Password: @\@b[<--] @p[Enter your Kerberos password.]
-@end[example]
-
-Now use the @i[sample_client] program as follows:
-@begin[example]
-host% @b([PATH]/sample_client  ariadne)
-@end[example]
-The command should display something like the following:
-@begin[example]
-The server says:
-You are @p[yourusername].@@REALMNAME (local name @p[yourusername]),
- at address @p[yournetaddress], version VERSION9, cksum 997
-@end[example]
-
-@chapter[Service names and other services]
-
-@section(rlogin, rsh, rcp, tftp, and others)
-
-Many services use a common principal name for authentication purposes.
-@i[rlogin], @i[rsh], @i[rcp], @i[tftp] and others use the principal name
-``@t[rcmd]''.  For example, to set up the machine @i[ariadne] to support
-Kerberos rlogin, it needs to have a service key for principal
-``@t[rcmd]'', instance ``@t[ariadne]''.  You create this key in the same
-way as shown above for the sample service.
-
-After creating this key, you need to run the @i[ext_srvtab] program
-again to generate a new srvtab file for ariadne.
-
-@section(NFS modifications)
-
-The NFS modifications distributed separately use the service name
-``@t[rvdsrv]'' with the instance set to the machine name (as for the
-sample server and the rlogin, rsh, rcp and tftp services).
-
-@section(inetd.conf entries)
-The following are the @i(/etc/inetd.conf) entries necessary to support
-rlogin, encrypted rlogin, rsh, and rcp services on a server machine.  As
-above, your @i(inetd.conf) may not support all the fields shown here.
-@begin[example]
-eklogin  stream   tcp   nowait   unswitched   root
-    [PATH]/klogind   eklogind
-kshell   stream   tcp   nowait   unswitched   root
-    [PATH]/kshd   kshd
-klogin   stream   tcp   nowait   unswitched   root
-    [PATH]/klogind   klogind
-@end[example]
diff --git a/doc/rpc/design.tex b/doc/rpc/design.tex
deleted file mode 100644
index fbd60f914..000000000
--- a/doc/rpc/design.tex
+++ /dev/null
@@ -1,1037 +0,0 @@
-\documentstyle[fullpage,12pt]{article}
-
-\title{GSS-API Extensions to Sun RPC}
-\date{Draft---\today}
-\author{Barry Jaspan}
-
-\setlength{\parskip}{.7\baselineskip}
-\setlength{\parindent}{0pt}
-
-\makeatletter
-\newcount\savecnt\savecnt=0
-\def\saveenum#1{\global\savecnt=\csname c@enum#1\endcsname}
-\def\restoreenum#1{\csname c@enum#1\endcsname=\savecnt}
-\makeatother
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Make _ actually generate an _, and allow line-breaking after it.
-\let\underscore=\_
-\catcode`_=13
-\def_{\underscore\penalty75\relax}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\begin{document}
-
-
-{\setlength{\parskip}{0pt}\maketitle\tableofcontents}
-
-\section{Introduction}
-
-This document describes the integration of GSS-API authentication and
-security with Sun RPC.
-
-\section{Requirements}
-
-The requirements of the GSS-API authentication system for Sun RPC are:
-
-\begin{enumerate}
-\item It must provide mutual authentication between RPC clients and
-servers.
-
-\item It must provide for integrity checking and encryption of all
-procedure arguments and results passed over the network.
-\saveenum{i}
-\end{enumerate}
-
-The following features are desired, but not mandatory:
-
-\begin{enumerate}
-\restoreenum{i}
-\item It should provide for integrity checking and encryption of all
-``header information'' that specifies the program and procedure being
-called.
-
-\item It should obey the Sun RPC protocol so that clients using
-it can interoperate with existing servers.  In this case,
-``interoperate'' means that existing servers will return an error code
-indicating that they do not understand the authentication flavor, but
-not that they do not understand the request at all.
-
-\item It should require minimal or no changes to the standard Sun RPC
-programming paradigm for either clients or servers so that existing
-code can use it with little or no effort.
-
-\item It should operate correctly with all the standard Sun RPC
-transport mechansims (e.g. UDP and TCP).
-\saveenum{i}
-\end{enumerate}
-
-\section{Functional Specification}
-
-This section describes the programmer's interface to the GSS-API
-authentication flavor.   Knowledge of standard Sun RPC programming is
-assumed.
-
-\subsection{Client Side}
-
-A RPC client can select the GSS-API authentication flavor in the same
-way it can select any other authentication flavor, by setting the
-cl_auth field of the CLIENT structure to the appropriate value:
-
-\begin{verbatim}
-    clnt = clnt_create(server_host, PROG_NUM, PROG_VERS, protocol);
-    clnt->cl_auth = auth_gssapi_create(clnt, ...);
-\end{verbatim}
-
-There are two functions that create GSS-API authentication flavor
-structures for the cl_auth field, auth_gssapi_create and
-auth_gssapi_create_default.
-
-\begin{verbatim}
-AUTH *auth_gssapi_create(CLIENT         *clnt,
-                        OM_uint32       *major_status,
-                        OM_uint32       *minor_status,
-                        gss_cred_id_t   claimant_cred_handle,
-                        gss_name_t      target_name,
-                        gss_OID         mech_type,
-                        int             req_flags,
-                        int             time_req,
-                        gss_OID         *actual_mech_type,
-                        int             *ret_flags,
-                        OM_uint32       *time_rec);
-\end{verbatim}
-
-auth_gssapi_create creates a GSS-API authentication structure and
-provides most of the flexibility of gss_init_sec_context.  The
-arguments have the same interpretation as those of
-gss_init_sec_context with the same name, except:
-
-\begin{description}
-\item[clnt] The CLIENT structure returned by client_create or one of
-its relatives.  It is not modified.
-\end{description}
-
-auth_gssapi_create calls gss_init_sec_context as needed, passing each
-generated token to and processing each token returned from the RPC
-server specified by the RPC handle clnt.  On return, if major_status
-is GSS_S_COMPLETE, the context has been established, the returned AUTH
-structure is valid, and all of the arguments filled in by
-gss_init_sec_context have the correct values.  If major_status is not
-GSS_S_COMPLETE then it and minor_status contain error codes that can
-be passed to gss_display_status and the returned value is NULL.
-
-\begin{verbatim}
-AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name);
-\end{verbatim}
-
-auth_gssapi_create_default is a shorthand for auth_gssapi_create that
-attempts to create a context that provides procedure call and result
-integrity, using the default credentials and GSS-API mechanism.
-service_name is parsed as a GSS-API ``service'' name and used as the
-target name.  The other arguments to auth_gssapi_create are as follows:
-
-\begin{verbatim}
-auth_gssapi_create(clnt,
-                   &dummy,
-                   &dummy,
-                   GSS_C_NO_CREDENTIAL,
-                   target_name,
-                   GSS_C_NULL_OID,
-                   GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
-                   0,
-                   NULL,
-                   NULL,
-                   NULL);
-\end{verbatim}
-
-Note that if the underlying default mechanism does not support data
-integrity (e.g. the trust mechanism), this function will fail.
-
-The GSS-API major and minor status codes can be interpreted with
-auth_gssapi_display_status:
-
-\begin{verbatim}
-void auth_gssapi_display_status(char *msg, OM_uint32 major, 
-                                OM_uint32 minor); 
-\end{verbatim}
-
-All of the error messages associated with the major and minor status
-are displated on the standard error output, preceeded by the message
-``GSS-API authentication error $<$msg$>$:''.
-
-\subsection{Server Side}
-
-\subsubsection{Service Name Registration}
-
-An application server must register the service name(s) that it will
-use for GSS-API connections before any AUTH_GSSAPI requests will
-succeed.
-
-\begin{verbatim}
-typedef struct _auth_gssapi_name {
-     char *name;
-     gss_OID type;
-} auth_gssapi_name;
-
-bool_t _svcauth_gssapi_set_names(auth_gssapi_name *names, int num);
-\end{verbatim}
-
-names is an array of name specifications, each of which consists of a
-null-terminated ASCII representation of a name and the GSS-API name
-type that should be used to import it with gss_import_name.  The
-name type ``gss_nt_service_name'' is recommended.
-
-\subsubsection{Calling Client and Service Identification}
-
-Each application server's dispatch function is passed two arguments,
-the transport mechanism (transp) and the RPC service request (rqstp).
-If the service request's credential flavor (rq_cred.oa_flavor) is
-AUTH_GSSAPI (300001)\footnote{The value 4 was originally used, but
-300001 has been officially assigned by the IETF.}, then the call has
-been authenticated.  The rq_clntcred field of transp contains the
-gss_name_t of the authenticated caller and can be passed to
-gss_display_name to obtain a string represtation or gss_compare_name
-to compare it with other names.  The rq_svccred field of transp
-contains the GSS-API context established with the caller and can be
-passed to gss_inquire_context.
-
-\subsubsection{Error Logging}
-
-An application server can register a function to be called when a
-failure occurs during GSS-API context establishment with
-_svcauth_set_log_badauth_func.
-
-\begin{verbatim}
-typedef void (*auth_gssapi_log_badauth_func)(OM_uint32 major,
-                                             OM_uint32 minor,
-                                             struct sockaddr_in *raddr,
-                                             caddr_t data);
-   
-void _svcauth_set_log_badauth_func(auth_gssapi_log_badauth_func func,
-                                   caddr_t data); 
-\end{verbatim}
-
-The function func is called each time gss_accept_sec_context fails.
-The major and minor arguments indicate the GSS-API major and minor
-status codes returned.  The raddr field contains the INET socket that
-the request came from, and the data field contains the data argument
-of _svcauth_gssapi_set_log_badauth_func.
-
-An application server can register a function to be called when an RPC
-request with an invalid verifier arrives with
-_svcauth_set_log_badverf_func.
-
-\begin{verbatim}
-typedef void (*auth_gssapi_log_badverf_func)(gss_name_t client,
-                                             gss_name_t server,
-                                             struct svc_req *rqst,
-                                             struct rpc_msg *msg,
-                                             caddr_t data);
-
-void _svcauth_set_log_badverf_func(auth_gssapi_log_badverf_func func,
-                                   caddr_t data); 
-\end{verbatim}
-
-The function specified in func is called each time an invalid verifier
-is received.  The client and server fields identify the (falsely
-claimed) originating client and the server it originally authenticated
-to.  The raddr and addrlen fields contain the INET socket that the
-request (claims to have) come from, and data contains the data
-argument of _svcauth_set_log_badverf_func.
-
-\section{Modifications to Sun RPC}
-
-The Sun RPC extensible authentication mechanism is designed to allow
-different authentication systems to be integrated into Sun RPC easily.
-Unfortunately, it has two drawbacks.  First, the existing system has a
-number of non-general design properties that are intended specifically
-for Sun's Secure RPC, and second, the existing system has no concept
-of or ability to perform authentication-flavor-specific operations on
-function arguments and results passed over the wire.  The first
-problem merely makes the system confusing, since a number of features
-touted as ``general'' do not make any sense for arbitrary
-authentication systems.  The second problem is more substantial, and
-can only be corrected by modifications to Sun RPC internals.
-
-The following sections describe the necessary modifications to Sun
-RPC.
-
-\subsection{Client Side Authentication, AUTH Structure}
-
-The AUTH structure (figure \ref{fig:auth}) encapsulates the data and
-function pointers for an authentication flavor instance.  It has been
-changed in two ways.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
-        struct  opaque_auth     ah_cred;
-        struct  opaque_auth     ah_verf;
-        union   des_block       ah_key;
-        struct auth_ops {
-                void    (*ah_nextverf)();
-                int     (*ah_marshal)();        /* nextverf & serialize */
-                int     (*ah_validate)();       /* validate varifier */
-                int     (*ah_refresh)();        /* refresh credentials */
-                int     (*ah_wrap)();           /* encode data for wire */
-                int     (*ah_unwrap)();         /* decode data from wire */
-                void    (*ah_destroy)();        /* destroy this structure */
-        } *ah_ops;
-        caddr_t ah_private;
-} AUTH;
-\end{verbatim}
-\caption{The AUTH structure, with the new function pointers ah_wrap
-and ah_unwrap.}
-\label{fig:auth}
-\end{figure}
-
-First, the new functions ah_wrap and ah_unwrap prepare function
-arguments and results for transmission over the wire.  The
-authentication mechanism can use them to sign, encrypt, or perform any
-other operation on the data.  Their prototype is:
-
-\begin{verbatim}
-bool_t ah_wrap(AUTH *auth, XDR *out_xdrs, xdrproc_t func, caddr_t ptr);
-bool_t ah_unwrap(AUTH *auth, XDR *in_xdrs, xdrproc_t func, caddr_t ptr);
-\end{verbatim}
-
-ah_wrap encodes function arguments for transmission.  func and ptr are
-the XDR procedure and pointer that serialize the arguments, and
-out_xdrs is the xdr stream that the encoded arguments should be
-written to.  ah_unwrap decodes function arguments received from the
-network.  Its arguments are the converse of those to ah_wrap.
-
-It is the responsibility of RPC transport mechanisms to call an
-authorization flavor's ah_wrap and ah_unwrap functions when function
-arguments or results would normally be written to or read from the
-wire.  Authorization flavors that do not need to perform any encoding
-or decoding can use the provided function authany_wrap for ah_wrap
-and ah_unwrap; it consists of the single statement ``return
-(*func)(out_xdrs, ptr)'' (or in_xdrs, as appropriate).
-
-Second, the function ah_refresh has been changed to take the RPC error
-message that resulted in its being called as an argument.  This is
-necessary since the contents of the error message may dictate how
-ah_refresh should go about correcting the authentication failure.
-
-\subsection{Client Side Transport Mechanisms}
-
-Each client side transport mechanism must be modified to call the
-ah_wrap and ah_unwrap functions from the cl_auth field of the CLIENT
-structure during the call and reply process.  The modification is
-fairly simple.  For example, the UDP transport mechanism used to
-encode procedure calls like this:
-
-\begin{verbatim}
-        if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
-            (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
-            (! (*xargs)(xdrs, argsp)))
-                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
-\end{verbatim}
-
-The last function call in the conditional serializes the arguments
-onto the xdr stream.  This must be replaced with a call to the
-appropriate ah_wrap function:
-
-\begin{verbatim}
-        if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
-            (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
-            (! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp)))
-                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
-\end{verbatim}
-
-AUTH_WRAP is a macro that takes the four arguments for an ah_wrap
-function and extracts and calls the function pointer from the cl_auth
-structure with the specified arguments.
-
-Similarly, the transport mechanism must unwrap procedure results.
-Again, the UDP mechanism will be instructive.  It used to deserialize
-function results like this:
-
-\begin{verbatim}
-        reply_msg.acpted_rply.ar_results.where = resultsp;
-        reply_msg.acpted_rply.ar_results.proc = xresults;
-
-        ok = xdr_replymsg(&reply_xdrs, &reply_msg);
-\end{verbatim}
-
-The problem here is that xdr_replymsg deserializes an entire reply
-message, including the results.  Since xresults and resultsp are the
-function and pointer to decode the results, they will be automatically
-deserialized {\it without} ah_unwrap being invoked.  The simplest
-solution (which is also the normal method used by the TCP mechanism)
-is to arrange to deserialize the function results explicitly:
-
-\begin{verbatim}
-        reply_msg.acpted_rply.ar_results.where = NULL;
-        reply_msg.acpted_rply.ar_results.proc = xdr_void;
-
-        if ((! xdr_replymsg(&reply_xdrs, &reply_msg)) ||
-            (! AUTH_UNWRAP(cl->cl_auth, reply_xdrs, xresults,
-                           resultsp))) {
-                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
-        }
-\end{verbatim}
-
-Since xdr_void does not read any data from the XDR stream, the
-function results are still available when AUTH_UNWRAP is called.  Note
-that AUTH_UNWRAP should only be called on {\it successful} calls; if
-the reply message status is not RPC_SUCCESS there are no arguments to
-read.
-
-Currently, the UDP and TCP transport mechanisms has been
-converted.\footnote{The ``raw'' mechanism, for direct connections, has
-not been.}
-
-\subsection{Service Side Authentication, SVCAUTH and XPRT}
-
-Standard Sun RPC service-side authentication consists of a single
-function per authentication flavor; there is no concept of an AUTH
-structure containing function pointers and private data as with the
-client side.  Previously, nothing else was necessary, because each
-flavor only did a single thing (authenticated individual calls in a
-stateless manner).  More functions and state are now required,
-however; they are stored in the SVCAUTH structure, see figure
-\ref{fig:svcauth}.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
-     struct svc_auth_ops {
-          int   (*svc_ah_wrap)();
-          int   (*svc_ah_unwrap)();
-     } *svc_ah_ops;
-     caddr_t svc_ah_private;
-} SVCAUTH;
-\end{verbatim}
-\caption{The new SVCAUTH structure.}
-\label{fig:svcauth}
-\end{figure}
-
-There is one SVCAUTH structure per authentication flavor (there is a
-default, svc_auth_any, for existing authentication flavors that do not
-need the extra functionality).  The svc_ah_wrap and svc_ah_unwrap
-perform the same logical function as their client-side counterparts.
-
-Just as with the client side, it is the responsibility of the
-transport mechanism to call the svc_ah_wrap and svc_ah_unwrap
-functions associated with the authentication flavor associated with
-each RPC call at the appropriate time.  Unfortunately, the transport
-mechanism code does not have access to the RPC call structure
-containing the authenticator flavor because the RPC call structure
-itself is not passed as an argument to the necessary functions.  The
-present solution is to add another argument to the transport mechanism
-structure, xp_auth, that stores the SVCAUTH of the {\it current} call
-on that mechanism; see figure \ref{fig:xprt}.  xp_auth is initialized
-to svc_auth_any so that existing authentication mechanisms that do not
-set the field will still operate correctly.  \footnote{This is not an
-great solution, because it forces each transport mechanism to be
-single threaded.  The correct solution is to store the SVCAUTH
-associated with each RPC call in the RPC call structure; however,
-doing so would require changing a lot of code to pass around the RPC
-call structure that currently does not do so.  Since other parts of
-Sun RPC use the XPRT structure in a non-reentrant way, the present
-solution does not make the situation any
-worse.}$^{\mbox{,}}$\footnote{A somewhat irrelevant side effect of
-adding SVCAUTH to XPRT is that the standard include file
-$<$rpc/rpc.h$>$ had to be changed to include $<$rpc/svc_auth$>$ before
-$<$rpc/svc.h$>$, whereas they used to be in the opposite order.}
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
-        int             xp_sock;
-        u_short         xp_port;         /* associated port number */
-        struct xp_ops {
-            bool_t      (*xp_recv)();    /* receive incomming requests */
-            enum xprt_stat (*xp_stat)(); /* get transport status */
-            bool_t      (*xp_getargs)(); /* get arguments */
-            bool_t      (*xp_reply)();   /* send reply */
-            bool_t      (*xp_freeargs)();/* free mem allocated for args */
-            void        (*xp_destroy)(); /* destroy this struct */
-        } *xp_ops;
-        int             xp_addrlen;      /* length of remote address */
-        struct sockaddr_in xp_raddr;     /* remote address */
-        struct opaque_auth xp_verf;      /* raw response verifier */
-        SVCAUTH         *xp_auth;        /* auth flavor of current req */
-        caddr_t         xp_p1;           /* private */
-        caddr_t         xp_p2;           /* private */
-} SVCXPRT;
-\end{verbatim}
-\caption{The modified XPRT structure, with the xp_auth field.}
-\label{fig:xprt}
-\end{figure}
-
-Finally, with the modified XPRT structure carrying around the
-authentication flavor structure, the functions that serialize and
-deserialize function arguments and results must be modified to use the
-svc_ah_wrap and svc_ah_unwrap functions.  Each service-side transport
-mechanism has getargs and reply functions that must be modified to use
-the SVCAUTH_UNWRAP and SVCAUTH_WRAP macros, respectively, in a manner
-completely parallel to the client side.
-
-\subsection{Authenticated Service Identification, svc_req}
-
-Sun RPC provides the authenticated credentials of a client to the
-application server via rq_clntcred (``cooked credentials'') field of
-the service request (svc_req) structure.  In many authentication
-systems, services are also named entities, and there is no reason that
-an RPC should be restricted to accepting connections as a single
-authenticated service name.  However, access control decisions may be
-based on the service name a client authenticated to, so that
-information must be available to the application server.
-
-Figure \ref{fig:svc-req} shows the modified service request structure
-that contains a single new field, rq_svccred.  Like rq_clntcred, the
-authentication flavor is responsible for setting rq_svccred to the
-``cooked'' service credentials associated with a given RPC call.
-Authentication flavors that do not have the concept of service names
-can of course leave this field blank.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-struct svc_req {
-        u_long          rq_prog;        /* service program number */
-        u_long          rq_vers;        /* service protocol version */
-        u_long          rq_proc;        /* the desired procedure */
-        struct opaque_auth rq_cred;     /* raw creds from the wire */
-        caddr_t         rq_clntcred;    /* read only cooked client cred */
-        caddr_t         rq_svccred;     /* read only cooked svc cred */
-        SVCXPRT         *rq_xprt;       /* associated transport */
-};
-\end{verbatim}
-\caption{The modified svc_req structure, with the rq_svccred field.}
-\label{fig:svc-req}
-\end{figure}
-
-
-
-\subsection{Authentication Negotiation, no_dispatch}
-
-In order to avoid having to transmit a full set of authentication
-information with every call, the service-side authentication mechanism
-must save state between calls.  Establishing that state may require
-multiple messages between the client-side and service-side
-authentication mechanisms.  The client-side authentication mechanism
-can make arbitrary RPC calls to the server simply by requiring the
-programmer to specify the CLIENT structure to the authentication
-flavor initialization routine.  The service side, however, is more
-complex.  In the normal course of events, an RPC call comes in, is
-authenticated, and is then dispatched to the appropriate procedure.
-For client- and service-side authentication flavors to communicate
-indepedent of the server implemented above the RPC layer, the
-service-side flavor must be able to send a reply to the client
-directly and {\it prevent} the call from being dispatched.
-
-This is implemented by a simple modification to the _authenticate
-routine, which dispatches each RPC call to the appropriate
-authentication flavor; see figure \ref{fig:authenticate}.  It takes an
-additional argument, no_dispatch, that instructs the mechanism not to
-dispatch the RPC call to the specified procedure.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-                why=_authenticate(&r, &msg, &no_dispatch);
-                if (why != AUTH_OK) {
-                     svcerr_auth(xprt, why);
-                     goto call_done;
-                } else if (no_dispatch) {
-                     goto call_done;
-                }
-\end{verbatim}
-\caption{A call to the modified _authenticate.}
-\label{fig:authenticate}
-\end{figure}
-
-If _authenticate sets no_dispatch to true, the call is considered
-finished and no procedure dispatch takes place.  Presumably, an
-authentication flavor that sets no_dispatch to true also replies to
-the RPC call with svc_sendreply.  Authentication flavors that do not
-modify no_dispatch implicitly leave it set to false, so the normal
-dispatch takes place.
-
-\subsection{Affected Files}
-
-Table \ref{tab:modfiles} lists the files that were
-affected for each of the modifications described in previous sections.
-
-\begin{table}[htbp]
-\centering
-\caption{Files modified for each change to Sun RPC.}
-\label{tab:modfiles}
-\begin{tabular}{ll}
-AUTH structure                  & auth.h \\
-                                & auth_none.c \\
-                                & auth_exit.c \\
-                                & auth_any.c \\
-Client Transport Mechanisms     & clnt_udp.c \\
-                                & clnt_tcp.c \\
-SVCAUTH and XPRT structures     & rpc.h \\
-                                & svc.h \\
-                                & svc_auth.h \\
-                                & svc.c \\
-                                & svc_auth.c \\
-                                & svc_auth_any.c \\
-                                & svc_auth_unix.c \\
-Server Transport Mechanisms     & svc_udp.c \\
-                                & svc_tcp.c
-\end{tabular}
-\end{table}
-
-\section{GSS-API Authentication Flavor}
-
-The following sections describe the implemetation of the GSS-API
-authentication flavor for Sun RPC.
-
-\subsection{Authentication Algorithms}
-\label{sec:algorithms}
-
-\subsubsection{Context Initiation}
-
-The client creates a GSS-API context with the server each time it
-calls auth_gssapi_create.  The context is created using the standard
-gss_init_sec_context and gss_accept_sec_context function calls.  The
-generated tokens are passed between the client and server as arguments
-and results of normal RPC calls.
-
-The client side, in auth_gssapi_create, performs the following steps
-to initiate a context:
-
-\begin{enumerate}
-\item\label{item:process-token} The client calls gss_init_sec_context.
-On the first such call, no input token is provided; on subsequent
-calls, the token received from the server is provided.
-
-\item If gss_init_sec_context produces an output token:
-
-\begin{enumerate}
-\item The client transmits the token to the server, identifying itself
-with client_handle if it has already been received (see next step).
-The return value from the server will contain a client_handle and one
-or both of a token and a signed initial sequence number.  
-
-\item If this is the first response from the server, the client_handle
-is stored for subsequent calls.  Otherwise, the client_handle should be
-the same as returned on the previous call.
-
-\item If the response contains a signed initian sequence number but
-the context is not yet established, then the response also contains a
-token that will established the context.  The signed initial sequence
-number is stored.
-
-\item If the response contains a token, step \ref{item:process-token}
-repeated.
-\end{enumerate}
-
-\item The signed initial sequence number is verified using the
-established context.
-\end{enumerate}
-
-The server side, in _svcauth_gssapi, performs the following steps to
-initiate a context:
-
-\begin{enumerate}
-\item If a call arrives with no client_handle, a new client_handle is
-allocated and stored in the database.  Otherwise, the client's
-previous state is is looked up in the database.
-
-\item The received token is passed to gss_accept_sec_context.  If an
-output token is generated, it is returned to the client.  Note that
-since the application server may have registered multiple service
-names and there is no way to determine {\it a priori} which service a
-token is for, _svcauth_gssapi calls gss_accept_sec_context once for
-each registered credential until one of them succeedes.  The code
-assumes that GSS_S_FAILURE is the only error that can result from a
-credential mismatch, so any other error terminates the loop
-immediately.
-
-\item If the context is established, the server signs an initial
-sequence number and returns it to the client.
-\end{enumerate}
-
-Note that these algorithms require context establishment to be
-synchronous.  If gss_init_sec_context returns GSS_S_COMPLETE upon
-processing a token, it will either produce a token or not.  If it
-does, then gss_accept_sec_context will return GSS_S_COMPLETE when that
-token is processed; if it does not, then gss_accept_sec_context
-already returned GSS_S_COMPLETE (and presumably returned the token
-that caused gss_init_sec_context to return GSS_S_COMPLETE when
-processed).  The reverse is also true.
-
-\subsubsection{RPC Calls}
-
-After the GSS-API context is established, both the server and the
-client posess a client handle and a corresponding sequence number.
-Each call from the client contains the client handle as the
-``credential'' so that the server can identify which context to apply
-to the call.
-
-Each client call and server response includes a ``verifier'' that
-contains the sealed current sequence number.\footnote{In a future
-version, the verifier will also contain a signature block for the call
-header, including the procedure number called.} The sequence number
-prevents replay attacks\footnote{Although some GSS-API mechanisms
-provide replay detection themselves, not all of them do; explicitly
-including the sequence number in the RPC therefore provides better
-end-to-end security}, but by itself it does not prevent splicing
-attacks.
-
-Each procedure argument and result block consists of the current
-sequence number and the actual serialized argument string, all sealed
-with gss_seal.  Combining the sequence number with the argument/result
-data prevents splicing attacks.
-
-The sequence number is incremented by one for each RPC call and by one
-for each response.  The client and server will both reject messages
-that do not contain the expected sequence number.  Packets
-retransmitted by the client should use the {\it same} sequence number
-as the original packet, since even if the server receives multiple
-copies only one will be honored.
-
-\subsection{RPC Call Credential Structure}
-
-Every message transmitted from the client to the server has a
-credentials (cb_cred) field of the type auth_gssapi_creds:
-
-\begin{verbatim}
-typedef struct _auth_gssapi_creds {
-        bool_t       auth_msg;
-        gss_buffer_desc client_handle;
-};
-\end{verbatim}
-
-The auth_msg field indicates whether the message is intended for the
-authentication mechanism for the actual server.  Any message whose
-auth_msg field is true is processed by the authentication mechanism;
-any message whose auth_msg is false is passed to the application
-server's dispatch function if authentication suceeds.  All messages
-must have an auth_msg of true until the context is established, since
-authentication cannot succeed until it is.
-
-The client_handle field contains the client handle obtained from the
-first call to the server.  On the first call, this field is empty.
-
-\subsection{GSS-API Authentication Flavor Procedures}
-
-The GSS-API authentication flavor uses standard RPC calls over the
-client handle it is provided for the interactions described in
-\ref{sec:algorithms}.  All of the following procedures require the
-auth_msg field in the credentials to be true; otherwise, the
-server-side authentication flavor will simply attempt to authenticate
-the caller and pass the call to the application server.  The
-server-side authentication flavor uses the no_dispatch variable to
-indicate that it has handled the call.
-
-\subsubsection{AUTH_GSSAPI_INIT, AUTH_GSSAPI_CONTINUE_INIT}
-
-Context initiation is performed via AUTH_GSSAPI_INIT and
-AUTH_GSSAPI_CONTINUE_INIT.  The former is used to transfer the first
-token generated by gss_init_sec_context, when no client handle is
-included in the credentials; the latter is used on subsequent calls,
-when a client handle is included.
-
-Both procedures take an argument of type auth_gssapi_init_arg and
-return results of the type auth_gssapi_init_res.
-
-\begin{verbatim}
-typedef struct _auth_gssapi_init_arg {
-        u_long       version;
-        gss_buffer_desc token;
-} auth_gssapi_init_arg;
-\end{verbatim}
-
-\begin{description}
-\item[version]  Three versions are presently defined.
-
-\begin{description}
-\item[1] The original version, as described in this document
-
-\item[2] In earlier versions of Secure there was a bug in the GSS-API
-library that affected the contents of accept_sec_context output
-tokens.  A client specifies version 2 to indicate that it expects the
-correct (fixed) behavior.  If the server indicates AUTH_BADCRED or
-AUTH_FAILED it does not understand this version, so the client should
-fall back to version 1.
-
-\item[3] Version three indicates that channel bindings are in use.
-The client must specify channel bindings with the version, and the
-server will as well.  If the server indicates AUTH_BADCRED or
-AUTH_FAILED it does not understand this version, so the client should
-fall back to version 2 (and cease specifying channel bindings).
-
-\item[4] The previous versions all used the old GSS-API krb5 mechanism
-oid; this version uses the new one specified in the RFC.  
-\end{description}
-
-\item[token] The token field contains the token generated by
-gss_init_sec_context.
-\end{description}
-
-\begin{verbatim}
-typedef struct _auth_gssapi_init_res {
-        u_long       version;
-        gss_buffer_desc client_handle;
-        gss_buffer_desc token;
-        OM_uint32 gss_major, gss_minor;
-        gss_buffer_desc signed_isn;
-} auth_gssapi_init_res;
-\end{verbatim}
-
-\begin{description}
-\item[version] There are two versions currently defined.
-\begin{description}
-\item[1] The original version, as described in this document.  This is
-the response version for {\it both} versions 1 and 2.  The Secure 1.1
-server will always return this version.
-
-\item[3] Version three indicates that the server specified channel
-bindings in response to a call arg version number of three.  The
-server must not specify this version unless the client does.
-\end{description}
-
-\item[client_handle] The client_handle field contains the client
-handle that the client must use in the credentials field in all
-subsequent RPC calls.  In response to AUTH_GSSAPI_CONTINUE_INIT, it is
-the same client handle that arrived in the credentials.
-
-\item[gss_major, gss_minor] The GSS-API error codes that resulted from
-processing the auth_gssapi_init_arg.  If gss_major is GSS_S_COMPLETE,
-the argument token was processed successfully.  Otherwise, gss_major
-and gss_minor contain the relevant major and minor status codes, and
-the context currently being negotiated is no longer valid.
-
-\item[token] In any response that the client is expecting another
-token (i.e.: gss_init_sec_context last returned GSS_S_CONTINUE), the
-token field contains the output token from gss_accept_sec_context.  If
-the client is not expecting a token and this field is not empty, an
-error has occurred.
-
-\item[signed_isn]  If the client is not expecting another token (i.e.:
-the previous call to gss_init_sec_context yielded a token and returned
-GSS_S_COMPLETE) or the supplied token completes the context, the
-signed_isn field contains the signed initial sequence number.  The
-server expects the first RPC call to have a sequence number one
-greater than the initial sequence number (so that the signed_isn block
-cannot be replayed).  If the client is expecting another token and the
-signed_isn field is not empty, an error has occurred.
-\end{description}
-
-\subsubsection{AUTH_GSSAPI_DESTROY}
-
-Context tear-down is performed via AUTH_GSSAPI_DESTROY.  This
-procedure takes no arguments and returns no results; it merely informs
-the server that the client wishes to destroy the established context.
-
-When a client wishes to tear down an established context between
-itself and a server, auth_gssapi_destroy first calls the
-AUTH_GSSAPI_DESTROY procedure.  The server authenticates the message
-and immediately sends a ``success'' response with no results.  The
-client and server then both independently call gss_delete_sec_context
-and discard the context-destruction token that is generated.
-
-No RPC error checking is performed by either the client or the server.
-The client waits a brief time for a success response from the server,
-but if none arrives it destroys the context anyway since presumably
-the user is waiting for the application to exit.  The server similar
-ignores any RPC errors since it knows that the client will ignore any
-errors that are reported.
-
-\subsection{RPC Call Authentication Implementation}
-
-Once the context has been established, all subsequent RPC calls are
-authenticated via the verifier described in section
-\ref{sec:algorithms}.
-
-auth_gssapi_marshall, invoked via AUTH_MARSHALL while the RPC call is
-being created on the client side, serializes the client_handle
-obtained during context initiation {\it in plaintext} as the
-credentials and serializes the current sequence number, sealed with
-gss_seal, as the verifier.
-
-auth_gssapi_wrap, invoked next via AUTH_WRAP, serializes a sealed
-token containing both the sequence number of the current call and the
-serialized arguments.
-
-_svcauth_gssapi, invoked on the server side by _authenticate, uses the
-client_handle contained in the credentials to look up the correct
-context and verifies the sequence number provided in the verifier; if
-the sequence number is not correct, it declares a potential replay
-attack.\footnote{Retransmitted packets will appear as replay attacks,
-of course.} The response verifier is set to the serialized sealed
-incremented sequence number.
-
-svc_auth_gssapi_unwrap, invoked when either the application server or
-_svcauth_gssapi (in response to an AUTH_GSSAPI authentication flavor
-message) attempts to read its arguments, deserialzes and unseals the
-block containing the current sequence number and serialized arguments.
-If the sequence number is incorrect, it declares a splicing attack;
-otherwise, it unserializes the arguments into the original structure.
-
-svc_auth_gssapi_wrap, invoked when either the application server or
-_svcauth_gssapi attempts to write its response, performs the same
-operation as auth_gssapi_wrap.
-
-auth_gssapi_validate, invoked by the client-side RPC mechanism when
-an RPC_SUCCESS response is received, verifies that the returned sequence
-number is one greater than the previous value sent by
-auth_gssapi_marshall.
-
-Finally, auth_gssapi_unwrap, invokved by the client-side RPC mechanism
-after auth_gssapi_validate succeeds, performs the same operation as
-svc_auth_gssapi_unwrap.
-
-If an RPC request generates an error message (a status of other than
-RPC_SUCCESS), auth_gssapi_refresh is called.  If the error status is
-AUTH_REJECTEDVERF, then the server rejected the sequence number as
-invalid or replayed.  The client guesses that, on some previous call,
-the server received a message but the server's response did not make
-it back to the client; this could happen if the packet got lost or if
-the server was being debugged and the client timed out waiting for it.
-As a result, the server is expected a higher sequence number than the
-client sent.  auth_gssapi_refresh increments the sequence number and
-returns true so that the call will be tried again.  The transport
-mechanism will only call auth_gssapi_refresh twice for each RPC
-request, so if some other error occurred an infinite loop will not
-result; however, it is unlikely the the client and server will be able
-to resynchronize after such an event.
-
-\subsection{Client State Information}
-
-The client-side GSS-API authentication flavor maintains an
-auth_gssapi_data structure for each authentication instance:
-
-\begin{verbatim}
-struct auth_gssapi_data {
-     bool_t established;
-     CLIENT *clnt;
-     gss_ctx_id_t context;
-     gss_buffer_desc client_handle;
-     u_long seq_num;
-     int def_cred;
-
-     /* pre-serialized ah_cred */
-     u_char cred_buf[MAX_AUTH_BYTES];
-     u_long cred_len;
-};
-\end{verbatim}
-
-The established field indicates whether the authentication context
-between the client and server has been established.  It is set to true
-when gss_init_sec_context returns GSS_S_COM\-PLETE.  When this field is
-false, the auth_gssapi functions marshall, validate, wrap, and unwrap
-mimic the ``no authentication'' flavor since there is no context with
-which to perform authentication functions.\footnote{This field is
-necessary because, when auth_gssapi_create calls clnt_call to make an
-RPC call, it has to have set the client's authentication flavor to
-AUTH_GSSAPI; otherwise, the service-side RPC mechanism will not know
-to dispatch the call to _svcauth_gssapi.  However, with the client's
-authentication flavor set, all of the authentication flavor's
-functions will be automatically invoked, even though they are not
-ready to operate.}
-
-The clnt field contains the RPC client structure that can be used to
-communicate with the GSS-API authentication flavor on the server.
-
-The context field contains the context structure created by
-gss_init_sec_context.
-
-The client_handle field contains the client handle used on all RPC
-calls except the first one; the handle is obtained as the result of
-the first call.
-
-The sequence_number field contains the sequence number that will be
-used when transmitting RPC calls to the server and verifing the
-server's responses after the context is initialized.
-
-The def_cred field is true if gss_init_sec_context created a default
-credential, in which case the authentication mechanism is responsible
-for releasing the default credential that gets automatically
-allocated.
-
-The cred_buf and cred_len fields contain the pre-serialized
-credentials structure used in each call.  This provides a small
-performance enhancement since the credentials structure does not
-change very often; the same pre-serialized version can be used on
-virtually every call.
-
-\subsection{Server State Information}
-\label{sec:server-state}
-
-The server-side GSS-API authentication flavor maintains an
-svcauth_gssapi_data structure for each established or partially
-established context:
-
-\begin{verbatim}
-typedef struct _svc_auth_gssapi_data {
-     bool_t established;
-     gss_ctx_id_t context;
-     gss_name_t client_name, server_name;
-     gss_cred_id_t server_creds;
-
-     u_long expiration;
-     u_long seq_num;
-     u_long key;
-
-     SVCAUTH svcauth;
-} svc_auth_gssapi_data;
-\end{verbatim}
-
-The established field indicates whether the context is fully
-established.
-
-The context field contains the context created by
-gss_accept_sec_context.
-
-The client_name field contains the client's authenticated name, as
-returned by gss_accept_sec_context.  _svcauth_gssapi sets the ``cooked
-credentials'' field of the RPC call structure to this value after the
-call is authenticated; the application server can use it to perform
-authorization.
-
-The server_name field contains the service name that the client
-established a context with.  This is useful if the application server
-registered more than one service name with the library; it allows the
-server to determine which service the client chose.
-
-The server_creds field contains the service credentials that the
-client established a context with.  It is used to avoid having to scan
-through the server_creds_list multiple times in the case that context
-establishment requires more than one round-trip to the server.
-
-The expiration field contains the expiration time of the context, as a
-Unix timestamp.  If a context has no expiration (time_rec is
-GSS_C_INDEFINITE), the expiration time is set to 24 hours in the
-future.  When the structure is created, before the context is
-established, the expiration time is initialized to small duration
-(currently 5 minutes) so that partially created and abandoned contexts
-will be expired quickly.
-
-The seq_num field is the current sequence number for the client.
-
-The key field is the client's key into the hash table (see below).
-The client_handle field sent to the client is the key treated as an
-arbitrary four-byte string.
-
-The svcauth field is a kludge that allows the svc_auth_gssapi
-functions to access the per-client data structure while processing a
-call.  One SVCAUTH structure is allocated for each client structure,
-and the svc_ah_private field is set to the corresponding client.  The
-client's svcauth field is then set to the new SVCAUTH structure, so
-that client_data->svcauth->svc_ah_private == client_data.  As each
-request is processed, the transport mechanism's xp_auth field is set
-to the client's svcauth field; thus, the server-side functions that
-dispatch to server-side authentication flavors can access an
-appropriate SVCAUTH structure, and the server-side authentication
-function that is called can determine the appropriate per-client
-structure from the SVCAUTH structure.
-
-The per-client structures are all stored both in a BSD 4.4 db library
-hash table and b-tree.  The hash table maps client handles (key
-fields) the client structures, and is used to look up client
-structures based on the client_handle field of a call's credentials
-structure.  The b-tree stores the client structures as keys, sorted by
-their expiration time.  Each time _svcauth_gssapi is activated, it
-traverses the tree and destroys all client structures that have
-expired.
-
-\end{document}
diff --git a/doc/salts.texinfo b/doc/salts.texinfo
deleted file mode 100644
index 3ed43db0e..000000000
--- a/doc/salts.texinfo
+++ /dev/null
@@ -1,19 +0,0 @@
-@ignore 
-the information in this file should be consistent with the information
-in krb5/src/lib/krb5/krb/str_conv.c, in the struct salttype_lookup_entry
-@end ignore
-
-@table @code
-@item normal
-default for Kerberos Version 5
-@item v4
-the only type used by Kerberos Version 4, no salt
-@item norealm
-same as the default, without using realm information
-@item onlyrealm
-uses only realm information as the salt
-@item afs3
-AFS version 3, only used for compatibility with Kerberos 4 in AFS
-@item special
-only used in very special cases; not fully supported
-@end table
diff --git a/doc/send-pr.texinfo b/doc/send-pr.texinfo
deleted file mode 100644
index e34ca935e..000000000
--- a/doc/send-pr.texinfo
+++ /dev/null
@@ -1,144 +0,0 @@
-In any complex software, there will be bugs.  If you have successfully
-built and installed @value{PRODUCT}, please use the @code{krb5-send-pr}
-program to fill out a Problem Report should you encounter any errors in
-our software.
-
-Bug reports that include proposed fixes are especially welcome.  If you
-do include fixes, please send them using either context diffs or unified
-diffs (using @samp{diff -c} or @samp{diff -u}, respectively).  Please be
-careful when using ``cut and paste'' or other such means to copy a patch
-into a bug report; depending on the system being used, that can result
-in converting TAB characters into spaces, which makes applying the
-patches more difficult.
-
-The @code{krb5-send-pr} program is installed in the directory
-@code{@value{ROOTDIR}/sbin}.
-
-The @code{krb5-send-pr} program enters the problem report into our
-Problem Report Management System (PRMS), which automatically assigns it
-to the engineer best able to help you with problems in the assigned
-category.
-@ifset CYGNUS
-The engineer will work with you via email, telephone, or both, and all
-email related to this Problem Report will be tracked by PRMS for future
-reference.  If you need to talk to someone else in our organization
-about the problem (@i{e.g.}, if the engineer gets hit by a truck), we
-can find out what the current state is through the PR number.
-@end ifset
-
-The @code{krb5-send-pr} program will try to intelligently fill in as
-many fields as it can.  You need to choose the @dfn{category},
-@dfn{class}, @dfn{severity}, and @dfn{priority} of the problem, as well
-as giving us as much information as you can about its exact nature.
-
-@need 1000
-The PR @b{category} will be one of:
-
-@smallexample
-@group
-krb5-admin   krb5-appl    krb5-build   krb5-clients 
-krb5-doc     krb5-kdc     krb5-libs    krb5-misc    
-pty          telnet       test         
-@end group
-@end smallexample
-
-@noindent
-Choose the category that best describes the area under which your
-problem falls.
-
-The @b{class} can be @dfn{sw-bug}, @dfn{doc-bug}, @dfn{change-request},
-or @dfn{support}.  The first two are exactly as their names imply.  Use
-@i{change-request} when the software is behaving according to
-specifications, but you want to request changes in some feature or
-behavior.  The @i{support} class is intended for more general questions
-about building or using @value{PRODUCT}.
-
-The @b{severity} of the problem indicates the problem's impact on the
-usability of @value{PRODUCT}.  If a problem is @dfn{critical}, that
-means the product, component or concept is completely non-operational,
-or some essential functionality is missing, and no workaround is known.
-A @dfn{serious} problem is one in which the product, component or
-concept is not working properly or significant functionality is missing.
-Problems that would otherwise be considered @i{critical} are rated
-@i{serious} when a workaround is known.  A @dfn{non-critical} problem is
-one that is indeed a problem, but one that is having a minimal effect on
-your ability to use @value{PRODUCT}.  @i{E.g.}, The product, component
-or concept is working in general, but lacks features, has irritating
-behavior, does something wrong, or doesn't match its documentation.  The
-default severity is @i{serious}.
-
-The @b{priority} indicates how urgent this particular problem is in
-relation to your work.  Note that low priority does not imply low
-importance.
-@ifset CYGNUS
-@value{COMPANY} considers all problems important, and
-encourages its customers to be realistic about priority ratings.
-@end ifset
-A priority of @dfn{high} means a solution is needed as soon as possible.
-A priority of @dfn{medium} means the problem should be solved no later
-than the next release.  A priority of @dfn{low} means the problem should
-be solved in a future release, but it is not important to your work how
-soon this happens.  The default priority is @i{medium}.
-
-Note that a given severity does not necessarily imply a given priority.
-For example, a non-critical problem might still have a high priority if
-you are faced with a hard deadline.  Conversely, a serious problem might
-have a low priority if the feature it is disabling is one that you do
-not need.
-
-It is important that you fill in the @i{release} field and tell us
-what changes you have made, if any.
-
-@iftex
-@vfill
-@end iftex
-
-@page
-A sample filled-out form from a company named ``Toasters, Inc.'' might
-look like this:
-
-@smallexample
-@group
-To: krb5-bugs@@mit.edu
-Subject: misspelled "Kerberos" in title of installation guide
-From: jcb
-Reply-To: jcb
-Cc: 
-X-send-pr-version: 3.99
-
-
->Submitter-Id:	mit
->Originator:	Jeffrey C. Gilman Bigler
->Organization:
-mit
->Confidential:	no
->Synopsis:	Misspelled "Kerberos" in title of installation guide
->Severity:	non-critical
->Priority:	low
->Category:	krb5-doc
->Class:		doc-bug
->Release:	1.0-development
->Environment:
-	<machine, os, target, libraries (multiple lines)>
-System: ULTRIX imbrium 4.2 0 RISC
-Machine: mips
->Description:
-        Misspelled "Kerberos" in title of "Kerboros V5 Installation Guide"
->How-To-Repeat:
-        N/A
->Fix:
-        Correct the spelling.
-@end group        
-@end smallexample
-
-@iftex
-@vfill
-@end iftex
-
-If the @code{krb5-send-pr} program does not work for you, or if you did
-not get far enough in the process to have an installed and working
-@code{krb5-send-pr}, you can generate your own form, using the above as
-an example.
-
-
-
diff --git a/doc/support-enc.texinfo b/doc/support-enc.texinfo
deleted file mode 100644
index 3f030bad9..000000000
--- a/doc/support-enc.texinfo
+++ /dev/null
@@ -1,27 +0,0 @@
-@ignore 
-the information in this file should be consistent with the information
-in krb5/src/lib/crypto/etypes.c (and krb5/src/include/krb5.h[in]?)
-@end ignore
-
-@table @code
-@item des-cbc-crc 
-DES cbc mode with CRC-32
-@item des-cbc-md4 
-DES cbc mode with RSA-MD4
-@item des-cbc-md5 
-DES cbc mode with RSA-MD5
-@item des3-cbc-sha1 
-@itemx des3-hmac-sha1
-@itemx des3-cbc-sha1-kd
-triple DES cbc mode with HMAC/sha1
-@item des-hmac-sha1 
-DES with HMAC/sha1
-@item arcfour-hmac 
-@itemx rc4-hmac
-@itemx arcfour-hmac-md5
-RC4 with HMAC/MD5
-@item arcfour-hmac-exp 
-@itemx rc4-hmac-exp
-@itemx arcfour-hmac-md5-exp
-exportable RC4 with HMAC/MD5
-@end table
diff --git a/doc/texinfo-suppl.tex b/doc/texinfo-suppl.tex
deleted file mode 100644
index 4a1c0cdac..000000000
--- a/doc/texinfo-suppl.tex
+++ /dev/null
@@ -1,7 +0,0 @@
-\def\temp{
-\chapternofonts
-\def\doubleleftarrow{\realbackslash doubleleftarrow}
-}
-\let\chapternofonts=\temp
-
-\def\doubleleftarrow{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Leftarrow$\hfil}}
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
deleted file mode 100644
index 9d4147edc..000000000
--- a/doc/texinfo.tex
+++ /dev/null
@@ -1,4355 +0,0 @@
-%% TeX macros to handle texinfo files
-
-%   Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
-
-%This texinfo.tex file is free software; you can redistribute it and/or
-%modify it under the terms of the GNU General Public License as
-%published by the Free Software Foundation; either version 2, or (at
-%your option) any later version.
-
-%This texinfo.tex file is distributed in the hope that it will be
-%useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%General Public License for more details.
-
-%You should have received a copy of the GNU General Public License
-%along with this texinfo.tex file; see the file COPYING.  If not, write
-%to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
-%USA.
-
-
-%In other words, you are welcome to use, share and improve this program.
-%You are forbidden to forbid anyone else to use, share and improve
-%what you give them.   Help stamp out software-hoarding!
-
-% This automatically updates the version number based on RCS.
-\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
-\deftexinfoversion$Revision$
-\message{Loading texinfo package [Version \texinfoversion]:}
-
-% Print the version number if in a .fmt file.
-\everyjob{\message{[Texinfo version \texinfoversion]}\message{}}
-
-% Save some parts of plain tex whose names we will redefine.
-
-\let\ptextilde=\~
-\let\ptexlbrace=\{
-\let\ptexrbrace=\}
-\let\ptexdots=\dots
-\let\ptexdot=\.
-\let\ptexstar=\*
-\let\ptexend=\end
-\let\ptexbullet=\bullet
-\let\ptexb=\b
-\let\ptexc=\c
-\let\ptexi=\i
-\let\ptext=\t
-\let\ptexl=\l
-\let\ptexL=\L
-
-% Be sure we're in horizontal mode when doing a tie, since we make space
-% equivalent to this in @example-like environments. Otherwise, a space
-% at the beginning of a line will start with \penalty -- and
-% since \penalty is valid in vertical mode, we'd end up putting the
-% penalty on the vertical list instead of in the new paragraph.
-{\catcode`@ = 11
- \gdef\tie{\leavevmode\penalty\@M\ }
-}
-\let\~ = \tie                  % And make it available as @~.
-
-\message{Basics,}
-\chardef\other=12
-
-% If this character appears in an error message or help string, it
-% starts a new line in the output.
-\newlinechar = `^^J
-
-% Set up fixed words for English.
-\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi%
-\def\putwordInfo{Info}%
-\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi%
-\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi%
-\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi%
-\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi%
-\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi%
-\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi%
-\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi%
-\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi%
-\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi%
-
-% Ignore a token.
-%
-\def\gobble#1{}
-
-\hyphenation{ap-pen-dix}
-\hyphenation{mini-buf-fer mini-buf-fers}
-\hyphenation{eshell}
-
-% Margin to add to right of even pages, to left of odd pages.
-\newdimen \bindingoffset  \bindingoffset=0pt
-\newdimen \normaloffset   \normaloffset=\hoffset
-\newdimen\pagewidth \newdimen\pageheight
-\pagewidth=\hsize \pageheight=\vsize
-
-% Sometimes it is convenient to have everything in the transcript file
-% and nothing on the terminal.  We don't just call \tracingall here,
-% since that produces some useless output on the terminal.
-%
-\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
-\def\loggingall{\tracingcommands2 \tracingstats2
-   \tracingpages1 \tracingoutput1 \tracinglostchars1
-   \tracingmacros2 \tracingparagraphs1 \tracingrestores1
-   \showboxbreadth\maxdimen\showboxdepth\maxdimen
-}%
-
-%---------------------Begin change-----------------------
-%
-%%%% For @cropmarks command.
-% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
-%
-\newdimen\cornerlong \newdimen\cornerthick
-\newdimen \topandbottommargin
-\newdimen \outerhsize \newdimen \outervsize
-\cornerlong=1pc\cornerthick=.3pt	% These set size of cropmarks
-\outerhsize=7in
-%\outervsize=9.5in
-% Alternative @smallbook page size is 9.25in
-\outervsize=9.25in
-\topandbottommargin=.75in
-%
-%---------------------End change-----------------------
-
-% \onepageout takes a vbox as an argument.  Note that \pagecontents
-% does insertions itself, but you have to call it yourself.
-\chardef\PAGE=255  \output={\onepageout{\pagecontents\PAGE}}
-\def\onepageout#1{\hoffset=\normaloffset
-\ifodd\pageno  \advance\hoffset by \bindingoffset
-\else \advance\hoffset by -\bindingoffset\fi
-{\escapechar=`\\\relax % makes sure backslash is used in output files.
-\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}%
-{\let\hsize=\pagewidth \makefootline}}}%
-\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
-
-%%%% For @cropmarks command %%%%
-
-% Here is a modification of the main output routine for Near East Publications
-% This provides right-angle cropmarks at all four corners.
-% The contents of the page are centerlined into the cropmarks,
-% and any desired binding offset is added as an \hskip on either
-% site of the centerlined box.  (P. A. MacKay, 12 November, 1986)
-%
-\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
-{\escapechar=`\\\relax % makes sure backslash is used in output files.
-		 \shipout
-		 \vbox to \outervsize{\hsize=\outerhsize
-                 \vbox{\line{\ewtop\hfill\ewtop}}
-                 \nointerlineskip
-                 \line{\vbox{\moveleft\cornerthick\nstop}
-                       \hfill
-                       \vbox{\moveright\cornerthick\nstop}}
-                 \vskip \topandbottommargin
-                 \centerline{\ifodd\pageno\hskip\bindingoffset\fi
-			\vbox{
-			{\let\hsize=\pagewidth \makeheadline}
-			\pagebody{#1}
-			{\let\hsize=\pagewidth \makefootline}}
-			\ifodd\pageno\else\hskip\bindingoffset\fi}
-		 \vskip \topandbottommargin plus1fill minus1fill
-                 \boxmaxdepth\cornerthick
-                 \line{\vbox{\moveleft\cornerthick\nsbot}
-                       \hfill
-                       \vbox{\moveright\cornerthick\nsbot}}
-                 \nointerlineskip
-                 \vbox{\line{\ewbot\hfill\ewbot}}
-	}}
-  \advancepageno
-  \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
-%
-% Do @cropmarks to get crop marks
-\def\cropmarks{\let\onepageout=\croppageout }
-
-\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
-{\catcode`\@ =11
-\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
-\dimen@=\dp#1 \unvbox#1
-\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
-\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
-}
-
-%
-% Here are the rules for the cropmarks.  Note that they are
-% offset so that the space between them is truly \outerhsize or \outervsize
-% (P. A. MacKay, 12 November, 1986)
-%
-\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
-\def\nstop{\vbox
-  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
-\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
-\def\nsbot{\vbox
-  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
-
-% Parse an argument, then pass it to #1.  The argument is the rest of
-% the input line (except we remove a trailing comment).  #1 should be a
-% macro which expects an ordinary undelimited TeX argument.
-%
-\def\parsearg#1{%
-  \let\next = #1%
-  \begingroup
-    \obeylines
-    \futurelet\temp\parseargx
-}
-
-% If the next token is an obeyed space (from an @example environment or
-% the like), remove it and recurse.  Otherwise, we're done.
-\def\parseargx{%
-  % \obeyedspace is defined far below, after the definition of \sepspaces.
-  \ifx\obeyedspace\temp
-    \expandafter\parseargdiscardspace
-  \else
-    \expandafter\parseargline
-  \fi
-}
-
-% Remove a single space (as the delimiter token to the macro call).
-{\obeyspaces %
- \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
-
-{\obeylines %
-  \gdef\parseargline#1^^M{%
-    \endgroup % End of the group started in \parsearg.
-    %
-    % First remove any @c comment, then any @comment.
-    % Result of each macro is put in \toks0.
-    \argremovec #1\c\relax %
-    \expandafter\argremovecomment \the\toks0 \comment\relax %
-    %
-    % Call the caller's macro, saved as \next in \parsearg.
-    \expandafter\next\expandafter{\the\toks0}%
-  }%
-}
-
-% Since all \c{,omment} does is throw away the argument, we can let TeX
-% do that for us.  The \relax here is matched by the \relax in the call
-% in \parseargline; it could be more or less anything, its purpose is
-% just to delimit the argument to the \c.
-\def\argremovec#1\c#2\relax{\toks0 = {#1}}
-\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
-
-% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
-%    @end itemize  @c foo
-% will have two active spaces as part of the argument with the
-% `itemize'.  Here we remove all active spaces from #1, and assign the
-% result to \toks0.
-%
-% This loses if there are any *other* active characters besides spaces
-% in the argument -- _ ^ +, for example -- since they get expanded.
-% Fortunately, Texinfo does not define any such commands.  (If it ever
-% does, the catcode of the characters in questionwill have to be changed
-% here.)  But this means we cannot call \removeactivespaces as part of
-% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
-% that \parsearg gets might well have any character at all in it.
-%
-\def\removeactivespaces#1{%
-  \begingroup
-    \ignoreactivespaces
-    \edef\temp{#1}%
-    \global\toks0 = \expandafter{\temp}%
-  \endgroup
-}
-
-% Change the active space to expand to nothing.
-%
-\begingroup
-  \obeyspaces
-  \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
-\endgroup
-
-
-\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
-
-%% These are used to keep @begin/@end levels from running away
-%% Call \inENV within environments (after a \begingroup)
-\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
-\def\ENVcheck{%
-\ifENV\errmessage{Still within an environment.  Type Return to continue.}
-\endgroup\fi} % This is not perfect, but it should reduce lossage
-
-% @begin foo  is the same as @foo, for now.
-\newhelp\EMsimple{Type <Return> to continue.}
-
-\outer\def\begin{\parsearg\beginxxx}
-
-\def\beginxxx #1{%
-\expandafter\ifx\csname #1\endcsname\relax
-{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
-\csname #1\endcsname\fi}
-
-% @end foo executes the definition of \Efoo.
-%
-\def\end{\parsearg\endxxx}
-\def\endxxx #1{%
-  \removeactivespaces{#1}%
-  \edef\endthing{\the\toks0}%
-  %
-  \expandafter\ifx\csname E\endthing\endcsname\relax
-    \expandafter\ifx\csname \endthing\endcsname\relax
-      % There's no \foo, i.e., no ``environment'' foo.
-      \errhelp = \EMsimple
-      \errmessage{Undefined command `@end \endthing'}%
-    \else
-      \unmatchedenderror\endthing
-    \fi
-  \else
-    % Everything's ok; the right environment has been started.
-    \csname E\endthing\endcsname
-  \fi
-}
-
-% There is an environment #1, but it hasn't been started.  Give an error.
-%
-\def\unmatchedenderror#1{%
-  \errhelp = \EMsimple
-  \errmessage{This `@end #1' doesn't have a matching `@#1'}%
-}
-
-% Define the control sequence \E#1 to give an unmatched @end error.
-%
-\def\defineunmatchedend#1{%
-  \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
-}
-
-
-% Single-spacing is done by various environments (specifically, in
-% \nonfillstart and \quotations).
-\newskip\singlespaceskip \singlespaceskip = 12.5pt
-\def\singlespace{%
-  % Why was this kern here?  It messes up equalizing space above and below
-  % environments.  --karl, 6may93
-  %{\advance \baselineskip by -\singlespaceskip
-  %\kern \baselineskip}%
-  \setleading \singlespaceskip
-}
-
-%% Simple single-character @ commands
-
-% @@ prints an @
-% Kludge this until the fonts are right (grr).
-\def\@{{\tt \char '100}}
-
-% This is turned off because it was never documented
-% and you can use @w{...} around a quote to suppress ligatures.
-%% Define @` and @' to be the same as ` and '
-%% but suppressing ligatures.
-%\def\`{{`}}
-%\def\'{{'}}
-
-% Used to generate quoted braces.
-
-\def\mylbrace {{\tt \char '173}}
-\def\myrbrace {{\tt \char '175}}
-\let\{=\mylbrace
-\let\}=\myrbrace
-
-% @: forces normal size whitespace following.
-\def\:{\spacefactor=1000 }
-
-% @* forces a line break.
-\def\*{\hfil\break\hbox{}\ignorespaces}
-
-% @. is an end-of-sentence period.
-\def\.{.\spacefactor=3000 }
-
-% @enddots{} is an end-of-sentence ellipsis.
-\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000}
-
-% @! is an end-of-sentence bang.
-\gdef\!{!\spacefactor=3000 }
-
-% @? is an end-of-sentence query.
-\gdef\?{?\spacefactor=3000 }
-
-% @w prevents a word break.  Without the \leavevmode, @w at the
-% beginning of a paragraph, when TeX is still in vertical mode, would
-% produce a whole line of output instead of starting the paragraph.
-\def\w#1{\leavevmode\hbox{#1}}
-
-% @group ... @end group forces ... to be all on one page, by enclosing
-% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
-% to keep its height that of a normal line.  According to the rules for
-% \topskip (p.114 of the TeXbook), the glue inserted is
-% max (\topskip - \ht (first item), 0).  If that height is large,
-% therefore, no glue is inserted, and the space between the headline and
-% the text is small, which looks bad.
-%
-\def\group{\begingroup
-  \ifnum\catcode13=\active \else
-    \errhelp = \groupinvalidhelp
-    \errmessage{@group invalid in context where filling is enabled}%
-  \fi
-  %
-  % The \vtop we start below produces a box with normal height and large
-  % depth; thus, TeX puts \baselineskip glue before it, and (when the
-  % next line of text is done) \lineskip glue after it.  (See p.82 of
-  % the TeXbook.)  Thus, space below is not quite equal to space
-  % above.  But it's pretty close.
-  \def\Egroup{%
-    \egroup           % End the \vtop.
-    \endgroup         % End the \group.
-  }%
-  %
-  \vtop\bgroup
-    % We have to put a strut on the last line in case the @group is in
-    % the midst of an example, rather than completely enclosing it.
-    % Otherwise, the interline space between the last line of the group
-    % and the first line afterwards is too small.  But we can't put the
-    % strut in \Egroup, since there it would be on a line by itself.
-    % Hence this just inserts a strut at the beginning of each line.
-    \everypar = {\strut}%
-    %
-    % Since we have a strut on every line, we don't need any of TeX's
-    % normal interline spacing.
-    \offinterlineskip
-    %
-    % OK, but now we have to do something about blank
-    % lines in the input in @example-like environments, which normally
-    % just turn into \lisppar, which will insert no space now that we've
-    % turned off the interline space.  Simplest is to make them be an
-    % empty paragraph.
-    \ifx\par\lisppar
-      \edef\par{\leavevmode \par}%
-      %
-      % Reset ^^M's definition to new definition of \par.
-      \obeylines
-    \fi
-    %
-    % Do @comment since we are called inside an environment such as
-    % @example, where each end-of-line in the input causes an
-    % end-of-line in the output.  We don't want the end-of-line after
-    % the `@group' to put extra space in the output.  Since @group
-    % should appear on a line by itself (according to the Texinfo
-    % manual), we don't worry about eating any user text.
-    \comment
-}
-%
-% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
-% message, so this ends up printing `@group can only ...'.
-%
-\newhelp\groupinvalidhelp{%
-group can only be used in environments such as @example,^^J%
-where each line of input produces a line of output.}
-
-% @need space-in-mils
-% forces a page break if there is not space-in-mils remaining.
-
-\newdimen\mil  \mil=0.001in
-
-\def\need{\parsearg\needx}
-
-% Old definition--didn't work.
-%\def\needx #1{\par %
-%% This method tries to make TeX break the page naturally
-%% if the depth of the box does not fit.
-%{\baselineskip=0pt%
-%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000
-%\prevdepth=-1000pt
-%}}
-
-\def\needx#1{%
-  % Go into vertical mode, so we don't make a big box in the middle of a
-  % paragraph.
-  \par
-  %
-  % Don't add any leading before our big empty box, but allow a page
-  % break, since the best break might be right here.
-  \allowbreak
-  \nointerlineskip
-  \vtop to #1\mil{\vfil}%
-  %
-  % TeX does not even consider page breaks if a penalty added to the
-  % main vertical list is 10000 or more.  But in order to see if the
-  % empty box we just added fits on the page, we must make it consider
-  % page breaks.  On the other hand, we don't want to actually break the
-  % page after the empty box.  So we use a penalty of 9999.
-  %
-  % There is an extremely small chance that TeX will actually break the
-  % page at this \penalty, if there are no other feasible breakpoints in
-  % sight.  (If the user is using lots of big @group commands, which
-  % almost-but-not-quite fill up a page, TeX will have a hard time doing
-  % good page breaking, for example.)  However, I could not construct an
-  % example where a page broke at this \penalty; if it happens in a real
-  % document, then we can reconsider our strategy.
-  \penalty9999
-  %
-  % Back up by the size of the box, whether we did a page break or not.
-  \kern -#1\mil
-  %
-  % Do not allow a page break right after this kern.
-  \nobreak
-}
-
-% @br   forces paragraph break
-
-\let\br = \par
-
-% @dots{}  output some dots
-
-\def\dots{$\ldots$}
-
-% @page    forces the start of a new page
-
-\def\page{\par\vfill\supereject}
-
-% @exdent text....
-% outputs text on separate line in roman font, starting at standard page margin
-
-% This records the amount of indent in the innermost environment.
-% That's how much \exdent should take out.
-\newskip\exdentamount
-
-% This defn is used inside fill environments such as @defun.
-\def\exdent{\parsearg\exdentyyy}
-\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
-
-% This defn is used inside nofill environments such as @example.
-\def\nofillexdent{\parsearg\nofillexdentyyy}
-\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
-\leftline{\hskip\leftskip{\rm#1}}}}
-
-%\hbox{{\rm#1}}\hfil\break}}
-
-% @include file    insert text of that file as input.
-
-\def\include{\parsearg\includezzz}
-%Use \input\thisfile to avoid blank after \input, which may be an active
-%char (in which case the blank would become the \input argument).
-%The grouping keeps the value of \thisfile correct even when @include
-%is nested.
-\def\includezzz #1{\begingroup
-\def\thisfile{#1}\input\thisfile
-\endgroup}
-
-\def\thisfile{}
-
-% @center line   outputs that line, centered
-
-\def\center{\parsearg\centerzzz}
-\def\centerzzz #1{{\advance\hsize by -\leftskip
-\advance\hsize by -\rightskip
-\centerline{#1}}}
-
-% @sp n   outputs n lines of vertical space
-
-\def\sp{\parsearg\spxxx}
-\def\spxxx #1{\par \vskip #1\baselineskip}
-
-% @comment ...line which is ignored...
-% @c is the same as @comment
-% @ignore ... @end ignore  is another way to write a comment
-
-\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
-\parsearg \commentxxx}
-
-\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
-
-\let\c=\comment
-
-% Prevent errors for section commands.
-% Used in @ignore and in failing conditionals.
-\def\ignoresections{%
-\let\chapter=\relax
-\let\unnumbered=\relax
-\let\top=\relax
-\let\unnumberedsec=\relax
-\let\unnumberedsection=\relax
-\let\unnumberedsubsec=\relax
-\let\unnumberedsubsection=\relax
-\let\unnumberedsubsubsec=\relax
-\let\unnumberedsubsubsection=\relax
-\let\section=\relax
-\let\subsec=\relax
-\let\subsubsec=\relax
-\let\subsection=\relax
-\let\subsubsection=\relax
-\let\appendix=\relax
-\let\appendixsec=\relax
-\let\appendixsection=\relax
-\let\appendixsubsec=\relax
-\let\appendixsubsection=\relax
-\let\appendixsubsubsec=\relax
-\let\appendixsubsubsection=\relax
-\let\contents=\relax
-\let\smallbook=\relax
-\let\titlepage=\relax
-}
-
-% Used in nested conditionals, where we have to parse the Texinfo source
-% and so want to turn off most commands, in case they are used
-% incorrectly.
-%
-\def\ignoremorecommands{%
-  \let\defcv = \relax
-  \let\deffn = \relax
-  \let\deffnx = \relax
-  \let\defindex = \relax
-  \let\defivar = \relax
-  \let\defmac = \relax
-  \let\defmethod = \relax
-  \let\defop = \relax
-  \let\defopt = \relax
-  \let\defspec = \relax
-  \let\deftp = \relax
-  \let\deftypefn = \relax
-  \let\deftypefun = \relax
-  \let\deftypevar = \relax
-  \let\deftypevr = \relax
-  \let\defun = \relax
-  \let\defvar = \relax
-  \let\defvr = \relax
-  \let\ref = \relax
-  \let\xref = \relax
-  \let\printindex = \relax
-  \let\pxref = \relax
-  \let\settitle = \relax
-  \let\include = \relax
-  \let\lowersections = \relax
-  \let\down = \relax
-  \let\raisesections = \relax
-  \let\up = \relax
-  \let\set = \relax
-  \let\clear = \relax
-  \let\item = \relax
-  \let\message = \relax
-}
-
-% Ignore @ignore ... @end ignore.
-%
-\def\ignore{\doignore{ignore}}
-
-% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text.
-%
-\def\ifinfo{\doignore{ifinfo}}
-\def\ifhtml{\doignore{ifhtml}}
-\def\html{\doignore{html}}
-\def\menu{\doignore{menu}}
-\def\direntry{\doignore{direntry}}
-
-% Ignore text until a line `@end #1'.
-%
-\def\doignore#1{\begingroup
-  % Don't complain about control sequences we have declared \outer.
-  \ignoresections
-  %
-  % Define a command to swallow text until we reach `@end #1'.
-  \long\def\doignoretext##1\end #1{\enddoignore}%
-  %
-  % Make sure that spaces turn into tokens that match what \doignoretext wants.
-  \catcode32 = 10
-  %
-  % And now expand that command.
-  \doignoretext
-}
-
-% What we do to finish off ignored text.
-%
-\def\enddoignore{\endgroup\ignorespaces}%
-
-\newif\ifwarnedobs\warnedobsfalse
-\def\obstexwarn{%
-  \ifwarnedobs\relax\else
-  % We need to warn folks that they may have trouble with TeX 3.0.
-  % This uses \immediate\write16 rather than \message to get newlines.
-    \immediate\write16{}
-    \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
-    \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
-    \immediate\write16{If you are running another version of TeX, relax.}
-    \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
-    \immediate\write16{  Then upgrade your TeX installation if you can.}
-    \immediate\write16{If you are stuck with version 3.0, run the}
-    \immediate\write16{  script ``tex3patch'' from the Texinfo distribution}
-    \immediate\write16{  to use a workaround.}
-    \immediate\write16{}
-    \warnedobstrue
-    \fi
-}
-
-% **In TeX 3.0, setting text in \nullfont hangs tex.  For a
-% workaround (which requires the file ``dummy.tfm'' to be installed),
-% uncomment the following line:
-%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
-
-% Ignore text, except that we keep track of conditional commands for
-% purposes of nesting, up to an `@end #1' command.
-%
-\def\nestedignore#1{%
-  \obstexwarn
-  % We must actually expand the ignored text to look for the @end
-  % command, so that nested ignore constructs work.  Thus, we put the
-  % text into a \vbox and then do nothing with the result.  To minimize
-  % the change of memory overflow, we follow the approach outlined on
-  % page 401 of the TeXbook: make the current font be a dummy font.
-  %
-  \setbox0 = \vbox\bgroup
-    % Don't complain about control sequences we have declared \outer.
-    \ignoresections
-    %
-    % Define `@end #1' to end the box, which will in turn undefine the
-    % @end command again.
-    \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
-    %
-    % We are going to be parsing Texinfo commands.  Most cause no
-    % trouble when they are used incorrectly, but some commands do
-    % complicated argument parsing or otherwise get confused, so we
-    % undefine them.
-    %
-    % We can't do anything about stray @-signs, unfortunately;
-    % they'll produce `undefined control sequence' errors.
-    \ignoremorecommands
-    %
-    % Set the current font to be \nullfont, a TeX primitive, and define
-    % all the font commands to also use \nullfont.  We don't use
-    % dummy.tfm, as suggested in the TeXbook, because not all sites
-    % might have that installed.  Therefore, math mode will still
-    % produce output, but that should be an extremely small amount of
-    % stuff compared to the main input.
-    %
-    \nullfont
-    \let\tenrm = \nullfont  \let\tenit = \nullfont  \let\tensl = \nullfont
-    \let\tenbf = \nullfont  \let\tentt = \nullfont  \let\smallcaps = \nullfont
-    \let\tensf = \nullfont
-    % Similarly for index fonts (mostly for their use in
-    % smallexample)
-    \let\indrm = \nullfont  \let\indit = \nullfont  \let\indsl = \nullfont
-    \let\indbf = \nullfont  \let\indtt = \nullfont  \let\indsc = \nullfont
-    \let\indsf = \nullfont
-    %
-    % Don't complain when characters are missing from the fonts.
-    \tracinglostchars = 0
-    %
-    % Don't bother to do space factor calculations.
-    \frenchspacing
-    %
-    % Don't report underfull hboxes.
-    \hbadness = 10000
-    %
-    % Do minimal line-breaking.
-    \pretolerance = 10000
-    %
-    % Do not execute instructions in @tex
-    \def\tex{\doignore{tex}}
-}
-
-% @set VAR sets the variable VAR to an empty value.
-% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
-%
-% Since we want to separate VAR from REST-OF-LINE (which might be
-% empty), we can't just use \parsearg; we have to insert a space of our
-% own to delimit the rest of the line, and then take it out again if we
-% didn't need it.
-%
-\def\set{\parsearg\setxxx}
-\def\setxxx#1{\setyyy#1 \endsetyyy}
-\def\setyyy#1 #2\endsetyyy{%
-  \def\temp{#2}%
-  \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
-  \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
-  \fi
-}
-\def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}}
-
-% @clear VAR clears (i.e., unsets) the variable VAR.
-%
-\def\clear{\parsearg\clearxxx}
-\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
-
-% @value{foo} gets the text saved in variable foo.
-%
-\def\value#1{\expandafter
-		\ifx\csname SET#1\endcsname\relax
-			{\{No value for ``#1''\}}
-		\else \csname SET#1\endcsname \fi}
-
-% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
-% with @set.
-%
-\def\ifset{\parsearg\ifsetxxx}
-\def\ifsetxxx #1{%
-  \expandafter\ifx\csname SET#1\endcsname\relax
-    \expandafter\ifsetfail
-  \else
-    \expandafter\ifsetsucceed
-  \fi
-}
-\def\ifsetsucceed{\conditionalsucceed{ifset}}
-\def\ifsetfail{\nestedignore{ifset}}
-\defineunmatchedend{ifset}
-
-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
-% defined with @set, or has been undefined with @clear.
-%
-\def\ifclear{\parsearg\ifclearxxx}
-\def\ifclearxxx #1{%
-  \expandafter\ifx\csname SET#1\endcsname\relax
-    \expandafter\ifclearsucceed
-  \else
-    \expandafter\ifclearfail
-  \fi
-}
-\def\ifclearsucceed{\conditionalsucceed{ifclear}}
-\def\ifclearfail{\nestedignore{ifclear}}
-\defineunmatchedend{ifclear}
-
-% @iftex always succeeds; we read the text following, through @end
-% iftex).  But `@end iftex' should be valid only after an @iftex.
-%
-\def\iftex{\conditionalsucceed{iftex}}
-\defineunmatchedend{iftex}
-
-% We can't just want to start a group at @iftex (for example) and end it
-% at @end iftex, since then @set commands inside the conditional have no
-% effect (they'd get reverted at the end of the group).  So we must
-% define \Eiftex to redefine itself to be its previous value.  (We can't
-% just define it to fail again with an ``unmatched end'' error, since
-% the @ifset might be nested.)
-%
-\def\conditionalsucceed#1{%
-  \edef\temp{%
-    % Remember the current value of \E#1.
-    \let\nece{prevE#1} = \nece{E#1}%
-    %
-    % At the `@end #1', redefine \E#1 to be its previous value.
-    \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
-  }%
-  \temp
-}
-
-% We need to expand lots of \csname's, but we don't want to expand the
-% control sequences after we've constructed them.
-%
-\def\nece#1{\expandafter\noexpand\csname#1\endcsname}
-
-% @asis just yields its argument.  Used with @table, for example.
-%
-\def\asis#1{#1}
-
-% @math means output in math mode.
-% We don't use $'s directly in the definition of \math because control
-% sequences like \math are expanded when the toc file is written.  Then,
-% we read the toc file back, the $'s will be normal characters (as they
-% should be, according to the definition of Texinfo).  So we must use a
-% control sequence to switch into and out of math mode.
-%
-% This isn't quite enough for @math to work properly in indices, but it
-% seems unlikely it will ever be needed there.
-%
-\let\implicitmath = $
-\def\math#1{\implicitmath #1\implicitmath}
-
-% @bullet and @minus need the same treatment as @math, just above.
-\def\bullet{\implicitmath\ptexbullet\implicitmath}
-\def\minus{\implicitmath-\implicitmath}
-
-\def\node{\ENVcheck\parsearg\nodezzz}
-\def\nodezzz#1{\nodexxx [#1,]}
-\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
-\let\nwnode=\node
-\let\lastnode=\relax
-
-\def\donoderef{\ifx\lastnode\relax\else
-\expandafter\expandafter\expandafter\setref{\lastnode}\fi
-\global\let\lastnode=\relax}
-
-\def\unnumbnoderef{\ifx\lastnode\relax\else
-\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
-\global\let\lastnode=\relax}
-
-\def\appendixnoderef{\ifx\lastnode\relax\else
-\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
-\global\let\lastnode=\relax}
-
-\let\refill=\relax
-
-% @setfilename is done at the beginning of every texinfo file.
-% So open here the files we need to have open while reading the input.
-% This makes it possible to make a .fmt file for texinfo.
-\def\setfilename{%
-   \readauxfile
-   \opencontents
-   \openindices
-   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
-   \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
-   \comment % Ignore the actual filename.
-}
-
-\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
-
-\def\inforef #1{\inforefzzz #1,,,,**}
-\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
-  node \samp{\ignorespaces#1{}}}
-
-\message{fonts,}
-
-% Font-change commands.
-
-% Texinfo supports the sans serif font style, which plain TeX does not.
-% So we set up a \sf analogous to plain's \rm, etc.
-\newfam\sffam
-\def\sf{\fam=\sffam \tensf}
-\let\li = \sf % Sometimes we call it \li, not \sf.
-
-%% Try out Computer Modern fonts at \magstephalf
-\let\mainmagstep=\magstephalf
-
-\ifx\bigger\relax
-\let\mainmagstep=\magstep1
-\font\textrm=cmr12
-\font\texttt=cmtt12
-\else
-\font\textrm=cmr10 scaled \mainmagstep
-\font\texttt=cmtt10 scaled \mainmagstep
-\fi
-% Instead of cmb10, you many want to use cmbx10.
-% cmbx10 is a prettier font on its own, but cmb10
-% looks better when embedded in a line with cmr10.
-\font\textbf=cmb10 scaled \mainmagstep
-\font\textit=cmti10 scaled \mainmagstep
-\font\textsl=cmsl10 scaled \mainmagstep
-\font\textsf=cmss10 scaled \mainmagstep
-\font\textsc=cmcsc10 scaled \mainmagstep
-\font\texti=cmmi10 scaled \mainmagstep
-\font\textsy=cmsy10 scaled \mainmagstep
-
-% A few fonts for @defun, etc.
-\font\defbf=cmbx10 scaled \magstep1 %was 1314
-\font\deftt=cmtt10 scaled \magstep1
-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
-
-% Fonts for indices and small examples.
-% We actually use the slanted font rather than the italic,
-% because texinfo normally uses the slanted fonts for that.
-% Do not make many font distinctions in general in the index, since they
-% aren't very useful.
-\font\ninett=cmtt9
-\font\indrm=cmr9
-\font\indit=cmsl9
-\let\indsl=\indit
-\let\indtt=\ninett
-\let\indsf=\indrm
-\let\indbf=\indrm
-\let\indsc=\indrm
-\font\indi=cmmi9
-\font\indsy=cmsy9
-
-% Fonts for headings
-\font\chaprm=cmbx12 scaled \magstep2
-\font\chapit=cmti12 scaled \magstep2
-\font\chapsl=cmsl12 scaled \magstep2
-\font\chaptt=cmtt12 scaled \magstep2
-\font\chapsf=cmss12 scaled \magstep2
-\let\chapbf=\chaprm
-\font\chapsc=cmcsc10 scaled\magstep3
-\font\chapi=cmmi12 scaled \magstep2
-\font\chapsy=cmsy10 scaled \magstep3
-
-\font\secrm=cmbx12 scaled \magstep1
-\font\secit=cmti12 scaled \magstep1
-\font\secsl=cmsl12 scaled \magstep1
-\font\sectt=cmtt12 scaled \magstep1
-\font\secsf=cmss12 scaled \magstep1
-\font\secbf=cmbx12 scaled \magstep1
-\font\secsc=cmcsc10 scaled\magstep2
-\font\seci=cmmi12 scaled \magstep1
-\font\secsy=cmsy10 scaled \magstep2
-
-% \font\ssecrm=cmbx10 scaled \magstep1    % This size an font looked bad.
-% \font\ssecit=cmti10 scaled \magstep1    % The letters were too crowded.
-% \font\ssecsl=cmsl10 scaled \magstep1
-% \font\ssectt=cmtt10 scaled \magstep1
-% \font\ssecsf=cmss10 scaled \magstep1
-
-%\font\ssecrm=cmb10 scaled 1315	% Note the use of cmb rather than cmbx.
-%\font\ssecit=cmti10 scaled 1315	% Also, the size is a little larger than
-%\font\ssecsl=cmsl10 scaled 1315	% being scaled magstep1.
-%\font\ssectt=cmtt10 scaled 1315
-%\font\ssecsf=cmss10 scaled 1315
-
-%\let\ssecbf=\ssecrm
-
-\font\ssecrm=cmbx12 scaled \magstephalf
-\font\ssecit=cmti12 scaled \magstephalf
-\font\ssecsl=cmsl12 scaled \magstephalf
-\font\ssectt=cmtt12 scaled \magstephalf
-\font\ssecsf=cmss12 scaled \magstephalf
-\font\ssecbf=cmbx12 scaled \magstephalf
-\font\ssecsc=cmcsc10 scaled \magstep1
-\font\sseci=cmmi12 scaled \magstephalf
-\font\ssecsy=cmsy10 scaled \magstep1
-% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
-% but that is not a standard magnification.
-
-% Fonts for title page:
-\font\titlerm = cmbx12 scaled \magstep3
-\let\authorrm = \secrm
-
-% In order for the font changes to affect most math symbols and letters,
-% we have to define the \textfont of the standard families.  Since
-% texinfo doesn't allow for producing subscripts and superscripts, we
-% don't bother to reset \scriptfont and \scriptscriptfont (which would
-% also require loading a lot more fonts).
-%
-\def\resetmathfonts{%
-  \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
-  \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
-  \textfont\ttfam = \tentt \textfont\sffam = \tensf
-}
-
-
-% The font-changing commands redefine the meanings of \tenSTYLE, instead
-% of just \STYLE.  We do this so that font changes will continue to work
-% in math mode, where it is the current \fam that is relevant in most
-% cases, not the current.  Plain TeX does, for example,
-% \def\bf{\fam=\bffam \tenbf}  By redefining \tenbf, we obviate the need
-% to redefine \bf itself.
-\def\textfonts{%
-  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
-  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
-  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
-  \resetmathfonts}
-\def\chapfonts{%
-  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
-  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
-  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
-  \resetmathfonts}
-\def\secfonts{%
-  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
-  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
-  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
-  \resetmathfonts}
-\def\subsecfonts{%
-  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
-  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
-  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
-  \resetmathfonts}
-\def\indexfonts{%
-  \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
-  \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
-  \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy
-  \resetmathfonts}
-
-% Set up the default fonts, so we can use them for creating boxes.
-%
-\textfonts
-
-% Count depth in font-changes, for error checks
-\newcount\fontdepth \fontdepth=0
-
-% Fonts for short table of contents.
-\font\shortcontrm=cmr12
-\font\shortcontbf=cmbx12
-\font\shortcontsl=cmsl12
-
-%% Add scribe-like font environments, plus @l for inline lisp (usually sans
-%% serif) and @ii for TeX italic
-
-% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
-% unless the following character is such as not to need one.
-\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
-\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
-
-\let\i=\smartitalic
-\let\var=\smartitalic
-\let\dfn=\smartitalic
-\let\emph=\smartitalic
-\let\cite=\smartitalic
-
-\def\b#1{{\bf #1}}
-\let\strong=\b
-
-% We can't just use \exhyphenpenalty, because that only has effect at
-% the end of a paragraph.  Restore normal hyphenation at the end of the
-% group within which \nohyphenation is presumably called.
-%
-\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
-\def\restorehyphenation{\hyphenchar\font = `- }
-
-\def\t#1{%
-  {\tt \nohyphenation \rawbackslash \frenchspacing #1}%
-  \null
-}
-\let\ttfont = \t
-%\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null}
-\def\samp #1{`\tclose{#1}'\null}
-\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null}
-\def\ctrl #1{{\tt \rawbackslash \hat}#1}
-
-\let\file=\samp
-
-% @code is a modification of @t,
-% which makes spaces the same size as normal in the surrounding text.
-\def\tclose#1{%
-  {%
-    % Change normal interword space to be same as for the current font.
-    \spaceskip = \fontdimen2\font
-    %
-    % Switch to typewriter.
-    \tt
-    %
-    % But `\ ' produces the large typewriter interword space.
-    \def\ {{\spaceskip = 0pt{} }}%
-    %
-    % Turn off hyphenation.
-    \nohyphenation
-    %
-    \rawbackslash
-    \frenchspacing
-    #1%
-  }%
-  \null
-}
-
-% We *must* turn on hyphenation at `-' and `_' in \code.
-% Otherwise, it is too hard to avoid overful hboxes
-% in the Emacs manual, the Library manual, etc.
-
-% Unfortunately, TeX uses one parameter (\hyphenchar) to control
-% both hyphenation at - and hyphenation within words.
-% We must therefore turn them both off (\tclose does that)
-% and arrange explicitly to hyphenate an a dash.
-%  -- rms.
-{
-\catcode`\-=\active
-\catcode`\_=\active
-\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
-% The following is used by \doprintindex to insure that long function names
-% wrap around.  It is necessary for - and _ to be active before the index is
-% read from the file, as \entry parses the arguments long before \code is
-% ever called.  -- mycroft
-\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
-}
-\def\realdash{-}
-\def\realunder{_}
-\def\codedash{-\discretionary{}{}{}}
-\def\codeunder{\normalunderscore\discretionary{}{}{}}
-\def\codex #1{\tclose{#1}\endgroup}
-
-%\let\exp=\tclose  %Was temporary
-
-% @kbd is like @code, except that if the argument is just one @key command,
-% then @kbd has no effect.
-
-\def\xkey{\key}
-\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
-\ifx\one\xkey\ifx\threex\three \key{#2}%
-\else\tclose{\look}\fi
-\else\tclose{\look}\fi}
-
-% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
-% argument is to make the input look right: @dmn{pt} instead of
-% @dmn{}pt.
-%
-\def\dmn#1{\thinspace #1}
-
-\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
-
-\def\l#1{{\li #1}\null}		%
-
-\def\r#1{{\rm #1}}		% roman font
-% Use of \lowercase was suggested.
-\def\sc#1{{\smallcaps#1}}	% smallcaps font
-\def\ii#1{{\it #1}}		% italic font
-
-\message{page headings,}
-
-\newskip\titlepagetopglue \titlepagetopglue = 1.5in
-\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
-
-% First the title page.  Must do @settitle before @titlepage.
-\def\titlefont#1{{\titlerm #1}}
-
-\newif\ifseenauthor
-\newif\iffinishedtitlepage
-
-\def\shorttitlepage{\parsearg\shorttitlepagezzz}
-\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
-	\endgroup\page\hbox{}\page}
-
-\def\titlepage{\begingroup \parindent=0pt \textfonts
-   \let\subtitlerm=\tenrm
-% I deinstalled the following change because \cmr12 is undefined.
-% This change was not in the ChangeLog anyway.  --rms.
-%   \let\subtitlerm=\cmr12
-   \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
-   %
-   \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
-   %
-   % Leave some space at the very top of the page.
-   \vglue\titlepagetopglue
-   %
-   % Now you can print the title using @title.
-   \def\title{\parsearg\titlezzz}%
-   \def\titlezzz##1{\leftline{\titlefont{##1}}
-		    % print a rule at the page bottom also.
-		    \finishedtitlepagefalse
-		    \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
-   % No rule at page bottom unless we print one at the top with @title.
-   \finishedtitlepagetrue
-   %
-   % Now you can put text using @subtitle.
-   \def\subtitle{\parsearg\subtitlezzz}%
-   \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
-   %
-   % @author should come last, but may come many times.
-   \def\author{\parsearg\authorzzz}%
-   \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
-      {\authorfont \leftline{##1}}}%
-   %
-   % Most title ``pages'' are actually two pages long, with space
-   % at the top of the second.  We don't want the ragged left on the second.
-   \let\oldpage = \page
-   \def\page{%
-      \iffinishedtitlepage\else
-	 \finishtitlepage
-      \fi
-      \oldpage
-      \let\page = \oldpage
-      \hbox{}}%
-%   \def\page{\oldpage \hbox{}}
-}
-
-\def\Etitlepage{%
-   \iffinishedtitlepage\else
-      \finishtitlepage
-   \fi
-   % It is important to do the page break before ending the group,
-   % because the headline and footline are only empty inside the group.
-   % If we use the new definition of \page, we always get a blank page
-   % after the title page, which we certainly don't want.
-   \oldpage
-   \endgroup
-   \HEADINGSon
-}
-
-\def\finishtitlepage{%
-   \vskip4pt \hrule height 2pt width \hsize
-   \vskip\titlepagebottomglue
-   \finishedtitlepagetrue
-}
-
-%%% Set up page headings and footings.
-
-\let\thispage=\folio
-
-\newtoks \evenheadline    % Token sequence for heading line of even pages
-\newtoks \oddheadline     % Token sequence for heading line of odd pages
-\newtoks \evenfootline    % Token sequence for footing line of even pages
-\newtoks \oddfootline     % Token sequence for footing line of odd pages
-
-% Now make Tex use those variables
-\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
-                            \else \the\evenheadline \fi}}
-\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
-                            \else \the\evenfootline \fi}\HEADINGShook}
-\let\HEADINGShook=\relax
-
-% Commands to set those variables.
-% For example, this is what  @headings on  does
-% @evenheading @thistitle|@thispage|@thischapter
-% @oddheading @thischapter|@thispage|@thistitle
-% @evenfooting @thisfile||
-% @oddfooting ||@thisfile
-
-\def\evenheading{\parsearg\evenheadingxxx}
-\def\oddheading{\parsearg\oddheadingxxx}
-\def\everyheading{\parsearg\everyheadingxxx}
-
-\def\evenfooting{\parsearg\evenfootingxxx}
-\def\oddfooting{\parsearg\oddfootingxxx}
-\def\everyfooting{\parsearg\everyfootingxxx}
-
-{\catcode`\@=0 %
-
-\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
-\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
-\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-
-\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
-\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
-\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-
-\gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish}
-\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{%
-\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
-\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-
-\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
-\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
-\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-
-\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
-\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
-\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-
-\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish}
-\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{%
-\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
-\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-%
-}% unbind the catcode of @.
-
-% @headings double	turns headings on for double-sided printing.
-% @headings single	turns headings on for single-sided printing.
-% @headings off		turns them off.
-% @headings on		same as @headings double, retained for compatibility.
-% @headings after	turns on double-sided headings after this page.
-% @headings doubleafter	turns on double-sided headings after this page.
-% @headings singleafter turns on single-sided headings after this page.
-% By default, they are off.
-
-\def\headings #1 {\csname HEADINGS#1\endcsname}
-
-\def\HEADINGSoff{
-\global\evenheadline={\hfil} \global\evenfootline={\hfil}
-\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
-\HEADINGSoff
-% When we turn headings on, set the page number to 1.
-% For double-sided printing, put current file name in lower left corner,
-% chapter name on inside top of right hand pages, document
-% title on inside top of left hand pages, and page numbers on outside top
-% edge of all pages.
-\def\HEADINGSdouble{
-%\pagealignmacro
-\global\pageno=1
-\global\evenfootline={\hfil}
-\global\oddfootline={\hfil}
-\global\evenheadline={\line{\folio\hfil\thistitle}}
-\global\oddheadline={\line{\thischapter\hfil\folio}}
-}
-% For single-sided printing, chapter title goes across top left of page,
-% page number on top right.
-\def\HEADINGSsingle{
-%\pagealignmacro
-\global\pageno=1
-\global\evenfootline={\hfil}
-\global\oddfootline={\hfil}
-\global\evenheadline={\line{\thischapter\hfil\folio}}
-\global\oddheadline={\line{\thischapter\hfil\folio}}
-}
-\def\HEADINGSon{\HEADINGSdouble}
-
-\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
-\let\HEADINGSdoubleafter=\HEADINGSafter
-\def\HEADINGSdoublex{%
-\global\evenfootline={\hfil}
-\global\oddfootline={\hfil}
-\global\evenheadline={\line{\folio\hfil\thistitle}}
-\global\oddheadline={\line{\thischapter\hfil\folio}}
-}
-
-\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
-\def\HEADINGSsinglex{%
-\global\evenfootline={\hfil}
-\global\oddfootline={\hfil}
-\global\evenheadline={\line{\thischapter\hfil\folio}}
-\global\oddheadline={\line{\thischapter\hfil\folio}}
-}
-
-% Subroutines used in generating headings
-% Produces Day Month Year style of output.
-\def\today{\number\day\space
-\ifcase\month\or
-January\or February\or March\or April\or May\or June\or
-July\or August\or September\or October\or November\or December\fi
-\space\number\year}
-
-% Use this if you want the Month Day, Year style of output.
-%\def\today{\ifcase\month\or
-%January\or February\or March\or April\or May\or June\or
-%July\or August\or September\or October\or November\or December\fi
-%\space\number\day, \number\year}
-
-% @settitle line...  specifies the title of the document, for headings
-% It generates no output of its own
-
-\def\thistitle{No Title}
-\def\settitle{\parsearg\settitlezzz}
-\def\settitlezzz #1{\gdef\thistitle{#1}}
-
-\message{tables,}
-
-% @tabs -- simple alignment
-
-% These don't work.  For one thing, \+ is defined as outer.
-% So these macros cannot even be defined.
-
-%\def\tabs{\parsearg\tabszzz}
-%\def\tabszzz #1{\settabs\+#1\cr}
-%\def\tabline{\parsearg\tablinezzz}
-%\def\tablinezzz #1{\+#1\cr}
-%\def\&{&}
-
-% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
-
-% default indentation of table text
-\newdimen\tableindent \tableindent=.8in
-% default indentation of @itemize and @enumerate text
-\newdimen\itemindent  \itemindent=.3in
-% margin between end of table item and start of table text.
-\newdimen\itemmargin  \itemmargin=.1in
-
-% used internally for \itemindent minus \itemmargin
-\newdimen\itemmax
-
-% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
-% these defs.
-% They also define \itemindex
-% to index the item name in whatever manner is desired (perhaps none).
-
-\newif\ifitemxneedsnegativevskip
-
-\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi}
-
-\def\internalBitem{\smallbreak \parsearg\itemzzz}
-\def\internalBitemx{\itemxpar \parsearg\itemzzz}
-
-\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
-\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
-
-\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
-\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
-
-\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
-                 \itemzzz {#1}}
-
-\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
-                 \itemzzz {#1}}
-
-\def\itemzzz #1{\begingroup %
-  \advance\hsize by -\rightskip
-  \advance\hsize by -\tableindent
-  \setbox0=\hbox{\itemfont{#1}}%
-  \itemindex{#1}%
-  \nobreak % This prevents a break before @itemx.
-  %
-  % Be sure we are not still in the middle of a paragraph.
-  %{\parskip = 0in
-  %\par
-  %}%
-  %
-  % If the item text does not fit in the space we have, put it on a line
-  % by itself, and do not allow a page break either before or after that
-  % line.  We do not start a paragraph here because then if the next
-  % command is, e.g., @kindex, the whatsit would get put into the
-  % horizontal list on a line by itself, resulting in extra blank space.
-  \ifdim \wd0>\itemmax
-    %
-    % Make this a paragraph so we get the \parskip glue and wrapping,
-    % but leave it ragged-right.
-    \begingroup
-      \advance\leftskip by-\tableindent
-      \advance\hsize by\tableindent
-      \advance\rightskip by0pt plus1fil
-      \leavevmode\unhbox0\par
-    \endgroup
-    %
-    % We're going to be starting a paragraph, but we don't want the
-    % \parskip glue -- logically it's part of the @item we just started.
-    \nobreak \vskip-\parskip
-    %
-    % Stop a page break at the \parskip glue coming up.  Unfortunately
-    % we can't prevent a possible page break at the following
-    % \baselineskip glue.
-    \nobreak
-    \endgroup
-    \itemxneedsnegativevskipfalse
-  \else
-    % The item text fits into the space.  Start a paragraph, so that the
-    % following text (if any) will end up on the same line.  Since that
-    % text will be indented by \tableindent, we make the item text be in
-    % a zero-width box.
-    \noindent
-    \rlap{\hskip -\tableindent\box0}\ignorespaces%
-    \endgroup%
-    \itemxneedsnegativevskiptrue%
-  \fi
-}
-
-\def\item{\errmessage{@item while not in a table}}
-\def\itemx{\errmessage{@itemx while not in a table}}
-\def\kitem{\errmessage{@kitem while not in a table}}
-\def\kitemx{\errmessage{@kitemx while not in a table}}
-\def\xitem{\errmessage{@xitem while not in a table}}
-\def\xitemx{\errmessage{@xitemx while not in a table}}
-
-%% Contains a kludge to get @end[description] to work
-\def\description{\tablez{\dontindex}{1}{}{}{}{}}
-
-\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
-{\obeylines\obeyspaces%
-\gdef\tablex #1^^M{%
-\tabley\dontindex#1        \endtabley}}
-
-\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
-{\obeylines\obeyspaces%
-\gdef\ftablex #1^^M{%
-\tabley\fnitemindex#1        \endtabley
-\def\Eftable{\endgraf\afterenvbreak\endgroup}%
-\let\Etable=\relax}}
-
-\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
-{\obeylines\obeyspaces%
-\gdef\vtablex #1^^M{%
-\tabley\vritemindex#1        \endtabley
-\def\Evtable{\endgraf\afterenvbreak\endgroup}%
-\let\Etable=\relax}}
-
-\def\dontindex #1{}
-\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
-\def\vritemindex #1{\doind {vr}{\code{#1}}}%
-
-{\obeyspaces %
-\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
-\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
-
-\def\tablez #1#2#3#4#5#6{%
-\aboveenvbreak %
-\begingroup %
-\def\Edescription{\Etable}% Neccessary kludge.
-\let\itemindex=#1%
-\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
-\ifnum 0#4>0 \tableindent=#4\mil \fi %
-\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
-\def\itemfont{#2}%
-\itemmax=\tableindent %
-\advance \itemmax by -\itemmargin %
-\advance \leftskip by \tableindent %
-\exdentamount=\tableindent
-\parindent = 0pt
-\parskip = \smallskipamount
-\ifdim \parskip=0pt \parskip=2pt \fi%
-\def\Etable{\endgraf\afterenvbreak\endgroup}%
-\let\item = \internalBitem %
-\let\itemx = \internalBitemx %
-\let\kitem = \internalBkitem %
-\let\kitemx = \internalBkitemx %
-\let\xitem = \internalBxitem %
-\let\xitemx = \internalBxitemx %
-}
-
-% This is the counter used by @enumerate, which is really @itemize
-
-\newcount \itemno
-
-\def\itemize{\parsearg\itemizezzz}
-
-\def\itemizezzz #1{%
-  \begingroup % ended by the @end itemsize
-  \itemizey {#1}{\Eitemize}
-}
-
-\def\itemizey #1#2{%
-\aboveenvbreak %
-\itemmax=\itemindent %
-\advance \itemmax by -\itemmargin %
-\advance \leftskip by \itemindent %
-\exdentamount=\itemindent
-\parindent = 0pt %
-\parskip = \smallskipamount %
-\ifdim \parskip=0pt \parskip=2pt \fi%
-\def#2{\endgraf\afterenvbreak\endgroup}%
-\def\itemcontents{#1}%
-\let\item=\itemizeitem}
-
-% Set sfcode to normal for the chars that usually have another value.
-% These are `.?!:;,'
-\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
-  \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
-
-% \splitoff TOKENS\endmark defines \first to be the first token in
-% TOKENS, and \rest to be the remainder.
-%
-\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
-
-% Allow an optional argument of an uppercase letter, lowercase letter,
-% or number, to specify the first label in the enumerated list.  No
-% argument is the same as `1'.
-%
-\def\enumerate{\parsearg\enumeratezzz}
-\def\enumeratezzz #1{\enumeratey #1  \endenumeratey}
-\def\enumeratey #1 #2\endenumeratey{%
-  \begingroup % ended by the @end enumerate
-  %
-  % If we were given no argument, pretend we were given `1'.
-  \def\thearg{#1}%
-  \ifx\thearg\empty \def\thearg{1}\fi
-  %
-  % Detect if the argument is a single token.  If so, it might be a
-  % letter.  Otherwise, the only valid thing it can be is a number.
-  % (We will always have one token, because of the test we just made.
-  % This is a good thing, since \splitoff doesn't work given nothing at
-  % all -- the first parameter is undelimited.)
-  \expandafter\splitoff\thearg\endmark
-  \ifx\rest\empty
-    % Only one token in the argument.  It could still be anything.
-    % A ``lowercase letter'' is one whose \lccode is nonzero.
-    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
-    %   not equal to itself.
-    % Otherwise, we assume it's a number.
-    %
-    % We need the \relax at the end of the \ifnum lines to stop TeX from
-    % continuing to look for a <number>.
-    %
-    \ifnum\lccode\expandafter`\thearg=0\relax
-      \numericenumerate % a number (we hope)
-    \else
-      % It's a letter.
-      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
-        \lowercaseenumerate % lowercase letter
-      \else
-        \uppercaseenumerate % uppercase letter
-      \fi
-    \fi
-  \else
-    % Multiple tokens in the argument.  We hope it's a number.
-    \numericenumerate
-  \fi
-}
-
-% An @enumerate whose labels are integers.  The starting integer is
-% given in \thearg.
-%
-\def\numericenumerate{%
-  \itemno = \thearg
-  \startenumeration{\the\itemno}%
-}
-
-% The starting (lowercase) letter is in \thearg.
-\def\lowercaseenumerate{%
-  \itemno = \expandafter`\thearg
-  \startenumeration{%
-    % Be sure we're not beyond the end of the alphabet.
-    \ifnum\itemno=0
-      \errmessage{No more lowercase letters in @enumerate; get a bigger
-                  alphabet}%
-    \fi
-    \char\lccode\itemno
-  }%
-}
-
-% The starting (uppercase) letter is in \thearg.
-\def\uppercaseenumerate{%
-  \itemno = \expandafter`\thearg
-  \startenumeration{%
-    % Be sure we're not beyond the end of the alphabet.
-    \ifnum\itemno=0
-      \errmessage{No more uppercase letters in @enumerate; get a bigger
-                  alphabet}
-    \fi
-    \char\uccode\itemno
-  }%
-}
-
-% Call itemizey, adding a period to the first argument and supplying the
-% common last two arguments.  Also subtract one from the initial value in
-% \itemno, since @item increments \itemno.
-%
-\def\startenumeration#1{%
-  \advance\itemno by -1
-  \itemizey{#1.}\Eenumerate\flushcr
-}
-
-% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
-% to @enumerate.
-%
-\def\alphaenumerate{\enumerate{a}}
-\def\capsenumerate{\enumerate{A}}
-\def\Ealphaenumerate{\Eenumerate}
-\def\Ecapsenumerate{\Eenumerate}
-
-% Definition of @item while inside @itemize.
-
-\def\itemizeitem{%
-\advance\itemno by 1
-{\let\par=\endgraf \smallbreak}%
-\ifhmode \errmessage{\in hmode at itemizeitem}\fi
-{\parskip=0in \hskip 0pt
-\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
-\vadjust{\penalty 1200}}%
-\flushcr}
-
-% @multitable macros
-% Amy Hendrickson, 8/18/94
-%
-% @multitable ... @endmultitable will make as many columns as desired.
-% Contents of each column will wrap at width given in preamble. Width
-% can be specified either with sample text given in a template line,
-% or in percent of \hsize, the current width of text on page.
-
-% Table can continue over pages but will only break between lines.
-
-% To make preamble:
-%
-% Either define widths of columns in terms of percent of \hsize: 
-%   @multitable @percentofhsize .2 .3 .5
-%   @item ...
-%
-%   Numbers following @percentofhsize are the percent of the total
-%   current hsize to be used for each column. You may use as many
-%   columns as desired.
-
-% Or use a template:
-%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-%   @item ...
-%   using the widest term desired in each column.
-
-
-% Each new table line starts with @item, each subsequent new column 
-% starts with @tab. Empty columns may be produced by supplying @tab's
-% with nothing between them for as many times as empty columns are needed,
-% ie, @tab@tab@tab will produce two empty columns.
-
-% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their
-% own lines, but it will not hurt if they are.
-
-% Sample multitable:
-
-%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-%   @item first col stuff @tab second col stuff @tab third col
-%   @item 
-%   first col stuff 
-%   @tab 
-%   second col stuff 
-%   @tab 
-%   third col 
-%   @item first col stuff @tab second col stuff 
-%   @tab Many paragraphs of text may be used in any column.
-%     
-%         They will wrap at the width determined by the template.
-%   @item@tab@tab This will be in third column.
-%   @endmultitable
-
-% Default dimensions may be reset by user.
-% @intableparskip will set vertical space between paragraphs in table.
-% @intableparindent will set paragraph indent in table.
-% @spacebetweencols will set horizontal space to be left between columns.
-% @spacebetweenlines will set vertical space to be left between lines.
-
-%%%%
-% Dimensions 
-
-\newdimen\intableparskip
-\newdimen\intableparindent
-\newdimen\spacebetweencols
-\newdimen\spacebetweenlines
-\intableparskip=0pt
-\intableparindent=6pt
-\spacebetweencols=12pt
-\spacebetweenlines=12pt
-
-%%%%
-% Macros used to set up halign preamble:
-\let\endsetuptable\relax
-\def\xendsetuptable{\endsetuptable}
-\let\percentofhsize\relax
-\def\xpercentofhsize{\percentofhsize}
-\newif\ifsetpercent
-
-\newcount\colcount
-\def\setuptable#1{\def\firstarg{#1}%
-\ifx\firstarg\xendsetuptable\let\go\relax%
-\else
-  \ifx\firstarg\xpercentofhsize\global\setpercenttrue%
-  \else
-    \ifsetpercent
-       \if#1.\else%
-       \global\advance\colcount by1 %
-       \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
-       \fi
-    \else
-       \global\advance\colcount by1
-       \setbox0=\hbox{#1}%
-       \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
-    \fi%
-  \fi%
-  \let\go\setuptable%
-\fi\go}
-%%%%
-% multitable syntax
-\def\tab{&}
-
-%%%%
-% @multitable ... @endmultitable definitions:
-
-\def\multitable#1\item{\bgroup
-\let\item\cr
-\tolerance=9500
-\hbadness=9500
-\parskip=\intableparskip
-\parindent=\intableparindent
-\overfullrule=0pt
-\global\colcount=0\relax%
-\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
- % To parse everything between @multitable and @item :
-\def\one{#1}\expandafter\setuptable\one\endsetuptable
- % Need to reset this to 0 after \setuptable.
-\global\colcount=0\relax% 
- %
- % This preamble sets up a generic column definition, which will
- % be used as many times as user calls for columns.
- % \vtop will set a single line and will also let text wrap and 
- % continue for many paragraphs if desired.
-\halign\bgroup&\global\advance\colcount by 1\relax%
-\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
- % In order to keep entries from bumping into each other
- % we will add a \leftskip of \spacebetweencols to all columns after
- % the first one.
- %  If a template has been used, we will add \spacebetweencols 
- % to the width of each template entry.
- %  If user has set preamble in terms of percent of \hsize
- % we will use that dimension as the width of the column, and
- % the \leftskip will keep entries from bumping into each other.
- % Table will start at left margin and final column will justify at
- % right margin.
-\ifnum\colcount=1
-\else
-  \ifsetpercent
-  \else
-   % If user has <not> set preamble in terms of percent of \hsize
-   % we will advance \hsize by \spacebetweencols 
-  \advance\hsize by \spacebetweencols
-  \fi
- % In either case we will make \leftskip=\spacebetweencols:
-\leftskip=\spacebetweencols
-\fi
-\noindent##}\cr%
- % \everycr will reset column counter, \colcount, at the end of
- % each line. Every column  entry will cause \colcount to advance by one. 
- % The table preamble
- % looks at the current \colcount to find the correct column width.
-\global\everycr{\noalign{\nointerlineskip\vskip\spacebetweenlines
-\filbreak%% keeps underfull box messages off when table breaks over pages.
-\global\colcount=0\relax}}}
-
-\message{indexing,}
-% Index generation facilities
-
-% Define \newwrite to be identical to plain tex's \newwrite
-% except not \outer, so it can be used within \newindex.
-{\catcode`\@=11
-\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
-
-% \newindex {foo} defines an index named foo.
-% It automatically defines \fooindex such that
-% \fooindex ...rest of line... puts an entry in the index foo.
-% It also defines \fooindfile to be the number of the output channel for
-% the file that	accumulates this index.  The file's extension is foo.
-% The name of an index should be no more than 2 characters long
-% for the sake of vms.
-
-\def\newindex #1{
-\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
-\openout \csname#1indfile\endcsname \jobname.#1	% Open the file
-\expandafter\xdef\csname#1index\endcsname{%	% Define \xxxindex
-\noexpand\doindex {#1}}
-}
-
-% @defindex foo  ==  \newindex{foo}
-
-\def\defindex{\parsearg\newindex}
-
-% Define @defcodeindex, like @defindex except put all entries in @code.
-
-\def\newcodeindex #1{
-\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
-\openout \csname#1indfile\endcsname \jobname.#1	% Open the file
-\expandafter\xdef\csname#1index\endcsname{%	% Define \xxxindex
-\noexpand\docodeindex {#1}}
-}
-
-\def\defcodeindex{\parsearg\newcodeindex}
-
-% @synindex foo bar    makes index foo feed into index bar.
-% Do this instead of @defindex foo if you don't want it as a separate index.
-\def\synindex #1 #2 {%
-\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
-\expandafter\let\csname#1indfile\endcsname=\synindexfoo
-\expandafter\xdef\csname#1index\endcsname{%	% Define \xxxindex
-\noexpand\doindex {#2}}%
-}
-
-% @syncodeindex foo bar   similar, but put all entries made for index foo
-% inside @code.
-\def\syncodeindex #1 #2 {%
-\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
-\expandafter\let\csname#1indfile\endcsname=\synindexfoo
-\expandafter\xdef\csname#1index\endcsname{%	% Define \xxxindex
-\noexpand\docodeindex {#2}}%
-}
-
-% Define \doindex, the driver for all \fooindex macros.
-% Argument #1 is generated by the calling \fooindex macro,
-%  and it is "foo", the name of the index.
-
-% \doindex just uses \parsearg; it calls \doind for the actual work.
-% This is because \doind is more useful to call from other macros.
-
-% There is also \dosubind {index}{topic}{subtopic}
-% which makes an entry in a two-level index such as the operation index.
-
-\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
-\def\singleindexer #1{\doind{\indexname}{#1}}
-
-% like the previous two, but they put @code around the argument.
-\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
-\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
-
-\def\indexdummies{%
-% Take care of the plain tex accent commands.
-\def\"{\realbackslash "}%
-\def\`{\realbackslash `}%
-\def\'{\realbackslash '}%
-\def\^{\realbackslash ^}%
-\def\~{\realbackslash ~}%
-\def\={\realbackslash =}%
-\def\b{\realbackslash b}%
-\def\c{\realbackslash c}%
-\def\d{\realbackslash d}%
-\def\u{\realbackslash u}%
-\def\v{\realbackslash v}%
-\def\H{\realbackslash H}%
-% Take care of the plain tex special European modified letters.
-\def\oe{\realbackslash oe}%
-\def\ae{\realbackslash ae}%
-\def\aa{\realbackslash aa}%
-\def\OE{\realbackslash OE}%
-\def\AE{\realbackslash AE}%
-\def\AA{\realbackslash AA}%
-\def\o{\realbackslash o}%
-\def\O{\realbackslash O}%
-\def\l{\realbackslash l}%
-\def\L{\realbackslash L}%
-\def\ss{\realbackslash ss}%
-% Take care of texinfo commands likely to appear in an index entry.
-\def\_{{\realbackslash _}}%
-\def\w{\realbackslash w }%
-\def\bf{\realbackslash bf }%
-\def\rm{\realbackslash rm }%
-\def\sl{\realbackslash sl }%
-\def\sf{\realbackslash sf}%
-\def\tt{\realbackslash tt}%
-\def\gtr{\realbackslash gtr}%
-\def\less{\realbackslash less}%
-\def\hat{\realbackslash hat}%
-\def\char{\realbackslash char}%
-\def\TeX{\realbackslash TeX}%
-\def\dots{\realbackslash dots }%
-\def\copyright{\realbackslash copyright }%
-\def\tclose##1{\realbackslash tclose {##1}}%
-\def\code##1{\realbackslash code {##1}}%
-\def\samp##1{\realbackslash samp {##1}}%
-\def\t##1{\realbackslash r {##1}}%
-\def\r##1{\realbackslash r {##1}}%
-\def\i##1{\realbackslash i {##1}}%
-\def\b##1{\realbackslash b {##1}}%
-\def\cite##1{\realbackslash cite {##1}}%
-\def\key##1{\realbackslash key {##1}}%
-\def\file##1{\realbackslash file {##1}}%
-\def\var##1{\realbackslash var {##1}}%
-\def\kbd##1{\realbackslash kbd {##1}}%
-\def\dfn##1{\realbackslash dfn {##1}}%
-\def\emph##1{\realbackslash emph {##1}}%
-}
-
-% \indexnofonts no-ops all font-change commands.
-% This is used when outputting the strings to sort the index by.
-\def\indexdummyfont#1{#1}
-\def\indexdummytex{TeX}
-\def\indexdummydots{...}
-
-\def\indexnofonts{%
-% Just ignore accents.
-\let\"=\indexdummyfont
-\let\`=\indexdummyfont
-\let\'=\indexdummyfont
-\let\^=\indexdummyfont
-\let\~=\indexdummyfont
-\let\==\indexdummyfont
-\let\b=\indexdummyfont
-\let\c=\indexdummyfont
-\let\d=\indexdummyfont
-\let\u=\indexdummyfont
-\let\v=\indexdummyfont
-\let\H=\indexdummyfont
-% Take care of the plain tex special European modified letters.
-\def\oe{oe}%
-\def\ae{ae}%
-\def\aa{aa}%
-\def\OE{OE}%
-\def\AE{AE}%
-\def\AA{AA}%
-\def\o{o}%
-\def\O{O}%
-\def\l{l}%
-\def\L{L}%
-\def\ss{ss}%
-\let\w=\indexdummyfont
-\let\t=\indexdummyfont
-\let\r=\indexdummyfont
-\let\i=\indexdummyfont
-\let\b=\indexdummyfont
-\let\emph=\indexdummyfont
-\let\strong=\indexdummyfont
-\let\cite=\indexdummyfont
-\let\sc=\indexdummyfont
-%Don't no-op \tt, since it isn't a user-level command
-% and is used in the definitions of the active chars like <, >, |...
-%\let\tt=\indexdummyfont
-\let\tclose=\indexdummyfont
-\let\code=\indexdummyfont
-\let\file=\indexdummyfont
-\let\samp=\indexdummyfont
-\let\kbd=\indexdummyfont
-\let\key=\indexdummyfont
-\let\var=\indexdummyfont
-\let\TeX=\indexdummytex
-\let\dots=\indexdummydots
-}
-
-% To define \realbackslash, we must make \ not be an escape.
-% We must first make another character (@) an escape
-% so we do not become unable to do a definition.
-
-{\catcode`\@=0 \catcode`\\=\other
-@gdef@realbackslash{\}}
-
-\let\indexbackslash=0  %overridden during \printindex.
-
-\def\doind #1#2{%
-{\count10=\lastpenalty %
-{\indexdummies % Must do this here, since \bf, etc expand at this stage
-\escapechar=`\\%
-{\let\folio=0% Expand all macros now EXCEPT \folio
-\def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
-% so it will be output as is; and it will print as backslash in the indx.
-%
-% Now process the index-string once, with all font commands turned off,
-% to get the string to sort the index by.
-{\indexnofonts
-\xdef\temp1{#2}%
-}%
-% Now produce the complete index entry.  We process the index-string again,
-% this time with font commands expanded, to get what to print in the index.
-\edef\temp{%
-\write \csname#1indfile\endcsname{%
-\realbackslash entry {\temp1}{\folio}{#2}}}%
-\temp }%
-}\penalty\count10}}
-
-\def\dosubind #1#2#3{%
-{\count10=\lastpenalty %
-{\indexdummies % Must do this here, since \bf, etc expand at this stage
-\escapechar=`\\%
-{\let\folio=0%
-\def\rawbackslashxx{\indexbackslash}%
-%
-% Now process the index-string once, with all font commands turned off,
-% to get the string to sort the index by.
-{\indexnofonts
-\xdef\temp1{#2 #3}%
-}%
-% Now produce the complete index entry.  We process the index-string again,
-% this time with font commands expanded, to get what to print in the index.
-\edef\temp{%
-\write \csname#1indfile\endcsname{%
-\realbackslash entry {\temp1}{\folio}{#2}{#3}}}%
-\temp }%
-}\penalty\count10}}
-
-% The index entry written in the file actually looks like
-%  \entry {sortstring}{page}{topic}
-% or
-%  \entry {sortstring}{page}{topic}{subtopic}
-% The texindex program reads in these files and writes files
-% containing these kinds of lines:
-%  \initial {c}
-%     before the first topic whose initial is c
-%  \entry {topic}{pagelist}
-%     for a topic that is used without subtopics
-%  \primary {topic}
-%     for the beginning of a topic that is used with subtopics
-%  \secondary {subtopic}{pagelist}
-%     for each subtopic.
-
-% Define the user-accessible indexing commands
-% @findex, @vindex, @kindex, @cindex.
-
-\def\findex {\fnindex}
-\def\kindex {\kyindex}
-\def\cindex {\cpindex}
-\def\vindex {\vrindex}
-\def\tindex {\tpindex}
-\def\pindex {\pgindex}
-
-\def\cindexsub {\begingroup\obeylines\cindexsub}
-{\obeylines %
-\gdef\cindexsub "#1" #2^^M{\endgroup %
-\dosubind{cp}{#2}{#1}}}
-
-% Define the macros used in formatting output of the sorted index material.
-
-% This is what you call to cause a particular index to get printed.
-% Write
-% @unnumbered Function Index
-% @printindex fn
-
-\def\printindex{\parsearg\doprintindex}
-
-\def\doprintindex#1{%
-  \tex
-  \dobreak \chapheadingskip {10000}
-  \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other
-  \catcode`\$=\other
-  \catcode`\~=\other
-  \indexbreaks
-  %
-  % The following don't help, since the chars were translated
-  % when the raw index was written, and their fonts were discarded
-  % due to \indexnofonts.
-  %\catcode`\"=\active
-  %\catcode`\^=\active
-  %\catcode`\_=\active
-  %\catcode`\|=\active
-  %\catcode`\<=\active
-  %\catcode`\>=\active
-  % %
-  \def\indexbackslash{\rawbackslashxx}
-  \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
-  \begindoublecolumns
-  %
-  % See if the index file exists and is nonempty.
-  \openin 1 \jobname.#1s
-  \ifeof 1
-    % \enddoublecolumns gets confused if there is no text in the index,
-    % and it loses the chapter title and the aux file entries for the
-    % index.  The easiest way to prevent this problem is to make sure
-    % there is some text.
-    (Index is nonexistent)
-    \else
-    %
-    % If the index file exists but is empty, then \openin leaves \ifeof
-    % false.  We have to make TeX try to read something from the file, so
-    % it can discover if there is anything in it.
-    \read 1 to \temp
-    \ifeof 1
-      (Index is empty)
-    \else
-      \input \jobname.#1s
-    \fi
-  \fi
-  \closein 1
-  \enddoublecolumns
-  \Etex
-}
-
-% These macros are used by the sorted index file itself.
-% Change them to control the appearance of the index.
-
-% Same as \bigskipamount except no shrink.
-% \balancecolumns gets confused if there is any shrink.
-\newskip\initialskipamount \initialskipamount 12pt plus4pt
-
-\def\initial #1{%
-{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
-\ifdim\lastskip<\initialskipamount
-\removelastskip \penalty-200 \vskip \initialskipamount\fi
-\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
-
-% This typesets a paragraph consisting of #1, dot leaders, and then #2
-% flush to the right margin.  It is used for index and table of contents
-% entries.  The paragraph is indented by \leftskip.
-%
-\def\entry #1#2{\begingroup
-  %
-  % Start a new paragraph if necessary, so our assignments below can't
-  % affect previous text.
-  \par
-  %
-  % Do not fill out the last line with white space.
-  \parfillskip = 0in
-  %
-  % No extra space above this paragraph.
-  \parskip = 0in
-  %
-  % Do not prefer a separate line ending with a hyphen to fewer lines.
-  \finalhyphendemerits = 0
-  %
-  % \hangindent is only relevant when the entry text and page number
-  % don't both fit on one line.  In that case, bob suggests starting the
-  % dots pretty far over on the line.  Unfortunately, a large
-  % indentation looks wrong when the entry text itself is broken across
-  % lines.  So we use a small indentation and put up with long leaders.
-  %
-  % \hangafter is reset to 1 (which is the value we want) at the start
-  % of each paragraph, so we need not do anything with that.
-  \hangindent=2em
-  %
-  % When the entry text needs to be broken, just fill out the first line
-  % with blank space.
-  \rightskip = 0pt plus1fil
-  %
-  % Start a ``paragraph'' for the index entry so the line breaking
-  % parameters we've set above will have an effect.
-  \noindent
-  %
-  % Insert the text of the index entry.  TeX will do line-breaking on it.
-  #1%
-  % The following is kluged to not output a line of dots in the index if
-  % there are no page numbers.  The next person who breaks this will be
-  % cursed by a Unix daemon.
-  \def\tempa{{\rm }}%
-  \def\tempb{#2}%
-  \edef\tempc{\tempa}%
-  \edef\tempd{\tempb}%
-  \ifx\tempc\tempd\ \else%
-    %
-    % If we must, put the page number on a line of its own, and fill out
-    % this line with blank space.  (The \hfil is overwhelmed with the
-    % fill leaders glue in \indexdotfill if the page number does fit.)
-    \hfil\penalty50
-    \null\nobreak\indexdotfill % Have leaders before the page number.
-    %
-    % The `\ ' here is removed by the implicit \unskip that TeX does as
-    % part of (the primitive) \par.  Without it, a spurious underfull
-    % \hbox ensues.
-    \ #2% The page number ends the paragraph.
-  \fi%
-  \par
-\endgroup}
-
-% Like \dotfill except takes at least 1 em.
-\def\indexdotfill{\cleaders
-  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
-
-\def\primary #1{\line{#1\hfil}}
-
-\newskip\secondaryindent \secondaryindent=0.5cm
-
-\def\secondary #1#2{
-{\parfillskip=0in \parskip=0in
-\hangindent =1in \hangafter=1
-\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
-}}
-
-%% Define two-column mode, which is used in indexes.
-%% Adapted from the TeXbook, page 416.
-\catcode `\@=11
-
-\newbox\partialpage
-
-\newdimen\doublecolumnhsize
-
-\def\begindoublecolumns{\begingroup
-  % Grab any single-column material above us.
-  \output = {\global\setbox\partialpage
-    =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
-  \eject
-  %
-  % Now switch to the double-column output routine.
-  \output={\doublecolumnout}%
-  %
-  % Change the page size parameters.  We could do this once outside this
-  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
-  % format, but then we repeat the same computation.  Repeating a couple
-  % of assignments once per index is clearly meaningless for the
-  % execution time, so we may as well do it once.
-  %
-  % First we halve the line length, less a little for the gutter between
-  % the columns.  We compute the gutter based on the line length, so it
-  % changes automatically with the paper format.  The magic constant
-  % below is chosen so that the gutter has the same value (well, +- <
-  % 1pt) as it did when we hard-coded it.
-  %
-  % We put the result in a separate register, \doublecolumhsize, so we
-  % can restore it in \pagesofar, after \hsize itself has (potentially)
-  % been clobbered.
-  %
-  \doublecolumnhsize = \hsize
-    \advance\doublecolumnhsize by -.04154\hsize
-    \divide\doublecolumnhsize by 2
-  \hsize = \doublecolumnhsize
-  %
-  % Double the \vsize as well.  (We don't need a separate register here,
-  % since nobody clobbers \vsize.)
-  \vsize = 2\vsize
-  \doublecolumnpagegoal
-}
-
-\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage}
-
-\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth
-  \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage
-  \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1}
-  \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3}
-  \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
-  \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
-}
-\def\doublecolumnpagegoal{%
-  \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@
-}
-\def\pagesofar{\unvbox\partialpage %
-  \hsize=\doublecolumnhsize % have to restore this since output routine
-  \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
-\def\doublecolumnout{%
-  \setbox5=\copy255
-  {\vbadness=10000 \doublecolumnsplit}
-  \ifvbox255
-    \setbox0=\vtop to\dimen@{\unvbox0}
-    \setbox2=\vtop to\dimen@{\unvbox2}
-    \onepageout\pagesofar \unvbox255 \penalty\outputpenalty
-  \else
-    \setbox0=\vbox{\unvbox5}
-    \ifvbox0
-      \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
-      \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth
-      {\vbadness=10000
-	\loop \global\setbox5=\copy0
-          \setbox1=\vsplit5 to\dimen@
-          \setbox3=\vsplit5 to\dimen@
-          \ifvbox5 \global\advance\dimen@ by1pt \repeat
-        \setbox0=\vbox to\dimen@{\unvbox1}
-        \setbox2=\vbox to\dimen@{\unvbox3}
-        \global\setbox\partialpage=\vbox{\pagesofar}
-        \doublecolumnpagegoal
-      }
-    \fi
-  \fi
-}
-
-\catcode `\@=\other
-\message{sectioning,}
-% Define chapters, sections, etc.
-
-\newcount \chapno
-\newcount \secno        \secno=0
-\newcount \subsecno     \subsecno=0
-\newcount \subsubsecno  \subsubsecno=0
-
-% This counter is funny since it counts through charcodes of letters A, B, ...
-\newcount \appendixno  \appendixno = `\@
-\def\appendixletter{\char\the\appendixno}
-
-\newwrite \contentsfile
-% This is called from \setfilename.
-\def\opencontents{\openout \contentsfile = \jobname.toc}
-
-% Each @chapter defines this as the name of the chapter.
-% page headings and footings can use it.  @section does likewise
-
-\def\thischapter{} \def\thissection{}
-\def\seccheck#1{\if \pageno<0 %
-\errmessage{@#1 not allowed after generating table of contents}\fi
-%
-}
-
-\def\chapternofonts{%
-\let\rawbackslash=\relax%
-\let\frenchspacing=\relax%
-\def\result{\realbackslash result}
-\def\equiv{\realbackslash equiv}
-\def\expansion{\realbackslash expansion}
-\def\print{\realbackslash print}
-\def\TeX{\realbackslash TeX}
-\def\dots{\realbackslash dots}
-\def\copyright{\realbackslash copyright}
-\def\tt{\realbackslash tt}
-\def\bf{\realbackslash bf}
-\def\w{\realbackslash w}
-\def\less{\realbackslash less}
-\def\gtr{\realbackslash gtr}
-\def\hat{\realbackslash hat}
-\def\char{\realbackslash char}
-\def\tclose##1{\realbackslash tclose {##1}}
-\def\code##1{\realbackslash code {##1}}
-\def\samp##1{\realbackslash samp {##1}}
-\def\r##1{\realbackslash r {##1}}
-\def\b##1{\realbackslash b {##1}}
-\def\key##1{\realbackslash key {##1}}
-\def\file##1{\realbackslash file {##1}}
-\def\kbd##1{\realbackslash kbd {##1}}
-% These are redefined because @smartitalic wouldn't work inside xdef.
-\def\i##1{\realbackslash i {##1}}
-\def\cite##1{\realbackslash cite {##1}}
-\def\var##1{\realbackslash var {##1}}
-\def\emph##1{\realbackslash emph {##1}}
-\def\dfn##1{\realbackslash dfn {##1}}
-}
-
-\newcount\absseclevel % used to calculate proper heading level
-\newcount\secbase\secbase=0 % @raise/lowersections modify this count
-
-% @raisesections: treat @section as chapter, @subsection as section, etc.
-\def\raisesections{\global\advance\secbase by -1}
-\let\up=\raisesections % original BFox name
-
-% @lowersections: treat @chapter as section, @section as subsection, etc.
-\def\lowersections{\global\advance\secbase by 1}
-\let\down=\lowersections % original BFox name
-
-% Choose a numbered-heading macro
-% #1 is heading level if unmodified by @raisesections or @lowersections
-% #2 is text for heading
-\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
-\ifcase\absseclevel
-  \chapterzzz{#2}
-\or
-  \seczzz{#2}
-\or
-  \numberedsubseczzz{#2}
-\or
-  \numberedsubsubseczzz{#2}
-\else
-  \ifnum \absseclevel<0
-    \chapterzzz{#2}
-  \else
-    \numberedsubsubseczzz{#2}
-  \fi
-\fi
-}
-
-% like \numhead, but chooses appendix heading levels
-\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
-\ifcase\absseclevel
-  \appendixzzz{#2}
-\or
-  \appendixsectionzzz{#2}
-\or
-  \appendixsubseczzz{#2}
-\or
-  \appendixsubsubseczzz{#2}
-\else
-  \ifnum \absseclevel<0
-    \appendixzzz{#2}
-  \else
-    \appendixsubsubseczzz{#2}
-  \fi
-\fi
-}
-
-% like \numhead, but chooses numberless heading levels
-\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
-\ifcase\absseclevel
-  \unnumberedzzz{#2}
-\or
-  \unnumberedseczzz{#2}
-\or
-  \unnumberedsubseczzz{#2}
-\or
-  \unnumberedsubsubseczzz{#2}
-\else
-  \ifnum \absseclevel<0
-    \unnumberedzzz{#2}
-  \else
-    \unnumberedsubsubseczzz{#2}
-  \fi
-\fi
-}
-
-
-\def\thischaptername{No Chapter Title}
-\outer\def\chapter{\parsearg\chapteryyy}
-\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
-\def\chapterzzz #1{\seccheck{chapter}%
-\secno=0 \subsecno=0 \subsubsecno=0
-\global\advance \chapno by 1 \message{Chapter \the\chapno}%
-\chapmacro {#1}{\the\chapno}%
-\gdef\thissection{#1}%
-\gdef\thischaptername{#1}%
-% We don't substitute the actual chapter name into \thischapter
-% because we don't want its macros evaluated now.
-\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
-{\chapternofonts%
-\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp  %
-\donoderef %
-\global\let\section = \numberedsec
-\global\let\subsection = \numberedsubsec
-\global\let\subsubsection = \numberedsubsubsec
-}}
-
-\outer\def\appendix{\parsearg\appendixyyy}
-\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
-\def\appendixzzz #1{\seccheck{appendix}%
-\secno=0 \subsecno=0 \subsubsecno=0
-\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
-\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
-\gdef\thissection{#1}%
-\gdef\thischaptername{#1}%
-\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
-{\chapternofonts%
-\edef\temp{{\realbackslash chapentry
-  {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp  %
-\appendixnoderef %
-\global\let\section = \appendixsec
-\global\let\subsection = \appendixsubsec
-\global\let\subsubsection = \appendixsubsubsec
-}}
-
-\outer\def\top{\parsearg\unnumberedyyy}
-\outer\def\unnumbered{\parsearg\unnumberedyyy}
-\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
-\def\unnumberedzzz #1{\seccheck{unnumbered}%
-\secno=0 \subsecno=0 \subsubsecno=0
-%
-% This used to be simply \message{#1}, but TeX fully expands the
-% argument to \message.  Therefore, if #1 contained @-commands, TeX
-% expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
-% expanded @cite (which turns out to cause errors because \cite is meant
-% to be executed, not expanded).
-%
-% Anyway, we don't want the fully-expanded definition of @cite to appear
-% as a result of the \message, we just want `@cite' itself.  We use
-% \the<toks register> to achieve this: TeX expands \the<toks> only once,
-% simply yielding the contents of the <toks register>.
-\toks0 = {#1}\message{(\the\toks0)}%
-%
-\unnumbchapmacro {#1}%
-\gdef\thischapter{#1}\gdef\thissection{#1}%
-{\chapternofonts%
-\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp  %
-\unnumbnoderef %
-\global\let\section = \unnumberedsec
-\global\let\subsection = \unnumberedsubsec
-\global\let\subsubsection = \unnumberedsubsubsec
-}}
-
-\outer\def\numberedsec{\parsearg\secyyy}
-\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
-\def\seczzz #1{\seccheck{section}%
-\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
-\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash secentry %
-{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\donoderef %
-\penalty 10000 %
-}}
-
-\outer\def\appenixsection{\parsearg\appendixsecyyy}
-\outer\def\appendixsec{\parsearg\appendixsecyyy}
-\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
-\def\appendixsectionzzz #1{\seccheck{appendixsection}%
-\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
-\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash secentry %
-{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\appendixnoderef %
-\penalty 10000 %
-}}
-
-\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
-\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
-\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
-\plainsecheading {#1}\gdef\thissection{#1}%
-{\chapternofonts%
-\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\unnumbnoderef %
-\penalty 10000 %
-}}
-
-\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
-\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
-\def\numberedsubseczzz #1{\seccheck{subsection}%
-\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
-\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash subsecentry %
-{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\donoderef %
-\penalty 10000 %
-}}
-
-\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
-\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
-\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
-\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
-\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash subsecentry %
-{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\appendixnoderef %
-\penalty 10000 %
-}}
-
-\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
-\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
-\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
-\plainsecheading {#1}\gdef\thissection{#1}%
-{\chapternofonts%
-\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\unnumbnoderef %
-\penalty 10000 %
-}}
-
-\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
-\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
-\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
-\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
-\subsubsecheading {#1}
-  {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash subsubsecentry %
-  {#1}
-  {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
-  {\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\donoderef %
-\penalty 10000 %
-}}
-
-\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
-\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
-\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
-\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
-\subsubsecheading {#1}
-  {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
-{\chapternofonts%
-\edef\temp{{\realbackslash subsubsecentry{#1}%
-  {\appendixletter}
-  {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\appendixnoderef %
-\penalty 10000 %
-}}
-
-\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
-\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
-\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
-\plainsecheading {#1}\gdef\thissection{#1}%
-{\chapternofonts%
-\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
-\escapechar=`\\%
-\write \contentsfile \temp %
-\unnumbnoderef %
-\penalty 10000 %
-}}
-
-% These are variants which are not "outer", so they can appear in @ifinfo.
-% Actually, they should now be obsolete; ordinary section commands should work.
-\def\infotop{\parsearg\unnumberedzzz}
-\def\infounnumbered{\parsearg\unnumberedzzz}
-\def\infounnumberedsec{\parsearg\unnumberedseczzz}
-\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
-\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
-
-\def\infoappendix{\parsearg\appendixzzz}
-\def\infoappendixsec{\parsearg\appendixseczzz}
-\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
-\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
-
-\def\infochapter{\parsearg\chapterzzz}
-\def\infosection{\parsearg\sectionzzz}
-\def\infosubsection{\parsearg\subsectionzzz}
-\def\infosubsubsection{\parsearg\subsubsectionzzz}
-
-% These macros control what the section commands do, according
-% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
-% Define them by default for a numbered chapter.
-\global\let\section = \numberedsec
-\global\let\subsection = \numberedsubsec
-\global\let\subsubsection = \numberedsubsubsec
-
-% Define @majorheading, @heading and @subheading
-
-% NOTE on use of \vbox for chapter headings, section headings, and
-% such:
-%	1) We use \vbox rather than the earlier \line to permit
-%	   overlong headings to fold.
-%	2) \hyphenpenalty is set to 10000 because hyphenation in a
-%	   heading is obnoxious; this forbids it.
-%       3) Likewise, headings look best if no \parindent is used, and
-%          if justification is not attempted.  Hence \raggedright.
-
-
-\def\majorheading{\parsearg\majorheadingzzz}
-\def\majorheadingzzz #1{%
-{\advance\chapheadingskip by 10pt \chapbreak }%
-{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                  \parindent=0pt\raggedright
-                  \rm #1\hfill}}\bigskip \par\penalty 200}
-
-\def\chapheading{\parsearg\chapheadingzzz}
-\def\chapheadingzzz #1{\chapbreak %
-{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                  \parindent=0pt\raggedright
-                  \rm #1\hfill}}\bigskip \par\penalty 200}
-
-\def\heading{\parsearg\secheadingi}
-
-\def\subheading{\parsearg\subsecheadingi}
-
-\def\subsubheading{\parsearg\subsubsecheadingi}
-
-% These macros generate a chapter, section, etc. heading only
-% (including whitespace, linebreaking, etc. around it),
-% given all the information in convenient, parsed form.
-
-%%% Args are the skip and penalty (usually negative)
-\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
-
-\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
-
-%%% Define plain chapter starts, and page on/off switching for it
-% Parameter controlling skip before chapter headings (if needed)
-
-\newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt
-
-\def\chapbreak{\dobreak \chapheadingskip {-4000}}
-\def\chappager{\par\vfill\supereject}
-\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
-
-\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
-
-\def\CHAPPAGoff{
-\global\let\pchapsepmacro=\chapbreak
-\global\let\pagealignmacro=\chappager}
-
-\def\CHAPPAGon{
-\global\let\pchapsepmacro=\chappager
-\global\let\pagealignmacro=\chappager
-\global\def\HEADINGSon{\HEADINGSsingle}}
-
-\def\CHAPPAGodd{
-\global\let\pchapsepmacro=\chapoddpage
-\global\let\pagealignmacro=\chapoddpage
-\global\def\HEADINGSon{\HEADINGSdouble}}
-
-\CHAPPAGon
-
-\def\CHAPFplain{
-\global\let\chapmacro=\chfplain
-\global\let\unnumbchapmacro=\unnchfplain}
-
-\def\chfplain #1#2{%
-  \pchapsepmacro
-  {%
-    \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                     \parindent=0pt\raggedright
-                     \rm #2\enspace #1}%
-  }%
-  \bigskip
-  \penalty5000
-}
-
-\def\unnchfplain #1{%
-\pchapsepmacro %
-{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                  \parindent=0pt\raggedright
-                  \rm #1\hfill}}\bigskip \par\penalty 10000 %
-}
-\CHAPFplain % The default
-
-\def\unnchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                       \parindent=0pt\raggedright
-                       \rm #1\hfill}}\bigskip \par\penalty 10000 %
-}
-
-\def\chfopen #1#2{\chapoddpage {\chapfonts
-\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
-\par\penalty 5000 %
-}
-
-\def\CHAPFopen{
-\global\let\chapmacro=\chfopen
-\global\let\unnumbchapmacro=\unnchfopen}
-
-% Parameter controlling skip before section headings.
-
-\newskip \subsecheadingskip  \subsecheadingskip = 17pt plus 8pt minus 4pt
-\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
-
-\newskip \secheadingskip  \secheadingskip = 21pt plus 8pt minus 4pt
-\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
-
-% @paragraphindent  is defined for the Info formatting commands only.
-\let\paragraphindent=\comment
-
-% Section fonts are the base font at magstep2, which produces
-% a size a bit more than 14 points in the default situation.
-
-\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}}
-\def\plainsecheading #1{\secheadingi {#1}}
-\def\secheadingi #1{{\advance \secheadingskip by \parskip %
-\secheadingbreak}%
-{\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                 \parindent=0pt\raggedright
-                 \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
-
-
-% Subsection fonts are the base font at magstep1,
-% which produces a size of 12 points.
-
-\def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}}
-\def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip %
-\subsecheadingbreak}%
-{\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                     \parindent=0pt\raggedright
-                     \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
-
-\def\subsubsecfonts{\subsecfonts} % Maybe this should change:
-				  % Perhaps make sssec fonts scaled
-				  % magstep half
-\def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}}
-\def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip %
-\subsecheadingbreak}%
-{\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
-                       \parindent=0pt\raggedright
-                       \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000}
-
-
-\message{toc printing,}
-
-% Finish up the main text and prepare to read what we've written
-% to \contentsfile.
-
-\newskip\contentsrightmargin \contentsrightmargin=1in
-\def\startcontents#1{%
-   \pagealignmacro
-   \immediate\closeout \contentsfile
-   \ifnum \pageno>0
-      \pageno = -1		% Request roman numbered pages.
-   \fi
-   % Don't need to put `Contents' or `Short Contents' in the headline.
-   % It is abundantly clear what they are.
-   \unnumbchapmacro{#1}\def\thischapter{}%
-   \begingroup   		% Set up to handle contents files properly.
-      \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
-      \raggedbottom             % Worry more about breakpoints than the bottom.
-      \advance\hsize by -\contentsrightmargin % Don't use the full line length.
-}
-
-
-% Normal (long) toc.
-\outer\def\contents{%
-   \startcontents{\putwordTableofContents}%
-      \input \jobname.toc
-   \endgroup
-   \vfill \eject
-}
-
-% And just the chapters.
-\outer\def\summarycontents{%
-   \startcontents{\putwordShortContents}%
-      %
-      \let\chapentry = \shortchapentry
-      \let\unnumbchapentry = \shortunnumberedentry
-      % We want a true roman here for the page numbers.
-      \secfonts
-      \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
-      \rm
-      \advance\baselineskip by 1pt % Open it up a little.
-      \def\secentry ##1##2##3##4{}
-      \def\unnumbsecentry ##1##2{}
-      \def\subsecentry ##1##2##3##4##5{}
-      \def\unnumbsubsecentry ##1##2{}
-      \def\subsubsecentry ##1##2##3##4##5##6{}
-      \def\unnumbsubsubsecentry ##1##2{}
-      \input \jobname.toc
-   \endgroup
-   \vfill \eject
-}
-\let\shortcontents = \summarycontents
-
-% These macros generate individual entries in the table of contents.
-% The first argument is the chapter or section name.
-% The last argument is the page number.
-% The arguments in between are the chapter number, section number, ...
-
-% Chapter-level things, for both the long and short contents.
-\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
-
-% See comments in \dochapentry re vbox and related settings
-\def\shortchapentry#1#2#3{%
-  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
-}
-
-% Typeset the label for a chapter or appendix for the short contents.
-% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
-% We could simplify the code here by writing out an \appendixentry
-% command in the toc file for appendices, instead of using \chapentry
-% for both, but it doesn't seem worth it.
-\setbox0 = \hbox{\shortcontrm \putwordAppendix }
-\newdimen\shortappendixwidth \shortappendixwidth = \wd0
-
-\def\shortchaplabel#1{%
-  % We typeset #1 in a box of constant width, regardless of the text of
-  % #1, so the chapter titles will come out aligned.
-  \setbox0 = \hbox{#1}%
-  \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
-  %
-  % This space should be plenty, since a single number is .5em, and the
-  % widest letter (M) is 1em, at least in the Computer Modern fonts.
-  % (This space doesn't include the extra space that gets added after
-  % the label; that gets put in in \shortchapentry above.)
-  \advance\dimen0 by 1.1em
-  \hbox to \dimen0{#1\hfil}%
-}
-
-\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
-\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
-
-% Sections.
-\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
-\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
-
-% Subsections.
-\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
-\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
-
-% And subsubsections.
-\def\subsubsecentry#1#2#3#4#5#6{%
-  \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
-\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
-
-
-% This parameter controls the indentation of the various levels.
-\newdimen\tocindent \tocindent = 3pc
-
-% Now for the actual typesetting. In all these, #1 is the text and #2 is the
-% page number.
-%
-% If the toc has to be broken over pages, we would want to be at chapters
-% if at all possible; hence the \penalty.
-\def\dochapentry#1#2{%
-   \penalty-300 \vskip\baselineskip
-   \begingroup
-     \chapentryfonts
-     \tocentry{#1}{\dopageno{#2}}%
-   \endgroup
-   \nobreak\vskip .25\baselineskip
-}
-
-\def\dosecentry#1#2{\begingroup
-  \secentryfonts \leftskip=\tocindent
-  \tocentry{#1}{\dopageno{#2}}%
-\endgroup}
-
-\def\dosubsecentry#1#2{\begingroup
-  \subsecentryfonts \leftskip=2\tocindent
-  \tocentry{#1}{\dopageno{#2}}%
-\endgroup}
-
-\def\dosubsubsecentry#1#2{\begingroup
-  \subsubsecentryfonts \leftskip=3\tocindent
-  \tocentry{#1}{\dopageno{#2}}%
-\endgroup}
-
-% Final typesetting of a toc entry; we use the same \entry macro as for
-% the index entries, but we want to suppress hyphenation here.  (We
-% can't do that in the \entry macro, since index entries might consist
-% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
-%
-\def\tocentry#1#2{\begingroup
-  \hyphenpenalty = 10000
-  \entry{#1}{#2}%
-\endgroup}
-
-% Space between chapter (or whatever) number and the title.
-\def\labelspace{\hskip1em \relax}
-
-\def\dopageno#1{{\rm #1}}
-\def\doshortpageno#1{{\rm #1}}
-
-\def\chapentryfonts{\secfonts \rm}
-\def\secentryfonts{\textfonts}
-\let\subsecentryfonts = \textfonts
-\let\subsubsecentryfonts = \textfonts
-
-
-\message{environments,}
-
-% Since these characters are used in examples, it should be an even number of
-% \tt widths. Each \tt character is 1en, so two makes it 1em.
-% Furthermore, these definitions must come after we define our fonts.
-\newbox\dblarrowbox    \newbox\longdblarrowbox
-\newbox\pushcharbox    \newbox\bullbox
-\newbox\equivbox       \newbox\errorbox
-
-\let\ptexequiv = \equiv
-
-%{\tentt
-%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
-%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
-%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
-%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
-% Adapted from the manmac format (p.420 of TeXbook)
-%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
-%                                      depth .1ex\hfil}
-%}
-
-\def\point{$\star$}
-
-\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
-\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
-\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
-
-\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
-
-% Adapted from the TeXbook's \boxit.
-{\tentt \global\dimen0 = 3em}% Width of the box.
-\dimen2 = .55pt % Thickness of rules
-% The text. (`r' is open on the right, `e' somewhat less so on the left.)
-\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
-
-\global\setbox\errorbox=\hbox to \dimen0{\hfil
-   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
-   \advance\hsize by -2\dimen2 % Rules.
-   \vbox{
-      \hrule height\dimen2
-      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
-         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
-         \kern3pt\vrule width\dimen2}% Space to right.
-      \hrule height\dimen2}
-    \hfil}
-
-% The @error{} command.
-\def\error{\leavevmode\lower.7ex\copy\errorbox}
-
-% @tex ... @end tex    escapes into raw Tex temporarily.
-% One exception: @ is still an escape character, so that @end tex works.
-% But \@ or @@ will get a plain tex @ character.
-
-\def\tex{\begingroup
-\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
-\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
-\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
-\catcode `\%=14
-\catcode 43=12
-\catcode`\"=12
-\catcode`\==12
-\catcode`\|=12
-\catcode`\<=12
-\catcode`\>=12
-\escapechar=`\\
-%
-\let\~=\ptextilde
-\let\{=\ptexlbrace
-\let\}=\ptexrbrace
-\let\.=\ptexdot
-\let\*=\ptexstar
-\let\dots=\ptexdots
-\def\@{@}%
-\let\bullet=\ptexbullet
-\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl
-\let\L=\ptexL
-%
-\let\Etex=\endgroup}
-
-% Define @lisp ... @endlisp.
-% @lisp does a \begingroup so it can rebind things,
-% including the definition of @endlisp (which normally is erroneous).
-
-% Amount to narrow the margins by for @lisp.
-\newskip\lispnarrowing \lispnarrowing=0.4in
-
-% This is the definition that ^^M gets inside @lisp, @example, and other
-% such environments.  \null is better than a space, since it doesn't
-% have any width.
-\def\lisppar{\null\endgraf}
-
-% Make each space character in the input produce a normal interword
-% space in the output.  Don't allow a line break at this space, as this
-% is used only in environments like @example, where each line of input
-% should produce a line of output anyway.
-%
-{\obeyspaces %
-\gdef\sepspaces{\obeyspaces\let =\tie}}
-
-% Define \obeyedspace to be our active space, whatever it is.  This is
-% for use in \parsearg.
-{\sepspaces%
-\global\let\obeyedspace= }
-
-% This space is always present above and below environments.
-\newskip\envskipamount \envskipamount = 0pt
-
-% Make spacing and below environment symmetrical.  We use \parskip here
-% to help in doing that, since in @example-like environments \parskip
-% is reset to zero; thus the \afterenvbreak inserts no space -- but the
-% start of the next paragraph will insert \parskip
-%
-\def\aboveenvbreak{{\advance\envskipamount by \parskip
-\endgraf \ifdim\lastskip<\envskipamount
-\removelastskip \penalty-50 \vskip\envskipamount \fi}}
-
-\let\afterenvbreak = \aboveenvbreak
-
-% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
-\let\nonarrowing=\relax
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \cartouche: draw rectangle w/rounded corners around argument
-\font\circle=lcircle10
-\newdimen\circthick
-\newdimen\cartouter\newdimen\cartinner
-\newskip\normbskip\newskip\normpskip\newskip\normlskip
-\circthick=\fontdimen8\circle
-%
-\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
-\def\ctr{{\hskip 6pt\circle\char'010}}
-\def\cbl{{\circle\char'012\hskip -6pt}}
-\def\cbr{{\hskip 6pt\circle\char'011}}
-\def\carttop{\hbox to \cartouter{\hskip\lskip
-	\ctl\leaders\hrule height\circthick\hfil\ctr
-	\hskip\rskip}}
-\def\cartbot{\hbox to \cartouter{\hskip\lskip
-	\cbl\leaders\hrule height\circthick\hfil\cbr
-	\hskip\rskip}}
-%
-\newskip\lskip\newskip\rskip
-
-\long\def\cartouche{%
-\begingroup
-	\lskip=\leftskip \rskip=\rightskip
-	\leftskip=0pt\rightskip=0pt %we want these *outside*.
-	\cartinner=\hsize \advance\cartinner by-\lskip
-		 	  \advance\cartinner by-\rskip
-	\cartouter=\hsize
-	\advance\cartouter by 18pt % allow for 3pt kerns on either
-%				     side, and for 6pt waste from
-%				     each corner char
-	\normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
-	% Flag to tell @lisp, etc., not to narrow margin.
-	\let\nonarrowing=\comment
-	\vbox\bgroup
-		\baselineskip=0pt\parskip=0pt\lineskip=0pt
-		\carttop
-		\hbox\bgroup
-			\hskip\lskip
-			\vrule\kern3pt
-			\vbox\bgroup
-				\hsize=\cartinner
-				\kern3pt
-				\begingroup
-					\baselineskip=\normbskip
-					\lineskip=\normlskip
-					\parskip=\normpskip
-					\vskip -\parskip
-\def\Ecartouche{%
-				\endgroup
-				\kern3pt
-			\egroup
-			\kern3pt\vrule
-			\hskip\rskip
-		\egroup
-		\cartbot
-	\egroup
-\endgroup
-}}
-
-
-% This macro is called at the beginning of all the @example variants,
-% inside a group.
-\def\nonfillstart{%
-  \aboveenvbreak
-  \inENV % This group ends at the end of the body
-  \hfuzz = 12pt % Don't be fussy
-  \sepspaces % Make spaces be word-separators rather than space tokens.
-  \singlespace
-  \let\par = \lisppar % don't ignore blank lines
-  \obeylines % each line of input is a line of output
-  \parskip = 0pt
-  \parindent = 0pt
-  \emergencystretch = 0pt % don't try to avoid overfull boxes
-  % @cartouche defines \nonarrowing to inhibit narrowing
-  % at next level down.
-  \ifx\nonarrowing\relax
-    \advance \leftskip by \lispnarrowing
-    \exdentamount=\lispnarrowing
-    \let\exdent=\nofillexdent
-    \let\nonarrowing=\relax
-  \fi
-}
-
-% To ending an @example-like environment, we first end the paragraph
-% (via \afterenvbreak's vertical glue), and then the group.  That way we
-% keep the zero \parskip that the environments set -- \parskip glue
-% will be inserted at the beginning of the next paragraph in the
-% document, after the environment.
-%
-\def\nonfillfinish{\afterenvbreak\endgroup}%
-
-% This macro is
-\def\lisp{\begingroup
-  \nonfillstart
-  \let\Elisp = \nonfillfinish
-  \tt
-  \rawbackslash % have \ input char produce \ char from current font
-  \gobble
-}
-
-% Define the \E... control sequence only if we are inside the
-% environment, so the error checking in \end will work.
-%
-% We must call \lisp last in the definition, since it reads the
-% return following the @example (or whatever) command.
-%
-\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
-\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
-\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
-
-% @smallexample and @smalllisp.  This is not used unless the @smallbook
-% command is given.  Originally contributed by Pavel@xerox.
-%
-\def\smalllispx{\begingroup
-  \nonfillstart
-  \let\Esmalllisp = \nonfillfinish
-  \let\Esmallexample = \nonfillfinish
-  %
-  % Smaller interline space and fonts for small examples.
-  \setleading{10pt}%
-  \indexfonts \tt
-  \rawbackslash % make \ output the \ character from the current font (tt)
-  \gobble
-}
-
-% This is @display; same as @lisp except use roman font.
-%
-\def\display{\begingroup
-  \nonfillstart
-  \let\Edisplay = \nonfillfinish
-  \gobble
-}
-
-% This is @format; same as @display except don't narrow margins.
-%
-\def\format{\begingroup
-  \let\nonarrowing = t
-  \nonfillstart
-  \let\Eformat = \nonfillfinish
-  \gobble
-}
-
-% @flushleft (same as @format) and @flushright.
-%
-\def\flushleft{\begingroup
-  \let\nonarrowing = t
-  \nonfillstart
-  \let\Eflushleft = \nonfillfinish
-  \gobble
-}
-\def\flushright{\begingroup
-  \let\nonarrowing = t
-  \nonfillstart
-  \let\Eflushright = \nonfillfinish
-  \advance\leftskip by 0pt plus 1fill
-  \gobble}
-
-% @quotation does normal linebreaking (hence we can't use \nonfillstart)
-% and narrows the margins.
-%
-\def\quotation{%
-  \begingroup\inENV %This group ends at the end of the @quotation body
-  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
-  \singlespace
-  \parindent=0pt
-  % We have retained a nonzero parskip for the environment, since we're
-  % doing normal filling. So to avoid extra space below the environment...
-  \def\Equotation{\parskip = 0pt \nonfillfinish}%
-  %
-  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
-  \ifx\nonarrowing\relax
-    \advance\leftskip by \lispnarrowing
-    \advance\rightskip by \lispnarrowing
-    \exdentamount = \lispnarrowing
-    \let\nonarrowing = \relax
-  \fi
-}
-
-\message{defuns,}
-% Define formatter for defuns
-% First, allow user to change definition object font (\df) internally
-\def\setdeffont #1 {\csname DEF#1\endcsname}
-
-\newskip\defbodyindent \defbodyindent=.4in
-\newskip\defargsindent \defargsindent=50pt
-\newskip\deftypemargin \deftypemargin=12pt
-\newskip\deflastargmargin \deflastargmargin=18pt
-
-\newcount\parencount
-% define \functionparens, which makes ( and ) and & do special things.
-% \functionparens affects the group it is contained in.
-\def\activeparens{%
-\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
-\catcode`\[=\active \catcode`\]=\active}
-
-% Make control sequences which act like normal parenthesis chars.
-\let\lparen = ( \let\rparen = )
-
-{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
-
-% Be sure that we always have a definition for `(', etc.  For example,
-% if the fn name has parens in it, \boldbrax will not be in effect yet,
-% so TeX would otherwise complain about undefined control sequence.
-\global\let(=\lparen \global\let)=\rparen
-\global\let[=\lbrack \global\let]=\rbrack
-
-\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
-\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
-
-% Definitions of (, ) and & used in args for functions.
-% This is the definition of ( outside of all parentheses.
-\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested %
-\global\advance\parencount by 1 }
-%
-% This is the definition of ( when already inside a level of parens.
-\gdef\opnested{\char`\(\global\advance\parencount by 1 }
-%
-\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
-% also in that case restore the outer-level definition of (.
-\ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
-\global\advance \parencount by -1 }
-% If we encounter &foo, then turn on ()-hacking afterwards
-\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ }
-%
-\gdef\normalparens{\boldbrax\let&=\ampnr}
-} % End of definition inside \activeparens
-%% These parens (in \boldbrax) actually are a little bolder than the
-%% contained text.  This is especially needed for [ and ]
-\def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&}
-\def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}}
-
-% First, defname, which formats the header line itself.
-% #1 should be the function name.
-% #2 should be the type of definition, such as "Function".
-
-\def\defname #1#2{%
-% Get the values of \leftskip and \rightskip as they were
-% outside the @def...
-\dimen2=\leftskip
-\advance\dimen2 by -\defbodyindent
-\dimen3=\rightskip
-\advance\dimen3 by -\defbodyindent
-\noindent        %
-\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
-\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
-\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
-\parshape 2 0in \dimen0 \defargsindent \dimen1     %
-% Now output arg 2 ("Function" or some such)
-% ending at \deftypemargin from the right margin,
-% but stuck inside a box of width 0 so it does not interfere with linebreaking
-{% Adjust \hsize to exclude the ambient margins,
-% so that \rightline will obey them.
-\advance \hsize by -\dimen2 \advance \hsize by -\dimen3
-\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
-% Make all lines underfull and no complaints:
-\tolerance=10000 \hbadness=10000
-\advance\leftskip by -\defbodyindent
-\exdentamount=\defbodyindent
-{\df #1}\enskip        % Generate function name
-}
-
-% Actually process the body of a definition
-% #1 should be the terminating control sequence, such as \Edefun.
-% #2 should be the "another name" control sequence, such as \defunx.
-% #3 should be the control sequence that actually processes the header,
-%    such as \defunheader.
-
-\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
-\medbreak %
-% Define the end token that this defining construct specifies
-% so that it will exit this group.
-\def#1{\endgraf\endgroup\medbreak}%
-\def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
-\parindent=0in
-\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-\exdentamount=\defbodyindent
-\begingroup %
-\catcode 61=\active % 61 is `='
-\obeylines\activeparens\spacesplit#3}
-
-\def\defmethparsebody #1#2#3#4 {\begingroup\inENV %
-\medbreak %
-% Define the end token that this defining construct specifies
-% so that it will exit this group.
-\def#1{\endgraf\endgroup\medbreak}%
-\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
-\parindent=0in
-\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-\exdentamount=\defbodyindent
-\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
-
-\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
-\medbreak %
-% Define the end token that this defining construct specifies
-% so that it will exit this group.
-\def#1{\endgraf\endgroup\medbreak}%
-\def#2##1 ##2 {\def#4{##1}%
-\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
-\parindent=0in
-\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-\exdentamount=\defbodyindent
-\begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
-
-% These parsing functions are similar to the preceding ones
-% except that they do not make parens into active characters.
-% These are used for "variables" since they have no arguments.
-
-\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
-\medbreak %
-% Define the end token that this defining construct specifies
-% so that it will exit this group.
-\def#1{\endgraf\endgroup\medbreak}%
-\def#2{\begingroup\obeylines\spacesplit#3}%
-\parindent=0in
-\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-\exdentamount=\defbodyindent
-\begingroup %
-\catcode 61=\active %
-\obeylines\spacesplit#3}
-
-% This is used for \def{tp,vr}parsebody.  It could probably be used for
-% some of the others, too, with some judicious conditionals.
-% 
-\def\parsebodycommon#1#2#3{%
-  \begingroup\inENV %
-  \medbreak %
-  % Define the end token that this defining construct specifies
-  % so that it will exit this group.
-  \def#1{\endgraf\endgroup\medbreak}%
-  \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
-  \parindent=0in
-  \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-  \exdentamount=\defbodyindent
-  \begingroup\obeylines
-}
-
-\def\defvrparsebody#1#2#3#4 {%
-  \parsebodycommon{#1}{#2}{#3}%
-  \spacesplit{#3{#4}}%
-}
-
-% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
-% type is just `struct', because we lose the braces in `{struct
-% termios}' when \spacesplit reads its undelimited argument.  Sigh.
-% \let\deftpparsebody=\defvrparsebody
-%
-% So, to get around this, we put \empty in with the type name.  That
-% way, TeX won't find exactly `{...}' as an undelimited argument, and
-% won't strip off the braces.
-%
-\def\deftpparsebody #1#2#3#4 {%
-  \parsebodycommon{#1}{#2}{#3}%
-  \spacesplit{\parsetpheaderline{#3{#4}}}\empty
-}
-
-% Fine, but then we have to eventually remove the \empty *and* the
-% braces (if any).  That's what this does, putting the result in \tptemp.
-% 
-\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}%
-
-% After \spacesplit has done its work, this is called -- #1 is the final
-% thing to call, #2 the type name (which starts with \empty), and #3
-% (which might be empty) the arguments.
-% 
-\def\parsetpheaderline#1#2#3{%
-  \removeemptybraces#2\relax
-  #1{\tptemp}{#3}%
-}%
-
-\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
-\medbreak %
-% Define the end token that this defining construct specifies
-% so that it will exit this group.
-\def#1{\endgraf\endgroup\medbreak}%
-\def#2##1 ##2 {\def#4{##1}%
-\begingroup\obeylines\spacesplit{#3{##2}}}%
-\parindent=0in
-\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
-\exdentamount=\defbodyindent
-\begingroup\obeylines\spacesplit{#3{#5}}}
-
-% Split up #2 at the first space token.
-% call #1 with two arguments:
-%  the first is all of #2 before the space token,
-%  the second is all of #2 after that space token.
-% If #2 contains no space token, all of it is passed as the first arg
-% and the second is passed as empty.
-
-{\obeylines
-\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
-\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
-\ifx\relax #3%
-#1{#2}{}\else #1{#2}{#3#4}\fi}}
-
-% So much for the things common to all kinds of definitions.
-
-% Define @defun.
-
-% First, define the processing that is wanted for arguments of \defun
-% Use this to expand the args and terminate the paragraph they make up
-
-\def\defunargs #1{\functionparens \sl
-% Expand, preventing hyphenation at `-' chars.
-% Note that groups don't affect changes in \hyphenchar.
-\hyphenchar\tensl=0
-#1%
-\hyphenchar\tensl=45
-\ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
-\interlinepenalty=10000
-\advance\rightskip by 0pt plus 1fil
-\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
-}
-
-\def\deftypefunargs #1{%
-% Expand, preventing hyphenation at `-' chars.
-% Note that groups don't affect changes in \hyphenchar.
-\functionparens
-\tclose{#1}% avoid \code because of side effects on active chars
-\interlinepenalty=10000
-\advance\rightskip by 0pt plus 1fil
-\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
-}
-
-% Do complete processing of one @defun or @defunx line already parsed.
-
-% @deffn Command forward-char nchars
-
-\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
-
-\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
-\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% @defun == @deffn Function
-
-\def\defun{\defparsebody\Edefun\defunx\defunheader}
-
-\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{Function}%
-\defunargs {#2}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% @deftypefun int foobar (int @var{foo}, float @var{bar})
-
-\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
-
-% #1 is the data type.  #2 is the name and args.
-\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
-% #1 is the data type, #2 the name, #3 the args.
-\def\deftypefunheaderx #1#2 #3\relax{%
-\doind {fn}{\code{#2}}% Make entry in function index
-\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
-\deftypefunargs {#3}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
-
-\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
-
-% \defheaderxcond#1\relax$$$
-% puts #1 in @code, followed by a space, but does nothing if #1 is null.
-\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
-
-% #1 is the classification.  #2 is the data type.  #3 is the name and args.
-\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
-% #1 is the classification, #2 the data type, #3 the name, #4 the args.
-\def\deftypefnheaderx #1#2#3 #4\relax{%
-\doind {fn}{\code{#3}}% Make entry in function index
-\begingroup
-\normalparens % notably, turn off `&' magic, which prevents
-%               at least some C++ text from working
-\defname {\defheaderxcond#2\relax$$$#3}{#1}%
-\deftypefunargs {#4}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% @defmac == @deffn Macro
-
-\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
-
-\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{Macro}%
-\defunargs {#2}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% @defspec == @deffn Special Form
-
-\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
-
-\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{Special Form}%
-\defunargs {#2}\endgroup %
-\catcode 61=\other % Turn off change made in \defparsebody
-}
-
-% This definition is run if you use @defunx
-% anywhere other than immediately after a @defun or @defunx.
-
-\def\deffnx #1 {\errmessage{@deffnx in invalid context}}
-\def\defunx #1 {\errmessage{@defunx in invalid context}}
-\def\defmacx #1 {\errmessage{@defmacx in invalid context}}
-\def\defspecx #1 {\errmessage{@defspecx in invalid context}}
-\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
-\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}}
-
-% @defmethod, and so on
-
-% @defop {Funny Method} foo-class frobnicate argument
-
-\def\defop #1 {\def\defoptype{#1}%
-\defopparsebody\Edefop\defopx\defopheader\defoptype}
-
-\def\defopheader #1#2#3{%
-\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
-\begingroup\defname {#2}{\defoptype{} on #1}%
-\defunargs {#3}\endgroup %
-}
-
-% @defmethod == @defop Method
-
-\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
-
-\def\defmethodheader #1#2#3{%
-\dosubind {fn}{\code{#2}}{on #1}% entry in function index
-\begingroup\defname {#2}{Method on #1}%
-\defunargs {#3}\endgroup %
-}
-
-% @defcv {Class Option} foo-class foo-flag
-
-\def\defcv #1 {\def\defcvtype{#1}%
-\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
-
-\def\defcvarheader #1#2#3{%
-\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
-\begingroup\defname {#2}{\defcvtype{} of #1}%
-\defvarargs {#3}\endgroup %
-}
-
-% @defivar == @defcv {Instance Variable}
-
-\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
-
-\def\defivarheader #1#2#3{%
-\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
-\begingroup\defname {#2}{Instance Variable of #1}%
-\defvarargs {#3}\endgroup %
-}
-
-% These definitions are run if you use @defmethodx, etc.,
-% anywhere other than immediately after a @defmethod, etc.
-
-\def\defopx #1 {\errmessage{@defopx in invalid context}}
-\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
-\def\defcvx #1 {\errmessage{@defcvx in invalid context}}
-\def\defivarx #1 {\errmessage{@defivarx in invalid context}}
-
-% Now @defvar
-
-% First, define the processing that is wanted for arguments of @defvar.
-% This is actually simple: just print them in roman.
-% This must expand the args and terminate the paragraph they make up
-\def\defvarargs #1{\normalparens #1%
-\interlinepenalty=10000
-\endgraf\penalty 10000\vskip -\parskip\penalty 10000}
-
-% @defvr Counter foo-count
-
-\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
-
-\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
-\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
-
-% @defvar == @defvr Variable
-
-\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
-
-\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
-\begingroup\defname {#1}{Variable}%
-\defvarargs {#2}\endgroup %
-}
-
-% @defopt == @defvr {User Option}
-
-\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
-
-\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
-\begingroup\defname {#1}{User Option}%
-\defvarargs {#2}\endgroup %
-}
-
-% @deftypevar int foobar
-
-\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
-
-% #1 is the data type.  #2 is the name.
-\def\deftypevarheader #1#2{%
-\doind {vr}{\code{#2}}% Make entry in variables index
-\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
-\interlinepenalty=10000
-\endgraf\penalty 10000\vskip -\parskip\penalty 10000
-\endgroup}
-
-% @deftypevr {Global Flag} int enable
-
-\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
-
-\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
-\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
-\interlinepenalty=10000
-\endgraf\penalty 10000\vskip -\parskip\penalty 10000
-\endgroup}
-
-% This definition is run if you use @defvarx
-% anywhere other than immediately after a @defvar or @defvarx.
-
-\def\defvrx #1 {\errmessage{@defvrx in invalid context}}
-\def\defvarx #1 {\errmessage{@defvarx in invalid context}}
-\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
-\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
-\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
-
-% Now define @deftp
-% Args are printed in bold, a slight difference from @defvar.
-
-\def\deftpargs #1{\bf \defvarargs{#1}}
-
-% @deftp Class window height width ...
-
-\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
-
-\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
-\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
-
-% This definition is run if you use @deftpx, etc
-% anywhere other than immediately after a @deftp, etc.
-
-\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
-
-\message{cross reference,}
-% Define cross-reference macros
-\newwrite \auxfile
-
-\newif\ifhavexrefs  % True if xref values are known.
-\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
-
-% \setref{foo} defines a cross-reference point named foo.
-
-\def\setref#1{%
-\dosetq{#1-title}{Ytitle}%
-\dosetq{#1-pg}{Ypagenumber}%
-\dosetq{#1-snt}{Ysectionnumberandtype}}
-
-\def\unnumbsetref#1{%
-\dosetq{#1-title}{Ytitle}%
-\dosetq{#1-pg}{Ypagenumber}%
-\dosetq{#1-snt}{Ynothing}}
-
-\def\appendixsetref#1{%
-\dosetq{#1-title}{Ytitle}%
-\dosetq{#1-pg}{Ypagenumber}%
-\dosetq{#1-snt}{Yappendixletterandtype}}
-
-% \xref, \pxref, and \ref generate cross-references to specified points.
-% For \xrefX, #1 is the node name, #2 the name of the Info
-% cross-reference, #3 the printed node name, #4 the name of the Info
-% file, #5 the name of the printed manual.  All but the node name can be
-% omitted.
-%
-\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
-\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
-\def\ref#1{\xrefX[#1,,,,,,,]}
-\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
-  \def\printedmanual{\ignorespaces #5}%
-  \def\printednodename{\ignorespaces #3}%
-  \setbox1=\hbox{\printedmanual}%
-  \setbox0=\hbox{\printednodename}%
-  \ifdim \wd0 = 0pt
-    % No printed node name was explicitly given.
-    \ifx\SETxref-automatic-section-title\relax %
-      % Use the actual chapter/section title appear inside
-      % the square brackets.  Use the real section title if we have it.
-      \ifdim \wd1>0pt%
-        % It is in another manual, so we don't have it.
-        \def\printednodename{\ignorespaces #1}%
-      \else
-        \ifhavexrefs
-          % We know the real title if we have the xref values.
-          \def\printednodename{\refx{#1-title}}%
-        \else
-          % Otherwise just copy the Info node name.
-          \def\printednodename{\ignorespaces #1}%
-        \fi%
-      \fi
-      \def\printednodename{#1-title}%
-    \else
-      % Use the node name inside the square brackets.
-      \def\printednodename{\ignorespaces #1}%
-    \fi
-  \fi
-  %
-  % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
-  % insert empty discretionaries after hyphens, which means that it will
-  % not find a line break at a hyphen in a node names.  Since some manuals
-  % are best written with fairly long node names, containing hyphens, this
-  % is a loss.  Therefore, we give the text of the node name again, so it
-  % is as if TeX is seeing it for the first time.
-  \ifdim \wd1 > 0pt
-    \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
-  \else
-    % _ (for example) has to be the character _ for the purposes of the
-    % control sequence corresponding to the node, but it has to expand
-    % into the usual \leavevmode...\vrule stuff for purposes of
-    % printing. So we \turnoffactive for the \refx-snt, back on for the
-    % printing, back off for the \refx-pg.
-    {\turnoffactive \refx{#1-snt}{}}%
-    \space [\printednodename],\space
-    \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
-  \fi
-\endgroup}
-
-% \dosetq is the interface for calls from other macros
-
-% Use \turnoffactive so that punctuation chars such as underscore
-% work in node names.
-\def\dosetq #1#2{{\let\folio=0 \turnoffactive%
-\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
-\next}}
-
-% \internalsetq {foo}{page} expands into
-% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
-% When the aux file is read, ' is the escape character
-
-\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
-
-% Things to be expanded by \internalsetq
-
-\def\Ypagenumber{\folio}
-
-\def\Ytitle{\thissection}
-
-\def\Ynothing{}
-
-\def\Ysectionnumberandtype{%
-\ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
-\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
-\else \ifnum \subsubsecno=0 %
-\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
-\else %
-\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
-\fi \fi \fi }
-
-\def\Yappendixletterandtype{%
-\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
-\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
-\else \ifnum \subsubsecno=0 %
-\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
-\else %
-\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
-\fi \fi \fi }
-
-\gdef\xreftie{'tie}
-
-% Use TeX 3.0's \inputlineno to get the line number, for better error
-% messages, but if we're using an old version of TeX, don't do anything.
-%
-\ifx\inputlineno\thisisundefined
-  \let\linenumber = \empty % Non-3.0.
-\else
-  \def\linenumber{\the\inputlineno:\space}
-\fi
-
-% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
-% If its value is nonempty, SUFFIX is output afterward.
-
-\def\refx#1#2{%
-  \expandafter\ifx\csname X#1\endcsname\relax
-    % If not defined, say something at least.
-    $\langle$un\-de\-fined$\rangle$%
-    \ifhavexrefs
-      \message{\linenumber Undefined cross reference `#1'.}%
-    \else
-      \ifwarnedxrefs\else
-        \global\warnedxrefstrue
-        \message{Cross reference values unknown; you must run TeX again.}%
-      \fi
-    \fi
-  \else
-    % It's defined, so just use it.
-    \csname X#1\endcsname
-  \fi
-  #2% Output the suffix in any case.
-}
-
-% Read the last existing aux file, if any.  No error if none exists.
-
-% This is the macro invoked by entries in the aux file.
-\def\xrdef #1#2{
-{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
-
-\def\readauxfile{%
-\begingroup
-\catcode `\^^@=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\^^C=\other
-\catcode `\^^D=\other
-\catcode `\^^E=\other
-\catcode `\^^F=\other
-\catcode `\^^G=\other
-\catcode `\^^H=\other
-\catcode `\=\other
-\catcode `\^^L=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode 26=\other
-\catcode `\^^[=\other
-\catcode `\^^\=\other
-\catcode `\^^]=\other
-\catcode `\^^^=\other
-\catcode `\^^_=\other
-\catcode `\@=\other
-\catcode `\^=\other
-\catcode `\~=\other
-\catcode `\[=\other
-\catcode `\]=\other
-\catcode`\"=\other
-\catcode`\_=\other
-\catcode`\|=\other
-\catcode`\<=\other
-\catcode`\>=\other
-\catcode `\$=\other
-\catcode `\#=\other
-\catcode `\&=\other
-% `\+ does not work, so use 43.
-\catcode 43=\other
-% Make the characters 128-255 be printing characters
-{%
-  \count 1=128
-  \def\loop{%
-    \catcode\count 1=\other
-    \advance\count 1 by 1
-    \ifnum \count 1<256 \loop \fi
-  }%
-}%
-% the aux file uses ' as the escape.
-% Turn off \ as an escape so we do not lose on
-% entries which were dumped with control sequences in their names.
-% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
-% Reference to such entries still does not work the way one would wish,
-% but at least they do not bomb out when the aux file is read in.
-\catcode `\{=1 \catcode `\}=2
-\catcode `\%=\other
-\catcode `\'=0
-\catcode `\\=\other
-\openin 1 \jobname.aux
-\ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue
-\global\warnedobstrue
-\fi
-% Open the new aux file.  Tex will close it automatically at exit.
-\openout \auxfile=\jobname.aux
-\endgroup}
-
-
-% Footnotes.
-
-\newcount \footnoteno
-
-% The trailing space in the following definition for supereject is
-% vital for proper filling; pages come out unaligned when you do a
-% pagealignmacro call if that space before the closing brace is
-% removed.
-\def\supereject{\par\penalty -20000\footnoteno =0 }
-
-% @footnotestyle is meaningful for info output only..
-\let\footnotestyle=\comment
-
-\let\ptexfootnote=\footnote
-
-{\catcode `\@=11
-%
-% Auto-number footnotes.  Otherwise like plain.
-\gdef\footnote{%
-  \global\advance\footnoteno by \@ne
-  \edef\thisfootno{$^{\the\footnoteno}$}%
-  %
-  % In case the footnote comes at the end of a sentence, preserve the
-  % extra spacing after we do the footnote number.
-  \let\@sf\empty
-  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
-  %
-  % Remove inadvertent blank space before typesetting the footnote number.
-  \unskip
-  \thisfootno\@sf
-  \footnotezzz
-}%
-
-% Don't bother with the trickery in plain.tex to not require the
-% footnote text as a parameter.  Our footnotes don't need to be so general.
-%
-\long\gdef\footnotezzz#1{\insert\footins{%
-  % We want to typeset this text as a normal paragraph, even if the
-  % footnote reference occurs in (for example) a display environment.
-  % So reset some parameters.
-  \interlinepenalty\interfootnotelinepenalty
-  \splittopskip\ht\strutbox % top baseline for broken footnotes
-  \splitmaxdepth\dp\strutbox
-  \floatingpenalty\@MM
-  \leftskip\z@skip
-  \rightskip\z@skip
-  \spaceskip\z@skip
-  \xspaceskip\z@skip
-  \parindent\defaultparindent
-  %
-  % Hang the footnote text off the number.
-  \hang
-  \textindent{\thisfootno}%
-  %
-  % Don't crash into the line above the footnote text.  Since this
-  % expands into a box, it must come within the paragraph, lest it
-  % provide a place where TeX can split the footnote.
-  \footstrut
-  #1\strut}%
-}
-
-}%end \catcode `\@=11
-
-% Set the baselineskip to #1, and the lineskip and strut size
-% correspondingly.  There is no deep meaning behind these magic numbers
-% used as factors; they just match (closely enough) what Knuth defined.
-%
-\def\lineskipfactor{.08333}
-\def\strutheightpercent{.70833}
-\def\strutdepthpercent {.29167}
-%
-\def\setleading#1{%
-  \normalbaselineskip = #1\relax
-  \normallineskip = \lineskipfactor\normalbaselineskip
-  \normalbaselines
-  \setbox\strutbox =\hbox{%
-    \vrule width0pt height\strutheightpercent\baselineskip
-                    depth \strutdepthpercent \baselineskip
-  }%
-}
-
-% @| inserts a changebar to the left of the current line.  It should
-% surround any changed text.  This approach does *not* work if the
-% change spans more than two lines of output.  To handle that, we would
-% have adopt a much more difficult approach (putting marks into the main
-% vertical list for the beginning and end of each change).
-%
-\def\|{%
-  % \vadjust can only be used in horizontal mode.
-  \leavevmode
-  %
-  % Append this vertical mode material after the current line in the output.
-  \vadjust{%
-    % We want to insert a rule with the height and depth of the current
-    % leading; that is exactly what \strutbox is supposed to record.
-    \vskip-\baselineskip
-    %
-    % \vadjust-items are inserted at the left edge of the type.  So
-    % the \llap here moves out into the left-hand margin.
-    \llap{%
-      %
-      % For a thicker or thinner bar, change the `1pt'.
-      \vrule height\baselineskip width1pt
-      %
-      % This is the space between the bar and the text.
-      \hskip 12pt
-    }%
-  }%
-}
-
-% For a final copy, take out the rectangles
-% that mark overfull boxes (in case you have decided
-% that the text looks ok even though it passes the margin).
-%
-\def\finalout{\overfullrule=0pt}
-
-
-% End of control word definitions.
-
-\message{and turning on texinfo input format.}
-
-\def\openindices{%
-   \newindex{cp}%
-   \newcodeindex{fn}%
-   \newcodeindex{vr}%
-   \newcodeindex{tp}%
-   \newcodeindex{ky}%
-   \newcodeindex{pg}%
-}
-
-% Set some numeric style parameters, for 8.5 x 11 format.
-
-%\hsize = 6.5in
-\newdimen\defaultparindent \defaultparindent = 15pt
-\parindent = \defaultparindent
-\parskip 18pt plus 1pt
-\setleading{15pt}
-\advance\topskip by 1.2cm
-
-% Prevent underfull vbox error messages.
-\vbadness=10000
-
-% Following George Bush, just get rid of widows and orphans.
-\widowpenalty=10000
-\clubpenalty=10000
-
-% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
-% using an old version of TeX, don't do anything.  We want the amount of
-% stretch added to depend on the line length, hence the dependence on
-% \hsize.  This makes it come to about 9pt for the 8.5x11 format.
-%
-\ifx\emergencystretch\thisisundefined
-  % Allow us to assign to \emergencystretch anyway.
-  \def\emergencystretch{\dimen0}%
-\else
-  \emergencystretch = \hsize
-  \divide\emergencystretch by 45
-\fi
-
-% Use @smallbook to reset parameters for 7x9.5 format  (or else 7x9.25)
-\def\smallbook{
-
-% These values for secheadingskip and subsecheadingskip are
-% experiments.  RJC 7 Aug 1992
-\global\secheadingskip = 17pt plus 6pt minus 3pt
-\global\subsecheadingskip = 14pt plus 6pt minus 3pt
-
-\global\lispnarrowing = 0.3in
-\setleading{12pt}
-\advance\topskip by -1cm
-\global\parskip 3pt plus 1pt
-\global\hsize = 5in
-\global\vsize=7.5in
-\global\tolerance=700
-\global\hfuzz=1pt
-\global\contentsrightmargin=0pt
-\global\deftypemargin=0pt
-\global\defbodyindent=.5cm
-
-\global\pagewidth=\hsize
-\global\pageheight=\vsize
-
-\global\let\smalllisp=\smalllispx
-\global\let\smallexample=\smalllispx
-\global\def\Esmallexample{\Esmalllisp}
-}
-
-% Use @afourpaper to print on European A4 paper.
-\def\afourpaper{
-\global\tolerance=700
-\global\hfuzz=1pt
-\setleading{12pt}
-\global\parskip 15pt plus 1pt
-
-\global\vsize= 53\baselineskip
-\advance\vsize by \topskip
-%\global\hsize=   5.85in     % A4 wide 10pt
-\global\hsize=  6.5in
-\global\outerhsize=\hsize
-\global\advance\outerhsize by 0.5in
-\global\outervsize=\vsize
-\global\advance\outervsize by 0.6in
-
-\global\pagewidth=\hsize
-\global\pageheight=\vsize
-}
-
-% Allow control of the text dimensions.  Parameters in order: textheight;
-% textwidth; \voffset; \hoffset (!); binding offset.  All require a dimension;
-% header is additional; added length extends the bottom of the page.
-
-\def\changepagesizes#1#2#3#4#5
-{\global\vsize= #1
- \advance\vsize by \topskip
- \global\voffset= #3
- \global\hsize= #2
- \global\outerhsize=\hsize
- \global\advance\outerhsize by 0.5in
- \global\outervsize=\vsize
- \global\advance\outervsize by 0.6in
- \global\pagewidth=\hsize
- \global\pageheight=\vsize
- \global\normaloffset= #4
- \global\bindingoffset= #5}
-
-% This layout is compatible with Latex on A4 paper.
-
-\def\afourlatex{\changepagesizes{22cm}{15cm}{7mm}{4.6mm}{5mm}}
-
-% Define macros to output various characters with catcode for normal text.
-\catcode`\"=\other
-\catcode`\~=\other
-\catcode`\^=\other
-\catcode`\_=\other
-\catcode`\|=\other
-\catcode`\<=\other
-\catcode`\>=\other
-\catcode`\+=\other
-\def\normaldoublequote{"}
-\def\normaltilde{~}
-\def\normalcaret{^}
-\def\normalunderscore{_}
-\def\normalverticalbar{|}
-\def\normalless{<}
-\def\normalgreater{>}
-\def\normalplus{+}
-
-% This macro is used to make a character print one way in ttfont
-% where it can probably just be output, and another way in other fonts,
-% where something hairier probably needs to be done.
-%
-% #1 is what to print if we are indeed using \tt; #2 is what to print
-% otherwise.  Since all the Computer Modern typewriter fonts have zero
-% interword stretch (and shrink), and it is reasonable to expect all
-% typewriter fonts to have this, we can check that font parameter.
-%
-\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
-
-% Turn off all special characters except @
-% (and those which the user can use as if they were ordinary).
-% Most of these we simply print from the \tt font, but for some, we can
-% use math or other variants that look better in normal text.
-
-\catcode`\"=\active
-\def\activedoublequote{{\tt \char '042}}
-\let"=\activedoublequote
-\catcode`\~=\active
-\def~{{\tt \char '176}}
-\chardef\hat=`\^
-\catcode`\^=\active
-\def^{{\tt \hat}}
-
-\catcode`\_=\active
-\def_{\ifusingtt\normalunderscore\_}
-% Subroutine for the previous macro.
-\def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}}
-
-% \lvvmode is equivalent in function to \leavevmode.
-% Using \leavevmode runs into trouble when written out to
-% an index file due to the expansion of \leavevmode into ``\unhbox
-% \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our
-% magic tricks with @.
-\def\lvvmode{\vbox to 0pt{}}
-
-\catcode`\|=\active
-\def|{{\tt \char '174}}
-\chardef \less=`\<
-\catcode`\<=\active
-\def<{{\tt \less}}
-\chardef \gtr=`\>
-\catcode`\>=\active
-\def>{{\tt \gtr}}
-\catcode`\+=\active
-\def+{{\tt \char 43}}
-%\catcode 27=\active
-%\def^^[{$\diamondsuit$}
-
-% Set up an active definition for =, but don't enable it most of the time.
-{\catcode`\==\active
-\global\def={{\tt \char 61}}}
-
-\catcode`\@=0
-
-% \rawbackslashxx output one backslash character in current font
-\global\chardef\rawbackslashxx=`\\
-%{\catcode`\\=\other
-%@gdef@rawbackslashxx{\}}
-
-% \rawbackslash redefines \ as input to do \rawbackslashxx.
-{\catcode`\\=\active
-@gdef@rawbackslash{@let\=@rawbackslashxx }}
-
-% \normalbackslash outputs one backslash in fixed width font.
-\def\normalbackslash{{\tt\rawbackslashxx}}
-
-% Say @foo, not \foo, in error messages.
-\escapechar=`\@
-
-% \catcode 17=0   % Define control-q
-\catcode`\\=\active
-
-% Used sometimes to turn off (effectively) the active characters
-% even after parsing them.
-@def@turnoffactive{@let"=@normaldoublequote
-@let\=@realbackslash
-@let~=@normaltilde
-@let^=@normalcaret
-@let_=@normalunderscore
-@let|=@normalverticalbar
-@let<=@normalless
-@let>=@normalgreater
-@let+=@normalplus}
-
-@def@normalturnoffactive{@let"=@normaldoublequote
-@let\=@normalbackslash
-@let~=@normaltilde
-@let^=@normalcaret
-@let_=@normalunderscore
-@let|=@normalverticalbar
-@let<=@normalless
-@let>=@normalgreater
-@let+=@normalplus}
-
-% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
-% That is what \eatinput is for; after that, the `\' should revert to printing
-% a backslash.
-%
-@gdef@eatinput input texinfo{@fixbackslash}
-@global@let\ = @eatinput
-
-% On the other hand, perhaps the file did not have a `\input texinfo'. Then
-% the first `\{ in the file would cause an error. This macro tries to fix
-% that, assuming it is called before the first `\' could plausibly occur.
-%
-@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi}
-
-%% These look ok in all fonts, so just make them not special.  The @rm below
-%% makes sure that the current font starts out as the newly loaded cmr10
-@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
-
-@textfonts
-@rm
-
-@c Local variables:
-@c page-delimiter: "^\\\\message"
-@c End:
diff --git a/doc/user-guide.texinfo b/doc/user-guide.texinfo
deleted file mode 100644
index c1fe46235..000000000
--- a/doc/user-guide.texinfo
+++ /dev/null
@@ -1,1700 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-@c %**start of header
-@c guide
-@setfilename krb5-user.info
-@settitle Kerberos V5 UNIX User's Guide
-@setchapternewpage odd                  @c chapter begins on next odd page
-@c @setchapternewpage on                   @c chapter begins on next page
-@c @smallbook                              @c Format for 7" X 9.25" paper
-@c %**end of header
-
-@paragraphindent 0
-@iftex
-@parskip 6pt plus 6pt
-@end iftex
-
-@include definitions.texinfo
-@set EDITION 1.0
-
-@finalout                               @c don't print black warning boxes
-
-@titlepage
-@title @value{PRODUCT} UNIX User's Guide
-@subtitle Release:  @value{RELEASE}
-@subtitle Document Edition:  @value{EDITION}
-@subtitle Last updated:  @value{UPDATED}
-@author @value{COMPANY}
-
-@page
-@vskip 0pt plus 1filll
-
-@end titlepage
-
-@comment  node-name,  next,  previous,  up
-@node Top, Copyright, (dir), (dir)
-
-@ifinfo
-This file describes how to use the @value{PRODUCT} client programs.
-@end ifinfo
-
-@c The master menu is updated using emacs19's M-x texinfo-all-menus-update
-@c function.  Don't forget to run M-x texinfo-every-node-update after
-@c you add a new section or subsection, or after you've rearranged the
-@c comand before each @section or @subsection!  All you need to enter
-@c is:
-@c
-@c @section New Section Name
-@c
-@c M-x texinfo-every-node-update will take care of calculating the
-@c node's forward and back pointers.
-@c
-@c ---------------------------------------------------------------------
-
-@menu
-* Copyright::                   
-* Introduction::                
-* Kerberos V5 Tutorial::        
-* Kerberos V5 Reference::       
-* Kerberos Glossary::           
-@end menu
-
-@node Copyright, Introduction, Top, Top
-@unnumbered Copyright
-
-@include copyright.texinfo
-
-@node Introduction, Kerberos V5 Tutorial, Copyright, Top
-@chapter Introduction
-
-@ifset CYGNUS
-@value{PRODUCT} is based on the Kerberos V5 authentication system
-developed at MIT.
-@end ifset
-@ifset MIT
-Kerberos V5 is an authentication system developed at MIT.
-@end ifset
-Kerberos is named for the three-headed watchdog from Greek mythology,
-who guarded the entrance to the underworld.
-
-Under Kerberos, a client (generally either a user or a service) sends a
-request for a ticket to the @i{Key Distribution Center} (KDC).  The KDC
-creates a @dfn{ticket-granting ticket} (TGT) for the client, encrypts it
-using the client's password as the key, and sends the encrypted TGT back
-to the client.  The client then attempts to decrypt the TGT, using its
-password.  If the client successfully decrypts the TGT (@i{i.e.}, if the
-client gave the correct password), it keeps the decrypted TGT, which
-indicates proof of the client's identity.
-
-The TGT, which expires at a specified time, permits the client to obtain
-additional tickets, which give permission for specific services.  The
-requesting and granting of these additional tickets is user-transparent.
-
-Since Kerberos negotiates authenticated, and optionally encrypted,
-communications between two points anywhere on the internet, it provides
-a layer of security that is not dependent on which side of a firewall
-either client is on.  Since studies have shown that half of the computer
-security breaches in industry happen from @i{inside} firewalls,
-@value{COMPANY}'s @value{PRODUCT} plays a vital role in maintaining your
-network security.
-
-The @value{PRODUCT} package is designed to be easy to use.  Most of the
-commands are nearly identical to UNIX network programs you already
-use.  @value{PRODUCT} is a @dfn{single-sign-on} system, which means
-that you have to type your password only once per session, and Kerberos
-does the authenticating and encrypting transparently.
-
-@menu
-* What is a Ticket?::           
-* What is a Kerberos Principal?::  
-@end menu
-
-@node What is a Ticket?, What is a Kerberos Principal?, Introduction, Introduction
-@section What is a Ticket?
-
-Your Kerberos @dfn{credentials}, or ``@dfn{tickets}'', are a set of
-electronic information that can be used to verify your identity.  Your
-Kerberos tickets may be stored in a file, or they may exist only in
-memory.
-
-The first ticket you obtain is a @dfn{ticket-granting ticket}, which
-permits you to obtain additional tickets.  These additional tickets give
-you permission for specific services.  The requesting and granting of
-these additional tickets happens transparently.
-
-A good analogy for the ticket-granting ticket is a three-day ski pass
-that is good at four different resorts.  You show the pass at whichever
-resort you decide to go to (until it expires), and you receive a lift
-ticket for that resort.  Once you have the lift ticket, you can ski all
-you want at that resort.  If you go to another resort the next day, you
-once again show your pass, and you get an additional lift ticket for the
-new resort.  The difference is that the @value{PRODUCT} programs notice
-that you have the weekend ski pass, and get the lift ticket for you, so
-you don't have to perform the transactions yourself.
-
-@node What is a Kerberos Principal?,  , What is a Ticket?, Introduction
-@section What is a Kerberos Principal?
-
-A Kerberos @dfn{principal} is a unique identity to which Kerberos can
-assign tickets.  Principals can have an arbitrary number of
-components.  Each component is separated by a component separator,
-generally `/'.  The last component is the realm, separated from the
-rest of the principal by the realm separator, generally `@@'.  If there
-is no realm component in the principal, then it will be assumed that
-the principal is in the default realm for the context in which it is
-being used.
-
-Traditionally, a principal is divided into three parts:  the
-@dfn{primary}, the @dfn{instance}, and the @dfn{realm}.  The format of
-a typical Kerberos V5 principal is @code{primary/instance@@REALM}.
-
-@itemize @bullet
-@item The @dfn{primary} is the first part of the principal.  In the case
-of a user, it's the same as your username.  For a host, the primary is
-the word @code{host}.
-
-@item The @dfn{instance} is an optional string that qualifies the
-primary.  The instance is separated from the primary by a slash
-(@code{/}).  In the case of a user, the instance is usually null, but a
-user might also have an additional principal, with an instance called
-@samp{admin}, which he/she uses to administrate a database.  The
-principal @code{@value{RANDOMUSER1}@@@value{PRIMARYREALM}} is completely
-separate from the principal
-@code{@value{RANDOMUSER1}/admin@@@value{PRIMARYREALM}}, with a separate
-password, and separate permissions.  In the case of a host, the instance
-is the fully qualified hostname, e.g.,
-@code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}.
-
-@item The @dfn{realm} is your Kerberos realm.  In most cases, your
-Kerberos realm is your domain name, in upper-case letters.  For example,
-the machine @code{@value{RANDOMHOST1}.@value{SECONDDOMAIN}} would be in
-the realm @code{@value{SECONDREALM}}.
-@end itemize
-
-@node Kerberos V5 Tutorial, Kerberos V5 Reference, Introduction, Top
-@chapter Kerberos V5 Tutorial
-
-This tutorial is intended to familiarize you with the @value{PRODUCT}
-client programs.  We will represent your prompt as ``@code{shell%}''.
-So an instruction to type the ``@kbd{ls}'' command would be represented as
-follows:
-
-@need 600
-@smallexample
-@group
-@b{shell%} ls
-@end group
-@end smallexample
-
-In these examples, we will use sample usernames, such as
-@code{@value{RANDOMUSER1}} and @code{@value{RANDOMUSER2}}, sample
-hostnames, such as @code{@value{RANDOMHOST1}} and
-@code{@value{RANDOMHOST2}}, and sample domain names, such as
-@code{@value{PRIMARYDOMAIN}} and @code{@value{SECONDDOMAIN}}.  When you
-see one of these, substitute your username, hostname, or domain name
-accordingly.
-
-@menu
-* Setting Up to Use Kerberos V5::  
-* Ticket Management::           
-* Password Management::         
-* Kerberos V5 Applications::    
-@end menu
-
-@node Setting Up to Use Kerberos V5, Ticket Management, Kerberos V5 Tutorial, Kerberos V5 Tutorial
-@section Setting Up to Use @value{PRODUCT}
-
-Your system administrator will have installed the @value{PRODUCT}
-programs in whichever directory makes the most sense for your system.
-We will use @code{@value{ROOTDIR}} throughout this guide to refer to the
-top-level directory @value{PRODUCT} directory.  We will therefor use
-@code{@value{BINDIR}} to denote the location of the @value{PRODUCT} user
-programs.  In your installation, the directory name may be different,
-but whatever the directory name is, you should make sure it is included
-in your path.  You will probably want to put it @i{ahead of} the
-directories @code{/bin} and @code{/usr/bin} so you will get the
-@value{PRODUCT} network programs, rather than the standard UNIX
-versions, when you type their command names.
-
-@node Ticket Management, Password Management, Setting Up to Use Kerberos V5, Kerberos V5 Tutorial
-@section Ticket Management
-
-On many systems, Kerberos is built into the login program, and you get
-tickets automatically when you log in.  Other programs, such as
-@code{rsh}, @code{rcp}, @code{telnet}, and @code{rlogin}, can forward
-copies of your tickets to the remote host.  Most of these programs also
-automatically destroy your tickets when they exit.  However,
-@value{COMPANY} recommends that you explicitly destroy your Kerberos
-tickets when you are through with them, just to be sure.  One way to
-help ensure that this happens is to add the @code{kdestroy} command to
-your @code{.logout} file.  Additionally, if you are going to be away
-from your machine and are concerned about an intruder using your
-permissions, it is safest to either destroy all copies of your tickets,
-or use a screensaver that locks the screen.
-
-@need 2000
-@menu
-* Kerberos Ticket Properties::  
-* Obtaining Tickets with kinit::  
-* Viewing Your Tickets with klist::  
-* Destroying Your Tickets with kdestroy::  
-@end menu
-
-@node Kerberos Ticket Properties, Obtaining Tickets with kinit, Ticket Management, Ticket Management
-@subsection Kerberos Ticket Properties
-
-@noindent
-There are various properties that Kerberos tickets can have:
-
-If a ticket is @dfn{forwardable}, then the KDC can issue a new ticket with
-a different network address based on the forwardable ticket.  This
-allows for authentication forwarding without requiring a password to be
-typed in again.  For example, if a user with a forwardable TGT logs
-into a remote system, the KDC could issue a new TGT for that user with
-the netword address of the remote system, allowing authentication on
-that host to work as though the user were logged in locally.
-
-When the KDC creates a new ticket based on a forwardable ticket, it
-sets the @dfn{forwarded} flag on that new ticket.  Any tickets that are
-created based on a ticket with the forwarded flag set will also have
-their forwarded flags set.
-
-A @dfn{proxiable} ticket is similar to a forwardable ticket in that it
-allows a service to take on the identity of the client.  Unlike a
-forwardable ticket, however, a proxiable ticket is only issued for
-specific services.  In other words, a ticket-granting ticket cannot be
-issued based on a ticket that is proxiable but not forwardable.
-
-A @dfn{proxy} ticket is one that was issued based on a proxiable ticket.
-
-A @dfn{postdated} ticket is issued with the @i{invalid} flag set.
-After the starting time listed on the ticket, it can be presented to
-the KDC to obtain valid tickets.  
-
-Tickets with the @dfn{postdateable} flag set can be used to issue postdated
-tickets.
-
-@dfn{Renewable} tickets can be used to obtain new session keys without
-the user entering their password again.  A renewable ticket has two
-expiration times.  The first is the time at which this particular
-ticket expires.  The second is the latest possible expiration time for
-any ticket issued based on this renewable ticket.
-
-A ticket with the @dfn{initial} flag set was issued based on the
-authentication protocol, and not on a ticket-granting ticket.   Clients
-that wish to ensure that the user's key has been recently presented for
-verification could specify that this flag must be set to accept the
-ticket.
-
-An @dfn{invalid} ticket must be rejected by application servers.  Postdated
-tickets are usually issued with this flag set, and must be validated by
-the KDC before they can be used.
-
-A @dfn{preauthenticated} ticket is one that was only issued after the
-client requesting the ticket had authenticated itself to the KDC.
-
-The @dfn{hardware authentication} flag is set on a ticket which
-required the use of hardware for authentication.  The hardware is
-expected to be possessed only by the client which requested the
-tickets.
-
-If a ticket has the @dfn{transit policy checked} flag set, then the KDC that
-issued this ticket implements the transited-realm check policy and
-checked the transited-realms list on the ticket.  The transited-realms
-list contains a list of all intermediate realms between the realm of the
-KDC that issued the first ticket and that of the one that issued the
-current ticket.  If this flag is not set, then the application server
-must check the transited realms itself or else reject the ticket.
-
-The @dfn{okay as delegate} flag indicates that the server specified in
-the ticket is suitable as a delegate as determined by the policy of
-that realm.  A server that is acting as a delegate has been granted a
-proxy or a forwarded TGT.  This flag is a new addition to the
-@value{PRODUCT} protocol and is not yet implemented on MIT servers.
-
-An @dfn{anonymous}  ticket is one in which the named principal is a generic
-principal for that realm; it does not actually specify the individual
-that will be using the ticket.  This ticket is meant only to securely
-distribute a session key.  This is a new addition to the @value{PRODUCT}
-protocol and is not yet implemented on MIT servers.
-
-@node Obtaining Tickets with kinit, Viewing Your Tickets with klist, Kerberos Ticket Properties, Ticket Management
-@subsection Obtaining Tickets with kinit
-
-If your site is using the @value{PRODUCT} login program, you will get
-Kerberos tickets automatically when you log in.  If your site uses a
-different login program, you may need to explicitly obtain your Kerberos
-tickets, using the @code{kinit} program.  Similarly, if your Kerberos
-tickets expire, use the @code{kinit} program to obtain new ones.
-
-@need 1500
-To use the @code{kinit} program, simply type @kbd{kinit} and then type
-your password at the prompt.  For example, Jennifer (whose username is
-@code{@value{RANDOMUSER1}}) works for Bleep, Inc. (a fictitious company
-with the domain name @code{@value{PRIMARYDOMAIN}} and the Kerberos realm
-@code{@value{PRIMARYREALM}}).  She would type:
-
-@smallexample
-@group
-@b{shell%} kinit
-@b{Password for @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<-- [Type @value{RANDOMUSER1}'s password here.]}
-@b{shell%}
-@end group
-@end smallexample
-
-@need 1000
-If you type your password incorrectly, kinit will give you the following
-error message:
-
-@smallexample
-@group
-@b{shell%} kinit
-@b{Password for @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<-- [Type the wrong password here.]}
-@b{kinit: Password incorrect}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent and you won't get Kerberos tickets.
-
-@noindent Notice that @code{kinit} assumes you want tickets for your own
-username in your default realm.  
-@need 1500
-Suppose Jennifer's friend David is visiting, and he wants to borrow a
-window to check his mail.  David needs to get tickets for himself in his
-own realm, @value{SECONDREALM}.@footnote{Note:  the realm
-@value{SECONDREALM} must be listed in your computer's Kerberos
-configuration file, @code{/etc/krb5.conf}.}  He would type:
-
-@smallexample
-@group
-@b{shell%} kinit @value{RANDOMUSER2}@@@value{SECONDREALM}
-@b{Password for @value{RANDOMUSER2}@@@value{SECONDREALM}:} @i{<-- [Type @value{RANDOMUSER2}'s password here.]}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent David would then have tickets which he could use to log onto
-his own machine.  Note that he typed his password locally on Jennifer's
-machine, but it never went over the network.  Kerberos on the local host
-performed the authentication to the KDC in the other realm.
-
-@need 1000
-If you want to be able to forward your tickets to another host, you need
-to request @dfn{forwardable} tickets.  You do this by specifying the
-@kbd{-f} option:
-
-@smallexample
-@group
-@b{shell%} kinit -f
-@b{Password for @value{RANDOMUSER1}@@@value{PRIMARYREALM}:} @i{<-- [Type your password here.]}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent
-Note that @code{kinit} does not tell you that it obtained forwardable
-tickets; you can verify this using the @code{klist} command
-(@pxref{Viewing Your Tickets with klist}).
-
-Normally, your tickets are good for your system's default ticket
-lifetime, which is ten hours on many systems.  You can specify a
-different ticket lifetime with the @samp{-l} option.  Add the letter
-@samp{s} to the value for seconds, @samp{m} for minutes, @samp{h} for
-hours, or @samp{d} for days.
-@need 1500
-For example, to obtain forwardable tickets for
-@code{@value{RANDOMUSER2}@@@value{SECONDREALM}} that would be good for
-three hours, you would type:
-
-@smallexample
-@group
-@b{shell%} kinit -f -l 3h @value{RANDOMUSER2}@@@value{SECONDREALM}
-@b{Password for @value{RANDOMUSER2}@@@value{SECONDREALM}:} @i{<-- [Type @value{RANDOMUSER2}'s password here.]}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent
-You cannot mix units; specifying a lifetime of @samp{3h30m} would result
-in an error.  Note also that most systems specify a maximum ticket
-lifetime.  If you request a longer ticket lifetime, it will be
-automatically truncated to the maximum lifetime.
-
-@node Viewing Your Tickets with klist, Destroying Your Tickets with kdestroy, Obtaining Tickets with kinit, Ticket Management
-@subsection Viewing Your Tickets with klist
-
-The @code{klist} command shows your tickets.  When you first obtain
-tickets, you will have only the ticket-granting ticket.  (@xref{What is
-a Ticket?}.)  The listing would look like this:
-
-@smallexample
-@group
-@b{shell%} klist
-Ticket cache: /tmp/krb5cc_ttypa
-Default principal: @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-
-Valid starting     Expires            Service principal
-06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent
-The ticket cache is the location of your ticket file.  In the above
-example, this file is named @code{/tmp/krb5cc_ttypa}.  The default
-principal is your kerberos @dfn{principal}.  (@pxref{What is a Kerberos
-Principal?})
-
-The ``valid starting'' and ``expires'' fields describe the period of
-time during which the ticket is valid.  The @dfn{service principal}
-describes each ticket.  The ticket-granting ticket has the primary
-@code{krbtgt}, and the instance is the realm name.
-
-@need 2000
-Now, if @value{RANDOMUSER1} connected to the machine
-@code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}, and then typed
-@kbd{klist} again, she would have gotten the following result:
-
-@smallexample
-@group
-@b{shell%} klist
-Ticket cache: /tmp/krb5cc_ttypa
-Default principal: @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-
-Valid starting     Expires            Service principal
-06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM}
-06/07/04 20:22:30  06/08/04 05:49:19  host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}
-@b{shell%}
-@end group
-@end smallexample
-
-@noindent
-Here's what happened:  when @value{RANDOMUSER1} used telnet to connect
-to the host @code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}, the telnet
-program presented her ticket-granting ticket to the KDC and requested a
-host ticket for the host
-@code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}.  The KDC sent the host
-ticket, which telnet then presented to the host
-@code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}, and she was allowed to
-log in without typing her password.
-
-@need 3000
-Suppose your Kerberos tickets allow you to log into a host in another
-domain, such as @code{@value{RANDOMHOST2}.@value{SECONDDOMAIN}}, which
-is also in another Kerberos realm, @code{@value{SECONDREALM}}.  If you
-telnet to this host, you will receive a ticket-granting ticket for the
-realm @code{@value{SECONDREALM}}, plus the new @code{host} ticket for
-@code{@value{RANDOMHOST2}.@value{SECONDDOMAIN}}.  @kbd{klist} will now
-show:
-
-@smallexample
-@group
-@b{shell%} klist
-Ticket cache: /tmp/krb5cc_ttypa
-Default principal: @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-
-Valid starting     Expires            Service principal
-06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM}
-06/07/04 20:22:30  06/08/04 05:49:19  host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}
-06/07/04 20:24:18  06/08/04 05:49:19  krbtgt/@value{SECONDREALM}@@@value{PRIMARYREALM}
-06/07/04 20:24:18  06/08/04 05:49:19  host/@value{RANDOMHOST2}.@value{SECONDDOMAIN}@@@value{PRIMARYREALM}
-@b{shell%}
-@end group
-@end smallexample
-
-You can use the @code{-f} option to view the @dfn{flags} that apply to
-your tickets.  The flags are:
-
-@table @b
-@itemx F
-@b{F}orwardable
-@itemx f
-@b{f}orwarded
-@itemx P
-@b{P}roxiable
-@itemx p
-@b{p}roxy
-@itemx D
-post@b{D}ateable
-@itemx d
-post@b{d}ated
-@itemx R
-@b{R}enewable
-@itemx I
-@b{I}nitial
-@itemx i
-@b{i}nvalid
-@itemx H
-@b{H}ardware authenticated
-@itemx A
-pre@b{A}uthenticated
-@itemx T
-@b{T}ransit policy checked
-@itemx O
-@b{O}kay as delegate
-@itemx a
-@b{a}nonymous
-@end table
-
-@need 1500
-Here is a sample listing.  In this example, the user @value{RANDOMUSER1}
-obtained her initial tickets (@samp{I}), which are forwardable
-(@samp{F}) and postdated (@samp{d}) but not yet validated (@samp{i}).
-(@xref{kinit Reference}, for more information about postdated tickets.)
-
-@smallexample
-@group
-@b{shell%} klist -f
-@b{Ticket cache: /tmp/krb5cc_320
-Default principal: @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-
-Valid starting      Expires             Service principal
-31/07/05 19:06:25  31/07/05 19:16:25  krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM}
-        Flags: FdiI
-shell%}
-@end group
-@end smallexample
-
-@need 1500
-In the following example, the user @value{RANDOMUSER2}'s tickets were
-forwarded (@samp{f}) to this host from another host.  The tickets are
-reforwardable (@samp{F}).
-
-@smallexample
-@group
-@b{shell%} klist -f
-@b{Ticket cache: /tmp/krb5cc_p11795
-Default principal: @value{RANDOMUSER2}@@@value{SECONDREALM}
-
-Valid starting     Expires            Service principal
-07/31/05 11:52:29  07/31/05 21:11:23  krbtgt/@value{SECONDREALM}@@@value{SECONDREALM}
-        Flags: Ff
-07/31/05 12:03:48  07/31/05 21:11:23  host/@value{RANDOMHOST2}.@value{SECONDDOMAIN}@@@value{SECONDREALM}
-        Flags: Ff
-shell%}
-@end group
-@end smallexample
-
-@node Destroying Your Tickets with kdestroy,  , Viewing Your Tickets with klist, Ticket Management
-@subsection Destroying Your Tickets with kdestroy
-
-Your Kerberos tickets are proof that you are indeed yourself, and
-tickets can be stolen.  If this happens, the person who has them can
-masquerade as you until they expire.  For this reason, you should
-destroy your Kerberos tickets when you are away from your computer.
-
-@need 1000
-Destroying your tickets is easy.  Simply type @kbd{kdestroy}.
-
-@smallexample
-@group
-@b{shell%} kdestroy
-@b{shell%}
-@end group
-@end smallexample
-
-@need 1500
-If @code{kdestroy} fails to destroy your tickets, it will beep and give
-an error message.  For example, if @code{kdestroy} can't find any
-tickets to destroy, it will give the following message:
-
-@smallexample
-@group
-@b{shell%} kdestroy
-@b{kdestroy: No credentials cache file found while destroying cache
-shell%}
-@end group
-@end smallexample
-
-@node Password Management, Kerberos V5 Applications, Ticket Management, Kerberos V5 Tutorial
-@section Password Management
-
-Your password is the only way Kerberos has of verifying your identity.
-If someone finds out your password, that person can masquerade as
-you---send email that comes from you, read, edit, or delete your files,
-or log into other hosts as you---and no one will be able to tell the
-difference.  For this reason, it is important that you choose a good
-password (@pxref{Password Advice}), and keep it secret.  If you need to
-give access to your account to someone else, you can do so through
-Kerberos.  (@xref{Granting Access to Your Account}.)  You should
-@i{never} tell your password to anyone, including your system
-administrator, for any reason.  You should change your password
-frequently, particularly any time you think someone may have found out
-what it is.
-
-@menu
-* Changing Your Password::      
-* Password Advice::             
-* Granting Access to Your Account::  
-@end menu
-
-@node Changing Your Password, Password Advice, Password Management, Password Management
-@subsection Changing Your Password
-
-@need 2500
-To change your Kerberos password, use the @code{kpasswd} command.  It
-will ask you for your old password (to prevent someone else from walking
-up to your computer when you're not there and changing your password),
-and then prompt you for the new one twice.  (The reason you have to type
-it twice is to make sure you have typed it correctly.)  For example,
-user @code{@value{RANDOMUSER2}} would do the following:
-
-@smallexample
-@group
-@b{shell%} kpasswd
-@b{Password for @value{RANDOMUSER2}:}    @i{<- Type your old password.}
-@b{Enter new password:}    @i{<- Type your new password.}
-@b{Enter it again:}  @i{<- Type the new password again.}
-@b{Password changed.}
-@b{shell%}
-@end group
-@end smallexample
-
-@need 1800
-If @value{RANDOMUSER2} typed the incorrect old password, he would get
-the following message:
-
-@smallexample
-@group
-@b{shell%} kpasswd
-@b{Password for @value{RANDOMUSER2}:}  @i{<- Type the incorrect old password.}
-@b{kpasswd: Password incorrect while getting initial ticket
-shell%}
-@end group
-@end smallexample
-
-@need 2500
-If you make a mistake and don't type the new password the same way
-twice, @code{kpasswd} will ask you to try again:
-
-@smallexample
-@group
-@b{shell%} kpasswd
-@b{Password for @value{RANDOMUSER2}:}  @i{<- Type the old password.}
-@b{Enter new password:}  @i{<- Type the new password.}
-@b{Enter it again:} @i{<- Type a different new password.}
-@b{kpasswd: Password mismatch while reading password
-shell%}
-@end group
-@end smallexample
-
-Once you change your password, it takes some time for the change to
-propagate through the system.  Depending on how your system is set up,
-this might be anywhere from a few minutes to an hour or more.  If you
-need to get new Kerberos tickets shortly after changing your password,
-try the new password.  If the new password doesn't work, try again using
-the old one.
-
-@node Password Advice, Granting Access to Your Account, Changing Your Password, Password Management
-@subsection Password Advice
-
-Your password can include almost any character you can type (except
-control keys and the ``enter'' key).  A good password is one you can
-remember, but that no one else can easily guess.  Examples of @i{bad}
-passwords are words that can be found in a dictionary, any common or
-popular name, especially a famous person (or cartoon character), your
-name or username in any form (@i{e.g.}, forward, backward, repeated
-twice, @i{etc.}), your spouse's, child's, or pet's name, your birth
-date, your social security number, and any sample password that appears
-in this (or any other) manual.
-
-@need 2200
-@value{COMPANY} recommends that your password be at least 6 characters
-long, and contain UPPER- and lower-case letters, numbers, and/or
-punctuation marks.  Some passwords that would be good if they weren't
-listed in this manual include:
-
-@itemize @bullet
-@item some initials, like ``GykoR-66.'' for ``Get your kicks on Route
-66.''
-
-@item an easy-to-pronounce nonsense word, like ``slaRooBey'' or
-``krang-its''
-
-@item a misspelled phrase, like ``2HotPeetzas!'' or ``ItzAGurl!!!''
-@end itemize
-
-@noindent Note:  don't actually use any of the above passwords.  They're
-only meant to show you how to make up a good password.  Passwords that
-appear in a manual are the first ones intruders will try.
-
-@need 3800 
-@value{PRODUCT} allows your system administrators to automatically
-reject bad passwords, based on certain criteria, such as a password
-dictionary or a minimum length.  For example, if the user
-@code{@value{RANDOMUSER1}}, who had a policy "strict" that required a
-minimum of 8 characaters, chose a password that was less than 8
-characters, Kerberos would give an error message like the following:
-
-@smallexample
-@group
-@b{shell%} kpasswd
-@b{Password for @value{RANDOMUSER1}:}  @i{<- Type your old password here.}
-
-@value{RANDOMUSER1}'s password is controlled by the policy strict, which
-requires a minimum of 8 characters from at least 3 classes (the five classes
-are lowercase, uppercase, numbers, punctuation, and all other characters).
-
-@b{Enter new password:}  @i{<- Type an insecure new password.}
-@b{Enter it again:}  @i{<- Type it again.}
-
-kpasswd: Password is too short while attempting to change password.
-Please choose another password.
-
-@b{Enter new password:}  @i{<- Type a good password here.}
-@b{Enter it again:}  @i{<- Type it again.}
-@b{Password changed.
-shell%}
-@end group
-@end smallexample
-
-@noindent Your system administrators can choose the message that is
-displayed if you choose a bad password, so the message you see may be
-different from the above example.
-
-@node Granting Access to Your Account,  , Password Advice, Password Management
-@subsection Granting Access to Your Account
-
-@need 1800
-If you need to give someone access to log into your account, you can do
-so through Kerberos, without telling the person your password.  Simply
-create a file called @code{.k5login} in your home directory.  This file
-should contain the Kerberos principal (@xref{What is a Kerberos
-Principal?}.) of each person to whom you wish to give access.  Each
-principal must be on a separate line.  Here is a sample @code{.k5login}
-file:
-
-@smallexample
-@group
-@value{RANDOMUSER1}@@@value{PRIMARYREALM}
-@value{RANDOMUSER2}@@@value{SECONDREALM}
-@end group
-@end smallexample
-
-@noindent This file would allow the users @code{@value{RANDOMUSER1}} and
-@code{@value{RANDOMUSER2}} to use your user ID, provided that they had
-Kerberos tickets in their respective realms.  If you will be logging
-into other hosts across a network, you will want to include your own
-Kerberos principal in your @code{.k5login} file on each of these hosts.
-
-@need 1000
-Using a @code{.k5login} file is much safer than giving out your
-password, because:
-
-@itemize @bullet
-@item You can take access away any time simply by removing the principal
-from your @code{.k5login} file.
-
-@item Although the user has full access to your account on one
-particular host (or set of hosts if your @code{.k5login} file is shared,
-@i{e.g.}, over NFS), that user does not inherit your network privileges.
-
-@item Kerberos keeps a log of who obtains tickets, so a system
-administrator could find out, if necessary, who was capable of using
-your user ID at a particular time.
-@end itemize
-
-One common application is to have a @code{.k5login} file in
-@code{root}'s home directory, giving root access to that machine to the
-Kerberos principals listed.  This allows system administrators to allow
-users to become root locally, or to log in remotely as @code{root},
-without their having to give out the root password, and without anyone
-having to type the root password over the network.
-
-@node Kerberos V5 Applications,  , Password Management, Kerberos V5 Tutorial
-@section Kerberos V5 Applications
-
-@value{PRODUCT} is a @dfn{single-sign-on} system.  This means that you
-only have to type your password once, and the @value{PRODUCT} programs
-do the authenticating (and optionally encrypting) for you.  The way this
-works is that Kerberos has been built into each of a suite of network
-programs.  For example, when you use a @value{PRODUCT} program to
-connect to a remote host, the program, the KDC, and the remote host
-perform a set of rapid negotiations.  When these negotiations are
-completed, your program has proven your identity on your behalf to the
-remote host, and the remote host has granted you access, all in the
-space of a few seconds.
-
-The @value{PRODUCT} applications are versions of existing UNIX network
-programs with the Kerberos features added.
-
-@menu
-* Overview of Additional Features::  
-* telnet::                      
-* rlogin::                      
-* FTP::                         
-* rsh::                         
-* rcp::                         
-* ksu::                         
-@end menu
-
-@node Overview of Additional Features, telnet, Kerberos V5 Applications, Kerberos V5 Applications
-@subsection Overview of Additional Features
-
-The @value{PRODUCT} @dfn{network programs} are those programs that
-connect to another host somewhere on the internet.  These programs
-include @code{rlogin}, @code{telnet}, @code{ftp}, @code{rsh},
-@code{rcp}, and @code{ksu}.  These programs have all of the original
-features of the corresponding non-Kerberos @code{rlogin}, @code{telnet},
-@code{ftp}, @code{rsh}, @code{rcp}, and @code{su} programs, plus
-additional features that transparently use your Kerberos tickets for
-negotiating authentication and optional encryption with the remote host.
-In most cases, all you'll notice is that you no longer have to type your
-password, because Kerberos has already proven your identity.
-
-The @value{PRODUCT} network programs allow you the options of forwarding
-your tickets to the remote host (if you obtained forwardable tickets
-with the @code{kinit} program; @pxref{Obtaining Tickets with kinit}), and
-encrypting data transmitted between you and the remote host.
-
-This section of the tutorial assumes you are familiar with the
-non-Kerberos versions of these programs, and highlights the Kerberos
-functions added in the @value{PRODUCT} package.
-
-@node telnet, rlogin, Overview of Additional Features, Kerberos V5 Applications
-@subsection telnet
-
-The @value{PRODUCT} @code{telnet} command works exactly like the
-standard UNIX telnet program, with the following Kerberos options added:
-
-@table @kbd
-@itemx -f
-forwards a copy of your tickets to the remote host.
-
-@itemx -F
-forwards a copy of your tickets to the remote host, and marks them
-re-forwardable from the remote host.
-
-@itemx -k @i{realm}
-requests tickets for the remote host in the specified realm, instead of
-determining the realm itself.
-
-@itemx -K
-uses your tickets to authenticate to the remote host, but does not log
-you in.
-
-@itemx -a
-attempt automatic login using your tickets.  @code{telnet} will assume
-the same username unless you explicitly specify another.
-
-@itemx -x
-turns on encryption.
-
-@end table
-
-@need 4000
-For example, if @code{@value{RANDOMUSER2}} wanted to use the standard
-UNIX telnet to connect to the machine
-@code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}, he would type:
-
-@smallexample
-@group
-@b{shell%} telnet @value{RANDOMHOST1}.@value{SECONDDOMAIN}
-@b{Trying 128.0.0.5 ...
-Connected to @value{RANDOMHOST1}.@value{SECONDDOMAIN}.
-Escape character is '^]'.
-
-NetBSD/i386 (daffodil) (ttyp3)
-
-login:} @value{RANDOMUSER2}
-@b{Password:}    @i{<- @value{RANDOMUSER2} types his password here}
-@b{Last login: Fri Jun 21 17:13:11 from @value{RANDOMHOST2}.@value{PRIMARYDOMAIN}
-Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
-        The Regents of the University of California.   All rights reserved.
-
-NetBSD 1.1: Tue May 21 00:31:42 EDT 1996
-
-Welcome to NetBSD!
-shell%}
-@end group
-@end smallexample
-
-@noindent Note that the machine
-@code{@value{RANDOMHOST1}.@value{SECONDDOMAIN}} asked for
-@code{@value{RANDOMUSER2}}'s password.  When he typed it, his password
-was sent over the network unencrypted.  If an intruder were watching
-network traffic at the time, that intruder would know
-@code{@value{RANDOMUSER2}}'s password.
-
-@need 4000
-If, on the other hand, @code{@value{RANDOMUSER1}} wanted to use the
-@value{PRODUCT} telnet to connect to the machine
-@code{@value{RANDOMHOST2}.@value{PRIMARYDOMAIN}}, she could forward a
-copy of her tickets, request an encrypted session, and log on as herself
-as follows:
-
-@smallexample
-@group
-@b{shell%} telnet -a -f -x @value{RANDOMHOST2}.@value{PRIMARYDOMAIN}
-@b{Trying 128.0.0.5...
-Connected to @value{RANDOMHOST2}.@value{PRIMARYDOMAIN}.
-Escape character is '^]'.
-[ Kerberos V5 accepts you as ``@value{RANDOMUSER1}@@@value{PRIMARYDOMAIN}'' ]
-[ Kerberos V5 accepted forwarded credentials ]
-What you type is protected by encryption.
-Last login: Tue Jul 30 18:47:44 from @value{RANDOMHOST}.@value{SECONDDOMAIN}
-Athena Server (sun4) Version 9.1.11 Tue Jul 30 14:40:08 EDT 2002
-
-shell%}
-@end group
-@end smallexample
-
-@noindent Note that @code{@value{RANDOMUSER1}}'s machine used Kerberos
-to authenticate her to @code{@value{RANDOMHOST2}.@value{PRIMARYDOMAIN}},
-and logged her in automatically as herself.  She had an encrypted
-session, a copy of her tickets already waiting for her, and she never
-typed her password.
-
-If you forwarded your Kerberos tickets, @code{telnet} automatically
-destroys them when it exits.  The full set of options to @value{PRODUCT}
-@code{telnet} are discussed in the Reference section of this manual.
-(@pxref{telnet Reference})
-
-@need 2000
-@node rlogin, FTP, telnet, Kerberos V5 Applications
-@subsection rlogin
-
-@need 1000
-The @value{PRODUCT} @code{rlogin} command works exactly like the
-standard UNIX rlogin program, with the following Kerberos options added:
-
-@table @kbd
-@itemx -f
-forwards a copy of your tickets to the remote host.
-
-@itemx -F
-forwards a copy of your tickets to the remote host, and marks them
-re-forwardable from the remote host.
-
-@itemx -k @i{realm}
-requests tickets for the remote host in the specified realm, instead of
-determining the realm itself.
-
-@itemx -x
-encrypts the input and output data streams (the username is sent unencrypted)
-
-@end table
-
-@need 3000
-For example, if @code{@value{RANDOMUSER2}} wanted to use the standard
-UNIX rlogin to connect to the machine
-@code{@value{RANDOMHOST1}.@value{SECONDDOMAIN}}, he would type:
-
-@smallexample
-@group
-@b{shell%} rlogin @value{RANDOMHOST1}.@value{SECONDDOMAIN} -l @value{RANDOMUSER2}
-@b{Password:}  @i{<- @value{RANDOMUSER2} types his password here}
-@b{Last login: Fri Jun 21 10:36:32 from :0.0
-Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
-        The Regents of the University of California.   All rights reserved.
-
-NetBSD 1.1: Tue May 21 00:31:42 EDT 1996
-
-Welcome to NetBSD!
-shell%}
-@end group
-@end smallexample
-
-@noindent Note that the machine
-@code{@value{RANDOMHOST1}.@value{SECONDDOMAIN}} asked for
-@code{@value{RANDOMUSER2}}'s password.  When he typed it, his password
-was sent over the network unencrypted.  If an intruder were watching
-network traffic at the time, that intruder would know
-@code{@value{RANDOMUSER2}}'s password.
-
-@need 4000
-If, on the other hand, @code{@value{RANDOMUSER1}} wanted to use
-@value{PRODUCT} rlogin to connect to the machine
-@code{@value{RANDOMHOST2}.@value{PRIMARYDOMAIN}}, she could forward a
-copy of her tickets, mark them as not forwardable from the remote host,
-and request an encrypted session as follows:
-
-@smallexample
-@group
-@b{shell%} rlogin @value{RANDOMHOST2}.@value{PRIMARYDOMAIN} -f -x
-@b{This rlogin session is using DES encryption for all data transmissions.
-Last login: Thu Jun 20 16:20:50 from @value{RANDOMHOST1}
-Athena Server (sun4) Version 9.1.11 Tue Jul 30 14:40:08 EDT 2002
-shell%}
-@end group
-@end smallexample
-
-@noindent Note that @code{@value{RANDOMUSER1}}'s machine used Kerberos
-to authenticate her to @code{@value{RANDOMHOST2}.@value{PRIMARYDOMAIN}},
-and logged her in automatically as herself.  She had an encrypted
-session, a copy of her tickets were waiting for her, and she never typed
-her password.
-
-If you forwarded your Kerberos tickets, @code{rlogin} automatically
-destroys them when it exits.  The full set of options to @value{PRODUCT}
-@code{rlogin} are discussed in the Reference section of this manual.
-(@pxref{rlogin Reference})
-
-@node FTP, rsh, rlogin, Kerberos V5 Applications
-@subsection FTP
-
-@need 1000
-The @value{PRODUCT} @code{FTP} program works exactly like the standard
-UNIX FTP program, with the following Kerberos features added:
-
-@table @kbd
-@itemx -k @i{realm}
-requests tickets for the remote host in the specified realm, instead of
-determining the realm itself.
-
-@itemx -f
-requests that your tickets be forwarded to the remote host.  The
-@kbd{-f} argument must be the last argument on the command line.
-
-@itemx protect @i{level}
-(issued at the @code{ftp>} prompt) sets the protection level.  ``Clear''
-is no protection; ``safe'' ensures data integrity by verifying the
-checksum, and ``private'' encrypts the data.  Encryption also ensures
-data integrity.
-@end table
-
-@need 5000
-For example, suppose @code{@value{RANDOMUSER1}} wants to get her
-@code{RMAIL} file from the directory @code{~@value{RANDOMUSER1}/Mail},
-on the host @code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}}.  She wants
-to encrypt the file transfer.  The exchange would look like the
-following:
-
-@smallexample
-@group
-@b{shell%} ftp @value{RANDOMHOST1}.@value{PRIMARYDOMAIN}
-Connected to @value{RANDOMHOST1}.@value{PRIMARYDOMAIN}.
-220 @value{RANDOMHOST1}.@value{PRIMARYDOMAIN} FTP server (Version 5.60) ready.
-334 Using authentication type GSSAPI; ADAT must follow
-GSSAPI accepted as authentication type
-GSSAPI authentication succeeded
-200 Data channel protection level set to private.
-Name (@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}:@value{RANDOMUSER1}): 
-232 GSSAPI user @value{RANDOMUSER1}@@@value{PRIMARYREALM} is authorized as @value{RANDOMUSER1}
-230 User @value{RANDOMUSER1} logged in.
-Remote system type is UNIX.
-Using binary mode to transfer files.
-ftp> protect private
-200 Protection level set to Private.
-ftp> cd ~@value{RANDOMUSER1}/MAIL
-250 CWD command successful.
-ftp> get RMAIL
-227 Entering Passive Mode (128,0,0,5,16,49)
-150 Opening BINARY mode data connection for RMAIL (361662 bytes).
-226 Transfer complete.
-361662 bytes received in 2.5 seconds (1.4e+02 Kbytes/s)
-ftp> quit
-@b{shell%}
-@end group
-@end smallexample
-
-The full set of options to @value{PRODUCT} @code{FTP} are discussed
-in the Reference section of this manual.  (@pxref{FTP Reference})
-
-@node rsh, rcp, FTP, Kerberos V5 Applications
-@subsection rsh
-
-The @value{PRODUCT} @code{rsh} program works exactly like the standard
-UNIX rlogin program, with the following Kerberos features added:
-
-@table @kbd
-@itemx -f
-forwards a copy of your tickets to the remote host.
-
-@itemx -F
-forwards a copy of your tickets to the remote host, and marks them
-re-forwardable from the remote host.
-
-@itemx -k @i{realm}
-requests tickets for the remote host in the specified realm, instead of
-determining the realm itself.
-
-@itemx -x
-encrypts the input and output data streams (the command line is not encrypted)
-
-@end table
-
-@need 1800
-For example, if your Kerberos tickets allowed you to run programs on the
-host @* @code{@value{RANDOMHOST2}@@@value{SECONDDOMAIN}} as root, you could
-run the @samp{date} program as follows:
-
-@smallexample
-@group
-@b{shell%} rsh @value{RANDOMHOST2}.@value{SECONDDOMAIN} -l root -x date
-@b{This rsh session is using DES encryption for all data transmissions.
-Tue Jul 30 19:34:21 EDT 2002
-shell%}
-@end group
-@end smallexample
-
-If you forwarded your Kerberos tickets, @code{rsh} automatically
-destroys them when it exits.  The full set of options to @value{PRODUCT}
-@code{rsh} are discussed in the Reference section of this manual.
-(@pxref{rsh Reference})
-
-@node rcp, ksu, rsh, Kerberos V5 Applications
-@subsection rcp
-
-@need 1000
-The @value{PRODUCT} @code{rcp} program works exactly like the standard
-UNIX rcp program, with the following Kerberos features added:
-
-@table @kbd
-@itemx -k @i{realm}
-requests tickets for the remote host in the specified realm, instead of
-determining the realm itself.
-
-@itemx -x
-turns on encryption.
-@end table
-
-
-@need 1500
-For example, if you wanted to copy the file @code{/etc/motd} from the
-host @code{@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}} into the current
-directory, via an encrypted connection, you would simply type:
-
-@smallexample
-@b{shell%} rcp -x @value{RANDOMHOST1}.@value{PRIMARYDOMAIN}:/etc/motd .
-@end smallexample
-
-The @kbd{rcp} program negotiates authentication and encryption
-transparently.  The full set of options to @value{PRODUCT} @code{rcp}
-are discussed in the Reference section of this manual.  (@pxref{rcp
-Reference})
-
-@node ksu,  , rcp, Kerberos V5 Applications
-@subsection ksu
-
-The @value{PRODUCT} @code{ksu} program replaces the standard UNIX su
-program.  @code{ksu} first authenticates you to Kerberos.  Depending on
-the configuration of your system, @code{ksu} may ask for your Kerberos
-password if authentication fails.  @emph{Note that you should never type
-your password if you are remotely logged in using an unencrypted
-connection.}
-
-Once @code{ksu} has authenticated you, if your Kerberos principal
-appears in the target's @code{.k5login} file (@pxref{Granting Access to
-Your Account}) or in the target's @code{.k5users} file (see below), it
-switches your user ID to the target user ID.
-
-@need 2000
-For example, @code{@value{RANDOMUSER2}} has put
-@code{@value{RANDOMUSER1}}'s Kerberos principal in his @code{.k5login}
-file.  If @code{@value{RANDOMUSER1}} uses @code{ksu} to become
-@code{@value{RANDOMUSER2}}, the exchange would look like this.  (To
-differentiate between the two shells, @code{@value{RANDOMUSER1}}'s
-prompt is represented as @code{@value{RANDOMUSER1}%} and
-@code{@value{RANDOMUSER2}}'s prompt is represented as
-@code{@value{RANDOMUSER2}%}.)
-
-@smallexample
-@group
-@b{@value{RANDOMUSER1}%} ksu @value{RANDOMUSER2}
-@b{Account @value{RANDOMUSER2}: authorization for @value{RANDOMUSER1}@@@value{PRIMARYREALM} successful
-Changing uid to @value{RANDOMUSER2} (3382)
-@value{RANDOMUSER2}%}
-@end group
-@end smallexample
-
-@noindent
-Note that the new shell has a copy of @code{@value{RANDOMUSER1}}'s
-tickets.  The ticket filename contains @code{@value{RANDOMUSER2}}'s UID
-with @samp{.1} appended to it:
-
-@smallexample
-@group
-@b{@value{RANDOMUSER2}%} klist
-@b{Ticket cache: /tmp/krb5cc_3382.1
-Default principal: @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-
-Valid starting      Expires             Service principal
-07/31/04 21:53:01  08/01/04 07:52:53  krbtgt/@value{PRIMARYREALM}@@@value{PRIMARYREALM}
-07/31/04 21:53:39  08/01/04 07:52:53  host/@value{RANDOMHOST1}.@value{PRIMARYDOMAIN}@@@value{PRIMARYREALM}
-@value{RANDOMUSER2}%}
-@end group
-@end smallexample
-
-@need 2500
-If @code{@value{RANDOMUSER1}} had not appeared in
-@code{@value{RANDOMUSER2}}'s @code{.k5login} file (and the system was
-configured to ask for a password), the exchange would have looked like
-this (assuming @code{@value{RANDOMUSER2}} has taken appropriate
-precautions in protecting his password):
-
-@smallexample
-@group
-@b{@value{RANDOMUSER1}%} ksu @value{RANDOMUSER2}
-@b{WARNING: Your password may be exposed if you enter it here and are logged 
-         in remotely using an unsecure (non-encrypted) channel. 
-Kerberos password for @value{RANDOMUSER2}@@@value{PRIMARYREALM}:}  @i{<-  @code{@value{RANDOMUSER1}} types the wrong password here.}
-@b{ksu: Password incorrect
-Authentication failed.
-@value{RANDOMUSER1}%}
-@end group
-@end smallexample
-
-Now, suppose @code{@value{RANDOMUSER2}} did not want to give
-@code{@value{RANDOMUSER1}} full access to his account, but wanted to
-give her permission to list his files and use the "more" command to view
-them.  He could create a @code{.k5users} file giving her permission to
-run only those specific commands.
-
-@need 3500
-The @code{.k5users} file is like the @code{.k5login} file, except that
-each principal is optionally followed by a list of commands.  @code{ksu}
-will let those principals execute only the commands listed, using the
-@kbd{-e} option.  @code{@value{RANDOMUSER2}}'s @code{.k5users} file
-might look like the following:
-
-@smallexample
-@group
-@value{RANDOMUSER1}@@@value{PRIMARYREALM}       /bin/ls /usr/bin/more
-@value{ADMINUSER}@@@value{PRIMARYREALM}         /bin/ls
-@value{ADMINUSER}/admin@@@value{PRIMARYREALM}   *
-@value{RANDOMUSER2}@@@value{SECONDREALM}
-@end group
-@end smallexample
-
-@noindent The above @code{.k5users} file would let
-@code{@value{RANDOMUSER1}} run only the commands @code{/bin/ls} and
-@code{/usr/bin/more}.  It would let @code{@value{ADMINUSER}} run only
-the command @code{/bin/ls} if he had regular tickets, but if he had
-tickets for his @code{admin} instance,
-@code{@value{ADMINUSER}/admin@@@value{PRIMARYREALM}}, he would be able
-to execute any command.  The last line gives @code{@value{RANDOMUSER2}}
-in the realm @value{SECONDREALM} permission to execute any command.
-(@i{I.e.}, having only a Kerberos principal on a line is equivalent to
-giving that principal permission to execute @code{*}.)  This is so that
-@value{RANDOMUSER2} can allow himself to execute commands when he logs
-in, using Kerberos, from a machine in the realm @value{SECONDREALM}.
-
-@need 2500
-Then, when @code{@value{RANDOMUSER1}} wanted to list his home directory,
-she would type:
-
-@smallexample
-@group
-@b{@value{RANDOMUSER1}%} ksu @value{RANDOMUSER2} -e ls ~@value{RANDOMUSER2}
-@b{Authenticated @value{RANDOMUSER1}@@@value{PRIMARYREALM}
-Account @value{RANDOMUSER2}: authorization for @value{RANDOMUSER1}@@@value{PRIMARYREALM} for execution of
-               /bin/ls successful
-Changing uid to @value{RANDOMUSER2} (3382)
-Mail            News            Personal        misc            bin
-@value{RANDOMUSER1}%}
-@end group
-@end smallexample
-
-@noindent If @code{@value{RANDOMUSER1}} had tried to give a different
-command to @code{ksu}, it would have prompted for a password as with the
-previous example.
-
-Note that unless the @code{.k5users} file gives the target permission to
-run any command, the user must use @code{ksu} with the @kbd{-e}
-@i{command} option.
-
-@need 1000
-The @code{ksu} options you are most likely to use are:
-
-@table @kbd
-@itemx -n @i{principal}
-specifies which Kerberos principal you want to use for @code{ksu}.
-(@i{e.g.}, the user @code{@value{ADMINUSER}} might want to use his
-@code{admin} instance.  @xref{What is a Ticket?}.)
-
-@itemx -c
-specifies the location of your Kerberos credentials cache (ticket file).
-
-@itemx -k
-tells @code{ksu} not to destroy your Kerberos tickets when @code{ksu} is
-finished.
-
-@itemx -f
-requests forwardable tickets.  (@xref{Obtaining Tickets with kinit}.)  This
-is only applicable if @code{ksu} needs to obtain tickets.
-
-@itemx -l @i{lifetime}
-sets the ticket lifetime.  (@xref{Obtaining Tickets with kinit}.)  This is
-only applicable if @code{ksu} needs to obtain tickets.
-
-@itemx -z
-tells @code{ksu} to copy your Kerberos tickets only if the UID you are
-switching is the same as the Kerberos primary (either yours or the one
-specified by the @kbd{-n} option).
-
-@itemx -Z
-tells @code{ksu} not to copy any Kerberos tickets to the new UID.
-
-@itemx -e @i{command}
-tells @code{ksu} to execute @i{command} and then exit.  See the
-description of the @code{.k5users} file above.
-
-@itemx -a @i{text}
-(at the end of the command line) tells @code{ksu} to pass everything
-after @samp{-a} to the target shell.
-@end table
-
-The full set of options to @value{PRODUCT} @code{ksu} are discussed
-in the Reference section of this manual.  (@pxref{ksu Reference})
-
-@node Kerberos V5 Reference, Kerberos Glossary, Kerberos V5 Tutorial, Top
-@chapter Kerberos V5 Reference
-
-This section will include copies of the manual pages for the
-@value{PRODUCT} client programs.  You can read the manual entry for any
-command by typing @code{man} @i{command}, where @i{command} is the name
-of the command for which you want to read the manual entry.  For
-example, to read the @code{kinit} manual entry, you would type:
-
-@smallexample
-@b{shell%} man kinit
-@end smallexample
-
-Note:  To be able to view the @value{PRODUCT} manual pages on line, you
-may need to add the directory @code{@value{ROOTDIR}/man} to your MANPATH
-environment variable.  (Remember to replace @code{@value{ROOTDIR}} with
-the top-level directory in which @value{PRODUCT} is installed.)  For
-example, if you had the the following line in your @code{.login}
-file@footnote{The MANPATH variable may be specified in a different
-initialization file, depending on your operating system.  Some of the
-files in which you might specify environment variables include
-@code{.login}, @code{.profile}, or @code{.cshrc}.}:
-
-@smallexample
-setenv MANPATH /usr/local/man:/usr/man
-@end smallexample
-
-@noindent
-and the @value{PRODUCT} man pages were in the directory
-@code{/usr/@value{LCPRODUCT}/man}, you would change the line to the following:
-
-@smallexample
-setenv MANPATH /usr/@value{LCPRODUCT}/man:/usr/local/man:/usr/man
-@end smallexample
-
-@ifinfo
-Note to info users:  the manual pages are not available within this info
-tree.  You can read them from emacs with the command:
-
-@smallexample
-M-x manual-entry @emph{command}
-@end smallexample
-@end ifinfo
-
-@page
-
-@menu
-* kinit Reference::             
-* klist Reference::             
-* ksu Reference::               
-* kdestroy Reference::          
-* kpasswd Reference::           
-* telnet Reference::            
-* FTP Reference::               
-* rlogin Reference::            
-* rsh Reference::               
-* rcp Reference::               
-@end menu
-
-@node kinit Reference, klist Reference, Kerberos V5 Reference, Kerberos V5 Reference
-@section kinit Reference
-
-@iftex
-@special{psfile=kinit1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{kinit}}
-@page
-
-@special{psfile=kinit2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{kinit}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry kinit} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="kinit.html"> kinit manpage</a>
-@end html
-@end ifhtml
-
-@node klist Reference, ksu Reference, kinit Reference, Kerberos V5 Reference
-@section klist Reference
-
-@iftex
-@special{psfile=klist1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{klist}}
-@page
-@end iftex
-
-@iftex
-@special{psfile=klist2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{klist}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry klist} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="klist.html"> klist manpage</a>
-@end html
-@end ifhtml
-
-@node ksu Reference, kdestroy Reference, klist Reference, Kerberos V5 Reference
-@section ksu Reference
-
-@iftex
-@special{psfile=ksu1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{ksu}}
-@page
-
-@special{psfile=ksu2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{ksu}}
-@page
-
-@special{psfile=ksu3.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{ksu}}
-@page
-
-@special{psfile=ksu4.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{ksu}}
-@page
-
-@special{psfile=ksu5.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{ksu}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry ksu} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="ksu.html"> ksu manpage</a>
-@end html
-@end ifhtml
-
-@node kdestroy Reference, kpasswd Reference, ksu Reference, Kerberos V5 Reference
-@section kdestroy Reference
-
-@iftex
-@special{psfile=kdestroy1.ps voffset=-700 hoffset=-60}
-@centerline{Reference Manual for @code{kdestroy}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry kdestroy} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="kdestroy.html"> kdestroy manpage</a>
-@end html
-@end ifhtml
-
-@node kpasswd Reference, telnet Reference, kdestroy Reference, Kerberos V5 Reference
-@section kpasswd Reference
-
-@iftex
-@special{psfile=kpasswd1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{kpasswd}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry kpasswd} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="kpasswd.html"> kpasswd manpage</a>
-@end html
-@end ifhtml
-
-@node telnet Reference, FTP Reference, kpasswd Reference, Kerberos V5 Reference
-@section telnet Reference
-
-@iftex
-@special{psfile=telnet1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet3.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet4.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet5.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet6.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet7.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet8.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-
-@special{psfile=telnet9.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{telnet}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry telnet} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="telnet.html"> telnet manpage</a>
-@end html
-@end ifhtml
-
-@node FTP Reference, rlogin Reference, telnet Reference, Kerberos V5 Reference
-@section FTP Reference
-
-@iftex
-@special{psfile=ftp1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp3.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp4.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp5.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp6.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp7.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp8.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-
-@special{psfile=ftp9.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{FTP}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry FTP} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="ftp.html"> ftp manpage</a>
-@end html
-@end ifhtml
-
-@node rlogin Reference, rsh Reference, FTP Reference, Kerberos V5 Reference
-@section rlogin Reference
-
-@iftex
-@special{psfile=rlogin1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rlogin}}
-@page
-
-@special{psfile=rlogin2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rlogin}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry rlogin} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="rlogin.html"> rlogin manpage</a>
-@end html
-@end ifhtml
-
-@node rsh Reference, rcp Reference, rlogin Reference, Kerberos V5 Reference
-@section rsh Reference
-
-@iftex
-@special{psfile=rsh1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rsh}}
-@page
-
-@special{psfile=rsh2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rsh}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry rsh} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="rsh.html"> rsh manpage</a>
-@end html
-@end ifhtml
-
-@node rcp Reference, , rsh Reference, Kerberos V5 Reference
-@section rcp Reference
-
-@iftex
-@special{psfile=rcp1.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rcp}}
-@page
-@end iftex
-
-@iftex
-@special{psfile=rcp2.ps voffset=-700 hoffset=-40}
-@centerline{Reference Manual for @code{rcp}}
-@page
-@end iftex
-
-@ifinfo
-Type @kbd{M-x manual-entry rcp} to read this manual page.
-@end ifinfo
-
-@ifhtml
-@html
-<a href="rcp.html"> rcp manpage</a>
-@end html
-@end ifhtml
-
-@node Kerberos Glossary,  , Kerberos V5 Reference, Top
-@appendix Kerberos Glossary
-
-@include glossary.texinfo
-
-@contents
-@bye
diff --git a/src/ChangeLog b/src/ChangeLog
index 1c8eeea11..ff98aee5f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,61 @@
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* Makefile.in (KRBHDEP): Add krb524_err header.
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* aclocal.m4 (WITH_KRB4): Don't set or substitute KRB524_DEPLIB,
+	KRB524_LIB, KRB524_H_DEP, or KRB524_ERR_H_DEP.
+	* Makefile.in (ETOUT): Update location of krb524_err files.
+	(krb524/krb524_err.h, krb524/krb524_err.c): Delete.
+	($(INC)krb524_err.h, $(ET)krb524_err.c): New targets.
+
+2003-05-22  Tom Yu  <tlyu@mit.edu>
+
+	* aclocal.m4: Add -DKRB5_DEPRECATED=1 so stuff in tree builds.
+
+2003-04-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* aclocal.m4: Require autoconf 2.52 only.
+
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* aclocal.m4: Require autoconf 2.53.
+	(CONFIG_RULES): Always set AUTOCONFINCFLAGS to --include.
+
+2003-04-10  Tom Yu  <tlyu@mit.edu>
+
+	* aclocal.m4: Revert requrement of autoconf-2.53, since MacOS X
+	doesn't have it.
+
+2003-04-01  Tom Yu  <tlyu@mit.edu>
+
+	* aclocal.m4 (KRB5_AC_CHOOSE_DB): Set new variable KDB5_DB_LIB to
+	empty if using in-tree db.  It is now used to pass -ldb to link
+	commands, if needed, when linking programs with libkdb5.  DB_LIB
+	is now only used for programs that explicitly need the actual
+	libdb independently of libkdb5.
+
+	* krb5-config.in: Use $KDB5_DB_LIB instead of "-ldb" for kdb
+	libraries.
+
+2003-03-31  Tom Yu  <tlyu@mit.edu>
+
+	* aclocal.m4: Require autoconf-2.53, since 2.52 generates
+	configure scripts that NetBSD /bin/sh doesn't like.
+
+2003-03-18  Alexandra Ellwood  <lxs@mit.edu>
+
+    * aclocal.m4: Define KRB5_AC_NEED_BIND_8_COMPAT to check for bind 9
+    and higher.  When bind 9 is present, BIND_8_COMPAT needs to be defined to
+    get bind 8 types.
+
+2003-03-12  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in (AWK): Default to awk, not gawk.  User can override
+	on make's command line if necessary.  Still, only really useful
+	for building kerbsrc.zip, etc.
+
 2003-03-05  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.in (WINMAKEFILES): Add lib\crypto\aes\Makefile.
diff --git a/src/Makefile.in b/src/Makefile.in
index d236af970..fa8983410 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -349,7 +349,7 @@ WINBINARYFILES=	windows/*/*.ico windows/*/*.doc windows/*/*.hlp \
 # Part of building the PC release has to be done on Unix. This includes
 # anything the requires awk.
 #
-AWK = gawk
+AWK = awk
 AH  = util/et/et_h.awk
 AC  = util/et/et_c.awk
 INC = include/
@@ -359,11 +359,11 @@ GK  = lib/gssapi/krb5/
 PR  = util/profile/
 
 ETOUT =	\
-	krb524\krb524_err.h krb524\krb524_err.c \
 	$(INC)asn1_err.h $(ET)asn1_err.c \
 	$(INC)kdb5_err.h $(ET)kdb5_err.c \
 	$(INC)krb5_err.h $(ET)krb5_err.c \
 	$(INC)kv5m_err.h $(ET)kv5m_err.c \
+	$(INC)krb524_err.h $(ET)krb524_err.c \
 	$(INC)/kerberosIV/kadm_err.h lib/krb4/kadm_err.c \
 	$(INC)/kerberosIV/krb_err.h lib/krb4/krb_err.c \
 	$(PR)prof_err.h $(PR)prof_err.c \
@@ -459,11 +459,6 @@ kerbsrc.mac.tar: awk-windows-mac macfile.list mac-bin-dirs Macfile
 	rm -rf bin
 	rm -f include/autoconf.h Makefile macsrc* macfile.maclist
 
-krb524/krb524_err.h: $(AH) krb524/krb524_err.et
-	$(AWK) -f $(AH) outfile=$@ krb524/krb524_err.et
-krb524/krb524_err.c: $(AC) krb524/krb524_err.et
-	$(AWK) -f $(AC) outfile=$@ krb524/krb524_err.et
-
 $(INC)asn1_err.h: $(AH) $(ET)asn1_err.et
 	$(AWK) -f $(AH) outfile=$@ $(ET)asn1_err.et
 $(INC)kdb5_err.h: $(AH) $(ET)kdb5_err.et
@@ -472,6 +467,8 @@ $(INC)krb5_err.h: $(AH) $(ET)krb5_err.et
 	$(AWK) -f $(AH) outfile=$@ $(ET)krb5_err.et
 $(INC)kv5m_err.h: $(AH) $(ET)kv5m_err.et
 	$(AWK) -f $(AH) outfile=$@ $(ET)kv5m_err.et
+$(INC)krb524_err.h: $(AH) $(ET)krb524_err.et
+	$(AWK) -f $(AH) outfile=$@ $(ET)krb524_err.et
 $(INC)/kerberosIV/kadm_err.h: $(AH) lib/krb4/kadm_err.et
 	$(AWK) -f $(AH) outfile=$@ lib/krb4/kadm_err.et
 $(INC)/kerberosIV/krb_err.h: $(AH) lib/krb4/krb_err.et
@@ -491,6 +488,8 @@ $(ET)krb5_err.c: $(AC) $(ET)krb5_err.et
 	$(AWK) -f $(AC) outfile=$@ $(ET)krb5_err.et
 $(ET)kv5m_err.c: $(AC) $(ET)kv5m_err.et
 	$(AWK) -f $(AC) outfile=$@ $(ET)kv5m_err.et
+$(ET)krb524_err.c: $(AC) $(ET)krb524_err.et
+	$(AWK) -f $(AC) outfile=$@ $(ET)krb524_err.et
 lib/krb4/kadm_err.c: $(AC) lib/krb4/kadm_err.et
 	$(AWK) -f $(AC) outfile=$@ lib/krb4/kadm_err.et
 lib/krb4/krb_err.c: $(AC) lib/krb4/krb_err.et
@@ -507,7 +506,7 @@ lib/krb4/krb_err_txt.c: lib/krb4/krb_err.et
 		lib/krb4/krb_err.et
 
 KRBHDEP = $(INC)krb5.hin $(INC)krb5_err.h $(INC)kdb5_err.h \
-	$(INC)kv5m_err.h $(INC)asn1_err.h
+	$(INC)kv5m_err.h $(INC)krb524_err.h $(INC)asn1_err.h
 
 $(INC)krb5.h: $(KRBHDEP)
 	rm -f $@
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 3a0895f71..142deee47 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -58,6 +58,7 @@ KRB5_AC_CHOOSE_SS dnl
 KRB5_AC_CHOOSE_DB dnl
 dnl allow stuff in tree to access deprecated/private stuff for now
 AC_DEFINE([KRB5_PRIVATE], 1, [Define only if building in-tree])
+AC_DEFINE([KRB5_DEPRECATED], 1, [Define only if building in-tree])
 AC_C_CONST dnl
 WITH_NETLIB dnl
 WITH_HESIOD dnl
@@ -79,9 +80,7 @@ dnl else
 	AUTOCONFFLAGS=
 	AUTOHEADER=autoheader
 	AUTOHEADERFLAGS=
-dnl Autoconf 2.54+ use --include, --localdir is obsolete and removed
-ifdef([AC_MSG_FAILURE],	AUTOCONFINCFLAGS="--include", dnl
-       AUTOCONFINCFLAGS="--localdir")
+	AUTOCONFINCFLAGS="--include"
 dnl fi
 AC_SUBST(AUTOCONF)
 AC_SUBST(AUTOCONFFLAGS)
@@ -394,11 +393,7 @@ if test $withval = no; then
 	KRB4_DEPLIB=
 	KRB4_INCLUDES=
 	KRB4_LIBPATH=
-	KRB524_DEPLIB=
-	KRB524_LIB=
 	KRB_ERR_H_DEP=
-	KRB524_H_DEP=
-	KRB524_ERR_H_DEP=
 	krb5_cv_build_krb4_libs=no
 	krb5_cv_krb4_libdir=
 else
@@ -409,11 +404,7 @@ else
 	KRB4_LIB=-lkrb4
 	KRB4_INCLUDES='-I$(SRCTOP)/include/kerberosIV -I$(BUILDTOP)/include/kerberosIV'
 	KRB4_LIBPATH=
-	KRB524_DEPLIB='$(BUILDTOP)/krb524/libkrb524.a'
-	KRB524_LIB='$(BUILDTOP)/krb524/libkrb524.a'
 	KRB_ERR_H_DEP='$(BUILDTOP)/include/kerberosIV/krb_err.h'
-	KRB524_H_DEP='$(BUILDTOP)/include/krb524.h'
-	KRB524_ERR_H_DEP='$(BUILDTOP)/include/krb524_err.h'
 	krb5_cv_build_krb4_libs=yes
 	krb5_cv_krb4_libdir=
  else
@@ -423,8 +414,6 @@ dnl	DEPKRB4_LIB="$withval/lib/libkrb.a"
 	KRB4_INCLUDES="-I$withval/include"
 	KRB4_LIBPATH="-L$withval/lib"
 	KRB_ERR_H_DEP=
-	KRB524_H_DEP=
-	KRB524_ERR_H_DEP=
 	krb5_cv_build_krb4_libs=no
 	krb5_cv_krb4_libdir="$withval/lib"
  fi
@@ -433,11 +422,7 @@ AC_SUBST(KRB4_INCLUDES)
 AC_SUBST(KRB4_LIBPATH)
 AC_SUBST(KRB4_LIB)
 AC_SUBST(KRB4_DEPLIB)
-AC_SUBST(KRB524_DEPLIB)
-AC_SUBST(KRB524_LIB)
 AC_SUBST(KRB_ERR_H_DEP)
-AC_SUBST(KRB524_H_DEP)
-AC_SUBST(KRB524_ERR_H_DEP)
 dnl We always compile the des425 library
 DES425_DEPLIB='$(TOPLIBD)/libdes425$(DEPLIBEXT)'
 DES425_LIB=-ldes425
@@ -1506,16 +1491,41 @@ if test "x$with_system_db" = xyes ; then
   else
     DB_HEADER_VERSION=redirect
   fi
+  KDB5_DB_LIB="$DB_LIB"
 else
   DB_VERSION=k5
   AC_DEFINE(HAVE_BT_RSEQ,1,[Define if bt_rseq is available, for recursive btree traversal.])
   DB_HEADER=db.h
   DB_HEADER_VERSION=k5
+  # libdb gets sucked into libkdb
+  KDB5_DB_LIB=
+  # needed for a couple of things that need libdb for its own sake
   DB_LIB=-ldb
 fi
 AC_SUBST(DB_VERSION)
 AC_SUBST(DB_HEADER)
 AC_SUBST(DB_HEADER_VERSION)
 AC_SUBST(DB_LIB)
+AC_SUBST(KDB5_DB_LIB)
+])
+dnl
+dnl
+dnl KRB5_AC_NEED_BIND_8_COMPAT --- check to see if we are on a bind 9 system
+dnl
+dnl
+AC_DEFUN(KRB5_AC_NEED_BIND_8_COMPAT,[
+AC_REQUIRE([AC_PROG_CC])dnl
+dnl
+dnl On a bind 9 system, we need to define BIND_8_COMPAT
+dnl
+AC_MSG_CHECKING(for bind 9 or higher)
+AC_CACHE_VAL(krb5_cv_need_bind_8_compat,[
+AC_TRY_COMPILE([#include <arpa/nameser.h>], [HEADER hdr;],
+krb5_cv_need_bind_8_compat=no, 
+[AC_TRY_COMPILE([#define BIND_8_COMPAT
+#include <arpa/nameser.h>], [HEADER hdr;],
+krb5_cv_need_bind_8_compat=yes, krb5_cv_need_bind_8_compat=no)])])
+AC_MSG_RESULT($krb5_cv_need_bind_8_compat)
+test $krb5_cv_need_bind_8_compat = yes && AC_DEFINE(BIND_8_COMPAT,1,[Define if OS has bind 9])
 ])
 dnl
diff --git a/src/appl/ChangeLog b/src/appl/ChangeLog
index 572f2b381..265179e78 100644
--- a/src/appl/ChangeLog
+++ b/src/appl/ChangeLog
@@ -1,3 +1,7 @@
+2004-02-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* configure.in: Check for sys/time.h and time.h.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
 	* configure.in: Use V5_AC_OUTPUT_MAKEFILE instead of
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index 303400170..d072fa7f1 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -1,3 +1,32 @@
+2003-08-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* krshd.c (ignore_signals): Split out from cleanup().
+	(doit): Call it when the shell process has completed, before
+	calling syslog.
+
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* configure.in: Don't use libkrb524.a any more.
+	* login.c: Don't include krb524.h.
+	(try_convert524): Don't call krb524_init_ets.
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* krcp.c (main): Rename getlocalsubkey -> getsendsubkey.
+
+	* krlogin.c (main): Rename getlocalsubkey -> getsendsubkey.
+
+	* krlogind.c (recvauth): Rename getremotesubkey -> getrecvsubkey.
+
+	* krsh.c (main): Rename getlocalsubkey -> getsendsubkey.
+
+	* krshd.c (recvauth): Rename getremotesubkey -> getrecvsubkey.
+
+2003-04-08  Ken Raeburn  <raeburn@mit.edu>
+
+	* krshd.c (main): Use LOG_AUTH syslog facility, not LOG_DAEMON,
+	for consistency with krlogind.c.
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* compat_recv.c: Only include krb.h if KRB5_KRB4_COMPAT.
diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in
index 0b08025c3..5abbaba5e 100644
--- a/src/appl/bsd/Makefile.in
+++ b/src/appl/bsd/Makefile.in
@@ -105,56 +105,60 @@ $(OUTPRE)krcp.$(OBJEXT): krcp.c $(BUILDTOP)/include/krb5.h \
   $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
   $(KRB_ERR_H_DEP) $(BUILDTOP)/include/profile.h defines.h \
   $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h
 $(OUTPRE)krlogin.$(OBJEXT): krlogin.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h rpaths.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  rpaths.h
 $(OUTPRE)krsh.$(OBJEXT): krsh.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h
 $(OUTPRE)kcmd.$(OBJEXT): kcmd.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h
 $(OUTPRE)forward.$(OBJEXT): forward.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h defines.h $(SRCTOP)/include/fake-addrinfo.h
+  defines.h $(SRCTOP)/include/fake-addrinfo.h
 $(OUTPRE)compat_recv.$(OBJEXT): compat_recv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  defines.h $(SRCTOP)/include/fake-addrinfo.h
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP) defines.h $(SRCTOP)/include/fake-addrinfo.h
 $(OUTPRE)login.$(OBJEXT): login.c $(BUILDTOP)/include/libpty.h \
   $(SRCTOP)/include/syslog.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(KRB524_H_DEP) $(KRB524_ERR_H_DEP) loginpaths.h
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP) loginpaths.h
 $(OUTPRE)krshd.$(OBJEXT): krshd.c $(BUILDTOP)/include/libpty.h \
   $(SRCTOP)/include/syslog.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) loginpaths.h $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
   $(BUILDTOP)/include/krb5/autoconf.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/k5-platform.h
 $(OUTPRE)krlogind.$(OBJEXT): krlogind.c $(SRCTOP)/include/syslog.h \
   $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/port-sockets.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/libpty.h \
   $(SRCTOP)/include/k5-util.h defines.h
diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in
index 8f4a16bd6..7bfc68e3b 100644
--- a/src/appl/bsd/configure.in
+++ b/src/appl/bsd/configure.in
@@ -62,8 +62,7 @@ if test $withval = no; then
 	V4RCP=
 	V4RCPO=
 else 
-	AC_MSG_RESULT(Adding in krb4 support)
-	LOGINLIBS="../../krb524/libkrb524.a $LOGINLIBS"
+	AC_MSG_RESULT(Adding in krb4 rcp support)
 	V4RCP=v4rcp
 	V4RCPO=v4rcp.o
 fi
diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c
index 5ad6a25a1..707985a5a 100644
--- a/src/appl/bsd/krcp.c
+++ b/src/appl/bsd/krcp.c
@@ -480,9 +480,9 @@ int main(argc, argv)
 			    try_normal(orig_argv); /* doesn't return */
 
 			if (!similar) {
-			    status = krb5_auth_con_getlocalsubkey (bsd_context,
-								   auth_context,
-								   &key);
+			    status = krb5_auth_con_getsendsubkey (bsd_context,
+								  auth_context,
+								  &key);
 			    if ((status || !key) && encryptflag)
 				try_normal(orig_argv);
 			}
@@ -599,9 +599,9 @@ int main(argc, argv)
 		    krb5_keyblock *key = &cred->keyblock;
 
 		    if (kcmd_proto == KCMD_NEW_PROTOCOL) {
-			status = krb5_auth_con_getlocalsubkey (bsd_context,
-							       auth_context,
-							       &key);
+			status = krb5_auth_con_getsendsubkey (bsd_context,
+							      auth_context,
+							      &key);
 			if (status) {
 			    com_err (argv[0], status,
 				     "determining subkey for session");
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
index c497dc2fb..a1e63a645 100644
--- a/src/appl/bsd/krlogin.c
+++ b/src/appl/bsd/krlogin.c
@@ -702,8 +702,8 @@ main(argc, argv)
 	if (kcmd_proto == KCMD_NEW_PROTOCOL) {
 	    do_inband = 1;
 
-	    status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context,
-						   &key);
+	    status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
+						  &key);
 	    if ((status || !key) && encrypt_flag)
 		try_normal(orig_argv);
 	}
diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c
index 82e560143..d2979e141 100644
--- a/src/appl/bsd/krlogind.c
+++ b/src/appl/bsd/krlogind.c
@@ -1537,7 +1537,7 @@ recvauth(valid_checksum)
 	return status;
 
     key = 0;
-    status = krb5_auth_con_getremotesubkey (bsd_context, auth_context, &key);
+    status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context, &key);
     if (status)
 	fatal (netf, "Server can't get session subkey");
     if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c
index 3f8273ec0..bd9c20572 100644
--- a/src/appl/bsd/krsh.c
+++ b/src/appl/bsd/krsh.c
@@ -411,8 +411,8 @@ main(argc, argv0)
 	krb5_keyblock *key = &cred->keyblock;
 
 	if (kcmd_proto == KCMD_NEW_PROTOCOL) {
-	    status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context,
-						   &key);
+	    status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
+						  &key);
 	    if (status) {
 		com_err (argv[0], status, "determining subkey for session");
 		exit (1);
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
index 2a67b7613..9fde43d6e 100644
--- a/src/appl/bsd/krshd.c
+++ b/src/appl/bsd/krshd.c
@@ -303,10 +303,10 @@ int main(argc, argv)
 #ifndef LOG_ODELAY /* 4.2 syslog */
     openlog(progname, LOG_PID);
 #else
-#ifndef LOG_DAEMON
-#define LOG_DAEMON 0
+#ifndef LOG_AUTH
+#define LOG_AUTH 0
 #endif
-    openlog(progname, LOG_PID | LOG_ODELAY, LOG_DAEMON);	
+    openlog(progname, LOG_PID | LOG_ODELAY, LOG_AUTH);
 #endif /* 4.2 syslog */
     
 #ifdef KERBEROS
@@ -535,9 +535,8 @@ int auth_sys = 0;	/* Which version of Kerberos used to authenticate */
 #define KRB5_RECVAUTH_V4	4
 #define KRB5_RECVAUTH_V5	5
 
-static krb5_sigtype
-cleanup(signumber)
-     int signumber;
+static void
+ignore_signals()
 {
 #ifdef POSIX_SIGNALS
     struct sigaction sa;
@@ -561,6 +560,13 @@ cleanup(signumber)
     
     killpg(pid, SIGTERM);
 #endif
+}
+
+static krb5_sigtype
+cleanup(signumber)
+     int signumber;
+{
+    ignore_signals();
     wait(0);
     
     pty_logwtmp(ttyn,"","");
@@ -1302,13 +1308,14 @@ void doit(f, fromp)
 			} else if (wcc != cc) {
 			  syslog(LOG_INFO, "only wrote %d/%d to child", 
 				 wcc, cc);
-		}
-		}
+			}
+		    }
 		}
 	    } while ((port&&FD_ISSET(s, &readfrom)) ||
 		     FD_ISSET(f, &readfrom) ||
 		     (port&&FD_ISSET(pv[0], &readfrom) )||
 		     FD_ISSET(pw[0], &readfrom));
+	    ignore_signals();
 #ifdef KERBEROS
 	    syslog(LOG_INFO ,
 		   "Shell process completed.");
@@ -1962,8 +1969,8 @@ recvauth(netfd, peersin, valid_checksum)
 
     {
 	krb5_keyblock *key;
-	status = krb5_auth_con_getremotesubkey (bsd_context, auth_context,
-						&key);
+	status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context,
+					      &key);
 	if (status)
 	    fatal (netfd, "Server can't get session subkey");
 	if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c
index 5b5603793..8259046d6 100644
--- a/src/appl/bsd/login.c
+++ b/src/appl/bsd/login.c
@@ -181,10 +181,6 @@ typedef sigtype (*handler)();
 #include <arpa/resolv.h>
 #endif /* BIND_HACK */
 
-#ifdef KRB4_CONVERT
-#include <krb524.h>
-#endif
-
 /* Hacks to maintain compatability with Athena libkrb*/
 #ifndef HAVE_KRB_SAVE_CREDENTIALS
 #define krb_save_credentials save_credentials
@@ -654,9 +650,6 @@ try_convert524(kctx, me, use_ccache)
     CREDENTIALS v4creds;
 
 
-    /* or do this directly with krb524_convert_creds_kdc */
-    krb524_init_ets(kctx);
-
     /* If we have forwarded v5 tickets, retrieve the credentials from
      * the cache; otherwise, the v5 credentials are in my_creds.
      */
diff --git a/src/appl/configure.in b/src/appl/configure.in
index ab7559f5e..abee28d48 100644
--- a/src/appl/configure.in
+++ b/src/appl/configure.in
@@ -3,6 +3,8 @@ CONFIG_RULES
 AC_PROG_INSTALL
 AC_CHECK_HEADERS(unistd.h stdlib.h string.h)
 AC_C_CONST
+dnl gss-misc.c needs this:
+AC_CHECK_HEADERS(sys/time.h time.h)
 dnl
 dnl Kludge for simple server --- FIXME is this the best way to do this?
 dnl
diff --git a/src/appl/gss-sample/ChangeLog b/src/appl/gss-sample/ChangeLog
index 50b003c04..fae968432 100644
--- a/src/appl/gss-sample/ChangeLog
+++ b/src/appl/gss-sample/ChangeLog
@@ -1,8 +1,35 @@
+2004-02-10  Jeffrey Altman <jaltman@mit.edu>
+
+    * gss-client.c: Remove extraneous parameters from 
+      client_establish_context()
+
+2004-02-06  Jeffrey Altman <jaltman@mit.edu>
+
+    * Update usage() for gss-client
+
+2004-02-06  Jeffrey Altman <jaltman@mit.edu>
+
+    * Add new command line switches to the gss-client
+      to support the use of GSS_C_SEQUENCE_FLAG or to 
+      disable the use of either GSS_C_MUTUAL_FLAG or 
+      GSS_C_REPLAY_FLAG
+
+2004-01-31  Ken Raeburn  <raeburn@mit.edu>
+
+	* gss-misc.c: Include sys/time.h or time.h, to get struct timeval
+	declaration.
+
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+    * gss-misc.c (read_all): Add call to select() so we don't block forever
+
+    * gss-server.c (main): Add missing "export" parameter to second sign_server()
+
 2003-01-08  Sam Hartman  <hartmans@mit.edu>
 
 	* gss-misc.c (recv_token): Support reading 0 token flags as part of length
 
-	* gss-client.c :  Support a -v1 argument meaning that no token flags are used o,
+	* gss-client.c :  Support a -v1 argument meaning that no token flags are used,
 
 	* gss-misc.c (send_token): If token flags are null, do not send them.
 
diff --git a/src/appl/gss-sample/README b/src/appl/gss-sample/README
index 8fc7cfee4..dc51fca1b 100644
--- a/src/appl/gss-sample/README
+++ b/src/appl/gss-sample/README
@@ -84,7 +84,8 @@ is used).  The command-line options have the following meanings:
 The client's command line usage is
 
 	gss-client [-port port] [-mech mechanism] [-d] [-f] [-q]
-		[-ccount count] [-mcount count] [-na] [-nw] [-nx] [-nm]
+        [-seq] [-noreplay] [-nomutual]		
+        [-ccount count] [-mcount count] [-na] [-nw] [-nx] [-nm]
 		host service_name msg
 
 where host is the host running the server, service_name is the service
@@ -105,6 +106,14 @@ the following meanings:
 	credential cache (you must have acquired your tickets with
 	"kinit -f" for this to work).
 
+-seq Tells the client to enforce ordered message delivery via
+    sequencing.  
+
+-noreplay Tells the client to disable the use of replay
+    detection.
+
+-nomutual Tells the client to disable the use of mutual authentication.
+
 -f	Tells the client that the "msg" argument is actually the name
 	of a file whose contents should be used as the message.
 
diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c
index a66c0c9fe..93b5eb35e 100644
--- a/src/appl/gss-sample/gss-client.c
+++ b/src/appl/gss-sample/gss-client.c
@@ -19,6 +19,29 @@
  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
+/*
+ * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -46,6 +69,7 @@ static int verbose = 1;
 static void usage()
 {
      fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n");
+     fprintf(stderr, "       [-seq] [-noreplay] [-nomutual]\n");
      fprintf(stderr, "       [-f] [-q] [-ccount count] [-mcount count]\n");
      fprintf(stderr, "       [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n");
      exit(1);
@@ -106,11 +130,12 @@ static int connect_to_server(host, port)
  *
  * Arguments:
  *
- * 	s		(r) an established TCP connection to the service
- * 	service_name	(r) the ASCII service name of the service
- *	deleg_flag	(r) GSS-API delegation flag (if any)
+ * 	s		    (r) an established TCP connection to the service
+ * 	service_name(r) the ASCII service name of the service
+ *	gss_flags	(r) GSS-API delegation flag (if any)
  *	auth_flag	(r) whether to actually do authentication
- *	oid		(r) OID of the mechanism to use
+ *  v1_format   (r) whether the v1 sample protocol should be used
+ *	oid		    (r) OID of the mechanism to use
  * 	context		(w) the established GSS-API context
  *	ret_flags	(w) the returned flags from init_sec_context
  *
@@ -128,12 +153,12 @@ static int connect_to_server(host, port)
  * unsuccessful, the GSS-API error messages are displayed on stderr
  * and -1 is returned.
  */
-static int client_establish_context(s, service_name, deleg_flag, auth_flag,
+static int client_establish_context(s, service_name, gss_flags, auth_flag,
 				    v1_format, oid, gss_context, ret_flags)
      int s;
      char *service_name;
      gss_OID oid;
-     OM_uint32 deleg_flag;
+     OM_uint32 gss_flags;
      int auth_flag;
      int v1_format;
      gss_ctx_id_t *gss_context;
@@ -191,8 +216,7 @@ static int client_establish_context(s, service_name, deleg_flag, auth_flag,
 				gss_context,
 				target_name,
 				oid,
-				GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
-				deleg_flag,
+				gss_flags,
 				0,
 				NULL,	/* no channel bindings */
 				token_ptr,
@@ -301,7 +325,7 @@ static void read_file(file_name, in_buf)
  * 	host		(r) the host providing the service
  * 	port		(r) the port to connect to on host
  * 	service_name	(r) the GSS-API service name to authenticate to
- *	deleg_flag	(r) GSS-API delegation flag (if any)
+ *	gss_flags	(r) GSS-API delegation flag (if any)
  *	auth_flag	(r) whether to do authentication
  *	wrap_flag	(r) whether to do message wrapping at all
  *	encrypt_flag	(r) whether to do encryption while wrapping
@@ -320,14 +344,14 @@ static void read_file(file_name, in_buf)
  * reads back a GSS-API signature block for msg from the server, and
  * verifies it with gss_verify.  -1 is returned if any step fails,
  * otherwise 0 is returned.  */
-static int call_server(host, port, oid, service_name, deleg_flag, auth_flag,
+static int call_server(host, port, oid, service_name, gss_flags, auth_flag,
 		       wrap_flag, encrypt_flag, mic_flag, v1_format, msg, use_file,
 		       mcount)
      char *host;
      u_short port;
      gss_OID oid;
      char *service_name;
-     OM_uint32 deleg_flag;
+     OM_uint32 gss_flags;
      int auth_flag, wrap_flag, encrypt_flag, mic_flag;
      int v1_format;
      char *msg;
@@ -357,7 +381,7 @@ static int call_server(host, port, oid, service_name, deleg_flag, auth_flag,
 	  return -1;
 
      /* Establish context */
-     if (client_establish_context(s, service_name, deleg_flag, auth_flag,
+     if (client_establish_context(s, service_name, gss_flags, auth_flag,
 				  v1_format, oid, &context,
 				  &ret_flags) < 0) {
 	  (void) close(s);
@@ -581,7 +605,8 @@ int main(argc, argv)
      char *mechanism = 0;
      u_short port = 4444;
      int use_file = 0;
-     OM_uint32 deleg_flag = 0, min_stat;
+     OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+     OM_uint32 min_stat;
      gss_OID oid = GSS_C_NULL_OID;
      int mcount = 1, ccount = 1;
      int i;
@@ -603,7 +628,13 @@ int main(argc, argv)
 	       if (!argc) usage();
 	       mechanism = *argv;
 	   } else if (strcmp(*argv, "-d") == 0) {
-	       deleg_flag = GSS_C_DELEG_FLAG;
+	       gss_flags |= GSS_C_DELEG_FLAG;
+	   } else if (strcmp(*argv, "-seq") == 0) {
+	       gss_flags |= GSS_C_SEQUENCE_FLAG;
+	   } else if (strcmp(*argv, "-noreplay") == 0) {
+	       gss_flags &= ~GSS_C_REPLAY_FLAG;
+	   } else if (strcmp(*argv, "-nomutual") == 0) {
+	       gss_flags &= ~GSS_C_MUTUAL_FLAG;
 	  } else if (strcmp(*argv, "-f") == 0) {
 	       use_file = 1;
 	  } else if (strcmp(*argv, "-q") == 0) {
@@ -644,7 +675,7 @@ int main(argc, argv)
 
      for (i = 0; i < ccount; i++) {
        if (call_server(server_host, port, oid, service_name,
-		       deleg_flag, auth_flag, wrap_flag, encrypt_flag, mic_flag,
+		       gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag,
 		       v1_format, 		       msg, use_file, mcount) < 0)
 	 exit(1);
      }
diff --git a/src/appl/gss-sample/gss-misc.c b/src/appl/gss-sample/gss-misc.c
index 183306c29..1347a547b 100644
--- a/src/appl/gss-sample/gss-misc.c
+++ b/src/appl/gss-sample/gss-misc.c
@@ -19,6 +19,29 @@
  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
+/*
+ * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 
 #if !defined(lint) && !defined(__CODECENTER__)
 static char *rcsid = "$Header$";
@@ -39,6 +62,13 @@ static char *rcsid = "$Header$";
 #endif
 #include <string.h>
 
+/* need struct timeval */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
 #include <gssapi/gssapi_generic.h>
 #include "gss-misc.h"
 
@@ -77,21 +107,31 @@ static int write_all(int fildes, char *buf, unsigned int nbyte)
 
 static int read_all(int fildes, char *buf, unsigned int nbyte)
 {
-     int ret;
-     char *ptr;
+    int ret;
+    char *ptr;
+    fd_set rfds;
+    struct timeval tv;
 
-     for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
-	  ret = recv(fildes, ptr, nbyte, 0);
-	  if (ret < 0) {
-	       if (errno == EINTR)
-		    continue;
-	       return(ret);
-	  } else if (ret == 0) {
-	       return(ptr-buf);
-	  }
-     }
+    FD_ZERO(&rfds);
+    FD_SET(fildes, &rfds);
+    tv.tv_sec = 10;
+    tv.tv_usec = 0;
 
-     return(ptr-buf);
+    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
+	if (select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0
+	    || !FD_ISSET(fildes, &rfds))
+	    return(ptr-buf);
+	ret = recv(fildes, ptr, nbyte, 0);
+	if (ret < 0) {
+	    if (errno == EINTR)
+		continue;
+	    return(ret);
+	} else if (ret == 0) {
+	    return(ptr-buf);
+	}
+    }
+
+    return(ptr-buf);
 }
 
 /*
diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c
index b3229f1be..e5adc618b 100644
--- a/src/appl/gss-sample/gss-server.c
+++ b/src/appl/gss-sample/gss-server.c
@@ -19,6 +19,29 @@
  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
+/*
+ * Copyright (C) 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 
 #include <stdio.h>
 #ifdef _WIN32
@@ -388,147 +411,147 @@ static int sign_server(s, server_creds, export)
      gss_cred_id_t server_creds;
      int export;
 {
-     gss_buffer_desc client_name, xmit_buf, msg_buf;
-     gss_ctx_id_t context;
-     OM_uint32 maj_stat, min_stat;
-     int i, conf_state, ret_flags;
-     char	*cp;
-     int token_flags;
-
-     /* Establish a context with the client */
-     if (server_establish_context(s, server_creds, &context,
-				  &client_name, &ret_flags) < 0)
-	return(-1);
-
-     if (context == GSS_C_NO_CONTEXT) {
-       printf("Accepted unauthenticated connection.\n");
-     }
-     else {
-       printf("Accepted connection: \"%.*s\"\n",
-	      (int) client_name.length, (char *) client_name.value);
-       (void) gss_release_buffer(&min_stat, &client_name);
-
-       if (export) {
-	 for (i=0; i < 3; i++)
-	   if (test_import_export_context(&context))
-	     return -1;
-       }
-     }
-
-     do {
-       /* Receive the message token */
-       if (recv_token(s, &token_flags, &xmit_buf) < 0)
-	 return(-1);
-
-       if (token_flags & TOKEN_NOOP) {
-	 if (log)
-	   fprintf(log, "NOOP token\n");
-	 if(xmit_buf.value) {
-	     free(xmit_buf.value);
-	     xmit_buf.value = 0;
-	 }
-	 break;
-       }
-
-       if (verbose && log) {
-	 fprintf(log, "Message token (flags=%d):\n", token_flags);
-	 print_token(&xmit_buf);
-       }
-
-       if ((context == GSS_C_NO_CONTEXT) &&
-	   (token_flags & (TOKEN_WRAPPED|TOKEN_ENCRYPTED|TOKEN_SEND_MIC))) {
-	 if (log)
-	   fprintf(log,
-		   "Unauthenticated client requested authenticated services!\n");
-	 if(xmit_buf.value) {
-	     free (xmit_buf.value);
-	     xmit_buf.value = 0;
-	 }
-	 return(-1);
-       }
-
-       if (token_flags & TOKEN_WRAPPED) {
-	 maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf,
-			       &conf_state, (gss_qop_t *) NULL);
-	 if (maj_stat != GSS_S_COMPLETE) {
-	   display_status("unsealing message", maj_stat, min_stat);
-	   if(xmit_buf.value) {
-	       free (xmit_buf.value);
-	       xmit_buf.value = 0;
-	   }
-	   return(-1);
-	 } else if (! conf_state && (token_flags & TOKEN_ENCRYPTED)) {
-	   fprintf(stderr, "Warning!  Message not encrypted.\n");
-	 }
-
-	 if(xmit_buf.value) {
-	     free (xmit_buf.value);
-	     xmit_buf.value = 0;
-	 }
-       }
-       else {
-	 msg_buf = xmit_buf;
-       }
-
-       if (log) {
-	 fprintf(log, "Received message: ");
-	 cp = msg_buf.value;
-	 if ((isprint((int) cp[0]) || isspace((int) cp[0])) &&
-	    (isprint((int) cp[1]) || isspace((int) cp[1]))) {
-	   fprintf(log, "\"%.*s\"\n", (int) msg_buf.length, 
-		   (char *) msg_buf.value);
-	 } else {
-	   fprintf(log, "\n");
-	   print_token(&msg_buf);
-	 }
-       }
-
-       if (token_flags & TOKEN_SEND_MIC) {
-	 /* Produce a signature block for the message */
-	 maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT,
-				&msg_buf, &xmit_buf);
-	 if (maj_stat != GSS_S_COMPLETE) {
-	   display_status("signing message", maj_stat, min_stat);
-	   return(-1);
-	 }
-
-	 if(msg_buf.value) {
-	     free (msg_buf.value);
-	     msg_buf.value = 0;
-	 }
-
-	 /* Send the signature block to the client */
-	 if (send_token(s, TOKEN_MIC, &xmit_buf) < 0)
-	   return(-1);
-
-	 if(xmit_buf.value) {
-	     free (xmit_buf.value);
-	     xmit_buf.value = 0;
-	 }
-       }
-       else {
-	 if(msg_buf.value) {
-	     free (msg_buf.value);
-	     msg_buf.value = 0;
-	 }
-	 if (send_token(s, TOKEN_NOOP, empty_token) < 0)
-	   return(-1);
-       }
-     } while (1 /* loop will break if NOOP received */);
-
-     if (context != GSS_C_NO_CONTEXT) {
-       /* Delete context */
-       maj_stat = gss_delete_sec_context(&min_stat, &context, NULL);
-       if (maj_stat != GSS_S_COMPLETE) {
-	 display_status("deleting context", maj_stat, min_stat);
-	 return(-1);
-       }
-     }
-
-     if (log)
-       fflush(log);
-
-     return(0);
+    gss_buffer_desc client_name, xmit_buf, msg_buf;
+    gss_ctx_id_t context;
+    OM_uint32 maj_stat, min_stat;
+    int i, conf_state, ret_flags;
+    char	*cp;
+    int token_flags;
+
+    /* Establish a context with the client */
+    if (server_establish_context(s, server_creds, &context,
+                                  &client_name, &ret_flags) < 0)
+        return(-1);
+
+    if (context == GSS_C_NO_CONTEXT) {
+        printf("Accepted unauthenticated connection.\n");
+    }
+    else {
+        printf("Accepted connection: \"%.*s\"\n",
+                (int) client_name.length, (char *) client_name.value);
+        (void) gss_release_buffer(&min_stat, &client_name);
+
+        if (export) {
+            for (i=0; i < 3; i++)
+                if (test_import_export_context(&context))
+                    return -1;
+        }
+    }
+
+    do {
+        /* Receive the message token */
+        if (recv_token(s, &token_flags, &xmit_buf) < 0)
+            return(-1);
+
+        if (token_flags & TOKEN_NOOP) {
+            if (log)
+                fprintf(log, "NOOP token\n");
+            if(xmit_buf.value) {
+                free(xmit_buf.value);
+                xmit_buf.value = 0;
+            }
+            break;
+        }
+
+        if (verbose && log) {
+            fprintf(log, "Message token (flags=%d):\n", token_flags);
+            print_token(&xmit_buf);
+        }
+
+        if ((context == GSS_C_NO_CONTEXT) &&
+             (    token_flags & (TOKEN_WRAPPED|TOKEN_ENCRYPTED|TOKEN_SEND_MIC))) {
+            if (log)
+                fprintf(log,
+                         "Unauthenticated client requested authenticated services!\n");
+            if(xmit_buf.value) {
+                free (xmit_buf.value);
+                xmit_buf.value = 0;
+            }
+            return(-1);
+        }
+
+        if (token_flags & TOKEN_WRAPPED) {
+            maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf,
+                                   &conf_state, (gss_qop_t *) NULL);
+            if (maj_stat != GSS_S_COMPLETE) {
+                display_status("unsealing message", maj_stat, min_stat);
+                if(xmit_buf.value) {
+                    free (xmit_buf.value);
+                    xmit_buf.value = 0;
+                }
+                return(-1);
+            } else if (! conf_state && (token_flags & TOKEN_ENCRYPTED)) {
+                fprintf(stderr, "Warning!  Message not encrypted.\n");
+            }
+
+            if(xmit_buf.value) {
+                free (xmit_buf.value);
+                xmit_buf.value = 0;
+            }
+        }
+        else {
+            msg_buf = xmit_buf;
+        }
+
+        if (log) {
+            fprintf(log, "Received message: ");
+            cp = msg_buf.value;
+            if ((isprint((int) cp[0]) || isspace((int) cp[0])) &&
+                 (isprint((int) cp[1]) || isspace((int) cp[1]))) {
+                fprintf(log, "\"%.*s\"\n", (int) msg_buf.length, 
+                         (char *) msg_buf.value);
+                 } else {
+                     fprintf(log, "\n");
+                     print_token(&msg_buf);
+                 }
+        }
+
+        if (token_flags & TOKEN_SEND_MIC) {
+            /* Produce a signature block for the message */
+            maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT,
+                                    &msg_buf, &xmit_buf);
+            if (maj_stat != GSS_S_COMPLETE) {
+                display_status("signing message", maj_stat, min_stat);
+                return(-1);
+            }
+
+            if(msg_buf.value) {
+                free (msg_buf.value);
+                msg_buf.value = 0;
+            }
+
+            /* Send the signature block to the client */
+            if (send_token(s, TOKEN_MIC, &xmit_buf) < 0)
+                return(-1);
+
+            if(xmit_buf.value) {
+                free (xmit_buf.value);
+                xmit_buf.value = 0;
+            }
+        }
+        else {
+            if(msg_buf.value) {
+                free (msg_buf.value);
+                msg_buf.value = 0;
+            }
+            if (send_token(s, TOKEN_NOOP, empty_token) < 0)
+                return(-1);
+        }
+    } while (1 /* loop will break if NOOP received */);
+
+    if (context != GSS_C_NO_CONTEXT) {
+        /* Delete context */
+        maj_stat = gss_delete_sec_context(&min_stat, &context, NULL);
+        if (maj_stat != GSS_S_COMPLETE) {
+            display_status("deleting context", maj_stat, min_stat);
+            return(-1);
+        }
+    }
+
+    if (log)
+        fflush(log);
+
+    return(0);
 }
 
 int
@@ -612,7 +635,7 @@ main(argc, argv)
  		 }
  		 /* this return value is not checked, because there's
  		    not really anything to do if it fails */
- 		 sign_server(s, server_creds);
+ 		 sign_server(s, server_creds, export);
  		 close(s);
  	     } while (!once);
  
diff --git a/src/appl/gssftp/ChangeLog b/src/appl/gssftp/ChangeLog
index 9f184f73c..2a6a5fdb7 100644
--- a/src/appl/gssftp/ChangeLog
+++ b/src/appl/gssftp/ChangeLog
@@ -1,3 +1,13 @@
+2003-06-05  Sam Hartman  <hartmans@mit.edu>
+
+	* configure.in: Don't check for vfork as we no longer use it
+
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* configure.in: Don't use libkrb524.a any more.
+	* ftpd.c: Don't include krb524.h.
+	(main): Don't call krb524_init_ets.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
 	* configure.in: Use V5_AC_OUTPUT_MAKEFILE instead of
diff --git a/src/appl/gssftp/configure.in b/src/appl/gssftp/configure.in
index 35ca40eb0..bf6d3b832 100644
--- a/src/appl/gssftp/configure.in
+++ b/src/appl/gssftp/configure.in
@@ -12,7 +12,6 @@ DECLARE_SYS_ERRLIST
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
 AC_CHECK_SIZEOF(long)
-AC_FUNC_VFORK
 AC_HEADER_STDARG
 AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS))])
 AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/select.h sys/sockio.h paths.h)
@@ -53,19 +52,6 @@ AC_MSG_RESULT($krb5_cv_shadow_pwd)
 if test $krb5_cv_shadow_pwd = yes; then
 AC_DEFINE(HAVE_SHADOW)
 fi
-AC_ARG_WITH([krb4],
-[  --without-krb4          don't include Kerberos V4 backwards compatibility
-  --with-krb4             use V4 libraries included with V5 (default)
-  --with-krb4=KRB4DIR     use preinstalled V4 libraries],
-,
-withval=yes
-)dnl
-if test $withval = no; then
-	AC_MSG_RESULT(no krb4 support)
-else 
-	AC_MSG_RESULT(Adding in krb4 support)
-	FTPD_LIBS="../../../krb524/libkrb524.a"
-fi
 case $krb5_cv_host in
 alpha*-dec-osf*)
 	AC_CHECK_LIB(security,setluid,
diff --git a/src/appl/gssftp/ftp/ChangeLog b/src/appl/gssftp/ftp/ChangeLog
index ba67eb573..445734fb2 100644
--- a/src/appl/gssftp/ftp/ChangeLog
+++ b/src/appl/gssftp/ftp/ChangeLog
@@ -1,3 +1,16 @@
+2003-06-16  Ken Raeburn  <raeburn@mit.edu>
+
+	* ftp.c (recvrequest): Add new argument indicating whether "-" and
+	"|..." special treatment should be disabled.
+	* ftp_var.h (recvrequest): Update declaration.
+	* cmds.c (remglob, ls, mls): Pass 0 as the extra argument.
+	(mget): Pass 1.
+	(getit): Pass 1 iff only one filename was supplied.
+
+2003-06-05  Sam Hartman  <hartmans@mit.edu>
+
+	* pclose.c (mypopen): use fork not vfork
+
 2003-01-09  Ken Raeburn  <raeburn@mit.edu>
 
 	* ftp.c (hookup, initconn, dataconn): Use socklen_t when passing
diff --git a/src/appl/gssftp/ftp/cmds.c b/src/appl/gssftp/ftp/cmds.c
index 38d721473..b9cb2a2a2 100644
--- a/src/appl/gssftp/ftp/cmds.c
+++ b/src/appl/gssftp/ftp/cmds.c
@@ -940,7 +940,7 @@ usage:
 	}
 
 	recvrequest("RETR", argv[2], argv[1], rmode,
-	    argv[1] != oldargv1 || argv[2] != oldargv2);
+	    argv[1] != oldargv1 || argv[2] != oldargv2, loc);
 	restart_point = 0;
 	return (0);
 }
@@ -1017,7 +1017,7 @@ void mget(argc, argv)
 				tp = domap(tp);
 			}
 			recvrequest("RETR", tp, cp, "w",
-			    tp != cp || !interactive);
+			    tp != cp || !interactive, 1);
 			if (!mflag && fromatty) {
 				ointer = interactive;
 				interactive = 1;
@@ -1085,7 +1085,7 @@ remglob(argv,doswitch)
 			pswitch(!proxy);
 		}
 		for (rmode = "w"; *++argv != NULL; rmode = "a")
-			recvrequest ("NLST", temp, *argv, rmode, 0);
+			recvrequest ("NLST", temp, *argv, rmode, 0, 0);
 		if (doswitch) {
 			pswitch(!proxy);
 		}
@@ -1455,7 +1455,7 @@ void ls(argc, argv)
 			code = -1;
 			return;
 	}
-	recvrequest(cmd, argv[2], argv[1], "w", 0);
+	recvrequest(cmd, argv[2], argv[1], "w", 0, 0);
 }
 
 /*
@@ -1493,7 +1493,7 @@ usage:
 	(void) setjmp(jabort);
 	for (i = 1; mflag && i < argc-1; ++i) {
 		*rmode = (i == 1) ? 'w' : 'a';
-		recvrequest(cmd, dest, argv[i], rmode, 0);
+		recvrequest(cmd, dest, argv[i], rmode, 0, 0);
 		if (!mflag && fromatty) {
 			ointer = interactive;
 			interactive = 1;
diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c
index ffbb42cd5..155f85792 100644
--- a/src/appl/gssftp/ftp/ftp.c
+++ b/src/appl/gssftp/ftp/ftp.c
@@ -1103,7 +1103,7 @@ abortrecv(int sig)
 }
 
 void recvrequest(char *cmd, char *volatile local, char *remote, char *lmode,
-		 int printnames)
+		 int printnames, int fnameonly)
 {
 	FILE *volatile fout, *volatile din = 0, *popen();
 	int (*volatile closefunc)(), pclose(), fclose();
@@ -1149,7 +1149,7 @@ void recvrequest(char *cmd, char *volatile local, char *remote, char *lmode,
 		return;
 	}
 	oldintr = signal(SIGINT, abortrecv);
-	if (strcmp(local, "-") && *local != '|') {
+	if (fnameonly || (strcmp(local, "-") && *local != '|')) {
 		if (access(local, 2) < 0) {
 			char *dir = strrchr(local, '/');
 
@@ -1223,9 +1223,9 @@ void recvrequest(char *cmd, char *volatile local, char *remote, char *lmode,
 	din = dataconn("r");
 	if (din == NULL)
 		goto die;
-	if (strcmp(local, "-") == 0)
+	if (strcmp(local, "-") == 0 && !fnameonly)
 		fout = stdout;
-	else if (*local == '|') {
+	else if (*local == '|' && !fnameonly) {
 #ifdef SIGPIPE
 		oldintp = signal(SIGPIPE, SIG_IGN);
 #endif
diff --git a/src/appl/gssftp/ftp/ftp_var.h b/src/appl/gssftp/ftp/ftp_var.h
index 4448448aa..9baa04730 100644
--- a/src/appl/gssftp/ftp/ftp_var.h
+++ b/src/appl/gssftp/ftp/ftp_var.h
@@ -249,7 +249,7 @@ void setpassive (void);
 
 /* ftp.c */
 void sendrequest (char *, char *, char *, int);
-void recvrequest (char *, char *volatile, char *, char *, int);
+void recvrequest (char *, char *volatile, char *, char *, int, int);
 int login (char *);
 void setpbsz (unsigned int);
 void pswitch (int);
diff --git a/src/appl/gssftp/ftp/pclose.c b/src/appl/gssftp/ftp/pclose.c
index 04e481b19..5d6a5aa57 100644
--- a/src/appl/gssftp/ftp/pclose.c
+++ b/src/appl/gssftp/ftp/pclose.c
@@ -15,9 +15,6 @@ static	char sccsid[] = "@(#)pclose.c 1.1 90/04/28 SMI"; /* from UCB 1.2 3/7/86 *
 #include <signal.h>
 #include <sys/param.h>
 #include <sys/wait.h>
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
 #define sig_t my_sig_t
 #define sigtype krb5_sigtype
 typedef sigtype (*sig_t)();
@@ -60,7 +57,7 @@ mypopen(cmd,mode)
 		return (NULL);
 	myside = tst(p[WTR], p[RDR]);
 	hisside = tst(p[RDR], p[WTR]);
-	if ((pid = vfork()) == 0) {
+	if ((pid = fork()) == 0) {
 		/* myside and hisside reverse roles in child */
 		(void) close(myside);
 		if (hisside != tst(0, 1)) {
diff --git a/src/appl/gssftp/ftpd/ChangeLog b/src/appl/gssftp/ftpd/ChangeLog
index c940e015c..73814761b 100644
--- a/src/appl/gssftp/ftpd/ChangeLog
+++ b/src/appl/gssftp/ftpd/ChangeLog
@@ -1,3 +1,11 @@
+2003-06-05  Sam Hartman  <hartmans@mit.edu>
+
+	* popen.c (ftpd_popen): Use fork not vfork
+
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* ftpd.c: Don't declare errno.
+
 2003-01-03  Ken Raeburn  <raeburn@mit.edu>
 
 	* ftpd.c (auth_data): Kerberos v4 checksum must be a 32-bit
diff --git a/src/appl/gssftp/ftpd/Makefile.in b/src/appl/gssftp/ftpd/Makefile.in
index e62ae104a..ba68b2229 100644
--- a/src/appl/gssftp/ftpd/Makefile.in
+++ b/src/appl/gssftp/ftpd/Makefile.in
@@ -85,8 +85,7 @@ $(OUTPRE)ftpd.$(OBJEXT): ftpd.c $(srcdir)/../arpa/ftp.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h $(KRB524_H_DEP) $(KRB524_ERR_H_DEP) \
-  $(SRCTOP)/include/socket-utils.h $(BUILDTOP)/include/gssapi/gssapi.h \
+  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/gssapi/gssapi.h \
   $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
   ftpd_var.h secure.h
 $(OUTPRE)ftpcmd.$(OBJEXT): ftpcmd.c $(srcdir)/../arpa/ftp.h \
diff --git a/src/appl/gssftp/ftpd/ftpd.c b/src/appl/gssftp/ftpd/ftpd.c
index 7fd78991e..2a09bf3d0 100644
--- a/src/appl/gssftp/ftpd/ftpd.c
+++ b/src/appl/gssftp/ftpd/ftpd.c
@@ -130,7 +130,6 @@ extern int yyparse(void);
 #ifdef KRB5_KRB4_COMPAT
 #include <krb5.h>
 #include <krb.h>
-#include <krb524.h>
 
 AUTH_DAT kdata;
 KTEXT_ST ticket;
@@ -170,7 +169,6 @@ int have_creds;		/* User has credentials on disk */
 #include "ftpd_var.h"
 #include "secure.h"
 
-extern	int errno;
 extern	char *crypt();
 extern	char version[];
 extern	char *home;		/* pointer to home directory for glob */
@@ -315,9 +313,6 @@ main(argc, argv, envp)
 
 #ifdef GSSAPI
 	krb5_init_context(&kcontext);
-#ifdef KRB5_KRB4_COMPAT
-	krb524_init_ets(kcontext);
-#endif
 #endif
 
 	while ((c = getopt(argc, argv, option_string)) != -1) {
diff --git a/src/appl/gssftp/ftpd/popen.c b/src/appl/gssftp/ftpd/popen.c
index 317b6fa56..e9e589594 100644
--- a/src/appl/gssftp/ftpd/popen.c
+++ b/src/appl/gssftp/ftpd/popen.c
@@ -46,9 +46,6 @@ static char sccsid[] = "@(#)popen.c	5.9 (Berkeley) 2/25/91";
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
 #include "ftpd_var.h"
 
 /*
@@ -109,7 +106,7 @@ ftpd_popen(program, type)
 	gargv[gargc] = NULL;
 
 	iop = NULL;
-	switch(pid = vfork()) {
+	switch(pid = fork()) {
 	case -1:			/* error */
 		(void)close(pdes[0]);
 		(void)close(pdes[1]);
diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog
index 899927446..4f9de7ade 100644
--- a/src/appl/telnet/libtelnet/ChangeLog
+++ b/src/appl/telnet/libtelnet/ChangeLog
@@ -1,3 +1,29 @@
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* kerberos5.c (kerberos5_send): Rename getlocalsubkey ->
+	getsendsubkey.
+	(kerberos5_is): Rename getremotesubkey -> getrecvsubkey.
+
+2003-04-10  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in: Use library build framework.
+
+	* configure.in: Add support for library build framework.  Remove
+	old explicit checks for ranlib, etc.
+
+2003-04-09  Tom Yu  <tlyu@mit.edu>
+
+	* kerberos.c (kerberos4_status): Always copy in username if
+	present.  Patch from Nathan Neulinger to make "-a user" work.
+
+	* kerberos5.c (kerberos5_status): Always copy in username if
+	present.  Patch from Nathan Neulinger to make "-a user" work.
+
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* kerberos5.c (kerberos5_is): Check principal name length before
+	examining components.
+
 2003-01-07  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.orig: Deleted.
diff --git a/src/appl/telnet/libtelnet/Makefile.in b/src/appl/telnet/libtelnet/Makefile.in
index 93986e005..783415b31 100644
--- a/src/appl/telnet/libtelnet/Makefile.in
+++ b/src/appl/telnet/libtelnet/Makefile.in
@@ -32,7 +32,12 @@ LIBOBJS=@LIBOBJS@
 SETENVSRC=@SETENVSRC@
 SETENVOBJ=@SETENVOBJ@
 
-LIB=    libtelnet.a
+LIB=telnet
+LIBMAJOR=0
+LIBMINOR=0
+RELDIR=../../../appl/telnet/libtelnet
+STOBJLISTS=OBJS.ST
+
 SRCS=   $(srcdir)/auth.c \
 	$(srcdir)/encrypt.c \
 	$(srcdir)/genget.c \
@@ -52,20 +57,15 @@ SRCS=   $(srcdir)/auth.c \
 	$(srcdir)/strftime.c \
 	$(srcdir)/strerror.c
 
-OBJS=   auth.o encrypt.o genget.o \
+STLIBOBJS=   auth.o encrypt.o genget.o \
 	misc.o kerberos.o kerberos5.o forward.o spx.o enc_des.o \
 	$(LIBOBJS) getent.o $(SETENVOBJ)
 
 TELNET_H= $(srcdir)/../arpa/telnet.h
 
-all:: $(LIB)
-$(LIB): $(OBJS)
-	$(RM) $(LIB)
-	$(ARADD) $@ $(OBJS)
-	$(RANLIB) $@
+all:: all-libs
 
-clean::
-	$(RM) $(LIB)
+clean:: clean-libs clean-libobjs
 
 auth.o: $(TELNET_H)
 auth.o: encrypt.h
@@ -88,40 +88,44 @@ enc_des.o: encrypt.h
 enc_des.o: key-proto.h
 enc_des.o: misc-proto.h
 install::
+
+# @lib_frag@
+# @libobj_frag@
+
 # +++ Dependency line eater +++
 # 
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-$(OUTPRE)auth.$(OBJEXT): auth.c $(srcdir)/../arpa/telnet.h \
+auth.so auth.po $(OUTPRE)auth.$(OBJEXT): auth.c $(srcdir)/../arpa/telnet.h \
   encrypt.h enc-proto.h auth.h auth-proto.h misc-proto.h
-$(OUTPRE)encrypt.$(OBJEXT): encrypt.c $(srcdir)/../arpa/telnet.h \
+encrypt.so encrypt.po $(OUTPRE)encrypt.$(OBJEXT): encrypt.c $(srcdir)/../arpa/telnet.h \
   encrypt.h enc-proto.h misc.h misc-proto.h
-$(OUTPRE)genget.$(OBJEXT): genget.c misc.h misc-proto.h
-$(OUTPRE)misc.$(OBJEXT): misc.c misc.h misc-proto.h \
+genget.so genget.po $(OUTPRE)genget.$(OBJEXT): genget.c misc.h misc-proto.h
+misc.so misc.po $(OUTPRE)misc.$(OBJEXT): misc.c misc.h misc-proto.h \
   auth.h auth-proto.h encrypt.h enc-proto.h
-$(OUTPRE)kerberos.$(OBJEXT): kerberos.c $(BUILDTOP)/include/krb5.h \
+kerberos.so kerberos.po $(OUTPRE)kerberos.$(OBJEXT): kerberos.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/../arpa/telnet.h $(SRCTOP)/include/kerberosIV/des.h \
   $(SRCTOP)/include/kerberosIV/krb.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h encrypt.h enc-proto.h \
   auth.h auth-proto.h misc.h misc-proto.h
-$(OUTPRE)kerberos5.$(OBJEXT): kerberos5.c $(srcdir)/../arpa/telnet.h \
+kerberos5.so kerberos5.po $(OUTPRE)kerberos5.$(OBJEXT): kerberos5.c $(srcdir)/../arpa/telnet.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/syslog.h \
   encrypt.h enc-proto.h auth.h auth-proto.h misc.h misc-proto.h \
   krb5forw.h
-$(OUTPRE)forward.$(OBJEXT): forward.c $(BUILDTOP)/include/krb5.h \
+forward.so forward.po $(OUTPRE)forward.$(OBJEXT): forward.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) krb5forw.h
-$(OUTPRE)spx.$(OBJEXT): spx.c misc-proto.h
-$(OUTPRE)enc_des.$(OBJEXT): enc_des.c $(BUILDTOP)/include/krb5.h \
+spx.so spx.po $(OUTPRE)spx.$(OBJEXT): spx.c misc-proto.h
+enc_des.so enc_des.po $(OUTPRE)enc_des.$(OBJEXT): enc_des.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/../arpa/telnet.h encrypt.h \
   enc-proto.h key-proto.h misc-proto.h
-$(OUTPRE)setenv.$(OBJEXT): setenv.c misc-proto.h
-$(OUTPRE)getent.$(OBJEXT): getent.c gettytab.h
-$(OUTPRE)parsetos.$(OBJEXT): parsetos.c misc-proto.h
-$(OUTPRE)strdup.$(OBJEXT): strdup.c
-$(OUTPRE)strcasecmp.$(OBJEXT): strcasecmp.c
-$(OUTPRE)strchr.$(OBJEXT): strchr.c
-$(OUTPRE)strrchr.$(OBJEXT): strrchr.c
-$(OUTPRE)strftime.$(OBJEXT): strftime.c
-$(OUTPRE)strerror.$(OBJEXT): strerror.c
+setenv.so setenv.po $(OUTPRE)setenv.$(OBJEXT): setenv.c misc-proto.h
+getent.so getent.po $(OUTPRE)getent.$(OBJEXT): getent.c gettytab.h
+parsetos.so parsetos.po $(OUTPRE)parsetos.$(OBJEXT): parsetos.c misc-proto.h
+strdup.so strdup.po $(OUTPRE)strdup.$(OBJEXT): strdup.c
+strcasecmp.so strcasecmp.po $(OUTPRE)strcasecmp.$(OBJEXT): strcasecmp.c
+strchr.so strchr.po $(OUTPRE)strchr.$(OBJEXT): strchr.c
+strrchr.so strrchr.po $(OUTPRE)strrchr.$(OBJEXT): strrchr.c
+strftime.so strftime.po $(OUTPRE)strftime.$(OBJEXT): strftime.c
+strerror.so strerror.po $(OUTPRE)strerror.$(OBJEXT): strerror.c
 
diff --git a/src/appl/telnet/libtelnet/configure.in b/src/appl/telnet/libtelnet/configure.in
index 8f2434eaa..8767cd7d0 100644
--- a/src/appl/telnet/libtelnet/configure.in
+++ b/src/appl/telnet/libtelnet/configure.in
@@ -1,8 +1,5 @@
 AC_INIT(auth.c)
 CONFIG_RULES
-AC_PROG_ARCHIVE
-AC_PROG_ARCHIVE_ADD
-AC_PROG_RANLIB
 AC_REPLACE_FUNCS([strcasecmp strdup setsid strerror strftime getopt herror parsetos])
 AC_CHECK_FUNCS(setenv unsetenv getenv gettosbyname cgetent)
 AC_CHECK_HEADERS(stdlib.h string.h unistd.h)
@@ -23,4 +20,6 @@ else
 	AC_MSG_RESULT(Kerberos 4 authentication enabled)
 	AC_DEFINE(KRB4)
 fi
+KRB5_BUILD_LIBRARY_STATIC
+KRB5_BUILD_LIBOBJS
 V5_AC_OUTPUT_MAKEFILE
diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c
index 56a073191..8d4c7f330 100644
--- a/src/appl/telnet/libtelnet/kerberos.c
+++ b/src/appl/telnet/libtelnet/kerberos.c
@@ -612,10 +612,17 @@ kerberos4_status(ap, kname, level)
 	if (level < AUTH_USER)
 		return(level);
 
-	if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
+	/*
+	 * Always copy in UserNameRequested if the authentication
+	 * is valid, because the higher level routines need it.
+	 */
+	if (UserNameRequested) {
 		/* the name buffer comes from telnetd/telnetd{-ktd}.c */
 		strncpy(kname, UserNameRequested, 255);
 		name[255] = '\0';
+	}
+
+	if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
 		return(AUTH_VALID);
 	} else
 		return(AUTH_USER);
diff --git a/src/appl/telnet/libtelnet/kerberos5.c b/src/appl/telnet/libtelnet/kerberos5.c
index 3a1c8f24e..ad36aedda 100644
--- a/src/appl/telnet/libtelnet/kerberos5.c
+++ b/src/appl/telnet/libtelnet/kerberos5.c
@@ -327,7 +327,7 @@ kerberos5_send(ap)
 				 &check_data, new_creds, &auth);
 
 #ifdef	ENCRYPTION
-	krb5_auth_con_getlocalsubkey(telnet_context, auth_context, &newkey);
+	krb5_auth_con_getsendsubkey(telnet_context, auth_context, &newkey);
 	if (session_key) {
 		krb5_free_keyblock(telnet_context, session_key);
 		session_key = 0;
@@ -446,6 +446,10 @@ kerberos5_is(ap, data, cnt)
 		 * first component of a service name especially since
 		 * the default is of length 4.
 		 */
+		if (krb5_princ_size(telnet_context,ticket->server) < 1) {
+		    (void) strcpy(errbuf, "malformed service name");
+		    goto errout;
+		}
 		if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) {
 		    char princ[256];
 		    strncpy(princ,	
@@ -548,7 +552,7 @@ kerberos5_is(ap, data, cnt)
 		
 		if (name)
 		    free(name);
-		krb5_auth_con_getremotesubkey(telnet_context, auth_context,
+		krb5_auth_con_getrecvsubkey(telnet_context, auth_context,
 					      &newkey);
 		if (session_key) {
 		    krb5_free_keyblock(telnet_context, session_key);
@@ -727,13 +731,20 @@ kerberos5_status(ap, name, level)
 	if (level < AUTH_USER)
 		return(level);
 
+	/*
+	 * Always copy in UserNameRequested if the authentication
+	 * is valid, because the higher level routines need it.
+	 * the name buffer comes from telnetd/telnetd{-ktd}.c
+	 */
+	if (UserNameRequested) {
+		strncpy(name, UserNameRequested, 255);
+		name[255] = '\0';
+	}
+
 	if (UserNameRequested &&
 	    krb5_kuserok(telnet_context, ticket->enc_part2->client, 
 			 UserNameRequested))
 	{
-		/* the name buffer comes from telnetd/telnetd{-ktd}.c */
-		strncpy(name, UserNameRequested, 255);
-		name[255] = '\0';
 		return(AUTH_VALID);
 	} else
 		return(AUTH_USER);
diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog
index bcc361750..60f9bf1f0 100644
--- a/src/appl/telnet/telnet/ChangeLog
+++ b/src/appl/telnet/telnet/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* externs.h: Don't declare errno.
+
 2003-01-07  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.orig: Deleted.
diff --git a/src/appl/telnet/telnet/Makefile.in b/src/appl/telnet/telnet/Makefile.in
index 31fb87a31..20a9ae755 100644
--- a/src/appl/telnet/telnet/Makefile.in
+++ b/src/appl/telnet/telnet/Makefile.in
@@ -84,7 +84,8 @@ $(OUTPRE)commands.$(OBJEXT): commands.c $(srcdir)/../arpa/telnet.h \
   $(srcdir)/../libtelnet/auth-proto.h $(srcdir)/../libtelnet/encrypt.h \
   $(srcdir)/../libtelnet/enc-proto.h $(srcdir)/../libtelnet/misc-proto.h \
   $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/k5-platform.h
 $(OUTPRE)main.$(OBJEXT): main.c $(srcdir)/../libtelnet/auth.h \
   $(srcdir)/../libtelnet/auth-proto.h $(srcdir)/../libtelnet/encrypt.h \
   $(srcdir)/../libtelnet/enc-proto.h ring.h externs.h \
diff --git a/src/appl/telnet/telnet/externs.h b/src/appl/telnet/telnet/externs.h
index 65a1c67c0..dccb424f0 100644
--- a/src/appl/telnet/telnet/externs.h
+++ b/src/appl/telnet/telnet/externs.h
@@ -111,10 +111,6 @@ extern char *malloc(), *calloc(), *realloc();
 
 #define	SUBBUFSIZE	256
 
-#ifndef CRAY
-extern int errno;		/* outside this world */
-#endif /* !CRAY */
-
 extern int
     autologin,		/* Autologin enabled */
     skiprc,		/* Don't process the ~/.telnetrc file */
diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog
index c380d11f8..b343e9cc0 100644
--- a/src/appl/telnet/telnetd/ChangeLog
+++ b/src/appl/telnet/telnetd/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* telnetd.h: Don't declare errno.
+
 2003-01-09  Ken Raeburn  <raeburn@mit.edu>
 
 	* telnetd.c (main): Use socklen_t when passing address to socket
diff --git a/src/appl/telnet/telnetd/Makefile.in b/src/appl/telnet/telnetd/Makefile.in
index 4a3e0a67c..ecf235c11 100644
--- a/src/appl/telnet/telnetd/Makefile.in
+++ b/src/appl/telnet/telnetd/Makefile.in
@@ -90,9 +90,10 @@ $(OUTPRE)telnetd.$(OBJEXT): telnetd.c telnetd.h defs.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/syslog.h \
   ext.h pathnames.h $(BUILDTOP)/include/libpty.h $(COM_ERR_DEPS) \
   $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5.h $(srcdir)/../libtelnet/auth.h \
-  $(srcdir)/../libtelnet/auth-proto.h $(srcdir)/../libtelnet/encrypt.h \
-  $(srcdir)/../libtelnet/enc-proto.h $(srcdir)/../libtelnet/misc-proto.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/auth-proto.h \
+  $(srcdir)/../libtelnet/encrypt.h $(srcdir)/../libtelnet/enc-proto.h \
+  $(srcdir)/../libtelnet/misc-proto.h
 $(OUTPRE)termio-tn.$(OBJEXT): termio-tn.c
 $(OUTPRE)termios-tn.$(OBJEXT): termios-tn.c
 $(OUTPRE)state.$(OBJEXT): state.c telnetd.h defs.h \
@@ -113,8 +114,9 @@ $(OUTPRE)sys_term.$(OBJEXT): sys_term.c telnetd.h defs.h \
   ext.h pathnames.h $(COM_ERR_DEPS) $(BUILDTOP)/include/libpty.h \
   $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/auth-proto.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/krb5/kdb.h
 $(OUTPRE)utility.$(OBJEXT): utility.c telnetd.h defs.h \
   $(srcdir)/../arpa/telnet.h $(SRCTOP)/include/socket-utils.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/syslog.h \
diff --git a/src/appl/telnet/telnetd/telnetd.h b/src/appl/telnet/telnetd/telnetd.h
index 234b9739e..f21f617e5 100644
--- a/src/appl/telnet/telnetd/telnetd.h
+++ b/src/appl/telnet/telnetd/telnetd.h
@@ -45,5 +45,4 @@
 
 /* other external variables */
 extern	char **environ;
-extern	int errno;
 
diff --git a/src/clients/kinit/ChangeLog b/src/clients/kinit/ChangeLog
index 802ab3e01..bf365e02f 100644
--- a/src/clients/kinit/ChangeLog
+++ b/src/clients/kinit/ChangeLog
@@ -1,3 +1,18 @@
+2003-08-01  Tom Yu  <tlyu@mit.edu>
+
+	* kinit.c (main): Apply patch from Stephen Grau to correctly
+	return non-zero for certain error conditions.
+
+2003-05-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* kinit.c (KRB4_BACKUP_DEFAULT_LIFE_SECS): Update to one day.
+
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* Makefile.in (kinit): Don't use krb524 library.
+	* kinit.c: Don't include krb524.h.
+	(try_convert524): Don't call krb524_init_ets.
+
 2002-11-05  Tom Yu  <tlyu@mit.edu>
 
 	* kinit.c (k4_kinit): Remove trailing colon, as new implementation
diff --git a/src/clients/kinit/Makefile.in b/src/clients/kinit/Makefile.in
index d7d5b9547..1d2a6e436 100644
--- a/src/clients/kinit/Makefile.in
+++ b/src/clients/kinit/Makefile.in
@@ -13,8 +13,8 @@ all-unix:: kinit
 all-windows:: $(OUTPRE)kinit.exe
 all-mac::
 
-kinit: kinit.o $(KRB4COMPAT_DEPLIBS) $(KRB524_DEPLIB)
-	$(CC_LINK) -o $@ kinit.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
+kinit: kinit.o $(KRB4COMPAT_DEPLIBS)
+	$(CC_LINK) -o $@ kinit.o $(KRB4COMPAT_LIBS)
 
 $(OUTPRE)kinit.exe: $(OUTPRE)kinit.obj $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib $(KLIB) $(CLIB)
 	link $(EXE_LINKOPTS) -out:$@ $** advapi32.lib
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
index 740b0302a..422c87d7d 100644
--- a/src/clients/kinit/kinit.c
+++ b/src/clients/kinit/kinit.c
@@ -55,10 +55,6 @@ extern int getopt();
 #endif /* HAVE_UNISTD_H */
 #endif /* GETOPT_LONG */
 
-#ifdef HAVE_KRB524
-#include "krb524.h"
-#endif
-
 #ifndef _WIN32
 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
 #else
@@ -117,7 +113,7 @@ static int default_k4 = 0;
 static int authed_k5 = 0;
 static int authed_k4 = 0;
 
-#define KRB4_BACKUP_DEFAULT_LIFE_SECS 10*60*60 /* 10 hours */
+#define KRB4_BACKUP_DEFAULT_LIFE_SECS 24*60*60 /* 1 day */
 
 typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
 
@@ -994,9 +990,6 @@ static int try_convert524(k5)
       initialized.
     */
 
-    /* or do this directly with krb524_convert_creds_kdc */
-    krb524_init_ets(k5->ctx);
-
     if ((code = krb5_build_principal(k5->ctx,
 				     &kpcserver, 
 				     krb5_princ_realm(k5->ctx, k5->me)->length,
@@ -1130,7 +1123,8 @@ main(argc, argv)
     k5_end(&k5);
     k4_end(&k4);
 
-    if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4))
+    if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4) ||
+	(!got_k5 && !got_k4))
 	exit(1);
     return 0;
 }
diff --git a/src/clients/ksu/ChangeLog b/src/clients/ksu/ChangeLog
index 44415a033..17a1dffe8 100644
--- a/src/clients/ksu/ChangeLog
+++ b/src/clients/ksu/ChangeLog
@@ -1,3 +1,10 @@
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* heuristic.c (get_closest_principal): Don't try to examine
+	principal name components after the last.
+	* krb_auth_su.c (get_best_principal): Check principal name length
+	before examining components.
+
 2002-12-23  Ezra Peisach  <epeisach@bu.edu>
 
 	* authorization.c, heuristic.c, ksu.h: Use uid_t instead of int in
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
index 5669d79ba..88c052cc4 100644
--- a/src/clients/ksu/Makefile.in
+++ b/src/clients/ksu/Makefile.in
@@ -47,39 +47,43 @@ install::
 #
 $(OUTPRE)krb_auth_su.$(OBJEXT): krb_auth_su.c ksu.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/k5-util.h \
+  $(SRCTOP)/include/syslog.h
 $(OUTPRE)ccache.$(OBJEXT): ccache.c ksu.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
-  $(SRCTOP)/include/syslog.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h \
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)authorization.$(OBJEXT): authorization.c ksu.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/k5-util.h \
+  $(SRCTOP)/include/syslog.h
 $(OUTPRE)main.$(OBJEXT): main.c ksu.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
-  $(SRCTOP)/include/syslog.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h \
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)heuristic.$(OBJEXT): heuristic.c ksu.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
-  $(SRCTOP)/include/syslog.h
+  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h
 $(OUTPRE)xmalloc.$(OBJEXT): xmalloc.c ksu.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
-  $(SRCTOP)/include/syslog.h
+  $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/syslog.h
 $(OUTPRE)setenv.$(OBJEXT): setenv.c
 
diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
index c79f94369..85b94b5e2 100644
--- a/src/clients/ksu/heuristic.c
+++ b/src/clients/ksu/heuristic.c
@@ -364,7 +364,7 @@ krb5_error_code get_closest_principal(context, plist, client, found)
 		krb5_data *p2 =
 		    krb5_princ_component(context, temp_client, j);
 		
-		if ((p1->length != p2->length) ||
+		if (!p1 || !p2 || (p1->length != p2->length) ||
 		    memcmp(p1->data,p2->data,p1->length)){
 		    got_one = FALSE;
 		    break;
diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
index 6e76149c1..8e1834240 100644
--- a/src/clients/ksu/krb_auth_su.c
+++ b/src/clients/ksu/krb_auth_su.c
@@ -547,7 +547,9 @@ krb5_error_code get_best_principal(context, plist, client)
 			 krb5_princ_realm(context, temp_client)->length))){
 	    
 	    
-	    if(nelem){ 
+	    if (nelem &&
+		krb5_princ_size(context, *client) > 0 &&
+		krb5_princ_size(context, temp_client) > 0) {
 		krb5_data *p1 =
 		    krb5_princ_component(context, *client, 0);
 		krb5_data *p2 = 
diff --git a/src/config-files/ChangeLog b/src/config-files/ChangeLog
index 0c038012d..502fc4b7d 100644
--- a/src/config-files/ChangeLog
+++ b/src/config-files/ChangeLog
@@ -1,3 +1,30 @@
+2003-06-27  Jen Selby <jenselby@mit.edu>
+
+	* kdc.conf.M: replaced the @LOCALSTATEDIR typos with
+	/usr/local/var
+
+2003-06-20  Tom Yu  <tlyu@mit.edu>
+
+	* krb5.conf.M: Sync with doc/krb5conf.texinfo.
+
+2003-05-30  Ken Raeburn  <raeburn@mit.edu>
+
+	* kdc.conf: Delete supported and master key type specs.
+
+	* krb5.conf: Delete Athena KDC specifications.  Delete Cygnus
+	realm info.  Replace CLUB.CC.CMU.EDU info with ANDREW.CMU.EDU,
+	which has SRV records and thus doesn't need KDC specs.  Provide a
+	commented-out example of a [logging] spec.  Delete commented-out
+	enctype specs.
+
+	* krb5.conf.M: Remove "kdc =" lines from "realms" section example,
+	and recommend not using it unless DNS info isn't available.
+
+2003-05-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* kdc.conf.M (FILES): Refer to correct location for kdc.conf in
+	the default installation path.
+
 2002-09-24  Sam Hartman  <hartmans@mit.edu>
 
 	* krb5.conf: Update enctypes and add club.cc.cmu.edu
diff --git a/src/config-files/kdc.conf b/src/config-files/kdc.conf
index cf8cbe1fd..3355699ff 100644
--- a/src/config-files/kdc.conf
+++ b/src/config-files/kdc.conf
@@ -10,6 +10,4 @@
 		kdc_ports = 750,88
 		max_life = 10h 0m 0s
 		max_renewable_life = 7d 0h 0m 0s
-		master_key_type = des-cbc-crc
-		supported_enctypes = des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
 	}
diff --git a/src/config-files/kdc.conf.M b/src/config-files/kdc.conf.M
index 103be2a0f..0c1735f3c 100644
--- a/src/config-files/kdc.conf.M
+++ b/src/config-files/kdc.conf.M
@@ -78,14 +78,14 @@ This
 .B string
 specifies the location of the access control list (acl) file that
 kadmin uses to determine which principals are allowed which permissions
-on the database. The default value is @LOCALSTATEDIR/krb5kdc/kadm5.acl.
+on the database. The default value is /usr/local/var/krb5kdc/kadm5.acl.
 
 .IP admin_keytab
 This
 .B string
 Specifies the location of the keytab file that kadmin uses to
 authenticate to the database.  The default value is
-@LOCALSTATEDIR/krb5kdc/kadm5.keytab.
+/usr/local/var/krb5kdc/kadm5.keytab.
 
 .IP database_name
 This
@@ -235,7 +235,7 @@ tickets should be checked against the transit path computed from the
 realm names and the [capaths] section of its krb5.conf file
 
 .SH FILES 
-/usr/local/lib/krb5kdc/kdc.conf
+/usr/local/var/krb5kdc/kdc.conf
 
 .SH SEE ALSO
 krb5.conf(5), krb5kdc(8)
diff --git a/src/config-files/krb5.conf b/src/config-files/krb5.conf
index 51f6aa8e5..efc19e45d 100644
--- a/src/config-files/krb5.conf
+++ b/src/config-files/krb5.conf
@@ -1,16 +1,10 @@
 [libdefaults]
 	default_realm = ATHENA.MIT.EDU
-# You don't actually need enctype lines
-# By default all enctypes are allowed.
-#	default_tgs_enctypes = des3-hmac-sha1 arcfour-hmac-md5 des-cbc-crc des-cbc-md5 des-cbc-md4
 	krb4_config = /usr/kerberos/lib/krb.conf
 	krb4_realms = /usr/kerberos/lib/krb.realms
 
 [realms]
 	ATHENA.MIT.EDU = {
-		kdc = KERBEROS-2.MIT.EDU:88
-		kdc = KERBEROS.MIT.EDU
-		kdc = KERBEROS-1.MIT.EDU
 		admin_server = KERBEROS.MIT.EDU
 		default_domain = MIT.EDU
 		v4_instance_convert = {
@@ -18,22 +12,15 @@
 			lithium = lithium.lcs.mit.edu
 		}
 	}
-	CYGNUS.COM = {
-		kdc = KERBEROS.CYGNUS.COM
-		kdc = KERBEROS-1.CYGNUS.COM
-		admin_server = KERBEROS.MIT.EDU
+	ANDREW.CMU.EDU = {
+		admin_server = vice28.fs.andrew.cmu.edu
 	}
+# use "kdc =" if realm admins haven't put SRV records into DNS
         GNU.ORG = {
                 kdc = kerberos.gnu.org
                 kdc = kerberos-2.gnu.org
                 admin_server = kerberos.gnu.org
         }
-CLUB.CC.CMU.EDU = {
-	kdc = kerberos.club.cc.cmu.edu
-	kdc = kerberos-1.club.cc.cmu.edu
-	admin_server = kerberos-admin.club.cc.cmu.edu
-	default_domain = club.cc.cmu.edu
-}
 
 [domain_realm]
 	.mit.edu = ATHENA.MIT.EDU
@@ -42,3 +29,5 @@ CLUB.CC.CMU.EDU = {
 	media.mit.edu = MEDIA-LAB.MIT.EDU
 	.ucsc.edu = CATS.UCSC.EDU
 
+[logging]
+#	kdc = CONSOLE
diff --git a/src/config-files/krb5.conf.M b/src/config-files/krb5.conf.M
index 61545f302..87582c0b4 100644
--- a/src/config-files/krb5.conf.M
+++ b/src/config-files/krb5.conf.M
@@ -128,10 +128,10 @@ that the library will tolerate before assuming that a Kerberos message
 is invalid.  The default value is 300 seconds, or five minutes.
 
 .IP kdc_timesync 
-If the value of this relation is non-zero, the library will compute the
-difference between the system clock and the time returned by the KDC and
-in order to correct for an inaccurate system clock.  This corrective
-factor is only used by the Kerberos library.
+If the value of this relation is non-zero (the default), the library
+will compute the difference between the system clock and the time
+returned by the KDC and in order to correct for an inaccurate system
+clock.  This corrective factor is only used by the Kerberos library.
 
 .IP kdc_req_checksum_type
 For compatability with DCE security servers which do not support the
@@ -164,6 +164,18 @@ do not support the default cache as created by this version of
 Kerberos. Use a value of 1 on DCE 1.0.3a systems, and a value of 2 on
 DCE 1.1 systems.
 
+.IP krb4_srvtab 
+Specifies the location of the Kerberos V4 srvtab file.  Default is
+"/etc/srvtab".
+
+.IP krb4_config
+Specifies the location of hte Kerberos V4 configuration file.  Default
+is "/etc/krb.conf".
+
+.IP krb4_realms
+Specifies the location of the Kerberos V4 domain/realm translation
+file.  Default is "/etc/krb.realms".
+
 .IP dns_lookup_kdc
 Indicate whether DNS SRV records shoud be used to locate the KDCs and 
 other servers for a realm, if they are not listed in the information 
@@ -182,6 +194,34 @@ This allows a computer to use multiple local addresses, in order to
 allow Kerberos to work in a network that uses NATs.  The addresses should
 be in a comma-separated list.
 
+.IP udp_preference_limit
+When sending a message to the KDC, the library will try using TCP
+before UDP if the size of the message is above "udp_preference_list".
+If the message is smaller than "udp_preference_list", then UDP will be
+tried before TCP.  Regardless of the size, both protocols will be
+tried if the first attempt fails.
+
+.IP verify_ap_req_nofail
+If this flag is set, then an attempt to get initial credentials will
+fail if the client machine does not have a keytab.  The default for the
+flag is false.
+
+.IP renew_lifetime
+The value of this tag is the default renewable lifetime for initial
+tickets.  The default value for the tag is 0.
+
+.IP noaddresses
+Setting this flag causes the initial Kerberos ticket to be addressless.
+The default for the flag is true.
+
+.IP forwardable
+If this flag is set, initial tickets by default will be forwardable.
+The default value for this flag is false.
+
+.IP proxiable
+If this flag is set, initial tickets by default will be proxiable.
+The default value for this flag is false.
+
 .SH APPDEFAULTS SECTION
 
 Each tag in the [appdefaults] section names a Kerberos V5 application
@@ -233,9 +273,6 @@ subsection define the properties of that particular realm.  For example:
 .in +1i
 [realms]
 	ATHENA.MIT.EDU = {
-		kdc = KERBEROS.MIT.EDU
-		kdc = KERBEROS-1.MIT.EDU:750
-		kdc = KERBEROS-2.MIT.EDU:88
 		admin_server = KERBEROS.MIT.EDU
 		default_domain = MIT.EDU
 		v4_instance_convert = {
@@ -254,7 +291,8 @@ subsection:
 .IP kdc
 The value of this relation is the name of a host running a KDC for that
 realm.  An optional port number (preceded by a colon) may be appended to
-the hostname.
+the hostname.  This tag should generally be used only if the realm
+administrator has not made the information available through DNS.
 
 .IP admin_server
 This relation identifies the host where the administration server is
diff --git a/src/config/ChangeLog b/src/config/ChangeLog
index 7a0623513..ac093951b 100644
--- a/src/config/ChangeLog
+++ b/src/config/ChangeLog
@@ -1,3 +1,44 @@
+2004-02-09  Tom Yu  <tlyu@mit.edu>
+
+	* config.guess: Update from autoconf-2.59.
+
+	* config.sub: Update from autoconf-2.59.
+
+	* install-sh: Update from autoconf-2.59.
+
+2003-11-26  Jeffrey Altman <jaltman@mit.edu>
+
+    * win-pre.in (KFWFLAGS): conditionally define USE_LEASH=1
+      to enable access to Leash apis for kinit dialogs within 
+      gssapi32.dll
+
+2003-09-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* shlib.conf (*-*-linux*): Use $(CC) for linking shared libraries,
+	and -Wl to pass linker flags in, so it can supply the necessary
+	support libraries.
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* win-pre.in (CPPFLAGS): Define KRB5_DEPRECATED=1.
+
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* pre.in (KRB524_H_DEP, KRB524_ERR_H_DEP, KRB524_LIB,
+	KRB524_DEPLIB): Deleted.
+
+2003-04-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* post.in (configure): Try running autoconf with --include, and if
+	that doesn't work, try --localdir.  Don't use AUTOCONFINCFLAGS.
+
+2003-04-01  Tom Yu  <tlyu@mit.edu>
+
+	* pre.in (KDB5_DEPLIBS): Don't depend on $(DB_DEPLIB) anymore.
+	(KDB5_DB_LIB): New variable; is empty if not building with system
+	libdb.
+	(KDB5_LIBS): Use $(KDB5_DB_LIB) instead of $(DB_LIB).
+
 2003-03-03  Tom Yu  <tlyu@mit.edu>
 
 	* libobj.in: Change .c.so and .c.po rules to use ALL_CFLAGS.
diff --git a/src/config/config.guess b/src/config/config.guess
index b4faaedca..500ee74b0 100644
--- a/src/config/config.guess
+++ b/src/config/config.guess
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-#   Free Software Foundation, Inc.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-version='2000-05-30'
+timestamp='2003-10-03'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,38 +24,50 @@ version='2000-05-30'
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
 #
 # This script attempts to guess a canonical system name similar to
 # config.sub.  If it succeeds, it prints the system name on stdout, and
 # exits with 0.  Otherwise, it exits with 1.
 #
 # The plan is that this can be called by configure scripts if you
-# don't specify an explicit system type (host/target name).
-#
-# Only a few systems have been added to this list; please add others
-# (but try to keep the structure clean).
-#
+# don't specify an explicit build system type.
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
 Usage: $0 [OPTION]
 
-Output the configuration name of this system.
+Output the configuration name of the system \`$me' is run on.
 
 Operation modes:
-  -h, --help               print this help, then exit
-  -V, --version            print version number, then exit"
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 
 help="
 Try \`$me --help' for more information."
 
 # Parse command line
 while test $# -gt 0 ; do
-  case "$1" in
-    --version | --vers* | -V )
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
        echo "$version" ; exit 0 ;;
     --help | --h* | -h )
        echo "$usage"; exit 0 ;;
@@ -64,9 +76,7 @@ while test $# -gt 0 ; do
     - )	# Use stdin as input.
        break ;;
     -* )
-       exec >&2
-       echo "$me: invalid option $1"
-       echo "$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
     * )
        break ;;
@@ -78,133 +88,204 @@ if test $# != 0; then
   exit 1
 fi
 
-# Use $HOST_CC if defined. $CC may point to a cross-compiler
-if test x"$CC_FOR_BUILD" = x; then
-  if test x"$HOST_CC" != x; then
-    CC_FOR_BUILD="$HOST_CC"
-  else
-    if test x"$CC" != x; then
-      CC_FOR_BUILD="$CC"
-    else
-      CC_FOR_BUILD=cc
-    fi
-  fi
-fi
+trap 'exit 1' 1 2 15
 
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
+# (ghazi@noc.rutgers.edu 1994-08-24)
 if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
-
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
-	# Netbsd (nbsd) targets should (where applicable) match one or
+	# NetBSD (nbsd) targets should (where applicable) match one or
 	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
 	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
 	# switched to ELF, *-*-netbsd* would select the old
 	# object file format.  This provides both forward
 	# compatibility and a consistent mechanism for selecting the
 	# object file format.
-	# Determine the machine/vendor (is the vendor relevant).
-	case "${UNAME_MACHINE}" in
-	    amiga) machine=m68k-cbm ;;
-	    arm32) machine=arm-unknown ;;
-	    atari*) machine=m68k-atari ;;
-	    sun3*) machine=m68k-sun ;;
-	    mac68k) machine=m68k-apple ;;
-	    macppc) machine=powerpc-apple ;;
-	    hp3[0-9][05]) machine=m68k-hp ;;
-	    ibmrt|romp-ibm) machine=romp-ibm ;;
-	    *) machine=${UNAME_MACHINE}-unknown ;;
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
 	esac
-	# The Operating System including object format.
-	if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-		| grep __ELF__ >/dev/null
-	then
-	    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
-	    # Return netbsd for either.  FIX?
-	    os=netbsd
-	else
-	    os=netbsdelf
-	fi
 	# The OS release
-	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	echo "${machine}-${os}${release}"
 	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
     alpha:OSF1:*:*)
 	if test $UNAME_RELEASE = "V4.0"; then
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
 	fi
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	cat <<EOF >$dummy.s
-	.data
-\$Lformat:
-	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
-
-	.text
-	.globl main
-	.align 4
-	.ent main
-main:
-	.frame \$30,16,\$26,0
-	ldgp \$29,0(\$27)
-	.prologue 1
-	.long 0x47e03d80 # implver \$0
-	lda \$2,-1
-	.long 0x47e20c21 # amask \$2,\$1
-	lda \$16,\$Lformat
-	mov \$0,\$17
-	not \$1,\$18
-	jsr \$26,printf
-	ldgp \$29,0(\$26)
-	mov 0,\$16
-	jsr \$26,exit
-	.end main
-EOF
-	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-	if test "$?" = 0 ; then
-		case `./$dummy` in
-			0-0)
-				UNAME_MACHINE="alpha"
-				;;
-			1-0)
-				UNAME_MACHINE="alphaev5"
-				;;
-			1-1)
-				UNAME_MACHINE="alphaev56"
-				;;
-			1-101)
-				UNAME_MACHINE="alphapca56"
-				;;
-			2-303)
-				UNAME_MACHINE="alphaev6"
-				;;
-			2-307)
-				UNAME_MACHINE="alphaev67"
-				;;
-		esac
-	fi
-	rm -f $dummy.s $dummy
 	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
 	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
     Alpha\ *:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# Should we change UNAME_MACHINE based on the output of uname instead
@@ -215,31 +296,13 @@ EOF
 	echo alpha-dec-winnt3.5
 	exit 0 ;;
     Amiga*:UNIX_System_V:4.0:*)
-	echo m68k-cbm-sysv4
+	echo m68k-unknown-sysv4
 	exit 0;;
-    amiga:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
     *:[Aa]miga[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-amigaos
 	exit 0 ;;
-    arc64:OpenBSD:*:*)
-	echo mips64el-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    arc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    hkmips:OpenBSD:*:*)
-	echo mips-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    pmax:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    sgi:OpenBSD:*:*)
-	echo mips-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    wgrisc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
 	exit 0 ;;
     *:OS/390:*:*)
 	echo i370-ibm-openedition
@@ -247,7 +310,7 @@ EOF
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
 	exit 0;;
-    SR2?01:HI-UX/MPP:*:*)
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
 	echo hppa1.1-hitachi-hiuxmpp
 	exit 0;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
@@ -261,6 +324,13 @@ EOF
     NILE*:*:*:dcosx)
 	echo pyramid-pyramid-svr4
 	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit 0 ;;
@@ -289,7 +359,7 @@ EOF
 	echo m68k-sun-sunos${UNAME_RELEASE}
 	exit 0 ;;
     sun*:*:4.2BSD:*)
-	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
 	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
 	case "`/bin/arch`" in
 	    sun3)
@@ -303,9 +373,6 @@ EOF
     aushp:SunOS:*:*)
 	echo sparc-auspex-sunos${UNAME_RELEASE}
 	exit 0 ;;
-    atari*:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -332,18 +399,6 @@ EOF
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
         echo m68k-unknown-mint${UNAME_RELEASE}
         exit 0 ;;
-    sun3*:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mac68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme88k:OpenBSD:*:*)
-	echo m88k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
     powerpc:machten:*:*)
 	echo powerpc-apple-machten${UNAME_RELEASE}
 	exit 0 ;;
@@ -360,6 +415,7 @@ EOF
 	echo clipper-intergraph-clix${UNAME_RELEASE}
 	exit 0 ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -381,12 +437,20 @@ EOF
 	  exit (-1);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy \
-	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
-	  && rm $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
 	echo mips-mips-riscos${UNAME_RELEASE}
 	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
     Night_Hawk:Power_UNIX:*:*)
 	echo powerpc-harris-powerunix
 	exit 0 ;;
@@ -434,11 +498,20 @@ EOF
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
 	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
 	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
-    i?86:AIX:*:*)
+    i*86:AIX:*:*)
 	echo i386-ibm-aix
 	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
 		sed 's/^		//' << EOF >$dummy.c
 		#include <sys/systemcfg.h>
 
@@ -450,8 +523,7 @@ EOF
 			exit(0);
 			}
 EOF
-		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
-		rm -f $dummy.c $dummy
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
 		echo rs6000-ibm-aix3.2.5
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
 		echo rs6000-ibm-aix3.2.4
@@ -459,9 +531,9 @@ EOF
 		echo rs6000-ibm-aix3.2
 	fi
 	exit 0 ;;
-    *:AIX:*:4)
-	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
-	if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
 	else
 		IBM_ARCH=powerpc
@@ -469,7 +541,7 @@ EOF
 	if [ -x /usr/bin/oslevel ] ; then
 		IBM_REV=`/usr/bin/oslevel`
 	else
-		IBM_REV=4.${UNAME_RELEASE}
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
 	exit 0 ;;
@@ -495,11 +567,28 @@ EOF
 	echo m68k-hp-bsd4.4
 	exit 0 ;;
     9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	case "${UNAME_MACHINE}" in
 	    9000/31? )            HP_ARCH=m68000 ;;
 	    9000/[34]?? )         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-              sed 's/^              //' << EOF >$dummy.c
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
 
               #define _HPUX_SOURCE
               #include <stdlib.h>
@@ -532,13 +621,29 @@ EOF
                   exit (0);
               }
 EOF
-	(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
-	rm -f $dummy.c $dummy
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
 	esac
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
 	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
     3050*:HI-UX:*:*)
+	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#include <unistd.h>
 	int
@@ -564,8 +669,7 @@ EOF
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
 	echo unknown-hitachi-hiuxwe2
 	exit 0 ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -574,7 +678,7 @@ EOF
     9000/8??:4.3bsd:*:*)
 	echo hppa1.0-hp-bsd
 	exit 0 ;;
-    *9??*:MPE/iX:*:*)
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
 	echo hppa1.0-hp-mpeix
 	exit 0 ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
@@ -583,7 +687,7 @@ EOF
     hp8??:OSF1:*:*)
 	echo hppa1.0-hp-osf
 	exit 0 ;;
-    i?86:OSF1:*:*)
+    i*86:OSF1:*:*)
 	if [ -x /usr/sbin/sysversion ] ; then
 	    echo ${UNAME_MACHINE}-unknown-osf1mk
 	else
@@ -593,9 +697,6 @@ EOF
     parisc*:Lites*:*:*)
 	echo hppa1.1-hp-lites
 	exit 0 ;;
-    hppa*:OpenBSD:*:*)
-	echo hppa-unknown-openbsd
-	exit 0 ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
         exit 0 ;;
@@ -614,41 +715,34 @@ EOF
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
         exit 0 ;;
-    CRAY*X-MP:*:*:*)
-	echo xmp-cray-unicos
-        exit 0 ;;
     CRAY*Y-MP:*:*:*)
-	echo ymp-cray-unicos${UNAME_RELEASE}
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit 0 ;;
     CRAY*[A-Z]90:*:*:*)
 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
 	exit 0 ;;
     CRAY*TS:*:*:*)
 	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit 0 ;;
     CRAY*T3E:*:*:*)
-	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit 0 ;;
     CRAY*SV1:*:*:*)
 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit 0 ;;
-    CRAY-2:*:*:*)
-	echo cray2-cray-unicos
-        exit 0 ;;
-    F300:UNIX_System_V:*:*)
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
         FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
         FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
         exit 0 ;;
-    F301:UNIX_System_V:*:*)
-       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
-       exit 0 ;;
-    hp300:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
 	exit 0 ;;
     sparc*:BSD/OS:*:*)
@@ -657,11 +751,22 @@ EOF
     *:BSD/OS:*:*)
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
 	exit 0 ;;
-    *:FreeBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit 0 ;;
-    *:OpenBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+    *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	# GNU/FreeBSD systems have a "k" prefix to indicate we are using
+	# FreeBSD's kernel, but not the complete OS.
+	case ${LIBC} in gnu) kernel_only='k' ;; esac
+	echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
 	exit 0 ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
@@ -669,11 +774,20 @@ EOF
     i*:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
 	# UNAME_MACHINE based on the output of uname instead of i386?
-	echo i386-pc-interix
+	echo i586-pc-interix
 	exit 0 ;;
     i*:UWIN*:*)
 	echo ${UNAME_MACHINE}-pc-uwin
@@ -687,223 +801,168 @@ EOF
     *:GNU:*:*)
 	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
 	exit 0 ;;
-    *:Linux:*:*)
-
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
 	# The BFD linker knows what the default object file format is, so
 	# first see if it will tell us. cd to the root directory to prevent
 	# problems with other programs or directories called `ld' in the path.
-	ld_help_string=`cd /; ld --help 2>&1`
-	ld_supported_emulations=`echo $ld_help_string \
-			 | sed -ne '/supported emulations:/!d
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
 				    s/[ 	][ 	]*/ /g
-				    s/.*supported emulations: *//
+				    s/.*supported targets: *//
 				    s/ .*//
 				    p'`
-        case "$ld_supported_emulations" in
-	  *ia64)
-		echo "${UNAME_MACHINE}-unknown-linux"
-		exit 0
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
 		;;
-	  i?86linux)
+	  a.out-i386-linux)
 		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit 0
-		;;
-	  elf_i?86)
-		echo "${UNAME_MACHINE}-pc-linux"
-		exit 0
-		;;
-	  i?86coff)
+		exit 0 ;;
+	  coff-i386)
 		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit 0
-		;;
-	  sparclinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  armlinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  elf32arm*)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
-		exit 0
-		;;
-	  armelf_linux*)
-		echo "${UNAME_MACHINE}-unknown-linux-gnu"
-		exit 0
-		;;
-	  m68klinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  elf32ppc | elf32ppclinux)
-		# Determine Lib Version
-		cat >$dummy.c <<EOF
-#include <features.h>
-#if defined(__GLIBC__)
-extern char __libc_version[];
-extern char __libc_release[];
-#endif
-main(argc, argv)
-     int argc;
-     char *argv[];
-{
-#if defined(__GLIBC__)
-  printf("%s %s\n", __libc_version, __libc_release);
-#else
-  printf("unkown\n");
-#endif
-  return 0;
-}
-EOF
-		LIBC=""
-		$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
-		if test "$?" = 0 ; then
-			./$dummy | grep 1\.99 > /dev/null
-			if test "$?" = 0 ; then
-				LIBC="libc1"
-			fi
-		fi
-		rm -f $dummy.c $dummy
-		echo powerpc-unknown-linux-gnu${LIBC}
-		exit 0
-		;;
-	  shelf_linux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnu"
-		exit 0
-		;;
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
 	esac
-
-	if test "${UNAME_MACHINE}" = "alpha" ; then
-		cat <<EOF >$dummy.s
-			.data
-		\$Lformat:
-			.byte 37,100,45,37,120,10,0	# "%d-%x\n"
-
-			.text
-			.globl main
-			.align 4
-			.ent main
-		main:
-			.frame \$30,16,\$26,0
-			ldgp \$29,0(\$27)
-			.prologue 1
-			.long 0x47e03d80 # implver \$0
-			lda \$2,-1
-			.long 0x47e20c21 # amask \$2,\$1
-			lda \$16,\$Lformat
-			mov \$0,\$17
-			not \$1,\$18
-			jsr \$26,printf
-			ldgp \$29,0(\$26)
-			mov 0,\$16
-			jsr \$26,exit
-			.end main
-EOF
-		LIBC=""
-		$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-		if test "$?" = 0 ; then
-			case `./$dummy` in
-			0-0)
-				UNAME_MACHINE="alpha"
-				;;
-			1-0)
-				UNAME_MACHINE="alphaev5"
-				;;
-			1-1)
-				UNAME_MACHINE="alphaev56"
-				;;
-			1-101)
-				UNAME_MACHINE="alphapca56"
-				;;
-			2-303)
-				UNAME_MACHINE="alphaev6"
-				;;
-			2-307)
-				UNAME_MACHINE="alphaev67"
-				;;
-			esac
-
-			objdump --private-headers $dummy | \
-			  grep ld.so.1 > /dev/null
-			if test "$?" = 0 ; then
-				LIBC="libc1"
-			fi
-		fi
-		rm -f $dummy.s $dummy
-		echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
-	elif test "${UNAME_MACHINE}" = "mips" ; then
-	  cat >$dummy.c <<EOF
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-	int main (int argc, char *argv[]) {
-#else
-	int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __MIPSEB__
-  printf ("%s-unknown-linux-gnu\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
-  printf ("%sel-unknown-linux-gnu\n", argv[1]);
-#endif
-  return 0;
-}
-EOF
-	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
-	  rm -f $dummy.c $dummy
-	elif test "${UNAME_MACHINE}" = "s390"; then
-	  echo s390-ibm-linux && exit 0
-	else
-	  # Either a pre-BFD a.out linker (linux-gnuoldld)
-	  # or one that does not give us useful --help.
-	  # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
-	  # If ld does not provide *any* "supported emulations:"
-	  # that means it is gnuoldld.
-	  echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
-	  test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
-
-	  case "${UNAME_MACHINE}" in
-	  i?86)
-	    VENDOR=pc;
-	    ;;
-	  *)
-	    VENDOR=unknown;
-	    ;;
-	  esac
-	  # Determine whether the default compiler is a.out or elf
-	  cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-	int main (int argc, char *argv[]) {
-#else
-	int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-#  if __GLIBC__ >= 2
-    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
-#  else
-    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-#  endif
-# else
-   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-# endif
-#else
-  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
-#endif
-  return 0;
-}
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
 EOF
-	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
-	  rm -f $dummy.c $dummy
-	fi ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
-# are messed up and put the nodename in both sysname and nodename.
-    i?86:DYNIX/ptx:4*:*)
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
 	echo i386-sequent-sysv4
 	exit 0 ;;
-    i?86:UNIX_SV:4.2MP:2.*)
+    i*86:UNIX_SV:4.2MP:2.*)
         # Unixware is an offshoot of SVR4, but it has its own version
         # number series starting with 2...
         # I am not positive that other SVR4 systems won't match this,
@@ -911,7 +970,24 @@ EOF
         # Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
 	exit 0 ;;
-    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
 		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
@@ -919,36 +995,32 @@ EOF
 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
 	fi
 	exit 0 ;;
-    i?86:*:5:7*)
-        # Fixed at (any) Pentium or better
-        UNAME_MACHINE=i586
-        if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
-	    echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
-	else
-	    echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
-	fi
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
 	exit 0 ;;
-    i?86:*:3.2:*)
+    i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
 		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
-		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
-		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 			&& UNAME_MACHINE=i586
-		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
 		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
 	else
 		echo ${UNAME_MACHINE}-pc-sysv32
 	fi
 	exit 0 ;;
-    i?86:*DOS:*:*)
-	echo ${UNAME_MACHINE}-pc-msdosdjgpp
-	exit 0 ;;
     pc:*:*:*)
 	# Left here for compatibility:
         # uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -972,9 +1044,15 @@ EOF
 	# "miniframe"
 	echo m68010-convergent-sysv
 	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
     M68*:*:R3V[567]*:*)
 	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
-    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -985,21 +1063,21 @@ EOF
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
           && echo i486-ncr-sysv4 && exit 0 ;;
-    m68*:LynxOS:2.*:*)
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
 	exit 0 ;;
     mc68030:UNIX_System_V:4.*:*)
 	echo m68k-atari-sysv4
 	exit 0 ;;
-    i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
-	echo i386-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
     TSUNAMI:LynxOS:2.*:*)
 	echo sparc-unknown-lynxos${UNAME_RELEASE}
 	exit 0 ;;
-    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+    rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
 	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
     SM[BE]S:UNIX_SV:*:*)
 	echo mips-dde-sysv${UNAME_RELEASE}
 	exit 0 ;;
@@ -1017,8 +1095,8 @@ EOF
 		echo ns32k-sni-sysv
 	fi
 	exit 0 ;;
-    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
         echo i586-unisys-sysv4
         exit 0 ;;
     *:UNIX_System_V:4*:FTX*)
@@ -1030,10 +1108,14 @@ EOF
 	# From seanf@swdc.stratus.com.
 	echo i860-stratus-sysv4
 	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
     mc68*:A/UX:*:*)
 	echo m68k-apple-aux${UNAME_RELEASE}
 	exit 0 ;;
-    news*:NEWS-OS:*:6*)
+    news*:NEWS-OS:6*:*)
 	echo mips-sony-newsos6
 	exit 0 ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
@@ -1058,6 +1140,9 @@ EOF
     SX-5:SUPER-UX:*:*)
 	echo sx5-nec-superux${UNAME_RELEASE}
 	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 	exit 0 ;;
@@ -1065,31 +1150,73 @@ EOF
 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
 	exit 0 ;;
     *:Darwin:*:*)
-	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit 0 ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
-	if test "${UNAME_MACHINE}" = "x86pc"; then
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
-	echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
 	exit 0 ;;
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit 0 ;;
-    NSR-W:NONSTOP_KERNEL:*:*)
+    NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
 	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
     BS2000:POSIX*:*:*)
 	echo bs2000-siemens-sysv
 	exit 0 ;;
     DS/*:UNIX_System_V:*:*)
 	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
 	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
 
+eval $set_cc_for_build
 cat >$dummy.c <<EOF
 #ifdef _SEQUENT_
 # include <sys/types.h>
@@ -1176,11 +1303,24 @@ main ()
 #endif
 
 #if defined (vax)
-#if !defined (ultrix)
-  printf ("vax-dec-bsd\n"); exit (0);
-#else
-  printf ("vax-dec-ultrix\n"); exit (0);
-#endif
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
 #endif
 
 #if defined (alliant) && defined (i860)
@@ -1191,8 +1331,7 @@ main ()
 }
 EOF
 
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
 
 # Apollos put the system type in the environment.
 
@@ -1227,8 +1366,9 @@ fi
 cat >&2 <<EOF
 $0: unable to guess system type
 
-The $version version of this script cannot recognize your system type.
-Please download the most up to date version of the config scripts:
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
 
     ftp://ftp.gnu.org/pub/gnu/config/
 
@@ -1237,7 +1377,7 @@ send the following data and any information you think might be
 pertinent to <config-patches@gnu.org> in order to provide the needed
 information to handle your system.
 
-config.guess version = $version
+config.guess timestamp = $timestamp
 
 uname -m = `(uname -m) 2>/dev/null || echo unknown`
 uname -r = `(uname -r) 2>/dev/null || echo unknown`
@@ -1264,7 +1404,7 @@ exit 1
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "version='"
+# time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
 # End:
diff --git a/src/config/config.sub b/src/config/config.sub
index cb86fe1ef..1f31816b9 100644
--- a/src/config/config.sub
+++ b/src/config/config.sub
@@ -1,9 +1,9 @@
 #! /bin/sh
-# Configuration validation subroutine script, version 1.1.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-#   Free Software Foundation, Inc.
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-version='2000-05-31'
+timestamp='2003-08-18'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -29,8 +29,8 @@ version='2000-05-31'
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -61,16 +61,30 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS
 Canonicalize a configuration name.
 
 Operation modes:
-  -h, --help               print this help, then exit
-  -V, --version            print version number, then exit"
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 
 help="
 Try \`$me --help' for more information."
 
 # Parse command line
 while test $# -gt 0 ; do
-  case "$1" in
-    --version | --vers* | -V )
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
        echo "$version" ; exit 0 ;;
     --help | --h* | -h )
        echo "$usage"; exit 0 ;;
@@ -79,9 +93,7 @@ while test $# -gt 0 ; do
     - )	# Use stdin as input.
        break ;;
     -* )
-       exec >&2
-       echo "$me: invalid option $1"
-       echo "$help"
+       echo "$me: invalid option $1$help"
        exit 1 ;;
 
     *local*)
@@ -106,7 +118,7 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu*)
+  nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
@@ -132,7 +144,7 @@ case $os in
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple)
+	-apple | -axis)
 		os=
 		basic_machine=$1
 		;;
@@ -146,6 +158,14 @@ case $os in
 		os=-vxworks
 		basic_machine=$1
 		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
 	-hiux*)
 		os=-hiuxwe2
 		;;
@@ -204,30 +224,64 @@ esac
 case $basic_machine in
 	# Recognize the basic CPU types without company name.
 	# Some are omitted here because they have special meanings below.
-	tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
-		| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
-		| 580 | i960 | h8300 \
-		| x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
-		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
-		| hppa64 \
-		| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
-		| alphaev6[78] \
-		| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
-		| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
-		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
-		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
-		| mips64vr5000 | miprs64vr5000el | mcore \
-		| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
-		| thumb | d10v | fr30 | avr)
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
 		basic_machine=$basic_machine-unknown
+		os=-none
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
-	i[34567]86)
+	i*86 | x86_64)
 	  basic_machine=$basic_machine-pc
 	  ;;
 	# Object if more than one company name word.
@@ -236,28 +290,61 @@ case $basic_machine in
 		exit 1
 		;;
 	# Recognize the basic CPU types with company name.
-	# FIXME: clean up the formatting here.
-	vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
-	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
-	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
-	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
-	      | xmp-* | ymp-* \
-	      | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
-	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
-	      | hppa2.0n-* | hppa64-* \
-	      | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
-	      | alphaev6[78]-* \
-	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
-	      | clipper-* | orion-* \
-	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
-	      | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
-	      | mips64el-* | mips64orion-* | mips64orionel-* \
-	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
-	      | mipstx39-* | mipstx39el-* | mcore-* \
-	      | f301-* | armv*-* | s390-* | sv1-* | t3e-* \
-	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
-	      | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
-	      | bs2000-*)
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
 		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
@@ -289,19 +376,22 @@ case $basic_machine in
 		basic_machine=a29k-none
 		os=-bsd
 		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
 	amdahl)
 		basic_machine=580-amdahl
 		os=-sysv
 		;;
 	amiga | amiga-*)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		;;
 	amigaos | amigados)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		os=-amigaos
 		;;
 	amigaunix | amix)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		os=-sysv4
 		;;
 	apollo68)
@@ -320,6 +410,10 @@ case $basic_machine in
 		basic_machine=ns32k-sequent
 		os=-dynix
 		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -340,27 +434,30 @@ case $basic_machine in
 		basic_machine=c38-convex
 		os=-bsd
 		;;
-	cray | ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	cray2)
-		basic_machine=cray2-cray
-		os=-unicos
-		;;
-	[ctj]90-cray)
-		basic_machine=c90-cray
+	cray | j90)
+		basic_machine=j90-cray
 		os=-unicos
 		;;
 	crds | unos)
 		basic_machine=m68k-crds
 		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
 	da30 | da30-*)
 		basic_machine=m68k-da30
 		;;
 	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
 		basic_machine=mips-dec
 		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
 	delta | 3300 | motorola-3300 | motorola-delta \
 	      | 3300-motorola | delta-motorola)
 		basic_machine=m68k-motorola
@@ -402,6 +499,10 @@ case $basic_machine in
 		basic_machine=tron-gmicro
 		os=-sysv
 		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
 	h3050r* | hiux*)
 		basic_machine=hppa1.1-hitachi
 		os=-hiuxwe2
@@ -477,19 +578,19 @@ case $basic_machine in
 		basic_machine=i370-ibm
 		;;
 # I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-	i[34567]86v32)
+	i*86v32)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv32
 		;;
-	i[34567]86v4*)
+	i*86v4*)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv4
 		;;
-	i[34567]86v)
+	i*86v)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv
 		;;
-	i[34567]86sol2)
+	i*86sol2)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-solaris2
 		;;
@@ -501,14 +602,6 @@ case $basic_machine in
 		basic_machine=i386-unknown
 		os=-vsta
 		;;
-	i386-go32 | go32)
-		basic_machine=i386-unknown
-		os=-go32
-		;;
-	i386-mingw32 | mingw32)
-		basic_machine=i386-unknown
-		os=-mingw32
-		;;
 	iris | iris4d)
 		basic_machine=mips-sgi
 		case $os in
@@ -534,6 +627,10 @@ case $basic_machine in
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -541,14 +638,6 @@ case $basic_machine in
 		basic_machine=m68k-atari
 		os=-mint
 		;;
-	mipsel*-linux*)
-		basic_machine=mipsel-unknown
-		os=-linux-gnu
-		;;
-	mips*-linux*)
-		basic_machine=mips-unknown
-		os=-linux-gnu
-		;;
 	mips3*-*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
 		;;
@@ -563,8 +652,12 @@ case $basic_machine in
 		basic_machine=m68k-rom68k
 		os=-coff
 		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
 	msdos)
-		basic_machine=i386-unknown
+		basic_machine=i386-pc
 		os=-msdos
 		;;
 	mvs)
@@ -628,9 +721,17 @@ case $basic_machine in
 		basic_machine=i960-intel
 		os=-mon960
 		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
 	np1)
 		basic_machine=np1-gould
 		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -638,6 +739,10 @@ case $basic_machine in
 		basic_machine=hppa1.1-oki
 		os=-proelf
 		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
 	OSE68000 | ose68000)
 		basic_machine=m68000-ericsson
 		os=-ose
@@ -660,45 +765,65 @@ case $basic_machine in
 	pbb)
 		basic_machine=m68k-tti
 		;;
-        pc532 | pc532-*)
+	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
-	pentium | p5 | k5 | k6 | nexen)
+	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
-	pentiumpro | p6 | 6x86 | athlon)
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
 		basic_machine=i686-pc
 		;;
-	pentiumii | pentium2)
+	pentium4)
 		basic_machine=i786-pc
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexen-*)
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentiumii-* | pentium2-*)
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
 		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	pn)
 		basic_machine=pn-gould
 		;;
-	power)	basic_machine=rs6000-ibm
+	power)	basic_machine=power-ibm
 		;;
 	ppc)	basic_machine=powerpc-unknown
-	        ;;
+		;;
 	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppcle | powerpclittle | ppc-le | powerpc-little)
 		basic_machine=powerpcle-unknown
-	        ;;
+		;;
 	ppcle-* | powerpclittle-*)
 		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	ps2)
 		basic_machine=i386-ibm
 		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -709,10 +834,26 @@ case $basic_machine in
 	rtpc | rtpc-*)
 		basic_machine=romp-ibm
 		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
 	sa29200)
 		basic_machine=a29k-amd
 		os=-udi
 		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
 	sequent)
 		basic_machine=i386-sequent
 		;;
@@ -720,7 +861,10 @@ case $basic_machine in
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
-	sparclite-wrs)
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
 		basic_machine=sparclite-wrs
 		os=-vxworks
 		;;
@@ -787,15 +931,35 @@ case $basic_machine in
 		os=-dynix
 		;;
 	t3e)
-		basic_machine=t3e-cray
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
 		os=-unicos
 		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
 	tx39)
 		basic_machine=mipstx39-unknown
 		;;
 	tx39el)
 		basic_machine=mipstx39el-unknown
 		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
 	tower | tower-32)
 		basic_machine=m68k-ncr
 		;;
@@ -820,8 +984,8 @@ case $basic_machine in
 		os=-vms
 		;;
 	vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
+		basic_machine=f301-fujitsu
+		;;
 	vxworks960)
 		basic_machine=i960-wrs
 		os=-vxworks
@@ -842,13 +1006,13 @@ case $basic_machine in
 		basic_machine=hppa1.1-winbond
 		os=-proelf
 		;;
-	xmp)
-		basic_machine=xmp-cray
-		os=-unicos
-		;;
-        xps | xps100)
+	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
 	z8k-*-coff)
 		basic_machine=z8k-unknown
 		os=-sim
@@ -869,13 +1033,6 @@ case $basic_machine in
 	op60c)
 		basic_machine=hppa1.1-oki
 		;;
-	mips)
-		if [ x$os = x-linux-gnu ]; then
-			basic_machine=mips-unknown
-		else
-			basic_machine=mips-mips
-		fi
-		;;
 	romp)
 		basic_machine=romp-ibm
 		;;
@@ -885,16 +1042,26 @@ case $basic_machine in
 	vax)
 		basic_machine=vax-dec
 		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
 	pdp11)
 		basic_machine=pdp11-dec
 		;;
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sparc | sparcv9)
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
 		basic_machine=sparc-sun
 		;;
-        cydra)
+	cydra)
 		basic_machine=cydra-cydrome
 		;;
 	orion)
@@ -909,9 +1076,8 @@ case $basic_machine in
 	pmac | pmac-mpw)
 		basic_machine=powerpc-apple
 		;;
-	c4x*)
-		basic_machine=c4x-none
-		os=-coff
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
 		;;
 	*)
 		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
@@ -965,27 +1131,34 @@ case $os in
 	      | -aos* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
 	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
-	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
-	      | -openstep* | -oskit*)
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
 		case $basic_machine in
-		    x86-* | i[34567]86-*)
+		    x86-* | i*86-*)
 			;;
 		    *)
 			os=-nto$os
 			;;
 		esac
 		;;
+	-nto-qnx*)
+		;;
 	-nto*)
-		os=-nto-qnx
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
 	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
 	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -994,6 +1167,9 @@ case $os in
 	-mac*)
 		os=`echo $os | sed -e 's|mac|macos|'`
 		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
 	-linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
@@ -1024,16 +1200,22 @@ case $os in
 	-acis*)
 		os=-aos
 		;;
+	-atheos*)
+		os=-atheos
+		;;
 	-386bsd)
 		os=-bsd
 		;;
 	-ctix* | -uts*)
 		os=-sysv
 		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
 	-ns2 )
-	        os=-nextstep2
+		os=-nextstep2
 		;;
-	-nsk)
+	-nsk*)
 		os=-nsk
 		;;
 	# Preserve the version number of sinix5.
@@ -1070,8 +1252,14 @@ case $os in
 	-xenix)
 		os=-xenix
 		;;
-        -*mint | -*MiNT)
-	        os=-mint
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
 		;;
 	-none)
 		;;
@@ -1104,7 +1292,14 @@ case $basic_machine in
 	arm*-semi)
 		os=-aout
 		;;
-        pdp11-*)
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
 		os=-none
 		;;
 	*-dec | vax-*)
@@ -1131,6 +1326,9 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
+	or32-*)
+		os=-coff
+		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
 		os=-sysv3
 		;;
@@ -1194,25 +1392,25 @@ case $basic_machine in
 	*-next)
 		os=-nextstep3
 		;;
-        *-gould)
+	*-gould)
 		os=-sysv
 		;;
-        *-highlevel)
+	*-highlevel)
 		os=-bsd
 		;;
 	*-encore)
 		os=-bsd
 		;;
-        *-sgi)
+	*-sgi)
 		os=-irix
 		;;
-        *-siemens)
+	*-siemens)
 		os=-sysv4
 		;;
 	*-masscomp)
 		os=-rtu
 		;;
-	f301-fujitsu)
+	f30[01]-fujitsu | f700-fujitsu)
 		os=-uxpv
 		;;
 	*-rom68k)
@@ -1278,7 +1476,7 @@ case $basic_machine in
 			-ptx*)
 				vendor=sequent
 				;;
-			-vxsim* | -vxworks*)
+			-vxsim* | -vxworks* | -windiss*)
 				vendor=wrs
 				;;
 			-aux*)
@@ -1290,9 +1488,12 @@ case $basic_machine in
 			-mpw* | -macos*)
 				vendor=apple
 				;;
-			-*mint | -*MiNT)
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 				vendor=atari
 				;;
+			-vos*)
+				vendor=stratus
+				;;
 		esac
 		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
 		;;
@@ -1303,7 +1504,7 @@ exit 0
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "version='"
+# time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
 # End:
diff --git a/src/config/install-sh b/src/config/install-sh
index e9de23842..f5061e7e2 100644
--- a/src/config/install-sh
+++ b/src/config/install-sh
@@ -1,19 +1,38 @@
 #!/bin/sh
-#
 # install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
+
+scriptversion=2003-09-24.23
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
 #
-# Copyright 1991 by the Massachusetts Institute of Technology
 #
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
+# FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
 # `make' implicit rules from creating a file called install from it
@@ -23,13 +42,11 @@
 # from scratch.  It can only install one file at a time, a restriction
 # shared with many OS's install programs.
 
-
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
 doit="${DOITPROG-}"
 
-
 # put in absolute paths if you don't have them in your path; or use env. vars.
 
 mvprog="${MVPROG-mv}"
@@ -41,211 +58,238 @@ stripprog="${STRIPPROG-strip}"
 rmprog="${RMPROG-rm}"
 mkdirprog="${MKDIRPROG-mkdir}"
 
-transformbasename=""
-transform_arg=""
+transformbasename=
+transform_arg=
 instcmd="$mvprog"
 chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
+chowncmd=
+chgrpcmd=
+stripcmd=
 rmcmd="$rmprog -f"
 mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-	-c) instcmd="$cpprog"
-	    shift
-	    continue;;
-
-	-d) dir_arg=true
-	    shift
-	    continue;;
-
-	-m) chmodcmd="$chmodprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-o) chowncmd="$chownprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-g) chgrpcmd="$chgrpprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-s) stripcmd="$stripprog"
-	    shift
-	    continue;;
-
-	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
-	    shift
-	    continue;;
-
-	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-	    shift
-	    continue;;
-
-	*)  if [ x"$src" = x ]
-	    then
-		src=$1
-	    else
-		# this colon is to work around a 386BSD /bin/sh bug
-		:
-		dst=$1
-	    fi
-	    shift
-	    continue;;
-    esac
+src=
+dst=
+dir_arg=
+
+usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
+   or: $0 -d DIR1 DIR2...
+
+In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
+In the second, create the directory path DIR.
+
+Options:
+-b=TRANSFORMBASENAME
+-c         copy source (using $cpprog) instead of moving (using $mvprog).
+-d         create directories instead of installing files.
+-g GROUP   $chgrp installed files to GROUP.
+-m MODE    $chmod installed files to MODE.
+-o USER    $chown installed files to USER.
+-s         strip installed files (using $stripprog).
+-t=TRANSFORM
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+        shift
+        continue;;
+
+    -c) instcmd=$cpprog
+        shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit 0;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+        shift
+        continue;;
+
+    --version) echo "$0 $scriptversion"; exit 0;;
+
+    *)  if test -z "$src"; then
+          src=$1
+        else
+          # this colon is to work around a 386BSD /bin/sh bug
+          :
+          dst=$1
+        fi
+        shift
+        continue;;
+  esac
 done
 
-if [ x"$src" = x ]
-then
-	echo "install:	no input file specified"
-	exit 1
-else
-	true
+if test -z "$src"; then
+  echo "$0: no input file specified." >&2
+  exit 1
 fi
 
-if [ x"$dir_arg" != x ]; then
-	dst=$src
-	src=""
-	
-	if [ -d $dst ]; then
-		instcmd=:
-		chmodcmd=""
-	else
-		instcmd=mkdir
-	fi
+# Protect names starting with `-'.
+case $src in
+  -*) src=./$src ;;
+esac
+
+if test -n "$dir_arg"; then
+  dst=$src
+  src=
+
+  if test -d "$dst"; then
+    instcmd=:
+    chmodcmd=
+  else
+    instcmd=$mkdirprog
+  fi
 else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-	if [ -f $src -o -d $src ]
-	then
-		true
-	else
-		echo "install:  $src does not exist"
-		exit 1
-	fi
-	
-	if [ x"$dst" = x ]
-	then
-		echo "install:	no destination specified"
-		exit 1
-	else
-		true
-	fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-	if [ -d $dst ]
-	then
-		dst="$dst"/`basename $src`
-	else
-		true
-	fi
+  # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+  # might cause directories to be created, which would be especially bad
+  # if $src (and thus $dsttmp) contains '*'.
+  if test ! -f "$src" && test ! -d "$src"; then
+    echo "$0: $src does not exist." >&2
+    exit 1
+  fi
+
+  if test -z "$dst"; then
+    echo "$0: no destination specified." >&2
+    exit 1
+  fi
+
+  # Protect names starting with `-'.
+  case $dst in
+    -*) dst=./$dst ;;
+  esac
+
+  # If destination is a directory, append the input filename; won't work
+  # if double slashes aren't ignored.
+  if test -d "$dst"; then
+    dst=$dst/`basename "$src"`
+  fi
 fi
 
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+# This sed command emulates the dirname command.
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
 
 # Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
 
 # Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='	
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
-	pathcomp="${pathcomp}${1}"
-	shift
-
-	if [ ! -d "${pathcomp}" ] ;
-        then
-		$mkdirprog "${pathcomp}"
-	else
-		true
-	fi
-
-	pathcomp="${pathcomp}/"
-done
+if test ! -d "$dstdir"; then
+  defaultIFS='
+	'
+  IFS="${IFS-$defaultIFS}"
+
+  oIFS=$IFS
+  # Some sh's can't handle IFS=/ for some reason.
+  IFS='%'
+  set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+  IFS=$oIFS
+
+  pathcomp=
+
+  while test $# -ne 0 ; do
+    pathcomp=$pathcomp$1
+    shift
+    test -d "$pathcomp" || $mkdirprog "$pathcomp"
+    pathcomp=$pathcomp/
+  done
 fi
 
-if [ x"$dir_arg" != x ]
-then
-	$doit $instcmd $dst &&
+if test -n "$dir_arg"; then
+  $doit $instcmd "$dst" \
+    && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+    && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+    && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
 
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
 else
-
-# If we're going to rename the final executable, determine the name now.
-
-	if [ x"$transformarg" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		dstfile=`basename $dst $transformbasename | 
-			sed $transformarg`$transformbasename
-	fi
-
-# don't allow the sed command to completely eliminate the filename
-
-	if [ x"$dstfile" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		true
-	fi
-
-# Make a temp file name in the proper directory.
-
-	dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
-	$doit $instcmd $src $dsttmp &&
-
-	trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
-	$doit $rmcmd -f $dstdir/$dstfile &&
-	$doit $mvcmd $dsttmp $dstdir/$dstfile 
-
+  # If we're going to rename the final executable, determine the name now.
+  if test -z "$transformarg"; then
+    dstfile=`basename "$dst"`
+  else
+    dstfile=`basename "$dst" $transformbasename \
+             | sed $transformarg`$transformbasename
+  fi
+
+  # don't allow the sed command to completely eliminate the filename.
+  test -z "$dstfile" && dstfile=`basename "$dst"`
+
+  # Make a couple of temp file names in the proper directory.
+  dsttmp=$dstdir/_inst.$$_
+  rmtmp=$dstdir/_rm.$$_
+
+  # Trap to clean up those temp files at exit.
+  trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Move or copy the file name to the temp name
+  $doit $instcmd "$src" "$dsttmp" &&
+
+  # and set any options; do chmod last to preserve setuid bits.
+  #
+  # If any of these fail, we abort the whole thing.  If we want to
+  # ignore errors from any of these, just make sure not to ignore
+  # errors from the above "$doit $instcmd $src $dsttmp" command.
+  #
+  { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+    && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+    && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+  # Now remove or move aside any old file at destination location.  We
+  # try this two ways since rm can't unlink itself on some systems and
+  # the destination file might be busy for other reasons.  In this case,
+  # the final cleanup might fail but the new file should still install
+  # successfully.
+  {
+    if test -f "$dstdir/$dstfile"; then
+      $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+      || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+      || {
+	  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+	  (exit 1); exit
+      }
+    else
+      :
+    fi
+  } &&
+
+  # Now rename the file to the real destination.
+  $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
 fi &&
 
-
-exit 0
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/src/config/post.in b/src/config/post.in
index 2c49dd304..0a14ce852 100644
--- a/src/config/post.in
+++ b/src/config/post.in
@@ -149,7 +149,8 @@ $(srcdir)/$(thisconfigdir)/configure: $(srcdir)/$(thisconfigdir)/configure.in \
 		$(SRCTOP)/aclocal.m4
 	-$(RM) -r $(srcdir)/$(thisconfigdir)/autom4te.cache
 	cd $(srcdir)/$(thisconfigdir) && \
-		$(AUTOCONF) ${AUTOCONFINCFLAGS}=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS)
+		($(AUTOCONF) --include=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS) || \
+		 $(AUTOCONF) --localdir=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS))
 	-$(RM) -r $(srcdir)/$(thisconfigdir)/autom4te.cache
 
 RECURSE_TARGETS=all-recurse clean-recurse distclean-recurse install-recurse \
diff --git a/src/config/pre.in b/src/config/pre.in
index c36b4ee8b..f89a9da40 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -291,12 +291,11 @@ COM_ERR_DEPLIB-k5 = $(TOPLIBD)/libcom_err$(DEPLIBEXT)
 SS_DEPLIB	= $(SS_DEPLIB-@SS_VERSION@)
 SS_DEPLIB-k5	= $(TOPLIBD)/libss.a
 SS_DEPLIB-sys	=
-KRB524_DEPLIB	= @KRB524_DEPLIB@
 PTY_DEPLIB	= $(TOPLIBD)/libpty.a
 
 KRB5_BASE_DEPLIBS	= $(KRB5_DEPLIB) $(CRYPTO_DEPLIB) $(COM_ERR_DEPLIB)
 KRB4COMPAT_DEPLIBS	= $(KRB4_DEPLIB) $(DES425_DEPLIB) $(KRB5_BASE_DEPLIBS)
-KDB5_DEPLIBS		= $(KDB5_DEPLIB) $(DB_DEPLIB)
+KDB5_DEPLIBS		= $(KDB5_DEPLIB)
 GSS_DEPLIBS		= $(GSS_DEPLIB)
 GSSRPC_DEPLIBS		= $(GSSRPC_DEPLIB) $(GSS_DEPLIBS)
 KADM_COMM_DEPLIBS	= $(GSSRPC_DEPLIBS) $(KDB5_DEPLIBS) $(GSSRPC_DEPLIBS)
@@ -325,8 +324,6 @@ DB_DEPS-redirect = $(BUILDTOP)/include/db.h
 # is compiled.
 
 KRB_ERR_H_DEP	= @KRB_ERR_H_DEP@
-KRB524_H_DEP	= @KRB524_H_DEP@
-KRB524_ERR_H_DEP= @KRB524_ERR_H_DEP@
 
 # LIBS gets substituted in... e.g. -lnsl -lsocket
 
@@ -338,6 +335,7 @@ SS_LIB-sys	= @SS_LIB@
 SS_LIB-k5	= $(TOPLIBD)/libss.a
 KDB5_LIB	= -lkdb5
 DB_LIB		= @DB_LIB@
+KDB5_DB_LIB	= @KDB5_DB_LIB@
 
 KRB5_LIB			= -lkrb5
 K5CRYPTO_LIB			= -lk5crypto
@@ -352,16 +350,12 @@ KRB4_LIB	= @KRB4_LIB@
 # needs fixing if ever used on Mac OS X!
 DES425_LIB	= @DES425_LIB@
 
-# KRB524_LIB is $(BUILDTOP)/krb524/libkrb524.a if building --with-krb4
-# needs fixing if ever used on Mac OS X!
-KRB524_LIB	= @KRB524_LIB@
-
 # HESIOD_LIBS is -lhesiod...
 HESIOD_LIBS	= @HESIOD_LIBS@
 
 KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(GEN_LIB) $(LIBS)
 KRB4COMPAT_LIBS	= $(KRB4_LIB) $(DES425_LIB) $(KRB5_BASE_LIBS)
-KDB5_LIBS	= $(KDB5_LIB) $(DB_LIB)
+KDB5_LIBS	= $(KDB5_LIB) $(KDB5_DB_LIB)
 GSS_LIBS	= $(GSS_KRB5_LIB)
 # needs fixing if ever used on Mac OS X!
 GSSRPC_LIBS	= -lgssrpc $(GSS_LIBS)
diff --git a/src/config/shlib.conf b/src/config/shlib.conf
index 156495f64..7f04155cc 100644
--- a/src/config/shlib.conf
+++ b/src/config/shlib.conf
@@ -263,21 +263,27 @@ mips-*-netbsd*)
 	SHLIBEXT=.so
 	# Linux ld doesn't default to stuffing the SONAME field...
 	# Use objdump -x to examine the fields of the library
-	LDCOMBINE='ld -shared -h lib$(LIB)$(SHLIBSEXT)'
-	# Linux libc does weird stuff at shlib link time, must be
-	# explicitly listed here.  This also makes it get used even
-	# for the libraries marked as not having any dependencies; while
-	# that's not strictly correct, the resulting behavior -- not adding
-	# extra -R directories -- is still what we want.
-	LDCOMBINE_TAIL="-lc"
+	LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,lib$(LIB)$(SHLIBSEXT)'
+	LDCOMBINE_TAIL=''
 	# For cases where we do have dependencies on other libraries
 	# built in this tree...
-	SHLIB_EXPFLAGS='-R$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
+	SHLIB_EXPFLAGS='-Wl,-R$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
 	PROFFLAGS=-pg
 	RPATH_FLAG='-Wl,-rpath -Wl,'
 	CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(RPATH_FLAG)$(PROG_RPATH) $(CFLAGS) $(LDFLAGS)'
 	CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
 	RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`; export LD_LIBRARY_PATH;'
+
+	## old version:
+	# Linux libc does weird stuff at shlib link time, must be
+	# explicitly listed here.  This also makes it get used even
+	# for the libraries marked as not having any dependencies; while
+	# that's not strictly correct, the resulting behavior -- not adding
+	# extra -R directories -- is still what we want.
+	#LDCOMBINE='ld -shared -h lib$(LIB)$(SHLIBSEXT)'
+	#LDCOMBINE_TAIL="-lc"
+	#SHLIB_EXPFLAGS='-R$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
+
 	;;
 
 *-*-aix*)
diff --git a/src/config/win-pre.in b/src/config/win-pre.in
index b6cfd0bc4..759046241 100644
--- a/src/config/win-pre.in
+++ b/src/config/win-pre.in
@@ -116,13 +116,17 @@ DNSLIBS=
 DNSFLAGS=
 !endif
 
+!if defined(KRB5_KFW_COMPILE)
+KFWFLAGS=-DUSE_LEASH=1
+!endif
+
 #
 # The name of the C compiler for the target
 #
 CC=cl
 
 PDB_OPTS=-Fd$(OUTPRE)\ -FD
-CPPFLAGS=-I$(SRCTOP)\include -I$(SRCTOP)\include\krb5 $(DNSFLAGS) -DKRB5_PRIVATE=1 -DWIN32_LEAN_AND_MEAN
+CPPFLAGS=-I$(SRCTOP)\include -I$(SRCTOP)\include\krb5 $(DNSFLAGS) -DKRB5_PRIVATE=1 -DWIN32_LEAN_AND_MEAN -DKRB5_DEPRECATED=1 $(KFWFLAGS)
 CCOPTS=-nologo /W3 $(PDB_OPTS) $(DLL_FILE_DEF)
 LOPTS=-nologo -incremental:no
 
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index a8e7726f5..f7283b900 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -1,3 +1,244 @@
+2004-01-04 Jeffrey Altman <jaltman@mit.edu>
+
+    * win-mac.h: conditionally define strcasecmp/strncasecmp macros 
+      only if they do not already exist.
+
+2003-12-18  Jeffrey Altman <jaltman@mit.edu>
+
+    * k5-int.h: add new functions to krb5int_access for use by gssapi
+
+2003-12-15  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-platform.h (SIZE_MAX): Provide default definition if stdint.h
+	doesn't define it.
+
+2003-12-15  Jeffrey Altman <jaltman@mit.edu>
+
+  * win-mac.h: source code written to the C99 standard assumes there
+    are standard definitions for the MAX sizes of C types including
+    size_t.  The MAX preprocessor variables are declared in limits.h
+    but limits.h is not included by any of the other header files.
+    We will therefore include it via win-mac.h.  We must also add a
+    declaration of SIZE_MAX (for size_t) because Microsoft does not
+    provide one.  
+
+2003-12-15  Jeffrey Altman <jaltman@mit.edu>
+
+  * k5-platform.h: apply casts (unsigned char) to the assignments from
+    64-bit ints to unsigned char fields to avoid warnings 
+
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* krb5.hin (KRB5_AUTH_CONTEXT_USE_SUBKEY): New macro.
+
+	* k5-int.h (struct krb5_keytypes): Added field required_ctype.
+	(krb5int_c_mandatory_cksumtype): New declaration.
+	(krb5int_generate_and_set_subkey): Declare.
+	(memset) [__GNUC__ && __GLIBC__]: Undef, to reduce compilation
+	warnings in zap() macro with volatile pointer.
+
+	* k5-platform.h: New header file.  Manages inline-function and
+	64-bit support, in platform-specific ways.
+	* fake-addrinfo.h: Include k5-platform.h.
+	(inline): Don't define here.
+	* k5-int.h: Include k5-platform.h.
+	(krb5_ui_8, krb5_int64): New typedefs.
+	(krb5_ser_pack_int64, krb5_ser_unpack_int64): New function decls.
+
+2003-10-08  Tom Yu  <tlyu@mit.edu>
+
+	* k5-int.h: Add prototypes for decode_krb5_safe_with_body and
+	encode_krb5_safe_with_body.
+
+2003-08-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* fake-addrinfo.h (WRAP_GETADDRINFO, COPY_FIRST_CANONNAME): Don't
+	define on Linux unless HAVE_GETADDRINFO is defined, for libc5
+	compatibility.
+
+2003-08-26  Ken Raeburn  <raeburn@mit.edu>
+
+	* foreachaddr.c (foreach_localaddr) [HAVE_IFADDRS_H]: Skip over
+	any returned data structure with a NULL ifa_addr field.
+
+2003-07-31  Jeffrey Altman  <jaltman@mit.edu>
+
+	* krb5.hin: krb5_get_host_realm and krb5_free_host_realm should
+	not be labeled as KRB5_PRIVATE.  They are required for many
+	applications including OpenAFS and UMich's Kx509.  1.2.8 had them
+	public but the change was never reflected on the trunk.
+
+2003-07-22  Alexandra Ellwood  <lxs@mit.edu>
+
+        * fake-addrinfo.h: Don't use broken getaddrinfo on Mac OS X
+
+2003-07-22  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (krb5int_zap_data, zap): New macros; call memset with
+	volatile cast for now.
+
+2003-07-21  Alexandra Ellwood  <lxs@mit.edu>
+
+        * krb5_32.def: Export krb5_principal2salt.
+
+2003-07-09  Alexandra Ellwood  <lxs@mit.edu>
+
+        * krb5.hin: Export krb5_get_permitted_enctypes and 
+        krb5_set_real_time for Samba.
+
+2003-06-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (struct krb5_cksumtypes): Add new field trunc_size.
+
+2003-06-12  Tom Yu  <tlyu@mit.edu>
+
+	* krb5.hin: krb524_init_ets() takes one argument.
+
+2003-06-06  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (struct srv_dns_entry): Declare.
+	(krb5int_make_srv_query_realm, krb5int_free_srv_dns_data):
+	Declare.
+	(struct _krb5int_access): Add make_srv_query_realm and
+	free_srv_dns_data fields.
+
+2003-06-03  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (struct _krb5int_access): Add locate_server back in.
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (KRB524_SERVICE, KRB524_PORT): Moved here...
+	* krb5.h: ...from here.
+	(krb5_524_convert_creds): Renamed from krb524_convert_creds_kdc,
+	fixed calling convention spec.
+	(krb524_convert_creds_kdc, krb524_init_ets) [KRB5_DEPRECATED]: New
+	macros.
+
+	* Makefile.in (clean-windows): Remove new "timestamp" file when
+	cleaning up.
+
+2003-05-25  Ezra Peisach  <epeisach@mit.edu>
+
+	* krb5.hin: Sequence number of krb5_replay_data should be unsigned.
+
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* Makefile.in (krb5.h): Include krb524_err.h.
+	(krb524_err.h): Depend on rebuild-error-tables like krb5_err.h and
+	friends.  Add a null command to cause make to recheck the
+	timestamp on the files possibly updated.
+	(clean-unix): Get rid of it.
+	* k5-int.h (KRb5INT_ACCESS_STRUCT_VERSION): Update to 7.
+	(struct ktext) [!defined(ANAME_SZ)]: Declare forward.
+	(krb5int_access): Delete krb5_locate_kdc, krb5_locate_server,
+	krb5_max_dgram_size and timeout fields.  Add krb_life_to_time,
+	krb_time_to_life, and krb524_encode_v4tkt function pointer
+	fields.  Reorder fields, and add comments.
+	(krb5int_krb_life_to_time, krb5int_krb_time_to_life,
+	krb5int_encode_v4tkt, krb5int_524_sendto_kdc): Declare.
+	* krb5.hin (KRB524_SERVICE, KRB524_PORT): New macros.
+	(struct credentials): Declare forward.
+	(krb524_convert_creds_kdc): Declare.
+
+2003-05-22  Tom Yu  <tlyu@mit.edu>
+
+	* k5-int.h: Add prototype for krb5int_auth_con_chkseqnum.
+
+	* krb5.hin: Default KRB5_DEPRECATED to 0.  Default KRB5_PRIVATE to
+	0 on all platforms.
+
+2003-05-22  Sam Hartman  <hartmans@mit.edu>
+
+	* k5-int.h: krb5int_populate_gic_opt returns void
+
+2003-05-19  Sam Hartman  <hartmans@mit.edu>
+
+	* k5-int.h: Prototype krb5int_populate_gic_opt
+
+2003-05-18  Tom Yu  <tlyu@mit.edu>
+
+	* k5-int.h: Sequence numbers are now unsigned.
+
+	* krb5.hin: Sequence numbers are now unsigned.
+
+2003-05-16  Ken Raeburn  <raeburn@mit.edu>
+
+	* krb5.hin (KRB5_KPASSWD_ACCESSDENIED): New macro.
+	(KRB5_KPASSWD_BAD_VERSION, KRB5_KPASSWD_INITIAL_FLAG_NEEDED): New
+	macros.
+
+2003-05-13  Sam Hartman  <hartmans@mit.edu>
+
+	* k5-int.h: Add krb5int_copy_data_contents
+
+2003-05-08  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5.hin: Add prototype for krb5_c_string_to_key_with_params
+
+	* k5-int.h: Add s2kparams to krb5_gic_get_as_key_fct
+
+2003-05-07  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5.hin: Add KRB5_PADATA_ETYPE_INFO2
+
+2003-05-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* k5-int.h (struct _krb5_context): New fields conf_tgs_ktypes,
+	conf_tgs_ktypes_count, use_conf_ktypes.
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* krb5.hin: Add krb5_auth_con_getsendsubkey,
+	krb5_auth_con_getrecvsubkey, krb5_auth_con_setsendsubkey,
+	krb5_auth_con_setrecvsubkey.  Mark krb5_auth_con_getlocalsubkey
+	and krb5_auth_con_getremotesubkey as deprecated.
+
+2003-05-06  Sam Hartman  <hartmans@mit.edu>
+
+	* k5-int.h: Add s2kparams to 
+	krb5_etype_info_entry
+	Add encode_etype_info2 and decode_etype_info2
+
+2003-05-02  Ken Raeburn  <raeburn@mit.edu>
+
+	* port-sockets.h (inet_ntop) [!_WIN32 && !HAVE_MACSOCK_H]: Define
+	as a macro if not provided by the OS.
+
+2003-04-17  Sam Hartman  <hartmans@mit.edu>
+
+	* k5-int.h: Add encode_krb5_setpw_req
+
+2003-04-15  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5.hin: Add krb5_set_password
+	Move krb5*_chpw internals to k5int.h
+
+	* k5-int.h: Add prototypes for set-password helper functions
+
+2003-04-07  Ken Raeburn  <raeburn@mit.edu>
+
+	* fake-addrinfo.h (getaddrinfo) [NUMERIC_SERVICE_BROKEN]:
+	Overwrite the port number only if a numeric service port was
+	supplied.
+
+2003-04-01  Ken Raeburn  <raeburn@mit.edu>
+
+	* fake-addrinfo.h (COPY_FIRST_CANONNAME) [_AIX]: Define.
+	(GET_HOST_BY_NAME) [_AIX]: New version for AIX version of
+	gethostbyname_r.
+	(getaddrinfo) [NUMERIC_SERVICE_BROKEN]: Use "discard" as a dummy
+	service name instead of none at all.  Don't check for unsigned
+	value less than zero.
+	(getaddrinfo) [COPY_FIRST_CANONNAME]: Set any ai_canonname fields
+	other than the first one to null.
+
+2003-03-18  Alexandra Ellwood  <lxs@mit.edu>
+
+    * configure.in: Use KRB5_AC_NEED_BIND_8_COMPAT to check for bind 9
+    and higher.  When bind 9 is present, BIND_8_COMPAT needs to be 
+    defined to get bind 8 types.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
     
     * krb5.h: Removed enumsalwaysint because there are no typed
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index df810299f..6674a7c94 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -31,18 +31,19 @@ $(srcdir)/krb5/autoconf.stmp: $(srcdir)/configure.in
 	cd $(srcdir) && $(AUTOHEADER) --localdir=$(CONFIG_RELTOPDIR) $(AUTOHEADERFLAGS)
 	touch $(srcdir)/krb5/autoconf.stmp
 
-krb5.h: krb5/autoconf.h $(srcdir)/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h \
+krb5.h: krb5/autoconf.h $(srcdir)/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h krb524_err.h \
 		asn1_err.h
 	echo "/* This file is generated, please don't edit it directly.  */" > krb5.h
 	grep SIZEOF krb5/autoconf.h >> krb5.h
-	cat $(srcdir)/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h \
+	cat $(srcdir)/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h krb524_err.h \
 		asn1_err.h >> krb5.h
 
 #
 # Build the error table include files:
-# asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h
+# asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h krb524_err.h
 
-asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h: rebuild-error-tables
+asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h krb524_err.h: rebuild-error-tables
+	: $@
 rebuild-error-tables:
 	(cd ../lib/krb5/error_tables && $(MAKE) includes)
 
@@ -53,9 +54,10 @@ asn1_err.h: $(SRCTOP)/lib/krb5/error_tables/asn1_err.et
 kdb5_err.h: $(SRCTOP)/lib/krb5/error_tables/kdb5_err.et
 krb5_err.h: $(SRCTOP)/lib/krb5/error_tables/krb5_err.et	
 kv5m_err.h: $(SRCTOP)/lib/krb5/error_tables/kv5m_err.et
+krb524_err.h: $(SRCTOP)/lib/krb5/error_tables/krb524_err.et
 
 clean-unix::
-	$(RM) krb5.h krb5_err.h kdb5_err.h kv5m_err.h \
+	$(RM) krb5.h krb5_err.h kdb5_err.h kv5m_err.h krb524_err.h \
 		asn1_err.h
 
 clean-mac::
diff --git a/src/include/configure.in b/src/include/configure.in
index 7287f153e..71b47ff3d 100644
--- a/src/include/configure.in
+++ b/src/include/configure.in
@@ -181,6 +181,9 @@ if test $krb5_cv_has_type_socklen_t = yes; then
 fi
 dnl
 dnl
+KRB5_AC_NEED_BIND_8_COMPAT
+dnl
+dnl
 AC_ARG_ENABLE([athena],
 [  --enable-athena         build with MIT Project Athena configuration],
 AC_DEFINE(KRB5_ATHENA_COMPAT,1,[Define if MIT Project Athena default configuration should be used]),)
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index d32802a77..79133c278 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -89,8 +89,10 @@
 #define FAI_DEFINED
 #include "port-sockets.h"
 #include "socket-utils.h"
+#include "k5-platform.h"
 
 #ifdef S_SPLINT_S
+/*@-incondefs@*/
 extern int
 getaddrinfo (/*@in@*/ /*@null@*/ const char *,
 	     /*@in@*/ /*@null@*/ const char *,
@@ -108,23 +110,28 @@ getnameinfo (const struct sockaddr *addr, socklen_t addrsz,
     /*@requires (maxSet(h)+1) >= hsz /\ (maxSet(s)+1) >= ssz @*/
     /* too hard: maxRead(addr) >= (addrsz-1) */
     /*@modifies *h, *s@*/;
-extern /*@dependent@*/ char *
-gai_strerror (int code) /*@*/;
+extern /*@dependent@*/ char *gai_strerror (int code) /*@*/;
+/*@=incondefs@*/
 #endif
 
 
-#if defined (__linux__) || defined (_AIX)
+#if defined (__APPLE__) && defined (__MACH__)
+#undef HAVE_GETADDRINFO
+#endif
+
+#if (defined (__linux__) && defined(HAVE_GETADDRINFO)) || defined (_AIX)
 /* See comments below.  */
 #  define WRAP_GETADDRINFO
 /* #  define WRAP_GETNAMEINFO */
 #endif
 
-#ifdef __linux__
+#if defined (__linux__) && defined(HAVE_GETADDRINFO)
 # define COPY_FIRST_CANONNAME
 #endif
 
 #ifdef _AIX
 # define NUMERIC_SERVICE_BROKEN
+# define COPY_FIRST_CANONNAME
 #endif
 
 
@@ -152,6 +159,29 @@ gai_strerror (int code) /*@*/;
 #define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
     { (HP) = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; }
 #else
+#ifdef _AIX /* XXX should have a feature test! */
+#define GET_HOST_BY_NAME(NAME, HP, ERR) \
+    {									\
+	struct hostent my_h_ent;					\
+	struct hostent_data my_h_ent_data;				\
+	(HP) = (gethostbyname_r((NAME), &my_h_ent, &my_h_ent_data)	\
+		? 0							\
+		: &my_h_ent);						\
+	(ERR) = h_errno;						\
+    }
+/*
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
+    {									\
+	struct hostent my_h_ent;					\
+	struct hostent_data my_h_ent_data;				\
+	(HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent,	\
+				&my_h_ent_data)				\
+		? 0							\
+		: &my_h_ent);						\
+	(ERR) = my_h_err;						\
+    }
+*/
+#else
 #ifdef GETHOSTBYNAME_R_RETURNS_INT
 #define GET_HOST_BY_NAME(NAME, HP, ERR) \
     {									\
@@ -196,7 +226,8 @@ gai_strerror (int code) /*@*/;
 			       my_h_buf, sizeof (my_h_buf), &my_h_err);	\
 	(ERR) = my_h_err;						\
     }
-#endif
+#endif /* returns int? */
+#endif /* _AIX */
 #endif
 
 /* Now do the same for getservby* functions.  */
@@ -898,19 +929,19 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
     /* AIX 4.3.3 is broken.  (Or perhaps out of date?)
 
        If a numeric service is provided, and it doesn't correspond to
-       a known service name, an error code (for "host not found") is
-       returned.  If the port maps to a known service, all is
-       well.  */
+       a known service name for tcp or udp (as appropriate), an error
+       code (for "host not found") is returned.  If the port maps to a
+       known service for both udp and tcp, all is well.  */
     if (serv && serv[0] && isdigit(serv[0])) {
 	unsigned long lport;
 	char *end;
 	lport = strtoul(serv, &end, 10);
 	if (!*end) {
-	    if (lport < 0 || lport > 65535)
+	    if (lport > 65535)
 		return EAI_SOCKTYPE;
 	    service_is_numeric = 1;
 	    service_port = htons(lport);
-	    serv = 0;
+	    serv = "discard";	/* defined for both udp and tcp */
 	    if (hint)
 		socket_type = hint->ai_socktype;
 	}
@@ -948,7 +979,10 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
        approach: If getaddrinfo sets ai_canonname, we'll replace the
        *first* one with allocated storage, and free up that pointer in
        freeaddrinfo if it's set; the other ai_canonname fields will be
-       left untouched.
+       left untouched.  And we'll just pray that the application code
+       won't mess around with the list structure; if we start doing
+       that, we'll have to start replacing and freeing all of the
+       ai_canonname fields.
 
        Ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=133668 .
 
@@ -961,7 +995,9 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
        set, the returned ai_canonname field can be null.  The NetBSD
        1.5 implementation also does this, if the input hostname is a
        numeric host address string.  That case isn't handled well at
-       the moment.  */
+       the moment.
+
+       Libc version 5 didn't have getaddrinfo at all.  */
 
 #ifdef COPY_FIRST_CANONNAME
     /*
@@ -1017,20 +1053,28 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
 #endif
 	    return EAI_MEMORY;
 	}
+	/* Zap the remaining ai_canonname fields glibc fills in, in
+	   case the application messes around with the list
+	   structure.  */
+	while ((ai = ai->ai_next) != NULL)
+	    ai->ai_canonname = 0;
     }
 #endif
 
 #ifdef NUMERIC_SERVICE_BROKEN
-    for (ai = *result; ai; ai = ai->ai_next) {
-	if (socket_type != 0 && ai->ai_socktype == 0)
-	    ai->ai_socktype = socket_type;
-	switch (ai->ai_family) {
-	case AF_INET:
-	    ((struct sockaddr_in *)ai->ai_addr)->sin_port = service_port;
-	    break;
-	case AF_INET6:
-	    ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = service_port;
-	    break;
+    if (service_port != 0) {
+	for (ai = *result; ai; ai = ai->ai_next) {
+	    if (socket_type != 0 && ai->ai_socktype == 0)
+		/* Is this check actually needed?  */
+		ai->ai_socktype = socket_type;
+	    switch (ai->ai_family) {
+	    case AF_INET:
+		((struct sockaddr_in *)ai->ai_addr)->sin_port = service_port;
+		break;
+	    case AF_INET6:
+		((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = service_port;
+		break;
+	    }
 	}
     }
 #endif
diff --git a/src/include/foreachaddr.c b/src/include/foreachaddr.c
index 101f8efca..f91034a77 100644
--- a/src/include/foreachaddr.c
+++ b/src/include/foreachaddr.c
@@ -383,6 +383,20 @@ foreach_localaddr (/*@null@*/ void *data,
 	if ((ifp->ifa_flags & IFF_UP) == 0)
 	    continue;
 	if (ifp->ifa_flags & IFF_LOOPBACK) {
+	    /* Pretend it's not up, so the second pass will skip
+	       it.  */
+	    ifp->ifa_flags &= ~IFF_UP;
+	    continue;
+	}
+	if (ifp->ifa_addr == NULL) {
+	    /* Can't use an interface without an address.  Linux
+	       apparently does this sometimes.  [RT ticket 1770 from
+	       Maurice Massar, also Debian bug 206851, shows the
+	       problem with a PPP link on a newer kernel than I'm
+	       running.]
+
+	       Pretend it's not up, so the second pass will skip
+	       it.  */
 	    ifp->ifa_flags &= ~IFF_UP;
 	    continue;
 	}
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 41c325da1..61333e453 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001 by the Massachusetts Institute of Technology,
+ * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003 by the Massachusetts Institute of Technology,
  * Cambridge, MA, USA.  All Rights Reserved.
  * 
  * This software is being provided to you, the LICENSEE, by the 
@@ -138,6 +138,13 @@ typedef unsigned char	u_char;
 #endif /* HAVE_SYS_TYPES_H */
 #endif /* KRB5_SYSTYPES__ */
 
+
+#include "k5-platform.h"
+/* not used in krb5.h (yet) */
+typedef UINT64_TYPE krb5_ui_8;
+typedef INT64_TYPE krb5_int64;
+
+
 #define DEFAULT_PWD_STRING1 "Enter password"
 #define DEFAULT_PWD_STRING2 "Re-enter password for verification"
 
@@ -282,12 +289,15 @@ typedef struct _krb5_alt_method {
  * A null-terminated array of this structure is returned by the KDC as
  * the data part of the ETYPE_INFO preauth type.  It informs the
  * client which encryption types are supported.
+ * The  same data structure is used by both etype-info and etype-info2
+ * but s2kparams must be null when encoding etype-info.
  */
 typedef struct _krb5_etype_info_entry {
 	krb5_magic	magic;
 	krb5_enctype	etype;
 	unsigned int	length;
 	krb5_octet	*salt;
+    krb5_data s2kparams;
 } krb5_etype_info_entry;
 
 /* 
@@ -638,6 +648,7 @@ struct krb5_keytypes {
     krb5_crypt_func encrypt;
     krb5_crypt_func decrypt;
     krb5_str2key_func str2key;
+    krb5_cksumtype required_ctype;
 };
 
 struct krb5_cksumtypes {
@@ -657,6 +668,12 @@ struct krb5_cksumtypes {
        kind of messy, but so is the krb5 api. */
     const struct krb5_keyhash_provider *keyhash;
     const struct krb5_hash_provider *hash;
+    /* This just gets uglier and uglier.  In the key derivation case,
+       we produce an hmac.  To make the hmac code work, we can't hack
+       the output size indicated by the hash provider, but we may want
+       a truncated hmac.  If we want truncation, this is the number of
+       bytes we truncate to; it should be 0 otherwise.  */
+    unsigned int trunc_size;
 };
 
 #define KRB5_CKSUMFLAG_DERIVE		0x0001
@@ -679,6 +696,10 @@ krb5_error_code krb5int_pbkdf2_hmac_sha1 (const krb5_data *, unsigned long,
 					  const krb5_data *,
 					  const krb5_data *);
 
+/* Make this a function eventually?  */
+#define krb5int_zap_data(ptr, len) memset((volatile void *)ptr, 0, len)
+#define zap(p,l) krb5int_zap_data(p,l)
+
 /* A definition of init_state for DES based encryption systems.
  * sets up an 8-byte IV of all zeros
  */
@@ -903,6 +924,8 @@ void krb5_free_etype_info
 /*
  * End "preauth.h"
  */
+krb5_error_code
+krb5int_copy_data_contents (krb5_context, const krb5_data *, krb5_data *);
 
 typedef krb5_error_code (*krb5_gic_get_as_key_fct)
     (krb5_context,
@@ -911,6 +934,7 @@ typedef krb5_error_code (*krb5_gic_get_as_key_fct)
 		     krb5_prompter_fct,
 		     void *prompter_data,
 		     krb5_data *salt,
+     krb5_data *s2kparams,
 		     krb5_keyblock *as_key,
 		     void *gak_data);
 
@@ -929,11 +953,17 @@ krb5_get_init_creds
 		int master,
 		krb5_kdc_rep **as_reply);
 
+void krb5int_populate_gic_opt (
+    krb5_context, krb5_get_init_creds_opt *,
+    krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
+    krb5_preauthtype *pre_auth_types);
+
 
 krb5_error_code krb5_do_preauth
 (krb5_context, krb5_kdc_req *,
 		krb5_pa_data **, krb5_pa_data ***,
-		krb5_data *, krb5_enctype *,
+		krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *,
 		krb5_keyblock *,
 		krb5_prompter_fct, void *,
 		krb5_gic_get_as_key_fct, void *);
@@ -1005,6 +1035,17 @@ struct _krb5_context {
 	   absolute limit on the UDP packet size.  */
 	int		udp_pref_limit;
 
+	/* This is the tgs_ktypes list as read from the profile, or
+	   set to compiled-in defaults.  The application code cannot
+	   override it.  This is used for session keys for
+	   intermediate ticket-granting tickets used to acquire the
+	   requested ticket (the session key of which may be
+	   constrained by tgs_ktypes above).  */
+	krb5_enctype	*conf_tgs_ktypes;
+	int		conf_tgs_ktypes_count;
+	/* Use the _configured version?  */
+	krb5_boolean	use_conf_ktypes;
+
 #ifdef KRB5_DNS_LOOKUP
         krb5_boolean    profile_in_memory;
 #endif /* KRB5_DNS_LOOKUP */
@@ -1023,7 +1064,7 @@ typedef struct _krb5_safe {
     krb5_timestamp timestamp;		/* client time, optional */
     krb5_int32 usec;			/* microsecond portion of time,
 					   optional */
-    krb5_int32 seq_number;		/* sequence #, optional */
+    krb5_ui_4 seq_number;		/* sequence #, optional */
     krb5_address *s_address;	/* sender address */
     krb5_address *r_address;	/* recipient address, optional */
     krb5_checksum *checksum;	/* data integrity checksum */
@@ -1039,7 +1080,7 @@ typedef struct _krb5_priv_enc_part {
     krb5_data user_data;		/* user data */
     krb5_timestamp timestamp;		/* client time, optional */
     krb5_int32 usec;			/* microsecond portion of time, opt. */
-    krb5_int32 seq_number;		/* sequence #, optional */
+    krb5_ui_4 seq_number;		/* sequence #, optional */
     krb5_address *s_address;	/* sender address */
     krb5_address *r_address;	/* recipient address, optional */
 } krb5_priv_enc_part;
@@ -1189,6 +1230,9 @@ krb5_error_code encode_krb5_kdc_req_body
 krb5_error_code encode_krb5_safe
 	(const krb5_safe *rep, krb5_data **code);
 
+krb5_error_code encode_krb5_safe_with_body
+	(const krb5_safe *rep, const krb5_data *body, krb5_data **code);
+
 krb5_error_code encode_krb5_priv
 	(const krb5_priv *rep, krb5_data **code);
 
@@ -1221,6 +1265,8 @@ krb5_error_code encode_krb5_alt_method
 
 krb5_error_code encode_krb5_etype_info
 	(const krb5_etype_info_entry **, krb5_data **code);
+krb5_error_code encode_krb5_etype_info2
+	(const krb5_etype_info_entry **, krb5_data **code);
 
 krb5_error_code encode_krb5_enc_data
     	(const krb5_enc_data *, krb5_data **);
@@ -1270,6 +1316,9 @@ krb5_error_code encode_krb5_sam_response
 krb5_error_code encode_krb5_predicted_sam_response
        (const krb5_predicted_sam_response * , krb5_data **);
 
+krb5_error_code encode_krb5_setpw_req
+(const krb5_principal target, char *password, krb5_data **code);
+
 /*************************************************************************
  * End of prototypes for krb5_encode.c
  *************************************************************************/
@@ -1363,6 +1412,9 @@ krb5_error_code decode_krb5_kdc_req_body
 krb5_error_code decode_krb5_safe
 	(const krb5_data *output, krb5_safe **rep);
 
+krb5_error_code decode_krb5_safe_with_body
+	(const krb5_data *output, krb5_safe **rep, krb5_data *body);
+
 krb5_error_code decode_krb5_priv
 	(const krb5_data *output, krb5_priv **rep);
 
@@ -1396,6 +1448,9 @@ krb5_error_code decode_krb5_alt_method
 krb5_error_code decode_krb5_etype_info
 	(const krb5_data *output, krb5_etype_info_entry ***rep);
 
+krb5_error_code decode_krb5_etype_info2
+	(const krb5_data *output, krb5_etype_info_entry ***rep);
+
 krb5_error_code decode_krb5_enc_data
 	(const krb5_data *output, krb5_enc_data **rep);
 
@@ -1448,6 +1503,8 @@ krb5_error_code krb5_encode_kdc_rep
 krb5_error_code krb5_validate_times
 	(krb5_context, 
 		krb5_ticket_times *);
+krb5_boolean krb5int_auth_con_chkseqnum
+	(krb5_context ctx, krb5_auth_context ac, krb5_ui_4 in_seq);
 /*
  * [De]Serialization Handle and operations.
  */
@@ -1537,6 +1594,11 @@ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int32
 	(krb5_int32 *,
 		krb5_octet **,
 		size_t *);
+/* [De]serialize 8-byte integer */
+krb5_error_code KRB5_CALLCONV krb5_ser_pack_int64
+	(krb5_int64, krb5_octet **, size_t *);
+krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int64
+	(krb5_int64 *, krb5_octet **, size_t *);
 /* [De]serialize byte string */
 krb5_error_code KRB5_CALLCONV krb5_ser_pack_bytes
 	(krb5_octet *,
@@ -1559,7 +1621,46 @@ krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred_default
 void krb5int_set_prompt_types
 	(krb5_context, krb5_prompt_type *);
 
-
+krb5_error_code
+krb5int_generate_and_save_subkey (krb5_context, krb5_auth_context,
+				  krb5_keyblock * /* Old keyblock, not new!  */);
+
+/* set and change password helpers */
+
+krb5_error_code krb5int_mk_chpw_req
+	(krb5_context context, krb5_auth_context auth_context,
+ 			krb5_data *ap_req, char *passwd, krb5_data *packet);
+krb5_error_code krb5int_rd_chpw_rep
+	(krb5_context context, krb5_auth_context auth_context,
+		       krb5_data *packet, int *result_code,
+		       krb5_data *result_data);
+krb5_error_code KRB5_CALLCONV krb5_chpw_result_code_string
+	(krb5_context context, int result_code,
+			char **result_codestr);
+krb5_error_code  krb5int_mk_setpw_req
+	(krb5_context context, krb5_auth_context auth_context,
+ 			krb5_data *ap_req, krb5_principal targetprinc, char *passwd, krb5_data *packet);
+krb5_error_code krb5int_rd_setpw_rep
+	(krb5_context context, krb5_auth_context auth_context,
+		       krb5_data *packet, int *result_code,
+		       krb5_data *result_data);
+krb5_error_code krb5int_setpw_result_code_string
+	(krb5_context context, int result_code,
+			const char **result_codestr);
+
+struct srv_dns_entry {
+    struct srv_dns_entry *next;
+    int priority;
+    int weight;
+    unsigned short port;
+    char *host;
+};
+krb5_error_code
+krb5int_make_srv_query_realm(const krb5_data *realm,
+			     const char *service,
+			     const char *protocol,
+			     struct srv_dns_entry **answers);
+void krb5int_free_srv_dns_data(struct srv_dns_entry *);
 
 #if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
 #pragma import reset
@@ -1577,26 +1678,24 @@ void krb5int_set_prompt_types
 /* To keep happy libraries which are (for now) accessing internal stuff */
 
 /* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 6
+#define KRB5INT_ACCESS_STRUCT_VERSION 8
 
+#ifndef ANAME_SZ
+struct ktext;			/* from krb.h, for krb524 support */
+#endif
 typedef struct _krb5int_access {
-    krb5_error_code (*krb5_locate_kdc) (krb5_context, const krb5_data *,
-					struct addrlist *, int, int, int);
-    krb5_error_code (*krb5_locate_server) (krb5_context, const krb5_data *,
-					   struct addrlist *, int,
-					   const char *, const char *,
-					   int, int, int, int);
-    void (*free_addrlist) (struct addrlist *);
-    unsigned int krb5_max_skdc_timeout;
-    unsigned int krb5_skdc_timeout_shift;
-    unsigned int krb5_skdc_timeout_1;
-    unsigned int krb5_max_dgram_size;
+    /* crypto stuff */
     const struct krb5_hash_provider *md5_hash_provider;
     const struct krb5_enc_provider *arcfour_enc_provider;
     krb5_error_code (* krb5_hmac) (const struct krb5_hash_provider *hash,
 				   const krb5_keyblock *key,
 				   unsigned int icount, const krb5_data *input,
 				   krb5_data *output);
+    /* service location and communication */
+    krb5_error_code (*locate_server) (krb5_context, const krb5_data *,
+				      struct addrlist *, int,
+				      const char *, const char *,
+				      int, int, int, int);
     krb5_error_code (*sendto_udp) (krb5_context, const krb5_data *msg,
 				   const struct addrlist *, krb5_data *reply,
 				   struct sockaddr *, socklen_t *);
@@ -1604,6 +1703,24 @@ typedef struct _krb5int_access {
 					const char *hostname,
 					int port, int secport,
 					int socktype, int family);
+    void (*free_addrlist) (struct addrlist *);
+
+    krb5_error_code (*make_srv_query_realm)(const krb5_data *realm,
+					    const char *service,
+					    const char *protocol,
+					    struct srv_dns_entry **answers);
+    void (*free_srv_dns_data)(struct srv_dns_entry *);
+
+    /* krb4 compatibility stuff -- may be null if not enabled */
+    krb5_int32 (*krb_life_to_time)(krb5_int32, int);
+    int (*krb_time_to_life)(krb5_int32, krb5_int32);
+    int (*krb524_encode_v4tkt)(struct ktext *, char *, unsigned int *);
+    krb5_error_code (*krb5int_c_mandatory_cksumtype)
+        (krb5_context, krb5_enctype, krb5_cksumtype *);
+    krb5_error_code (KRB5_CALLCONV *krb5_ser_pack_int64)
+        (krb5_int64, krb5_octet **, size_t *);
+    krb5_error_code (KRB5_CALLCONV *krb5_ser_unpack_int64)
+        (krb5_int64 *, krb5_octet **, size_t *);
 } krb5int_access;
 
 #define KRB5INT_ACCESS_VERSION \
@@ -1613,6 +1730,29 @@ typedef struct _krb5int_access {
 krb5_error_code KRB5_CALLCONV krb5int_accessor
 	(krb5int_access*, krb5_int32);
 
+/* Ick -- some krb524 and krb4 support placed in the krb5 library,
+   because AFS (and potentially other applications?) use the krb4
+   object as an opaque token, which (in some implementations) is not
+   in fact a krb4 ticket, so we don't want to drag in the krb4 support
+   just to enable this.  */
+
+#define KRB524_SERVICE "krb524"
+#define KRB524_PORT 4444
+
+/* v4lifetime.c */
+extern krb5_int32 krb5int_krb_life_to_time(krb5_int32, int);
+extern int krb5int_krb_time_to_life(krb5_int32, krb5_int32);
+
+/* conv_creds.c */
+int krb5int_encode_v4tkt
+	(struct ktext *v4tkt, char *buf, unsigned int *encoded_len);
+
+/* send524.c */
+int krb5int_524_sendto_kdc
+        (krb5_context context, const krb5_data * message, 
+	 const krb5_data * realm, krb5_data * reply,
+	 struct sockaddr *, socklen_t *);
+
 /* temporary -- this should be under lib/krb5/ccache somewhere */
 
 struct _krb5_ccache {
@@ -1744,4 +1884,8 @@ extern const krb5_kt_ops krb5_kt_dfl_ops;
 
 extern krb5_error_code krb5int_translate_gai_error (int);
 
+/* Not sure it's ready for exposure just yet.  */
+extern krb5_error_code
+krb5int_c_mandatory_cksumtype (krb5_context, krb5_enctype, krb5_cksumtype *);
+
 #endif /* _KRB5_INT_H */
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
new file mode 100644
index 000000000..c4cc7bb75
--- /dev/null
+++ b/src/include/k5-platform.h
@@ -0,0 +1,170 @@
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003  by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.	Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently: make "static inline" work; 64-bit types and load/store
+ * code; SIZE_MAX.
+ */
+
+#ifndef K5_PLATFORM_H
+#define K5_PLATFORM_H
+
+#if !defined(inline)
+# if __STDC_VERSION__ >= 199901L
+/* C99 supports inline, don't do anything.  */
+# elif defined(__GNUC__)
+#  define inline __inline__ /* this form silences -pedantic warnings */
+# elif defined(__mips) && defined(__sgi)
+#  define inline __inline /* IRIX used at MIT does inline but not c99 yet */
+# elif defined(__sun) && __SUNPRO_C >= 0x540
+/* The Forte Developer 7 C compiler supports "inline".  */
+# elif defined(_WIN32)
+#  define inline __inline
+# else
+#  define inline /* nothing, just static */
+# endif
+#endif
+
+#include "autoconf.h"
+
+/* 64-bit support: krb5_ui_8 and krb5_int64.
+
+   This should move to krb5.h eventually, but without the namespace
+   pollution from the autoconf macros.  */
+#if defined(HAVE_STDINT_H) || defined(HAVE_INTTYPES_H)
+# ifdef HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+# ifdef HAVE_INTTYPES_H
+#  include <inttypes.h>
+# endif
+# define INT64_TYPE int64_t
+# define UINT64_TYPE uint64_t
+#elif defined(_WIN32)
+# define INT64_TYPE signed __int64
+# define UINT64_TYPE unsigned __int64
+#else /* not Windows, and neither stdint.h nor inttypes.h */
+# define INT64_TYPE signed long long
+# define UINT64_TYPE unsigned long long
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t)((size_t)0 - 1))
+#endif
+
+/* Read and write integer values as (unaligned) octet strings in
+   specific byte orders.
+
+   Add per-platform optimizations later if needed.  (E.g., maybe x86
+   unaligned word stores and gcc/asm instructions for byte swaps,
+   etc.)  */
+
+static inline void
+store_16_be (unsigned int val, unsigned char *p)
+{
+    p[0] = (val >>  8) & 0xff;
+    p[1] = (val      ) & 0xff;
+}
+static inline void
+store_16_le (unsigned int val, unsigned char *p)
+{
+    p[1] = (val >>  8) & 0xff;
+    p[0] = (val      ) & 0xff;
+}
+static inline void
+store_32_be (unsigned int val, unsigned char *p)
+{
+    p[0] = (val >> 24) & 0xff;
+    p[1] = (val >> 16) & 0xff;
+    p[2] = (val >>  8) & 0xff;
+    p[3] = (val      ) & 0xff;
+}
+static inline void
+store_32_le (unsigned int val, unsigned char *p)
+{
+    p[3] = (val >> 24) & 0xff;
+    p[2] = (val >> 16) & 0xff;
+    p[1] = (val >>  8) & 0xff;
+    p[0] = (val      ) & 0xff;
+}
+static inline void
+store_64_be (UINT64_TYPE val, unsigned char *p)
+{
+    p[0] = (unsigned char)((val >> 56) & 0xff);
+    p[1] = (unsigned char)((val >> 48) & 0xff);
+    p[2] = (unsigned char)((val >> 40) & 0xff);
+    p[3] = (unsigned char)((val >> 32) & 0xff);
+    p[4] = (unsigned char)((val >> 24) & 0xff);
+    p[5] = (unsigned char)((val >> 16) & 0xff);
+    p[6] = (unsigned char)((val >>  8) & 0xff);
+    p[7] = (unsigned char)((val      ) & 0xff);
+}
+static inline void
+store_64_le (UINT64_TYPE val, unsigned char *p)
+{
+    p[7] = (unsigned char)((val >> 56) & 0xff);
+    p[6] = (unsigned char)((val >> 48) & 0xff);
+    p[5] = (unsigned char)((val >> 40) & 0xff);
+    p[4] = (unsigned char)((val >> 32) & 0xff);
+    p[3] = (unsigned char)((val >> 24) & 0xff);
+    p[2] = (unsigned char)((val >> 16) & 0xff);
+    p[1] = (unsigned char)((val >>  8) & 0xff);
+    p[0] = (unsigned char)((val      ) & 0xff);
+}
+static inline unsigned short
+load_16_be (unsigned char *p)
+{
+    return (p[1] | (p[0] << 8));
+}
+static inline unsigned short
+load_16_le (unsigned char *p)
+{
+    return (p[0] | (p[1] << 8));
+}
+static inline unsigned int
+load_32_be (unsigned char *p)
+{
+    return (p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24));
+}
+static inline unsigned int
+load_32_le (unsigned char *p)
+{
+    return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
+}
+static inline UINT64_TYPE
+load_64_be (unsigned char *p)
+{
+    return ((UINT64_TYPE)load_32_be(p) << 32) | load_32_be(p+4);
+}
+static inline UINT64_TYPE
+load_64_le (unsigned char *p)
+{
+    return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p);
+}
+
+#endif /* K5_PLATFORM_H */
diff --git a/src/include/kerberosIV/ChangeLog b/src/include/kerberosIV/ChangeLog
index baa927a2b..226443b38 100644
--- a/src/include/kerberosIV/ChangeLog
+++ b/src/include/kerberosIV/ChangeLog
@@ -1,3 +1,8 @@
+2003-09-23  Jeffrey Altman  <jaltman@mit.edu>
+
+	* krb.h: Modify the declaration of the CREDENTIALS structure to
+	support the additional address field used on Windows.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
     * des.h, krb.h: Removed deprecated KfM functions.  They will be 
     exported but not in the headers to discourage new callers. Removed 
diff --git a/src/include/kerberosIV/krb.h b/src/include/kerberosIV/krb.h
index 26ac08647..a79df13b6 100644
--- a/src/include/kerberosIV/krb.h
+++ b/src/include/kerberosIV/krb.h
@@ -122,6 +122,7 @@ extern const char * const krb_err_txt[MAX_KRB_ERRORS];
 #define		REALM_SZ	40
 #define		SNAME_SZ	40
 #define		INST_SZ		40
+#define     ADDR_SZ     40
 /*
  * NB: This overcounts due to NULs.
  */
@@ -209,6 +210,9 @@ struct credentials {
     KRB_UINT32 address;			/* Address in ticket */
     KRB_UINT32 stk_type;		/* string_to_key function needed */
 #endif
+#ifdef _WIN32
+    char    address[ADDR_SZ];   /* Address in ticket */
+#endif
 };
 
 typedef struct credentials CREDENTIALS;
diff --git a/src/include/krb5.hin b/src/include/krb5.hin
index eece828f1..ea2fcd647 100644
--- a/src/include/krb5.hin
+++ b/src/include/krb5.hin
@@ -56,8 +56,13 @@
 #ifndef KRB5_GENERAL__
 #define KRB5_GENERAL__
 
+/* By default, do not expose deprecated interfaces. */
 #ifndef KRB5_DEPRECATED
-#define KRB5_DEPRECATED 1 /* Expose deprecated things for now. */
+#define KRB5_DEPRECATED 0
+#endif
+/* Do not expose private interfaces.  Build system will override. */
+#ifndef KRB5_PRIVATE
+#define KRB5_PRIVATE 0
 #endif
 
 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
@@ -65,20 +70,6 @@
 #    if TARGET_RT_MAC_CFM
 #	error "Use KfM 4.0 SDK headers for CFM compilation."
 #    endif
-
-#	ifndef KRB5_PRIVATE /* Allow e.g. build system to override */
-#		define KRB5_PRIVATE 0
-#	endif
-#else
-#if defined(_WIN32)
-#	ifndef KRB5_PRIVATE
-#		define KRB5_PRIVATE 0
-#	endif
-#else
-#	ifndef KRB5_PRIVATE
-#		define KRB5_PRIVATE 1
-#	endif
-#endif
 #endif
 
 #if defined(_MSDOS) || defined(_WIN32)
@@ -491,6 +482,13 @@ krb5_error_code KRB5_CALLCONV
     (krb5_context context, krb5_enctype enctype,
 		    const krb5_data *string, const krb5_data *salt,
 		    krb5_keyblock *key);
+krb5_error_code KRB5_CALLCONV
+krb5_c_string_to_key_with_params(krb5_context context,
+				 krb5_enctype enctype,
+				 const krb5_data *string,
+				 const krb5_data *salt,
+				 const krb5_data *params,
+				 krb5_keyblock *key);
 
 krb5_error_code KRB5_CALLCONV
     krb5_c_enctype_compare
@@ -874,7 +872,7 @@ krb5_error_code krb5_decrypt_data
 #define KRB5_PADATA_SAM_RESPONSE	13 /* draft challenge system response */
 #define KRB5_PADATA_PK_AS_REQ		14 /* PKINIT */
 #define KRB5_PADATA_PK_AS_REP		15 /* PKINIT */
-
+#define KRB5_PADATA_ETYPE_INFO2 19
 #define KRB5_PADATA_SAM_CHALLENGE_2	30 /* draft challenge system, updated */
 #define KRB5_PADATA_SAM_RESPONSE_2	31 /* draft challenge system, updated */
     
@@ -902,6 +900,11 @@ krb5_error_code krb5_decrypt_data
 #define KRB5_KPASSWD_HARDERROR		2
 #define KRB5_KPASSWD_AUTHERROR		3
 #define KRB5_KPASSWD_SOFTERROR		4
+/* These are Microsoft's extensions in RFC 3244, and it looks like
+   they'll become standardized, possibly with other additions.  */
+#define KRB5_KPASSWD_ACCESSDENIED	5	/* unused */
+#define KRB5_KPASSWD_BAD_VERSION	6
+#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7	/* unused */
 
 /*
  * end "proto.h"
@@ -962,7 +965,7 @@ typedef struct _krb5_authenticator {
     krb5_int32 cusec;			/* client usec portion */
     krb5_timestamp ctime;		/* client sec portion */
     krb5_keyblock *subkey;		/* true session key, optional */
-    krb5_int32 seq_number;		/* sequence #, optional */
+    krb5_ui_4 seq_number;		/* sequence #, optional */
     krb5_authdata **authorization_data; /* New add by Ari, auth data */
 } krb5_authenticator;
 
@@ -1088,7 +1091,7 @@ typedef struct _krb5_ap_rep_enc_part {
     krb5_timestamp ctime;		/* client time, seconds portion */
     krb5_int32 cusec;			/* client time, microseconds portion */
     krb5_keyblock *subkey;		/* true session key, optional */
-    krb5_int32 seq_number;		/* sequence #, optional */
+    krb5_ui_4 seq_number;		/* sequence #, optional */
 } krb5_ap_rep_enc_part;
 
 typedef struct _krb5_response {
@@ -1152,11 +1155,12 @@ typedef struct _krb5_pwd_data {
 #define KRB5_AUTH_CONTEXT_DO_SEQUENCE	0x00000004
 #define KRB5_AUTH_CONTEXT_RET_SEQUENCE	0x00000008
 #define KRB5_AUTH_CONTEXT_PERMIT_ALL	0x00000010
+#define KRB5_AUTH_CONTEXT_USE_SUBKEY	0x00000020
  
 typedef struct krb5_replay_data { 
     krb5_timestamp	timestamp; 
     krb5_int32		usec;
-    krb5_int32		seq; 
+    krb5_ui_4		seq; 
 } krb5_replay_data;
 
 /* flags for krb5_auth_con_genaddrs() */
@@ -1166,7 +1170,7 @@ typedef struct krb5_replay_data {
 #define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR	0x00000008
 
 /* type of function used as a callback to generate checksum data for
-	* mk_req*/
+ * mk_req */
 
 typedef krb5_error_code 
 (KRB5_CALLCONV * krb5_mk_req_checksum_func) (krb5_context, krb5_auth_context , void *,
@@ -1407,9 +1411,12 @@ krb5_error_code KRB5_CALLCONV krb5_get_tgs_ktypes
 	(krb5_context,
 		krb5_const_principal,
 		krb5_enctype **);
+#endif
 
-krb5_error_code krb5_get_permitted_enctypes
+krb5_error_code KRB5_CALLCONV krb5_get_permitted_enctypes
 	(krb5_context, krb5_enctype **);
+
+#if KRB5_PRIVATE
 void KRB5_CALLCONV krb5_free_ktypes
 	(krb5_context, krb5_enctype *);
 
@@ -1632,7 +1639,7 @@ krb5_error_code krb5_generate_subkey
 		const krb5_keyblock *, krb5_keyblock **);
 krb5_error_code krb5_generate_seq_number
 	(krb5_context,
-		const krb5_keyblock *, krb5_int32 *);
+		const krb5_keyblock *, krb5_ui_4 *);
 #endif
 krb5_error_code KRB5_CALLCONV krb5_get_server_rcache
 	(krb5_context,
@@ -1658,17 +1665,13 @@ krb5_error_code KRB5_CALLCONV krb5_524_conv_principal
 	(krb5_context context, krb5_const_principal princ, 
 		char *name, char *inst, char *realm);
 
-#if KRB5_PRIVATE
-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);
-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);
-krb5_error_code KRB5_CALLCONV krb5_chpw_result_code_string
-	(krb5_context context, int result_code,
-			char **result_codestr);
+struct credentials;
+int KRB5_CALLCONV krb5_524_convert_creds
+	(krb5_context context, krb5_creds *v5creds,
+	 struct credentials *v4creds);
+#if KRB5_DEPRECATED
+#define krb524_convert_creds_kdc krb5_524_convert_creds
+#define krb524_init_ets(x) (0)
 #endif
 
 /* libkt.spec */
@@ -1708,10 +1711,10 @@ krb5_error_code KRB5_CALLCONV krb5_kt_add_entry
 	(krb5_context,
 		krb5_keytab,
 		krb5_keytab_entry * );
-#if KRB5_PRIVATE
 krb5_error_code krb5_principal2salt
 	(krb5_context,
 		krb5_const_principal, krb5_data *);
+#if KRB5_PRIVATE
 krb5_error_code krb5_principal2salt_norealm
 	(krb5_context,
 		krb5_const_principal, krb5_data *);
@@ -1871,6 +1874,14 @@ krb5_change_password
 	(krb5_context context, krb5_creds *creds, char *newpw,
 			int *result_code, krb5_data *result_code_string,
 			krb5_data *result_string);
+krb5_error_code KRB5_CALLCONV
+krb5_set_password
+	(krb5_context context, krb5_creds *creds, char *newpw, krb5_principal change_password_for,
+			int *result_code, krb5_data *result_code_string, krb5_data *result_string);
+krb5_error_code KRB5_CALLCONV
+krb5_set_password_using_ccache
+	(krb5_context context, krb5_ccache ccache, char *newpw, krb5_principal change_password_for,
+			int *result_code, krb5_data *result_code_string, krb5_data *result_string);
 
 #if KRB5_PRIVATE
 #ifndef macintosh
@@ -2152,11 +2163,30 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_getkey
 		krb5_auth_context,
 		krb5_keyblock **);
 
+krb5_error_code KRB5_CALLCONV krb5_auth_con_getsendsubkey(
+    krb5_context, krb5_auth_context, krb5_keyblock **);
+
+krb5_error_code KRB5_CALLCONV krb5_auth_con_getrecvsubkey(
+    krb5_context, krb5_auth_context, krb5_keyblock **);
+
+krb5_error_code KRB5_CALLCONV krb5_auth_con_setsendsubkey(
+    krb5_context, krb5_auth_context, krb5_keyblock *);
+
+krb5_error_code KRB5_CALLCONV krb5_auth_con_setrecvsubkey(
+    krb5_context, krb5_auth_context, krb5_keyblock *);
+
+#if KRB5_DEPRECATED
 krb5_error_code KRB5_CALLCONV krb5_auth_con_getlocalsubkey
 	(krb5_context,
 		krb5_auth_context,
 		krb5_keyblock **);
 
+krb5_error_code KRB5_CALLCONV krb5_auth_con_getremotesubkey
+	(krb5_context,
+		krb5_auth_context,
+		krb5_keyblock **);
+#endif
+
 #if KRB5_PRIVATE
 krb5_error_code KRB5_CALLCONV krb5_auth_con_set_req_cksumtype
 	(krb5_context,
@@ -2224,11 +2254,6 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_getauthenticator
 		krb5_auth_context,
 		krb5_authenticator **);
 
-krb5_error_code KRB5_CALLCONV krb5_auth_con_getremotesubkey
-	(krb5_context,
-		krb5_auth_context,
-		krb5_keyblock **);
-
 #define KRB5_REALM_BRANCH_CHAR '.'
 
 /*
@@ -2257,7 +2282,6 @@ krb5_error_code KRB5_CALLCONV krb5_aname_to_localname
 		krb5_const_principal,
 		int,
 		char * );
-#if KRB5_PRIVATE
 krb5_error_code KRB5_CALLCONV krb5_get_host_realm
 	(krb5_context,
 		const char *,
@@ -2265,6 +2289,7 @@ krb5_error_code KRB5_CALLCONV krb5_get_host_realm
 krb5_error_code KRB5_CALLCONV krb5_free_host_realm
 	(krb5_context,
 		char * const * );
+#if KRB5_PRIVATE
 krb5_error_code KRB5_CALLCONV krb5_get_realm_domain
 	(krb5_context,
 		const char *,
@@ -2293,9 +2318,12 @@ krb5_error_code krb5_make_fulladdr
 		krb5_address *,
 		krb5_address *,
 		krb5_address *);
+#endif
 
-krb5_error_code krb5_set_real_time
+krb5_error_code KRB5_CALLCONV krb5_set_real_time
 	(krb5_context, krb5_int32, krb5_int32);
+
+#if KRB5_PRIVATE
 krb5_error_code krb5_set_debugging_time
 	(krb5_context, krb5_int32, krb5_int32);
 krb5_error_code krb5_use_natural_time
diff --git a/src/include/krb5/ChangeLog b/src/include/krb5/ChangeLog
index ff3d7b301..72dc6e4c4 100644
--- a/src/include/krb5/ChangeLog
+++ b/src/include/krb5/ChangeLog
@@ -1,3 +1,7 @@
+2003-05-25  Ezra Peisach  <epeisach@mit.edu>
+
+	* kdb.h: Add prototype for krb5_db_iterate_ext.
+
 2003-03-05  Tom Yu  <tlyu@mit.edu>
 
 	* kdb_kt.h: Add krb5_ktkdb_set_context.  Update prototype of
diff --git a/src/include/krb5/kdb.h b/src/include/krb5/kdb.h
index 1670b5436..73a3972aa 100644
--- a/src/include/krb5/kdb.h
+++ b/src/include/krb5/kdb.h
@@ -212,6 +212,10 @@ krb5_error_code krb5_db_iterate (krb5_context,
 				 krb5_error_code (* ) (krb5_pointer,
 						       krb5_db_entry *),
 				 krb5_pointer);
+krb5_error_code krb5_db_iterate_ext (krb5_context,
+				     krb5_error_code (* ) (krb5_pointer,
+					  	           krb5_db_entry *),
+				     krb5_pointer, int, int);
 krb5_error_code krb5_db_verify_master_key (krb5_context, krb5_principal, 
 					   krb5_keyblock *);
 krb5_error_code krb5_db_store_mkey (krb5_context, char *, krb5_principal,
diff --git a/src/include/krb5/stock/ChangeLog b/src/include/krb5/stock/ChangeLog
index 3c7bb4f61..bd0d76f0f 100644
--- a/src/include/krb5/stock/ChangeLog
+++ b/src/include/krb5/stock/ChangeLog
@@ -1,3 +1,7 @@
+2003-05-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* osconf.h (DEFAULT_KDC_ENCTYPE): Default to des3 now.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * osconf.h: Added DEFAULT_SECURE_PROFILE_PATH so that KfM will only
diff --git a/src/include/krb5/stock/osconf.h b/src/include/krb5/stock/osconf.h
index b56d05748..876e9f245 100644
--- a/src/include/krb5/stock/osconf.h
+++ b/src/include/krb5/stock/osconf.h
@@ -64,7 +64,7 @@
 #define	DEFAULT_KDC_PROFILE	"@LOCALSTATEDIR/krb5kdc/kdc.conf"
 #define	KDC_PROFILE_ENV		"KRB5_KDC_PROFILE"
 
-#define	DEFAULT_KDC_ENCTYPE	ENCTYPE_DES_CBC_CRC
+#define	DEFAULT_KDC_ENCTYPE	ENCTYPE_DES3_CBC_SHA1
 #define KDCRCACHE		"dfl:krb5kdc_rcache"
 
 #define KDC_PORTNAME		"kerberos" /* for /etc/services or equiv. */
diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h
index 34489669b..eb87bc1c9 100644
--- a/src/include/port-sockets.h
+++ b/src/include/port-sockets.h
@@ -153,6 +153,21 @@ typedef struct iovec sg_buf;
 #define SHUTDOWN_WRITE	1
 #define SHUTDOWN_BOTH	2
 
+#ifndef HAVE_INET_NTOP
+#define inet_ntop(AF,SRC,DST,CNT)					    \
+    ((AF) == AF_INET							    \
+     ? ((CNT) < 16							    \
+	? (SOCKET_SET_ERRNO(ENOSPC), NULL)				    \
+	: (sprintf((DST), "%d.%d.%d.%d",				    \
+		   ((const unsigned char *)(const void *)(SRC))[0] & 0xff,  \
+		   ((const unsigned char *)(const void *)(SRC))[1] & 0xff,  \
+		   ((const unsigned char *)(const void *)(SRC))[2] & 0xff,  \
+		   ((const unsigned char *)(const void *)(SRC))[3] & 0xff), \
+	   (DST)))							    \
+     : (SOCKET_SET_ERRNO(EAFNOSUPPORT), NULL))
+#define HAVE_INET_NTOP
+#endif
+
 #endif /* HAVE_MACSOCK_H */
 
 #endif /* _WIN32 */
diff --git a/src/include/win-mac.h b/src/include/win-mac.h
index b6cf96dfa..4cf155e62 100644
--- a/src/include/win-mac.h
+++ b/src/include/win-mac.h
@@ -30,9 +30,14 @@
 #define SIZEOF_LONG     4
 
 #include <windows.h>
+#include <limits.h>
 
 #define HAVE_LABS
 
+#ifndef SIZE_MAX    /* in case Microsoft defines max size of size_t */
+#define SIZE_MAX UINT_MAX
+#endif
+
 #ifndef KRB5_CALLCONV
 #  define KRB5_CALLCONV __stdcall
 #  define KRB5_CALLCONV_C __cdecl
@@ -145,8 +150,12 @@ typedef unsigned char	u_char;
 /*
  * Functions with slightly different names on the PC
  */
+#ifndef strcasecmp
 #define strcasecmp   stricmp
+#endif
+#ifndef strncasecmp
 #define strncasecmp  strnicmp
+#endif
 
 HINSTANCE get_lib_instance(void);
 
diff --git a/src/kadmin/cli/ChangeLog b/src/kadmin/cli/ChangeLog
index aa463ba12..2c54a5326 100644
--- a/src/kadmin/cli/ChangeLog
+++ b/src/kadmin/cli/ChangeLog
@@ -1,3 +1,12 @@
+2003-06-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* kadmin.c (strdate): Increase size of buffer to 40.  Use sizeof
+	for length passed to strftime.
+
+2003-05-19  Sam Hartman  <hartmans@mit.edu>
+
+	* kadmin.c (kadmin_startup): Don't register writable keytabs as this is always done by the library now.
+
 2003-02-07  Tom Yu  <tlyu@mit.edu>
 
 	* Makefile.in (install): Fix typo in k5srvutil.M install rule.
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index 189938e65..eb5468dde 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -132,11 +132,11 @@ static char *strdate(when)
     krb5_timestamp when;
 {
     struct tm *tm;
-    static char out[30];
+    static char out[40];
     
     time_t lcltim = when;
     tm = localtime(&lcltim);
-    strftime(out, 30, "%a %b %d %H:%M:%S %Z %Y", tm);
+    strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm);
     return out;
 }
 
@@ -175,7 +175,6 @@ char *kadmin_startup(argc, argv)
     int argc;
     char *argv[];
 {
-    extern krb5_kt_ops krb5_ktf_writable_ops;
     extern char *optarg;
     char *princstr = NULL, *keytab_name = NULL, *query = NULL;
     char *password = NULL;
@@ -449,11 +448,6 @@ char *kadmin_startup(argc, argv)
     }
 
     /* register the WRFILE keytab type and set it as the default */
-    if ((retval = krb5_kt_register(context, &krb5_ktf_writable_ops))) {
-	 com_err(whoami, retval,
-		 "while registering writable key table functions");
-	 exit(1);
-    }
     {
 #define DEFAULT_KEYTAB "WRFILE:/etc/krb5.keytab"
 	 /* XXX krb5_defkeyname is an internal library global and
diff --git a/src/kadmin/dbutil/ChangeLog b/src/kadmin/dbutil/ChangeLog
index 5f32c1eee..711302500 100644
--- a/src/kadmin/dbutil/ChangeLog
+++ b/src/kadmin/dbutil/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* kdb5_destroy.c, kdb5_stash.c: Don't declare errno.
+
 2003-01-07  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.ov: Deleted.
diff --git a/src/kadmin/dbutil/kdb5_destroy.c b/src/kadmin/dbutil/kdb5_destroy.c
index 62d65ed49..2545bdb5d 100644
--- a/src/kadmin/dbutil/kdb5_destroy.c
+++ b/src/kadmin/dbutil/kdb5_destroy.c
@@ -36,7 +36,6 @@
 #include <kadm5/adb.h>
 #include "kdb5_util.h"
 
-extern int errno;
 extern int exit_status;
 extern krb5_boolean dbactive;
 extern kadm5_config_params global_params;
diff --git a/src/kadmin/dbutil/kdb5_stash.c b/src/kadmin/dbutil/kdb5_stash.c
index 37db048ac..6d7251541 100644
--- a/src/kadmin/dbutil/kdb5_stash.c
+++ b/src/kadmin/dbutil/kdb5_stash.c
@@ -59,8 +59,6 @@
 #include <stdio.h>
 #include "kdb5_util.h"
 
-extern int errno;
-
 extern krb5_keyblock master_keyblock;
 extern krb5_principal master_princ;
 extern kadm5_config_params global_params;
diff --git a/src/kadmin/ktutil/ChangeLog b/src/kadmin/ktutil/ChangeLog
index cccc49363..0202686b7 100644
--- a/src/kadmin/ktutil/ChangeLog
+++ b/src/kadmin/ktutil/ChangeLog
@@ -1,3 +1,8 @@
+2003-05-19  Sam Hartman  <hartmans@mit.edu>
+
+	* ktutil.c (main): Don't register writable keytab ops as they are
+	registered by the library now  
+
 2002-11-05  Tom Yu  <tlyu@mit.edu>
 
 	* ktutil_funcs.c (ktutil_add): Remove trailing colon, as new
diff --git a/src/kadmin/ktutil/Makefile.in b/src/kadmin/ktutil/Makefile.in
index fb21d7f43..fe5c4273f 100644
--- a/src/kadmin/ktutil/Makefile.in
+++ b/src/kadmin/ktutil/Makefile.in
@@ -42,16 +42,17 @@ clean::
 #
 $(OUTPRE)ktutil.$(OBJEXT): ktutil.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h ktutil.h $(SRCTOP)/include/krb5/adm_proto.h \
-  $(SS_DEPS)
+  ktutil.h $(SRCTOP)/include/krb5/adm_proto.h $(SS_DEPS)
 $(OUTPRE)ktutil_ct.$(OBJEXT): ktutil_ct.c $(SS_DEPS) \
   $(COM_ERR_DEPS)
 $(OUTPRE)ktutil_funcs.$(OBJEXT): ktutil_funcs.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h ktutil.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP)
+  ktutil.h $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP)
 
diff --git a/src/kadmin/ktutil/ktutil.c b/src/kadmin/ktutil/ktutil.c
index e01bbdbef..e2464e853 100644
--- a/src/kadmin/ktutil/ktutil.c
+++ b/src/kadmin/ktutil/ktutil.c
@@ -45,7 +45,6 @@ int main(argc, argv)
     char *argv[];
 {
     krb5_error_code retval;
-    extern krb5_kt_ops krb5_ktf_writable_ops;
     int sci_idx;
 
     retval = krb5_init_context(&kcontext);
@@ -53,12 +52,6 @@ int main(argc, argv)
         com_err(argv[0], retval, "while initializing krb5");
 	exit(1);
     }
-    retval = krb5_kt_register(kcontext, &krb5_ktf_writable_ops);
-    if (retval) {
-	com_err(argv[0], retval,
-		"while registering writable key table functions");
-	exit(1);
-    }
     sci_idx = ss_create_invocation("ktutil", "5.0", (char *)NULL,
 				   &ktutil_cmds, &retval);
     if (retval) {
diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog
index 6c3d72be0..66fad7429 100644
--- a/src/kadmin/server/ChangeLog
+++ b/src/kadmin/server/ChangeLog
@@ -1,3 +1,16 @@
+2003-09-02  Alexandra Ellwood  <lxs@mit.edu>
+
+	* ovsec_kadmd.c: Added Apple password server support.
+
+2003-05-27  Tom Yu  <tlyu@mit.edu>
+
+	* schpw.c (process_chpw_request): Log chpw requests.
+
+2003-05-16  Ken Raeburn  <raeburn@mit.edu>
+
+	* schpw.c (process_chpw_request): Return KRB5_KPASSWD_BAD_VERSION
+	if the version number isn't 1.
+
 2003-03-07  Tom Yu  <tlyu@mit.edu>
 
 	* ovsec_kadmd.c (REQUIRED_PARAMS): Remove
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 290af20ee..4510b1bb7 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -113,6 +113,10 @@ void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
 int schpw;
 void do_schpw(int s, kadm5_config_params *params);
 
+#ifdef USE_PASSWORD_SERVER
+void kadm5_set_use_password_server (void);
+#endif
+
 /*
  * Function: usage
  * 
@@ -127,6 +131,9 @@ void do_schpw(int s, kadm5_config_params *params);
 static void usage()
 {
      fprintf(stderr, "Usage: kadmind [-r realm] [-m] [-nofork] "
+#ifdef USE_PASSWORD_SERVER
+             "[-passwordserver] "
+#endif
 	     "[-port port-number]\n");
      exit(1);
 }
@@ -242,6 +249,10 @@ int main(int argc, char *argv[])
 	       params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
 	  } else if (strcmp(*argv, "-nofork") == 0) {
 	       nofork = 1;
+#ifdef USE_PASSWORD_SERVER
+          } else if (strcmp(*argv, "-passwordserver") == 0) {
+              kadm5_set_use_password_server ();
+#endif              
 	  } else if(strcmp(*argv, "-port") == 0) {
 	    argc--; argv++;
 	    if(!argc)
diff --git a/src/kadmin/server/schpw.c b/src/kadmin/server/schpw.c
index ddf623886..2a0fe9d87 100644
--- a/src/kadmin/server/schpw.c
+++ b/src/kadmin/server/schpw.c
@@ -1,7 +1,8 @@
 #define NEED_SOCKETS
 #include "k5-int.h"
 #include <kadm5/admin.h>
-
+#include <syslog.h>
+#include <krb5/adm_proto.h>	/* krb5_klog_syslog */
 #include <stdio.h>
 #include <errno.h>
 
@@ -39,6 +40,7 @@ process_chpw_request(context, server_handle, realm, s, keytab, sockin,
     krb5_error krberror;
     int numresult;
     char strresult[1024];
+    char *clientstr;
 
     ret = 0;
     rep->length = 0;
@@ -76,7 +78,7 @@ process_chpw_request(context, server_handle, realm, s, keytab, sockin,
 
     if (vno != 1) {
 	ret = KRB5KDC_ERR_BAD_PVNO;
-	numresult = KRB5_KPASSWD_MALFORMED;
+	numresult = KRB5_KPASSWD_BAD_VERSION;
 	sprintf(strresult,
 		"Request contained unknown protocol version number %d", vno);
 	goto chpwfail;
@@ -235,6 +237,12 @@ process_chpw_request(context, server_handle, realm, s, keytab, sockin,
 	goto chpwfail;
     }
 
+    ret = krb5_unparse_name(context, ticket->enc_part2->client, &clientstr);
+    if (ret) {
+	numresult = KRB5_KPASSWD_HARDERROR;
+	strcpy(strresult, "Failed unparsing client name for log");
+	goto chpwfail;
+    }
     /* change the password */
 
     ptr = (char *) malloc(clear.length+1);
@@ -251,6 +259,11 @@ process_chpw_request(context, server_handle, realm, s, keytab, sockin,
     free(ptr);
     clear.length = 0;
 
+    krb5_klog_syslog(LOG_NOTICE, "chpw request from %s for %s: %s",
+		     inet_ntoa(((struct sockaddr_in *)&remote_addr)->sin_addr),
+		     clientstr, ret ? error_message(ret) : "success");
+    krb5_free_unparsed_name(context, clientstr);
+
     if (ret) {
 	if ((ret != KADM5_PASS_Q_TOOSHORT) && 
 	    (ret != KADM5_PASS_REUSE) && (ret != KADM5_PASS_Q_CLASS) && 
diff --git a/src/kadmin/testing/util/Makefile.in b/src/kadmin/testing/util/Makefile.in
index b065ab0f0..38fb30c5a 100644
--- a/src/kadmin/testing/util/Makefile.in
+++ b/src/kadmin/testing/util/Makefile.in
@@ -53,10 +53,11 @@ $(OUTPRE)tcl_ovsec_kadm.$(OBJEXT): tcl_ovsec_kadm.c \
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h tcl_kadm5.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  tcl_kadm5.h
 $(OUTPRE)tcl_kadm5.$(OBJEXT): tcl_kadm5.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -64,10 +65,10 @@ $(OUTPRE)tcl_kadm5.$(OBJEXT): tcl_kadm5.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  tcl_kadm5.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h tcl_kadm5.h
 $(OUTPRE)test.$(OBJEXT): test.c tcl_kadm5.h
 
diff --git a/src/kadmin/v5passwdd/Makefile.in b/src/kadmin/v5passwdd/Makefile.in
index 4f1f76b65..9a4a9211b 100644
--- a/src/kadmin/v5passwdd/Makefile.in
+++ b/src/kadmin/v5passwdd/Makefile.in
@@ -57,37 +57,40 @@ $(OUTPRE)main.$(OBJEXT): main.c $(SRCTOP)/include/syslog.h \
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h \
-  kadm5_defs.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(SRCTOP)/include/krb5/adm_proto.h kadm5_defs.h
 $(OUTPRE)srv_net.$(OBJEXT): srv_net.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kadm5_defs.h $(SRCTOP)/include/krb5/adm.h
+  kadm5_defs.h $(SRCTOP)/include/krb5/adm.h
 $(OUTPRE)proto_serv.$(OBJEXT): proto_serv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kadm5_defs.h $(SRCTOP)/include/krb5/adm.h \
-  $(SRCTOP)/include/krb5/adm_proto.h
+  kadm5_defs.h $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)adm_rw.$(OBJEXT): adm_rw.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)kpasswd.$(OBJEXT): kpasswd.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/adm_defs.h \
-  $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/krb5/adm_defs.h $(SRCTOP)/include/krb5/adm.h \
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)adm_conn.$(OBJEXT): adm_conn.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/adm.h \
-  $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h
 
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog
index eb4273615..974fd5479 100644
--- a/src/kdc/ChangeLog
+++ b/src/kdc/ChangeLog
@@ -1,3 +1,115 @@
+2004-02-09  Tom Yu  <tlyu@mit.edu>
+
+	* main.c (init_realm): Apply patch from Will Fiveash to use
+	correct TCP listening ports.
+
+2004-02-06  Sam Hartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* kdc_util.c:  Ignore unknown TGS options
+
+2004-01-05  Sam Hartman  <hartmans@mit.edu>
+
+	* kerberos_v4.c (kerberos_v4): Only backdate the rquest in the
+	issued ticket.  Client libraries tend to verify that the
+	backdating falls within clockskew.  a
+
+2003-06-03  Tom Yu  <tlyu@mit.edu>
+
+	* extern.h (master_princ): Remove realm_mkvno, realm_tgskey,
+	realm_tgskvno, realm_kstypes, realm_nkstypes.  They're not needed
+	anymore.
+
+	* main.c (finish_realm): Remove references to realm_kstypes,
+	realm_tgskey.
+	(init_realm): Don't bother with realm_kstypes.  Don't bother
+	looking up the master kvno.  Don't bother caching the TGS key.
+	None of these were being used.
+
+2003-05-30  Ken Raeburn  <raeburn@mit.edu>
+
+	* main.c (init_realm): Use KRB5_KDB_MAX_RLIFE, not
+	KRB5_KDB_MAX_LIFE, as default for realm's max renewable lifetime.
+
+2003-05-23  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_preauth.c (_make_etype_info_entry): Add flag to know if we
+	are producing etype_info2 so we know whether filling in s2kparams
+	is allowed.    In the etype_info2 case support afs3 salts.
+	(etype_info_helper): Pass in flag
+	(return_etype_info2): And here
+
+2003-05-23  Ezra Peisach  <epeisach@mit.edu>
+
+	* kdc_preauth.c (return_etype_info2): After encoding the
+	etype_info2 and copying the pointers to the pa_data, free the
+	krb5_data pointer.
+
+2003-05-22  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_util.c (validate_as_request): Only reject options we
+	understand and believe are inappropriate for AS requests. Per
+	spec, unknown options are ignored.
+
+2003-05-14  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_preauth.c (check_padata): Allow bad_integrity to be returned to a client
+
+2003-05-08  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_preauth.c (return_pw_salt): Don't return pw-salt if the
+	client's enctype list  mandates it supports enctype-info2
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* kdc_util.c (kdc_process_tgs_req): Rename getremotesubkey ->
+	getrecvsubkey.
+
+2003-05-07  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_preauth.c (get_etype_info): Patch from Sun to reorganize
+	code and make sure that even for md5 the database order is
+	preserved. 
+	(enctype_requires_etype_info_2): new function; determines wether a
+	particular enctype in a client request means that the client  is
+	required to support etype_info2 by Kerberos clarifications.
+	(etype_info_helper): Renamed from get_etype_info  to abstract out
+	code in common between etype_info and etype_info2
+	(get_enctype_info): Return etype info only if request contains no
+	enctypes that  require etype_info2
+	(return_etype_info2): New function.
+
+2003-04-02  Sam Hartman  <hartmans@mit.edu>
+
+	* kdc_preauth.c (get_etype_info): Avoid infinite loop if request
+	does not contain des-cbc-crc and database does 
+
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* do_tgs_req.c (process_tgs_req): Check that principal name
+	component 1 is present before examining it.
+	* kdc_util.c (krb5_is_tgs_principal, validate_tgs_request): Check
+	principal name length before examining components.
+
+2003-03-28  Tom Yu  <tlyu@mit.edu>
+
+	* kdc_preauth.c (verify_enc_timestamp): Save decryption error, in
+	case we get NO_MATCHING_KEY later.  This allows us to log a more
+	sane error if an incorrect password is used for encrypting the
+	enc-timestamp preauth.
+
+2003-03-16  Sam Hartman  <hartmans@mit.edu>
+
+	* main.c (initialize_realms): Add support to call
+	enable_v4_crossrealm if the user wants insecure operation 
+
+	* kerberos_v4.c: Add enable_v4_crossrealm.  By default krb4
+	cross-realm is not allowed as it is insecure.  Also, remove
+	support for generating krb4 tickets encrypted in 3DES as they are
+	insecure. 
+
+	* kdc_util.h: Define enable_v4_crossrealm, new function to enable
+	secure krb4 cross-realm authentication 
+
 2003-03-05  Tom Yu  <tlyu@mit.edu>
 
 	* main.c (init_realm): Update call to krb5_ktdb_resolve().
diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in
index 368dfaf91..680ded33a 100644
--- a/src/kdc/Makefile.in
+++ b/src/kdc/Makefile.in
@@ -101,80 +101,87 @@ clean::
 $(OUTPRE)kdc5_err.$(OBJEXT): kdc5_err.c $(COM_ERR_DEPS)
 $(OUTPRE)dispatch.$(OBJEXT): dispatch.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/syslog.h \
-  kdc_util.h extern.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/syslog.h kdc_util.h extern.h $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)do_as_req.$(OBJEXT): do_as_req.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/syslog.h \
-  kdc_util.h policy.h $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h \
-  extern.h
+  $(SRCTOP)/include/syslog.h kdc_util.h policy.h $(SRCTOP)/include/krb5/adm.h \
+  $(SRCTOP)/include/krb5/adm_proto.h extern.h
 $(OUTPRE)do_tgs_req.$(OBJEXT): do_tgs_req.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/syslog.h \
-  kdc_util.h policy.h extern.h $(SRCTOP)/include/krb5/adm_proto.h
+  $(SRCTOP)/include/syslog.h kdc_util.h policy.h extern.h \
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)kdc_util.$(OBJEXT): kdc_util.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h extern.h $(SRCTOP)/include/syslog.h \
-  $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h
+  kdc_util.h extern.h $(SRCTOP)/include/syslog.h $(SRCTOP)/include/krb5/adm.h \
+  $(SRCTOP)/include/krb5/adm_proto.h
 $(OUTPRE)kdc_preauth.$(OBJEXT): kdc_preauth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h extern.h $(SRCTOP)/include/krb5/adm_proto.h \
+  kdc_util.h extern.h $(SRCTOP)/include/krb5/adm_proto.h \
   $(SRCTOP)/include/syslog.h
 $(OUTPRE)logger.$(OBJEXT): $(SRCTOP)/lib/kadm5/logger.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/adm_proto.h \
+  $(SRCTOP)/include/syslog.h
 $(OUTPRE)main.$(OBJEXT): main.c $(SRCTOP)/include/syslog.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/krb5/adm.h $(SRCTOP)/include/krb5/adm_proto.h \
-  kdc_util.h extern.h kdc5_err.h $(SRCTOP)/include/krb5/kdb_kt.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/adm.h \
+  $(SRCTOP)/include/krb5/adm_proto.h kdc_util.h extern.h \
+  kdc5_err.h $(SRCTOP)/include/krb5/kdb_kt.h $(SRCTOP)/include/kerberosIV/des.h
 $(OUTPRE)network.$(OBJEXT): network.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h extern.h kdc5_err.h \
-  $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h \
-  $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/cm.h \
-  $(SRCTOP)/include/foreachaddr.c
+  kdc_util.h extern.h kdc5_err.h $(SRCTOP)/include/krb5/adm_proto.h \
+  $(SRCTOP)/include/syslog.h $(SRCTOP)/include/fake-addrinfo.h \
+  $(SRCTOP)/include/cm.h $(SRCTOP)/include/foreachaddr.c
 $(OUTPRE)policy.$(OBJEXT): policy.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h
+  kdc_util.h
 $(OUTPRE)extern.$(OBJEXT): extern.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h extern.h
+  extern.h
 $(OUTPRE)replay.$(OBJEXT): replay.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h extern.h
+  kdc_util.h extern.h
 $(OUTPRE)kerberos_v4.$(OBJEXT): kerberos_v4.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kdc_util.h $(SRCTOP)/include/krb5/adm_proto.h \
-  $(SRCTOP)/include/syslog.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(SRCTOP)/include/kerberosIV/klog.h $(SRCTOP)/include/kerberosIV/prot.h \
-  $(SRCTOP)/include/kerberosIV/krb_db.h $(SRCTOP)/include/kerberosIV/kdc.h \
-  extern.h
+  kdc_util.h $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h \
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP) $(SRCTOP)/include/kerberosIV/klog.h \
+  $(SRCTOP)/include/kerberosIV/prot.h $(SRCTOP)/include/kerberosIV/krb_db.h \
+  $(SRCTOP)/include/kerberosIV/kdc.h extern.h
 
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 0c6116e21..c8b679bc2 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -174,7 +174,7 @@ tgt_again:
 		krb5_data *tgs_1 =
 		    krb5_princ_component(kdc_context, tgs_server, 1);
 
-		if (server_1->length != tgs_1->length ||
+		if (!tgs_1 || server_1->length != tgs_1->length ||
 		    memcmp(server_1->data, tgs_1->data, tgs_1->length)) {
 		    krb5_db_free_principal(kdc_context, &server, nprincs);
 		    find_alternate_tgs(request, &server, &more, &nprincs);
diff --git a/src/kdc/extern.h b/src/kdc/extern.h
index ad06674b8..d4db86aac 100644
--- a/src/kdc/extern.h
+++ b/src/kdc/extern.h
@@ -49,13 +49,10 @@ typedef struct __kdc_realm_data {
     char *		realm_mpname;	/* Master principal name for realm  */
     krb5_principal	realm_mprinc;	/* Master principal for realm	    */
     krb5_keyblock	realm_mkey;	/* Master key for this realm	    */
-    krb5_kvno		realm_mkvno;	/* Master key vno for this realm    */
     /*
      * TGS per-realm data.
      */
     krb5_principal	realm_tgsprinc;	/* TGS principal for this realm	    */
-    krb5_keyblock	realm_tgskey;	/* TGS' key for this realm	    */
-    krb5_kvno		realm_tgskvno;	/* TGS' key vno for this realm	    */
     /*
      * Other per-realm data.
      */
@@ -66,8 +63,6 @@ typedef struct __kdc_realm_data {
      */
     krb5_deltat		realm_maxlife;	/* Maximum ticket life for realm    */
     krb5_deltat		realm_maxrlife;	/* Maximum renewable life for realm */
-    void		*realm_kstypes;	/* Key/Salts supported for realm    */
-    krb5_int32		realm_nkstypes;	/* Number of key/salts		    */
     krb5_boolean	realm_reject_bad_transit; /* Accept unverifiable transited_realm ? */
 } kdc_realm_t;
 
@@ -87,8 +82,6 @@ kdc_realm_t *find_realm_data (char *, krb5_ui_4);
 #define	max_renewable_life_for_realm	kdc_active_realm->realm_maxrlife
 #define	master_keyblock			kdc_active_realm->realm_mkey
 #define	master_princ			kdc_active_realm->realm_mprinc
-#define	tgs_key				kdc_active_realm->realm_tgskey
-#define	tgs_kvno			kdc_active_realm->realm_tgskvno
 #define	tgs_server_struct		*(kdc_active_realm->realm_tgsprinc)
 #define	tgs_server			kdc_active_realm->realm_tgsprinc
 #define	dbm_db_name			kdc_active_realm->realm_dbname
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 4747f27de..342f05021 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -59,6 +59,8 @@
 #include "adm_proto.h"
 #include <syslog.h>
 
+#include <assert.h>
+
 /* XXX This is ugly and should be in a header file somewhere */
 #ifndef KRB5INT_DES_TYPES_DEFINED
 #define KRB5INT_DES_TYPES_DEFINED
@@ -104,6 +106,18 @@ static krb5_error_code get_etype_info
     (krb5_context, krb5_kdc_req *request,
 		    krb5_db_entry *client, krb5_db_entry *server,
 		    krb5_pa_data *data);
+static krb5_error_code
+get_etype_info2(krb5_context context, krb5_kdc_req *request,
+	       krb5_db_entry *client, krb5_db_entry *server,
+		  krb5_pa_data *pa_data);
+static krb5_error_code
+return_etype_info2(krb5_context, krb5_pa_data * padata, 
+		   krb5_db_entry *client,
+		   krb5_kdc_req *request, krb5_kdc_rep *reply,
+		   krb5_key_data *client_key,
+		   krb5_keyblock *encrypting_key,
+		   krb5_pa_data **send_pa);
+
 static krb5_error_code return_pw_salt
     (krb5_context, krb5_pa_data * padata, 
 		    krb5_db_entry *client,
@@ -155,6 +169,14 @@ static krb5_preauth_systems preauth_systems[] = {
 	0,
 	0
     },
+    {
+	"etype-info2",
+	KRB5_PADATA_ETYPE_INFO2,
+	0,
+	get_etype_info2,
+	0,
+	return_etype_info2
+    },
     {
 	"pw-salt",
 	KRB5_PADATA_PW_SALT,
@@ -362,6 +384,7 @@ check_padata (krb5_context context, krb5_db_entry *client,
  * to return some preauth system errors back to the client.
  */
         switch(retval) {
+	case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     case KRB5KRB_AP_ERR_SKEW:
 	return retval;
     default:
@@ -431,6 +454,26 @@ cleanup:
     return (retval);
 }
 
+static krb5_boolean
+enctype_requires_etype_info_2(krb5_enctype enctype)
+{
+    switch(enctype) {
+    case ENCTYPE_DES_CBC_CRC:
+    case ENCTYPE_DES_CBC_MD4:
+    case ENCTYPE_DES_CBC_MD5:
+    case ENCTYPE_DES3_CBC_SHA1:
+    case ENCTYPE_DES3_CBC_RAW:
+    case ENCTYPE_ARCFOUR_HMAC:
+    case ENCTYPE_ARCFOUR_HMAC_EXP :
+    case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
+	return 0;
+    default:
+	if (krb5_c_valid_enctype(enctype))
+	    return 1;
+	else return 0;
+    }
+}
+
 static krb5_boolean
 request_contains_enctype (krb5_context context,  const krb5_kdc_req *request,
 			  krb5_enctype enctype)
@@ -457,7 +500,8 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
     krb5_key_data *		client_key;
     krb5_int32			start;
     krb5_timestamp		timenow;
-    
+    krb5_error_code		decrypt_err;
+
     scratch.data = pa->contents;
     scratch.length = pa->length;
 
@@ -471,6 +515,7 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
 	goto cleanup;
 
     start = 0;
+    decrypt_err = 0;
     while (1) {
 	if ((retval = krb5_dbe_search_enctype(context, client,
 					      &start, enc_data->enctype,
@@ -488,6 +533,8 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
 	krb5_free_keyblock_contents(context, &key);
 	if (retval == 0)
 	    break;
+	else
+	    decrypt_err = retval;
     }
 
     if ((retval = decode_krb5_pa_enc_ts(&enc_ts_data, &pa_enc)) != 0)
@@ -513,29 +560,98 @@ cleanup:
     krb5_free_data_contents(context, &enc_ts_data);
     if (pa_enc)
 	free(pa_enc);
+    /*
+     * If we get NO_MATCHING_KEY and decryption previously failed, and
+     * we failed to find any other keys of the correct enctype after
+     * that failed decryption, it probably means that the password was
+     * incorrect.
+     */
+    if (retval == KRB5_KDB_NO_MATCHING_KEY && decrypt_err != 0)
+	retval = decrypt_err;
     return retval;
 }
 
+static krb5_error_code
+_make_etype_info_entry(krb5_context context,
+		       krb5_kdc_req *request, krb5_key_data *client_key,
+		       krb5_enctype etype, krb5_etype_info_entry **entry,
+		       int etype_info2)
+{
+    krb5_data			salt;
+    krb5_etype_info_entry *	tmp_entry; 
+    krb5_error_code		retval;
+
+    if ((tmp_entry = malloc(sizeof(krb5_etype_info_entry))) == NULL)
+       return ENOMEM;
+
+    salt.data = 0;
+
+    tmp_entry->magic = KV5M_ETYPE_INFO_ENTRY;
+    tmp_entry->etype = etype;
+    tmp_entry->length = KRB5_ETYPE_NO_SALT;
+    tmp_entry->salt = 0;
+    tmp_entry->s2kparams.data = NULL;
+    tmp_entry->s2kparams.length = 0;
+    retval = get_salt_from_key(context, request->client,
+			       client_key, &salt);
+    if (retval)
+	goto fail;
+    if (etype_info2 && client_key->key_data_ver > 1 &&
+	client_key->key_data_type[1] == KRB5_KDB_SALTTYPE_AFS3) {
+	switch (etype) {
+	case ENCTYPE_DES_CBC_CRC:
+	case ENCTYPE_DES_CBC_MD4:
+	case ENCTYPE_DES_CBC_MD5:
+	    tmp_entry->s2kparams.data = malloc(1);
+	    if (tmp_entry->s2kparams.data == NULL) {
+		retval = ENOMEM;
+		goto fail;
+	    }
+	    tmp_entry->s2kparams.length = 1;
+	    tmp_entry->s2kparams.data[0] = 1;
+	    break;
+	default:
+	    break;
+	}
+    }
+
+    if (salt.length >= 0) {
+	tmp_entry->length = salt.length;
+	tmp_entry->salt = (unsigned char *) salt.data;
+	salt.data = 0;
+    }
+    *entry = tmp_entry;
+    return 0;
+
+fail:
+    if (tmp_entry) {
+	if (tmp_entry->s2kparams.data)
+	    free(tmp_entry->s2kparams.data);
+	free(tmp_entry);
+    }
+    if (salt.data)
+	free(salt.data);
+    return retval;
+}
 /*
  * This function returns the etype information for a particular
  * client, to be passed back in the preauth list in the KRB_ERROR
- * message.
+ * message.  It supports generating both etype_info  and etype_info2
+ *  as most of the work is the same.   
  */
 static krb5_error_code
-get_etype_info(krb5_context context, krb5_kdc_req *request,
+etype_info_helper(krb5_context context, krb5_kdc_req *request,
 	       krb5_db_entry *client, krb5_db_entry *server,
-	       krb5_pa_data *pa_data)
+	       krb5_pa_data *pa_data, int etype_info2)
 {
     krb5_etype_info_entry **	entry = 0;
     krb5_key_data		*client_key;
     krb5_error_code		retval;
-    krb5_data			salt;
     krb5_data *			scratch;
     krb5_enctype		db_etype;
     int 			i = 0;
     int 			start = 0;
-
-    salt.data = 0;
+    int				seen_des = 0;
 
     entry = malloc((client->n_key_data * 2 + 1) * sizeof(krb5_etype_info_entry *));
     if (entry == NULL)
@@ -550,51 +666,55 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
 	if (retval)
 	    goto cleanup;
 	db_etype = client_key->key_data_type[0];
-	if (db_etype == ENCTYPE_DES_CBC_MD4 || db_etype == ENCTYPE_DES_CBC_MD5)
-	    db_etype = ENCTYPE_DES_CBC_CRC;
+	if (db_etype == ENCTYPE_DES_CBC_MD4)
+	    db_etype = ENCTYPE_DES_CBC_MD5;
 	
-	while (1) {
-	    if (!request_contains_enctype(context,
-					  request, db_etype)) {
-		if (db_etype == ENCTYPE_DES_CBC_CRC)
-                    continue;
-                else break;
-            }
-
-	    if ((entry[i] = malloc(sizeof(krb5_etype_info_entry))) == NULL) {
-		retval = ENOMEM;
+	if (request_contains_enctype(context, request, db_etype)) {
+	    assert(etype_info2 ||
+		   !enctype_requires_etype_info_2(db_etype));
+	    if ((retval = _make_etype_info_entry(context, request, client_key,
+			    db_etype, &entry[i], etype_info2)) != 0) {
 		goto cleanup;
 	    }
 	    entry[i+1] = 0;
-	    entry[i]->magic = KV5M_ETYPE_INFO_ENTRY;
-	    entry[i]->etype = db_etype;
-	    entry[i]->length = KRB5_ETYPE_NO_SALT;
-	    entry[i]->salt = 0;
-	    retval = get_salt_from_key(context, request->client,
-				       client_key, &salt);
-	    if (retval)
-		goto cleanup;
-	    if (salt.length >= 0 && salt.length != SALT_TYPE_NO_LENGTH) {
-		entry[i]->length = salt.length;
-		entry[i]->salt = salt.data;
-		salt.data = 0;
-	    }
 	    i++;
-	    /*
-	     * If we have a DES_CRC key, it can also be used as a
-	     * DES_MD5 key.
-	     */
-	    if (db_etype == ENCTYPE_DES_CBC_CRC)
+	}
+
+	/* 
+	 * If there is a des key in the kdb, try the "similar" enctypes,
+	 * avoid duplicate entries. 
+	 */
+	if (!seen_des) {
+	    switch (db_etype) {
+	    case ENCTYPE_DES_CBC_MD5:
+		db_etype = ENCTYPE_DES_CBC_CRC;
+		break;
+	    case ENCTYPE_DES_CBC_CRC:
 		db_etype = ENCTYPE_DES_CBC_MD5;
-	    else
 		break;
+	    default:
+		continue;
+
+	    }
+	    if (request_contains_enctype(context, request, db_etype)) {
+		if ((retval = _make_etype_info_entry(context, request,
+				client_key, db_etype, &entry[i], etype_info2)) != 0) {
+		    goto cleanup;
+		}
+		entry[i+1] = 0;
+		i++;
+	    }
+	    seen_des++;
 	}
     }
-    retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry,
+    if (etype_info2)
+	retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry,
+				    &scratch);
+    else 	retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry,
 				    &scratch);
     if (retval)
 	goto cleanup;
-    pa_data->contents = scratch->data;
+    pa_data->contents = (unsigned char *)scratch->data;
     pa_data->length = scratch->length;
     free(scratch);
 
@@ -603,11 +723,84 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
 cleanup:
     if (entry)
 	krb5_free_etype_info(context, entry);
-    if (salt.data)
-	free(salt.data);
     return retval;
 }
 
+static krb5_error_code
+get_etype_info(krb5_context context, krb5_kdc_req *request,
+	       krb5_db_entry *client, krb5_db_entry *server,
+	       krb5_pa_data *pa_data)
+{
+  int i;
+    for (i=0;  i < request->nktypes; i++) {
+	if (enctype_requires_etype_info_2(request->ktype[i])) 
+	    return KRB5KDC_ERR_PADATA_TYPE_NOSUPP ;;;; /*Caller will
+							* skip this
+							* type*/
+    }
+    return etype_info_helper(context, request, client, server, pa_data, 0);
+}
+
+static krb5_error_code
+get_etype_info2(krb5_context context, krb5_kdc_req *request,
+	       krb5_db_entry *client, krb5_db_entry *server,
+	       krb5_pa_data *pa_data)
+{
+    return etype_info_helper( context, request, client, server, pa_data, 1);
+}
+
+static krb5_error_code
+return_etype_info2(krb5_context context, krb5_pa_data * padata, 
+		   krb5_db_entry *client,
+		   krb5_kdc_req *request, krb5_kdc_rep *reply,
+		   krb5_key_data *client_key,
+		   krb5_keyblock *encrypting_key,
+		   krb5_pa_data **send_pa)
+{
+    krb5_error_code retval;
+    krb5_pa_data *tmp_padata;
+    krb5_etype_info_entry **entry = NULL;
+    krb5_data *scratch = NULL;
+    tmp_padata = malloc( sizeof(krb5_pa_data));
+    if (tmp_padata == NULL)
+	return ENOMEM;
+    tmp_padata->pa_type = KRB5_PADATA_ETYPE_INFO2;
+    entry = malloc(2 * sizeof(krb5_etype_info_entry *));
+    if (entry == NULL) {
+	retval = ENOMEM;
+	goto cleanup;
+    }
+    entry[0] = NULL;
+    entry[1] = NULL;
+    retval = _make_etype_info_entry(context, request, client_key, client_key->key_data_type[0],
+				    entry, 1);
+    if (retval)
+	goto cleanup;
+    retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry, &scratch);
+    if (retval)
+	goto cleanup;
+    tmp_padata->contents = scratch->data;
+    tmp_padata->length = scratch->length;
+    *send_pa = tmp_padata;
+
+    /* For cleanup - we no longer own the contents of the krb5_data 
+     * only to pointer to the krb5_data
+     */
+    scratch->data = 0;
+
+ cleanup:
+    if (entry)
+	krb5_free_etype_info(context, entry);
+    if (retval) {
+	if (tmp_padata)
+	    free(tmp_padata);
+    }
+    if (scratch)
+	    krb5_free_data(context, scratch);
+    return retval;
+}
+
+
 static krb5_error_code
 return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
 	       krb5_db_entry *client, krb5_kdc_req *request,
@@ -618,7 +811,12 @@ return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
     krb5_pa_data *	padata;
     krb5_data *		scratch;
     krb5_data		salt_data;
+    int i;
     
+    for (i = 0; i < request->nktypes; i++) {
+	if (enctype_requires_etype_info_2(request->ktype[i]))
+	    return 0;
+    }
     if (client_key->key_data_ver == 1 ||
 	client_key->key_data_type[1] == KRB5_KDB_SALTTYPE_NORMAL)
 	return 0;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 736c51d12..4e2b26d42 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -150,7 +150,8 @@ realm_compare(krb5_principal princ1, krb5_principal princ2)
  */
 krb5_boolean krb5_is_tgs_principal(krb5_principal principal)
 {
-	if ((krb5_princ_component(kdc_context, principal, 0)->length ==
+	if ((krb5_princ_size(kdc_context, principal) > 0) &&
+	    (krb5_princ_component(kdc_context, principal, 0)->length ==
 	     KRB5_TGS_NAME_SIZE) &&
 	    (!memcmp(krb5_princ_component(kdc_context, principal, 0)->data,
 		     KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE)))
@@ -312,8 +313,8 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
 	goto cleanup_auth_context;
     }
 
-    if ((retval = krb5_auth_con_getremotesubkey(kdc_context,
-						auth_context, subkey)))
+    if ((retval = krb5_auth_con_getrecvsubkey(kdc_context,
+					      auth_context, subkey)))
 	goto cleanup_auth_context;
 
     if ((retval = krb5_auth_con_getauthenticator(kdc_context, auth_context,
@@ -827,9 +828,8 @@ fail:
  * Returns a Kerberos protocol error number, which is _not_ the same
  * as a com_err error number!
  */
-#define AS_OPTIONS_HANDLED (KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE | \
-			     KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \
-			     KDC_OPT_RENEWABLE | KDC_OPT_RENEWABLE_OK)
+#define AS_INVALID_OPTIONS (KDC_OPT_FORWARDED | KDC_OPT_PROXY |\
+KDC_OPT_VALIDATE | KDC_OPT_RENEW | KDC_OPT_ENC_TKT_IN_SKEY)
 int
 validate_as_request(register krb5_kdc_req *request, krb5_db_entry client,
 		    krb5_db_entry server, krb5_timestamp kdc_time,
@@ -838,9 +838,9 @@ validate_as_request(register krb5_kdc_req *request, krb5_db_entry client,
     int		errcode;
     
     /*
-     * If an illegal option is set, complain.
+     * If an option is set that is only allowed in TGS requests, complain.
      */
-    if (request->kdc_options & ~(AS_OPTIONS_HANDLED)) {
+    if (request->kdc_options & AS_INVALID_OPTIONS) {
 	*status = "INVALID AS OPTIONS";
 	return KDC_ERR_BADOPTION;
     }
@@ -1113,13 +1113,10 @@ validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
     int		st_idx = 0;
 
     /*
-     * If an illegal option is set, complain.
+     * If an illegal option is set, ignore it.
      */
-    if (request->kdc_options & ~(TGS_OPTIONS_HANDLED)) {
-	*status = "INVALID TGS OPTIONS";
-	return KDC_ERR_BADOPTION;
-    }
-    
+    request->kdc_options &= ~(TGS_OPTIONS_HANDLED);
+
     /* Check to see if server has expired */
     if (server.expiration && server.expiration < kdc_time) {
 	*status = "SERVICE EXPIRED";
@@ -1162,7 +1159,8 @@ validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
 	    return KRB_AP_ERR_NOT_US;
 	}
 	/* ...and that the second component matches the server realm... */
-	if ((krb5_princ_component(kdc_context, ticket->server, 1)->length !=
+	if ((krb5_princ_size(kdc_context, ticket->server) <= 1) ||
+	    (krb5_princ_component(kdc_context, ticket->server, 1)->length !=
 	     krb5_princ_realm(kdc_context, request->server)->length) ||
 	    memcmp(krb5_princ_component(kdc_context, ticket->server, 1)->data,
 		   krb5_princ_realm(kdc_context, request->server)->data,
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 9abe3b860..05ba07f4f 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -176,6 +176,7 @@ krb5_error_code process_v4 (const krb5_data *,
 				      const krb5_fulladdr *,
 				      krb5_data **);
 void process_v4_mode (const char *, const char *);
+void enable_v4_crossrealm(char *);
 #else
 #define process_v4(foo,bar,quux,foobar)	KRB5KRB_AP_ERR_BADVERSION
 #endif
diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c
index a87a1d5e5..1d1ca702e 100644
--- a/src/kdc/kerberos_v4.c
+++ b/src/kdc/kerberos_v4.c
@@ -146,7 +146,7 @@ static krb5_data *response;
 
 void kerberos_v4 (struct sockaddr_in *, KTEXT);
 void kerb_err_reply (struct sockaddr_in *, KTEXT, long, char *);
-static int set_tgtkey (char *, krb5_kvno);
+static int set_tgtkey (char *, krb5_kvno, krb5_boolean);
 
 /* Attributes converted from V5 to V4 - internal representation */
 #define V4_KDB_REQUIRES_PREAUTH  0x1
@@ -180,6 +180,8 @@ static const struct v4mode_lookup_entry  v4mode_table[] = {
 static const int v4mode_table_nents = sizeof(v4mode_table)/
 				      sizeof(v4mode_table[0]);
 
+static int allow_v4_crossrealm = 0;
+
 void process_v4_mode(const char *program_name, const char *string)
 {
     int i, found;
@@ -205,6 +207,11 @@ void process_v4_mode(const char *program_name, const char *string)
     return;
 }
 
+void enable_v4_crossrealm ( char *programname) {
+    allow_v4_crossrealm = 1;
+    krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole");
+}
+
 krb5_error_code
 process_v4(const krb5_data *pkt, const krb5_fulladdr *client_fulladdr,
 	   krb5_data **resp)
@@ -382,6 +389,14 @@ compat_decrypt_key (krb5_key_data *in5, unsigned char *out4,
 /* array of name-components + NULL ptr
  */
 
+/*
+ * Previously this code returned either a v4 key or a v5 key  and you
+ * could tell from the enctype of the v5 key whether the v4 key was
+ * useful.  Now we return both keys so the code can try both des3 and
+ * des decryption.  We fail if the ticket doesn't have a v4 key.
+ * Also, note as a side effect, the v5 key is basically useless  in
+ * the client case.  It is still returned so the caller can free it.
+ */
 static int
 kerb_get_principal(char *name, char *inst, /* could have wild cards */
 		   Principal *principal,
@@ -461,8 +476,28 @@ kerb_get_principal(char *name, char *inst, /* could have wild cards */
 	    return(0);
 	}
     } else {
-	/* XXX yes I know this is a hardcoded search order */
-	if (krb5_dbe_find_enctype(kdc_context, &entries,
+	if ( krb5_dbe_find_enctype(kdc_context, &entries,
+				  ENCTYPE_DES_CBC_CRC,
+				  KRB5_KDB_SALTTYPE_V4, kvno, &pkey) &&
+	    krb5_dbe_find_enctype(kdc_context, &entries,
+				  ENCTYPE_DES_CBC_CRC,
+				  -1, kvno, &pkey)) {
+	    lt = klog(L_KRB_PERR,
+		      "KDC V4: failed to find key for %s.%s #%d",
+		      name, inst, kvno);
+	    krb5_db_free_principal(kdc_context, &entries, nprinc);
+	    return(0);
+	}
+    }
+
+    if (!compat_decrypt_key(pkey, k, k5key, issrv)) {
+ 	memcpy( &principal->key_low, k, LONGLEN);
+       	memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN);
+    }
+    memset(k, 0, sizeof k);
+    if (issrv) {
+	krb5_free_keyblock_contents (kdc_context, k5key);
+      	if (krb5_dbe_find_enctype(kdc_context, &entries,
 				  ENCTYPE_DES3_CBC_RAW,
 				  -1, kvno, &pkey) &&
 	    krb5_dbe_find_enctype(kdc_context, &entries,
@@ -478,17 +513,16 @@ kerb_get_principal(char *name, char *inst, /* could have wild cards */
 				  ENCTYPE_DES_CBC_CRC,
 				  -1, kvno, &pkey)) {
 	    lt = klog(L_KRB_PERR,
-		      "KDC V4: failed to find key for %s.%s #%d",
+		      "KDC V4: failed to find key for %s.%s #%d (after having found it once)",
 		      name, inst, kvno);
 	    krb5_db_free_principal(kdc_context, &entries, nprinc);
 	    return(0);
 	}
-    }
+	compat_decrypt_key(pkey, k, k5key, issrv);
+    memset (k, 0, sizeof k);
+	}
+
 
-    if (!compat_decrypt_key(pkey, k, k5key, issrv)) {
- 	memcpy( &principal->key_low, k, LONGLEN);
-       	memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN);
-    }
     /*
      * Convert v5's entries struct to v4's Principal struct:
      * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes,
@@ -639,10 +673,9 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 
     case AUTH_MSG_KDC_REQUEST:
 	{
-#ifdef notdef
-	    u_long  time_ws;	/* Workstation time */
-#endif
 	    int    req_life;	/* Requested liftime */
+	    unsigned int request_backdate =  0; /*How far to backdate
+						  in seconds.*/
 	    char   *service;	/* Service name */
 	    char   *instance;	/* Service instance */
 #ifdef notdef
@@ -715,7 +748,7 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 	     * kerb_time, which is potentially problematic.
 	     */
 	    if (v4endtime > v4req_end)
-		kerb_time.tv_sec -= v4endtime - v4req_end;
+		request_backdate = v4endtime - v4req_end;
 
 #ifdef NOENCRYPTION
 	    memset(session_key, 0, sizeof(C_Block));
@@ -732,21 +765,14 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 	    kdb_encrypt_key(key, key, master_key,
 			    master_key_schedule, DECRYPT);
 	    /* construct and seal the ticket */
-	    if (K4KDC_ENCTYPE_OK(k5key.enctype)) {
-		krb_create_ticket(tk, k_flags, a_name_data.name,
-				  a_name_data.instance, local_realm,
-				  client_host.s_addr, (char *) session_key,
-				  lifetime, kerb_time.tv_sec,
-				  s_name_data.name, s_name_data.instance,
-				  key);
-	    } else {
-		krb_cr_tkt_krb5(tk, k_flags, a_name_data.name,
-				a_name_data.instance, local_realm,
-				client_host.s_addr, (char *) session_key,
-				lifetime, kerb_time.tv_sec,
-				s_name_data.name, s_name_data.instance,
-				&k5key);
-	    }
+	    /* We always issue des tickets; the 3des tickets are a broken hack*/
+	    krb_create_ticket(tk, k_flags, a_name_data.name,
+			      a_name_data.instance, local_realm,
+			      client_host.s_addr, (char *) session_key,
+			      lifetime, kerb_time.tv_sec - request_backdate,
+			      s_name_data.name, s_name_data.instance,
+			      key);
+
 	    krb5_free_keyblock_contents(kdc_context, &k5key);
 	    memset(key, 0, sizeof(key));
 	    memset(key_s, 0, sizeof(key_s));
@@ -826,8 +852,15 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 	    strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ);
 	    tktrlm[REALM_SZ-1] = '\0';
 	    kvno = (krb5_kvno)auth->dat[2];
-	    if (set_tgtkey(tktrlm, kvno)) {
-		lt = klog(L_ERR_UNK,
+	    if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) {
+	      lt = klog(L_ERR_UNK,
+			"Cross realm ticket from %s denied by policy,", tktrlm);
+	      kerb_err_reply(client, pkt,
+			       KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+		return;
+	    }
+	    if (set_tgtkey(tktrlm, kvno, 0)) {
+	      lt = klog(L_ERR_UNK,
 			  "FAILED set_tgtkey realm %s, kvno %d. Host: %s ",
 			  tktrlm, kvno, inet_ntoa(client_host));
 		/* no better error code */
@@ -837,6 +870,19 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 	    }
 	    kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
 		ad, 0);
+	    if (kerno) {
+		if (set_tgtkey(tktrlm, kvno, 1)) {
+		    lt = klog(L_ERR_UNK,
+			      "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ",
+			      tktrlm, kvno, inet_ntoa(client_host));
+		    /* no better error code */
+		    kerb_err_reply(client, pkt,
+				   KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+		    return;
+		}
+		kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
+				   ad, 0);
+	    }
 
 	    if (kerno) {
 		klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
@@ -913,21 +959,13 @@ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
 	    des_new_random_key(session_key);
 #endif
 
-	    if (K4KDC_ENCTYPE_OK(k5key.enctype)) {
-		krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
-				  ad->prealm, client_host.s_addr,
-				  (char *) session_key, lifetime,
-				  kerb_time.tv_sec,
-				  s_name_data.name, s_name_data.instance,
-				  key);
-	    } else {
-		krb_cr_tkt_krb5(tk, k_flags, ad->pname, ad->pinst,
-				ad->prealm, client_host.s_addr,
-				(char *) session_key, lifetime,
-				kerb_time.tv_sec,
-				s_name_data.name, s_name_data.instance,
-				&k5key);
-	    }
+	    /* ALways issue des tickets*/
+	    krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
+			      ad->prealm, client_host.s_addr,
+			      (char *) session_key, lifetime,
+			      kerb_time.tv_sec,
+			      s_name_data.name, s_name_data.instance,
+			      key);
 	    krb5_free_keyblock_contents(kdc_context, &k5key);
 	    memset(key, 0, sizeof(key));
 	    memset(key_s, 0, sizeof(key_s));
@@ -1107,11 +1145,12 @@ check_princ(char *p_name, char *instance, int lifetime, Principal *p,
 
 /* Set the key for krb_rd_req so we can check tgt */
 static int
-set_tgtkey(char *r, krb5_kvno kvno)
+set_tgtkey(char *r, krb5_kvno kvno, krb5_boolean use_3des)
 {
     int     n;
     static char lastrealm[REALM_SZ] = "";
     static int last_kvno = 0;
+    static krb5_boolean last_use_3des = 0;
     static int more;
     Principal p_st;
     Principal *p = &p_st;
@@ -1119,7 +1158,7 @@ set_tgtkey(char *r, krb5_kvno kvno)
     krb5_keyblock k5key;
 
     k5key.contents = NULL;
-    if (!strcmp(lastrealm, r) && last_kvno == kvno)
+    if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des)
 	return (KSUCCESS);
 
 /*  log("Getting key for %s", r); */
@@ -1141,11 +1180,12 @@ set_tgtkey(char *r, krb5_kvno kvno)
 	return KFAILURE;
     }
 
-    if (!K4KDC_ENCTYPE_OK(k5key.enctype)) {
+    if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) {
 	krb_set_key_krb5(kdc_context, &k5key);
 	strncpy(lastrealm, r, sizeof(lastrealm) - 1);
 	lastrealm[sizeof(lastrealm) - 1] = '\0';
 	last_kvno = kvno;
+	last_use_3des = use_3des;
     } else {
 	/* unseal tgt key from master key */
 	memcpy(key,                &p->key_low,  4);
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 3e5091cbf..9ddcaaa9e 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -121,8 +121,6 @@ finish_realm(kdc_realm_t *rdp)
 	free(rdp->realm_ports);
     if (rdp->realm_tcp_ports)
 	free(rdp->realm_tcp_ports);
-    if (rdp->realm_kstypes)
-	free(rdp->realm_kstypes);
     if (rdp->realm_keytab)
 	krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
     if (rdp->realm_context) {
@@ -132,10 +130,6 @@ finish_realm(kdc_realm_t *rdp)
 	    memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
 	    free(rdp->realm_mkey.contents);
 	}
-	if (rdp->realm_tgskey.length && rdp->realm_tgskey.contents) {
-	    memset(rdp->realm_tgskey.contents, 0, rdp->realm_tgskey.length);
-	    free(rdp->realm_tgskey.contents);
-	}
 	krb5_db_fini(rdp->realm_context);
 	if (rdp->realm_tgsprinc)
 	    krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
@@ -159,14 +153,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, char *def_dbname,
 {
     krb5_error_code	kret;
     krb5_boolean	manual;
-    krb5_db_entry	db_entry;
-    int			num2get;
-    krb5_boolean	more;
     krb5_realm_params	*rparams;
-    krb5_key_data	*kdata;
-    krb5_key_salt_tuple	*kslist;
-    krb5_int32		nkslist;
-    int			i;
 
     memset((char *) rdp, 0, sizeof(kdc_realm_t));
     if (!realm) {
@@ -213,7 +200,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, char *def_dbname,
     else
 	rdp->realm_ports = strdup(def_udp_ports);
     if (rparams && rparams->realm_kdc_tcp_ports)
-	rdp->realm_tcp_ports = strdup(rparams->realm_kdc_ports);
+	rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
     else
 	rdp->realm_tcp_ports = strdup(def_tcp_ports);
 
@@ -242,35 +229,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, char *def_dbname,
 
     /* Handle ticket renewable maximum life */
     rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
-	rparams->realm_max_rlife : KRB5_KDB_MAX_LIFE;
-
-    /* Handle key/salt list */
-    if (rparams && rparams->realm_num_keysalts) {
-	rdp->realm_kstypes = rparams->realm_keysalts;
-	rdp->realm_nkstypes = rparams->realm_num_keysalts;
-	rparams->realm_keysalts = NULL;
-	rparams->realm_num_keysalts = 0;
-	kslist = (krb5_key_salt_tuple *) rdp->realm_kstypes;
-	nkslist = rdp->realm_nkstypes;
-    } else {
-	/*
-	 * XXX  Initialize default key/salt list.
-	 */
-	if ((kslist = (krb5_key_salt_tuple *)
-	     malloc(sizeof(krb5_key_salt_tuple)))) {
-	    kslist->ks_enctype = ENCTYPE_DES_CBC_CRC;
-	    kslist->ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
-	    rdp->realm_kstypes = kslist;
-	    rdp->realm_nkstypes = 1;
-	    nkslist = 1;
-	}
-	else {
-	    com_err(progname, ENOMEM,
-		    "while setting up key/salt list for realm %s",
-		    realm);
-	    exit(1);
-	}
-    }
+	rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
 
     if (rparams)
 	krb5_free_realm_params(rdp->realm_context, rparams);
@@ -332,51 +291,6 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, char *def_dbname,
 	goto whoops;
     }
 
-    /* Fetch the master key and get its version number */
-    num2get = 1;
-    kret = krb5_db_get_principal(rdp->realm_context, rdp->realm_mprinc,
-				 &db_entry, &num2get, &more);
-    if (!kret) {
-	if (num2get != 1)
-	    kret = KRB5_KDB_NOMASTERKEY;
-	else {
-	    if (more) {
-		krb5_db_free_principal(rdp->realm_context,
-				       &db_entry,
-				       num2get);
-		kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
-	    }
-	}
-    }
-    if (kret) {
-	com_err(progname, kret,
-		"while fetching master entry for realm %s", realm);
-	goto whoops;
-    }
-	
-    /*
-     * Get the most recent master key.  Search the key list in
-     * the order specified by the key/salt list.
-     */
-    kdata = (krb5_key_data *) NULL;
-    for (i=0; i<nkslist; i++) {
-	if (!(kret = krb5_dbe_find_enctype(rdp->realm_context,
-					   &db_entry,
-					   kslist[i].ks_enctype,
-					   -1,
-					   -1,
-					   &kdata)))
-	    break;
-    }
-    if (!kdata) {
-	com_err(progname, kret,
-		"while finding master key for realm %s",
-		realm);
-	goto whoops;
-    }
-    rdp->realm_mkvno = kdata->key_data_kvno;
-    krb5_db_free_principal(rdp->realm_context, &db_entry, num2get);
-
     if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) {
 	com_err(progname, kret,
 		"while setting master key for realm %s", realm);
@@ -400,63 +314,6 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, char *def_dbname,
 	goto whoops;
     }
 
-    /* Get the TGS database entry */
-    num2get = 1;
-    if (!(kret = krb5_db_get_principal(rdp->realm_context,
-				       rdp->realm_tgsprinc,
-				       &db_entry,
-				       &num2get,
-				       &more))) {
-	if (num2get != 1)
-	    kret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
-	else {
-	    if (more) {
-		krb5_db_free_principal(rdp->realm_context,
-				       &db_entry,
-				       num2get);
-		kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
-	    }
-	}
-    }
-    if (kret) {
-	com_err(progname, kret,
-		"while fetching TGS entry for realm %s", realm);
-	goto whoops;
-    } 
-    /*
-     * Get the most recent TGS key.  Search the key list in
-     * the order specified by the key/salt list.
-     */
-    kdata = (krb5_key_data *) NULL;
-    for (i=0; i<nkslist; i++) {
-	if (!(kret = krb5_dbe_find_enctype(rdp->realm_context,
-					   &db_entry,
-					   kslist[i].ks_enctype,
-					   -1,
-					   -1,
-					   &kdata)))
-	    break;
-    }
-    if (!kdata) {
-	com_err(progname, kret, "while finding TGS key for realm %s",
-		realm);
-	goto whoops;
-    }
-    if (!(kret = krb5_dbekd_decrypt_key_data(rdp->realm_context,
-					     &rdp->realm_mkey,
-					     kdata,
-					     &rdp->realm_tgskey, NULL))){
-	rdp->realm_tgskvno = kdata->key_data_kvno;
-    }
-    krb5_db_free_principal(rdp->realm_context,
-			   &db_entry,
-			   num2get);
-    if (kret) {
-	com_err(progname, kret,
-		"while decrypting TGS key for realm %s", realm);
-	goto whoops;
-    }
-
     if (!rkey_init_done) {
 	krb5_data seed;
 #ifdef KRB5_KRB4_COMPAT
@@ -551,7 +408,7 @@ setup_sam(void)
 void
 usage(char *name)
 {
-    fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-n]\n", name);
+    fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n", name);
     return;
 }
 
@@ -606,7 +463,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
      * Loop through the option list.  Each time we encounter a realm name,
      * use the previously scanned options to fill in for defaults.
      */
-    while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:3")) != -1) {
+    while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
 	switch(c) {
 	case 'r':			/* realm name for db */
 	    if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
@@ -662,6 +519,11 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
 	    v4mode = strdup(optarg);
 #endif
 	    break;
+	case 'X':
+#ifdef KRB5_KRB4_COMPAT
+		enable_v4_crossrealm(argv[0]);
+#endif
+		break;
 	case '3':
 #ifdef ATHENA_DES3_KLUDGE
 	    if (krb5_enctypes_list[krb5_enctypes_length-1].etype
diff --git a/src/krb5-config.in b/src/krb5-config.in
index d5ace8b39..4096cccd4 100644
--- a/src/krb5-config.in
+++ b/src/krb5-config.in
@@ -34,6 +34,7 @@ libdir=@libdir@
 CC_LINK='@CC_LINK@'
 KRB4_LIB=@KRB4_LIB@
 DES425_LIB=@DES425_LIB@
+KDB5_DB_LIB=@KDB5_DB_LIB@
 LDFLAGS='@LDFLAGS@'
 RPATH_FLAG='@RPATH_FLAG@'
 
@@ -179,12 +180,12 @@ if test -n "$do_libs"; then
 	    -e 's#\$(CFLAGS)#'"$CFLAGS"'#'`
 
     if test $library = 'kdb'; then
-	lib_flags="$lib_flags -lkdb5 -ldb"
+	lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
 	library=krb5
     fi
 
     if test $library = 'kadm_server'; then
-	lib_flags="$lib_flags -lkadm5srv -lkdb5 -ldb"
+	lib_flags="$lib_flags -lkadm5srv -lkdb5 $KDB5_DB_LIB"
 	library=kadm_common
     fi
 
diff --git a/src/krb524/.Sanitize b/src/krb524/.Sanitize
index 7f018c3a7..52d0746f8 100644
--- a/src/krb524/.Sanitize
+++ b/src/krb524/.Sanitize
@@ -27,23 +27,15 @@ Things-to-keep:
 ChangeLog
 Makefile.in
 README
-RELEASE_NOTES
 configure
 configure.in
 cnv_tkt_skey.c
-conv_creds.c
 conv_princ.c
 conv_tkt.c
-encode.c
-getcred.c
-globals.c
 k524init.c
-krb524.h
-krb524_err.et
+krb524d.h
 krb524_prot
 krb524d.c
-misc.c
-sendmsg.c
 test.c
 
 Things-to-lose:
diff --git a/src/krb524/ChangeLog b/src/krb524/ChangeLog
index 672bffe8c..2c6278176 100644
--- a/src/krb524/ChangeLog
+++ b/src/krb524/ChangeLog
@@ -1,3 +1,100 @@
+2003-09-02  Tom Yu  <tlyu@mit.edu>
+
+	* cnv_tkt_skey.c (krb524_convert_tkt_skey): Apply patch from Cesar
+	Garcia to fix lifetime computation.
+
+2003-08-11  Tom Yu  <tlyu@mit.edu>
+
+	* cnv_tkt_skey.c (krb524_convert_tkt_skey): Call krb_create_ticket
+	instead of local version.  Remove local version of
+	krb_create_ticket.  This file no longer gets included into a
+	krb524 library, so accessing internal functions isn't that big of
+	an issue anymore.
+
+2003-06-12  Tom Yu  <tlyu@mit.edu>
+
+	* krb524.c (krb524_convert_creds_kdc, krb524_init_ets): Mark as
+	KRB5_CALLCONV_WRONG.
+	(krb524_init_ets): Takes a krb5_context.
+
+2003-06-09  Tom Yu  <tlyu@mit.edu>
+
+	* krb524.c: Fix copyright notice.
+
+2003-06-05  Jeffery Altman  <jaltman@mit.edu>
+
+	* Makefile.in: Build krb524.dll on Windows.
+
+	* krb524.c: New file; stub for Windows krb524.dll.
+
+2003-06-05  Ken Raeburn  <raeburn@mit.edu>
+
+	* k524init.c (main): Remove debugging printf.
+
+2003-05-29  Alexandra Ellwood  <lxs@mit.edu>
+
+	* krb524d.h: removed invalid Mac pragmas
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* k524init.c (main): Call krb5_524_convert_creds instead of
+	krb524_convert_creds_kdc.
+
+	* Makefile.in ($(OUTPRE)k524init.exe): Don't depend on K524DEP.
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* conv_creds.c, encode.c, globals.c, sendmsg.c: Deleted.  Contents
+	added to krb5 library.
+	* getcred.c, misc.c: Deleted.
+	* krb524.h: Library declarations moved to krb5.hin and k5-int.h.
+	Remainder renamed to krb524d.h.
+	* krb524_err.et: Moved to lib/krb5/error_tables.
+	* cnv_tkt_skey.c: Include krb524d.h, not krb524.h.
+	(krb524d_debug): Define new variable.  Replace all references to
+	krb524_debug.
+	* conv_princ.c: Don't include krb524.h.
+	* k524init.c: Don't include krb524.h.
+	(main): Don't call krb524_init_ets.
+	* krb524d.c: Include krb524d.h, not krb524.h.
+	(encode_v4tkt): New function pointer variable.
+	(main): Initialize it using krb5int_accessor.
+	* test.c: Don't include krb524.h.
+	(main): Don't set krb524_debug, and don't call krb524_init_ets.
+	* Makefile.in: Don't pull in library makefile fragments.
+	(LIB, LIBMAJOR, LIBMINOR, RELDIR): Deleted.
+	(KRB524_DEPLIB, KRB524_LIB, STOBJLISTS, STLIBOBJS): Deleted.
+	(GENS, KRB524_HDR, KRB524_ERR_HDR): Deleted.
+	(SRCS): Remove deleted/moved files.
+	(all-unix): Don't depend on $(GENS) on includes.
+	(includes, all-windows): Don't depend on headers.
+	($(KRB524_HDR), $(KRB524_ERR_HDR)): Delete rules.
+	(all-windows): Comment out dependency on $(K524LIB) for now.
+	(CLIENT_OBJS, SERVER_OBJS): New variables.
+	(krb524test, krb524d, k524init): Don't use KRB524_*LIB, just
+	KRB5_*LIB.  Use *_OBJS lists.
+	(install-unix, clean-unix, clean-windows): Don't install or clean
+	libs or headers.
+	(krb524_err.c): Target deleted.
+
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* krb524d.c (do_connection): Use krb5_princ_size rather than
+	direct structure field access.
+
+2003-03-16  Sam Hartman  <hartmans@mit.edu>
+
+	* krb524d.c (handle_classic_v4): Do not support 3des enctypes as
+	they are insecure.  Also, by default do not allow krb4
+	cross-realm.
+
+	* cnv_tkt_skey.c (krb524_convert_tkt_skey): Don't support 3des tickets
+
+2003-03-12  Ken Raeburn  <raeburn@mit.edu>
+
+	* cnv_tkt_skey.c (krb524_convert_tkt_skey): Extract source IP
+	address in its proper size, not as 'long'.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
     * cnv_tkt_skey.c, conv_creds.c, conv_princ.c, encode.c, sendmsg.c: 
       Removed Mac-specific includes.
diff --git a/src/krb524/Makefile.in b/src/krb524/Makefile.in
index 1e5b5dc31..5140bdcf8 100644
--- a/src/krb524/Makefile.in
+++ b/src/krb524/Makefile.in
@@ -23,19 +23,9 @@ BUILDTOP=$(REL)..
 # PERFORMANCE OF THIS SOFTWARE.
 # 
 
-##WIN32##!if 0
-LIB=krb524
-##WIN32##!endif
-LIBMAJOR=1
-LIBMINOR=0
-RELDIR=../krb524
-STOBJLISTS=OBJS.ST
-
 DEFINES = -DUSE_MASTER -DKRB524_PRIVATE=1
 PROG_LIBPATH=-L$(TOPLIBD) $(KRB4_LIBPATH)
 PROG_RPATH=$(KRB5_LIBDIR)
-KRB524_DEPLIB	= libkrb524.a
-KRB524_LIB	= libkrb524.a
 
 ##WIN32##!ifdef USE_ALTERNATE_KRB4_INCLUDES
 ##WIN32##KRB4_INCLUDES=-I$(USE_ALTERNATE_KRB4_INCLUDES)
@@ -55,32 +45,16 @@ LOCALINCLUDES= $(KRB4_INCLUDES) -I. -I$(srcdir)
 
 # Library sources
 SRCS	= \
-	$(srcdir)/conv_creds.c \
 	$(srcdir)/conv_princ.c \
 	$(srcdir)/cnv_tkt_skey.c \
-	$(srcdir)/encode.c \
-	$(srcdir)/misc.c \
-	$(srcdir)/globals.c \
-	$(srcdir)/sendmsg.c \
-	$(srcdir)/krb524_err.et \
-	$(srcdir)/libinit.c
+	$(srcdir)/libinit.c	\
+    $(srcdir)/krb524.c
 
 EXTRADEPSRCS = \
 	$(srcdir)/test.c \
 	$(srcdir)/k524init.c \
 	$(srcdir)/krb524d.c
 
-STLIBOBJS = \
-	$(OUTPRE)conv_creds.$(OBJEXT) \
-	$(OUTPRE)conv_princ.$(OBJEXT) \
-	$(OUTPRE)cnv_tkt_skey.$(OBJEXT) \
-	$(OUTPRE)encode.$(OBJEXT) \
-	$(OUTPRE)misc.$(OBJEXT) \
-	$(OUTPRE)globals.$(OBJEXT) \
-	$(OUTPRE)sendmsg.$(OBJEXT) \
-	$(OUTPRE)krb524_err.$(OBJEXT) \
-	$(OUTPRE)libinit.$(OBJEXT)
-
 ##WIN32##!ifdef KRB524_STATIC_HACK
 ##WIN32##LPREFIX=..\lib
 ##WIN32##K5_GLUE=$(LPREFIX)\$(OUTPRE)k5_glue.obj
@@ -93,148 +67,77 @@ STLIBOBJS = \
 ##WIN32##K524DEP=$(STLIBOBJS)
 ##WIN32##!endif
 
-GENS	= krb524_err.c krb524_err.h
-
-KRB524_HDR=$(BUILDTOP)$(S)include$(S)krb524.h
-KRB524_ERR_HDR=$(BUILDTOP)$(S)include$(S)krb524_err.h
-
-all-unix:: $(GENS) 
-all-unix:: all-libs
-all-unix:: includes
-
 all-unix:: krb524d krb524test k524init
 
-includes:: $(KRB524_HDR) $(KRB524_ERR_HDR)
-
-$(KRB524_HDR): krb524.h
-##WIN32##	$(CP) $? "$@"
-##WIN32##!if 0
-$(KRB524_HDR): krb524.h
-	if cmp $(srcdir)/krb524.h \
-	$(BUILDTOP)/include/krb524.h  >/dev/null 2>&1; then :; \
-	else \
-		(set -x; $(RM) $(BUILDTOP)/include/krb524.h; \
-		 $(CP) $(srcdir)/krb524.h \
-			$(BUILDTOP)/include/krb524.h) ; \
-	fi
-##WIN32##!endif
+all-windows:: $(OUTPRE)k524init.exe $(K524LIB)
 
-$(KRB524_ERR_HDR): krb524_err.h
-##WIN32##	$(CP) $? "$@"
-##WIN32##!if 0
-$(KRB524_ERR_HDR): krb524_err.h
-	if cmp krb524_err.h \
-	$(BUILDTOP)/include/krb524_err.h  >/dev/null 2>&1; then :; \
-	else \
-		(set -x; $(RM) $(BUILDTOP)/include/krb524_err.h; \
-		 $(CP) krb524_err.h \
-			$(BUILDTOP)/include/krb524_err.h) ; \
-	fi
-##WIN32##!endif
+krb524test: test.o $(KRB5_DEPLIB) $(KRB4COMPAT_DEPLIBS)
+	$(CC_LINK) -o krb524test test.o $(KRB5_LIB) $(KRB4COMPAT_LIBS)
 
-all-windows:: $(KRB524_HDR) $(K524LIB) $(OUTPRE)k524init.exe
+SERVER_OBJS= krb524d.o cnv_tkt_skey.o conv_princ.o
+CLIENT_OBJS= $(OUTPRE)k524init.$(OBJEXT)
 
-krb524test: libkrb524.a test.o $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
-	$(CC_LINK) -o krb524test test.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
+krb524d: $(SERVER_OBJS) $(KADMSRV_DEPLIBS) $(KRB5_DEPLIB) $(KRB4COMPAT_DEPLIBS)
+	$(CC_LINK) -o krb524d $(SERVER_OBJS) $(KADMSRV_LIBS) $(KRB5_LIB) $(KRB4COMPAT_LIBS)
 
-krb524d: krb524d.o $(KADMSRV_DEPLIBS) $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
-	$(CC_LINK) -o krb524d krb524d.o $(KADMSRV_LIBS) $(KRB524_LIB) $(KRB4COMPAT_LIBS)
+k524init: $(CLIENT_OBJS) $(KRB5_DEPLIB) $(KRB4COMPAT_DEPLIBS)
+	$(CC_LINK) -o k524init $(CLIENT_OBJS) $(KRB5_LIB) $(KRB4COMPAT_LIBS)
 
-k524init: k524init.o  $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
-	$(CC_LINK) -o k524init k524init.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
-
-$(K524LIB): $(STLIBOBJS) $(K4LIB) $(KLIB)
+$(K524LIB): $(OUTPRE)krb524.$(OBJEXT) $(OUTPRE)libinit.$(OBJEXT) $(KLIB) $(CLIB)
 	link $(DLL_LINKOPTS) -def:$(K524DEF) -out:$*.dll $** $(WINLIBS)
 
-$(OUTPRE)k524init.exe: $(OUTPRE)k524init.$(OBJEXT) $(K524DEP) $(KLIB) $(K4LIB) $(CLIB) $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib
+$(OUTPRE)k524init.exe: $(OUTPRE)k524init.$(OBJEXT) $(KLIB) $(K4LIB) $(CLIB) $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib
 	link $(EXE_LINKOPTS) -out:$@ $** $(WINLIBS)
 
-install-unix:: install-libs
+install-unix::
 	$(INSTALL_PROGRAM) krb524d $(DESTDIR)$(SERVER_BINDIR)/krb524d
 	$(INSTALL_PROGRAM) k524init $(DESTDIR)$(CLIENT_BINDIR)/krb524init
 
-clean-unix:: clean-libs clean-libobjs
-	$(RM) $(OBJS) $(GENS) core *~ *.bak #*
+clean-unix::
+	$(RM) $(OBJS) core *~ *.bak #*
 	$(RM) krb524test krb524d k524init test.o krb524d.o k524init.o
-	$(RM) $(BUILDTOP)/include/krb524.h $(BUILDTOP)/include/krb524_err.h
-
-clean-windows::
-	$(RM) $(GENS)
-
-krb524_err.c : krb524_err.et
-
-# @libobj_frag@
-# @lib_frag@
 
 # +++ Dependency line eater +++
 # 
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-conv_creds.so conv_creds.po $(OUTPRE)conv_creds.$(OBJEXT): conv_creds.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h krb524.h krb524_err.h
-conv_princ.so conv_princ.po $(OUTPRE)conv_princ.$(OBJEXT): conv_princ.c $(BUILDTOP)/include/krb5.h \
+$(OUTPRE)conv_princ.$(OBJEXT): conv_princ.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h krb524.h krb524_err.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
-cnv_tkt_skey.so cnv_tkt_skey.po $(OUTPRE)cnv_tkt_skey.$(OBJEXT): cnv_tkt_skey.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/profile.h
+$(OUTPRE)cnv_tkt_skey.$(OBJEXT): cnv_tkt_skey.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  krb524.h krb524_err.h
-encode.so encode.po $(OUTPRE)encode.$(OBJEXT): encode.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h krb524.h krb524_err.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
-misc.so misc.po $(OUTPRE)misc.$(OBJEXT): misc.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h krb524.h krb524_err.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
-globals.so globals.po $(OUTPRE)globals.$(OBJEXT): globals.c
-sendmsg.so sendmsg.po $(OUTPRE)sendmsg.$(OBJEXT): sendmsg.c $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
-  $(KRB_ERR_H_DEP) krb524.h krb524_err.h
-libinit.so libinit.po $(OUTPRE)libinit.$(OBJEXT): libinit.c
-test.so test.po $(OUTPRE)test.$(OBJEXT): test.c $(SRCTOP)/include/k5-int.h \
+  $(KRB_ERR_H_DEP) krb524d.h
+$(OUTPRE)libinit.$(OBJEXT): libinit.c
+$(OUTPRE)krb524.$(OBJEXT): krb524.c
+$(OUTPRE)test.$(OBJEXT): test.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h \
-  $(SRCTOP)/include/kerberosIV/krb.h $(KRB_ERR_H_DEP) \
-  krb524.h krb524_err.h
-k524init.so k524init.po $(OUTPRE)k524init.$(OBJEXT): k524init.c $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/kerberosIV/krb.h \
+  $(KRB_ERR_H_DEP)
+$(OUTPRE)k524init.$(OBJEXT): k524init.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(BUILDTOP)/include/profile.h krb524.h krb524_err.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h
-krb524d.so krb524d.po $(OUTPRE)krb524d.$(OBJEXT): krb524d.c $(BUILDTOP)/include/krb5.h \
+  $(BUILDTOP)/include/profile.h
+$(OUTPRE)krb524d.$(OBJEXT): krb524d.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
   $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
   $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  krb524.h krb524_err.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h \
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP) krb524d.h
 
diff --git a/src/krb524/cnv_tkt_skey.c b/src/krb524/cnv_tkt_skey.c
index 67349765c..97d8bbfdd 100644
--- a/src/krb524/cnv_tkt_skey.c
+++ b/src/krb524/cnv_tkt_skey.c
@@ -1,3 +1,28 @@
+/*
+ * Copyright 2003  by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.	Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
 /*
  * Copyright 1994 by OpenVision Technologies, Inc.
  * 
@@ -31,21 +56,9 @@
 #include <netinet/in.h>
 #endif
 #include <krb.h>
-#include "krb524.h"
-
-static int
-krb524int_krb_create_ticket(KTEXT, unsigned int, char *, char *, char *, long,
-			    char *, int, long, char *, char *, C_Block);
+#include "krb524d.h"
 
-static int
-krb524int_krb_cr_tkt_krb5(KTEXT, unsigned int, char *, char *, char *, long,
-			  char *, int, long, char *, char *,
-			  krb5_keyblock *);
-
-static int
-krb524int_krb_cr_tkt_int(KTEXT, unsigned int, char *, char *, char *, long,
-			 char *, int, long, char *, char *, C_Block,
-			 krb5_keyblock *);
+static int krb524d_debug = 0;
 
 /*
  * Convert a v5 ticket for server to a v4 ticket, using service key
@@ -104,7 +117,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
 	  v5etkt->session->enctype != ENCTYPE_DES_CBC_MD4 &&
 	  v5etkt->session->enctype != ENCTYPE_DES_CBC_MD5) ||
 	 v5etkt->session->length != sizeof(C_Block)) {
-	  if (krb524_debug)
+	  if (krb524d_debug)
 	       fprintf(stderr, "v5 session keyblock type %d length %d != C_Block size %d\n",
 		       v5etkt->session->enctype,
 		       v5etkt->session->length,
@@ -121,7 +134,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
 	give out a v4 ticket with as much of the v5 lifetime is available
 	"now" instead. */
      if ((ret = krb5_timeofday(context, &server_time))) {
-         if (krb524_debug)
+         if (krb524d_debug)
 	      fprintf(stderr, "krb5_timeofday failed!\n");
 	 krb5_free_enc_tkt_part(context, v5etkt);
 	 v5tkt->enc_part2 = NULL;
@@ -130,7 +143,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
      if ((server_time + context->clockskew >= v5etkt->times.starttime)
 	 && (server_time - context->clockskew <= v5etkt->times.endtime)) {
 	  lifetime = krb_time_to_life(server_time, v5etkt->times.endtime);
-	  v4endtime = krb_life_to_time(v5etkt->times.starttime, lifetime);
+	  v4endtime = krb_life_to_time(server_time, lifetime);
 	  /*
 	   * Adjust start time backwards if the lifetime value
 	   * returned by krb_time_to_life() maps to a longer lifetime
@@ -139,7 +152,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
 	  if (v4endtime > v5etkt->times.endtime)
 	      server_time -= v4endtime - v5etkt->times.endtime;
      } else {
-          if (krb524_debug)
+          if (krb524d_debug)
 	       fprintf(stderr, "v5 ticket time out of bounds\n");
 	  krb5_free_enc_tkt_part(context, v5etkt);
 	  v5tkt->enc_part2 = NULL;
@@ -156,14 +169,14 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
      kaddr.contents = (krb5_octet *)&sinp->sin_addr;
 
      if (!krb5_address_search(context, &kaddr, v5etkt->caddrs)) {
-	 if (krb524_debug)
+	 if (krb524d_debug)
 	     fprintf(stderr, "Invalid v5creds address information.\n");
 	 krb5_free_enc_tkt_part(context, v5etkt);
 	 v5tkt->enc_part2 = NULL;
 	 return KRB524_BADADDR;
      }
 
-     if (krb524_debug)
+     if (krb524d_debug)
 	printf("startime = %ld, authtime = %ld, lifetime = %ld\n",
 	       (long) v5etkt->times.starttime,
 	       (long) v5etkt->times.authtime,
@@ -171,12 +184,12 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
 
      /* XXX are there V5 flags we should map to V4 equivalents? */
      if (v4_skey->enctype == ENCTYPE_DES_CBC_CRC) {
-	 ret = krb524int_krb_create_ticket(v4tkt,
+	 ret = krb_create_ticket(v4tkt,
 				 0, /* flags */			     
 				 pname,
 				 pinst,
 				 prealm,
-				 *((unsigned long *)kaddr.contents),
+				 sinp->sin_addr.s_addr,
 				 (char *) v5etkt->session->contents,
 				 lifetime,
 				 /* issue_data */
@@ -184,26 +197,8 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
 				 sname,
 				 sinst,
 				 v4_skey->contents);
-     } else {
-	 /* Force enctype to be raw if using DES3. */
-	 if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 ||
-	     v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1)
-	     v4_skey->enctype = ENCTYPE_DES3_CBC_RAW;
-	 ret = krb524int_krb_cr_tkt_krb5(v4tkt,
-			       0, /* flags */			     
-			       pname,
-			       pinst,
-			       prealm,
-			       *((unsigned long *)kaddr.contents),
-			       (char *) v5etkt->session->contents,
-			       lifetime,
-			       /* issue_data */
-			       server_time,
-			       sname,
-			       sinst,
-			       v4_skey);
      }
-
+     else abort();
      krb5_free_enc_tkt_part(context, v5etkt);
      v5tkt->enc_part2 = NULL;
      if (ret == KSUCCESS)
@@ -211,226 +206,3 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey,
      else
 	  return KRB524_V4ERR;
 }
-
-/*****************************************************************************
- * Copied from krb4's cr_tkt.
- * Modified functions below to be static.
- *****************************************************************************/
-
-#define          HOST_BYTE_ORDER (* (const char *) &temp_ONE)
-static const int temp_ONE = 1;
-
-/*
- * Create ticket takes as arguments information that should be in a
- * ticket, and the KTEXT object in which the ticket should be
- * constructed.  It then constructs a ticket and returns, leaving the
- * newly created ticket in tkt.
-#ifndef NOENCRYPTION
- * The data in tkt->dat is encrypted in the server's key.
-#endif
- * The length of the ticket is a multiple of
- * eight bytes and is in tkt->length.
- *
- * If the ticket is too long, the ticket will contain nulls.
- * The return value of the routine is undefined.
- *
- * The corresponding routine to extract information from a ticket it
- * decomp_ticket.  When changes are made to this routine, the
- * corresponding changes should also be made to that file.
- *
- * The packet is built in the following format:
- * 
- * 			variable
- * type			or constant	   data
- * ----			-----------	   ----
- *
- * tkt->length		length of ticket (multiple of 8 bytes)
- * 
-#ifdef NOENCRYPTION
- * tkt->dat:
-#else
- * tkt->dat:		(encrypted in server's key)
-#endif
- * 
- * unsigned char	flags		   namely, HOST_BYTE_ORDER
- * 
- * string		pname		   client's name
- * 
- * string		pinstance	   client's instance
- * 
- * string		prealm		   client's realm
- * 
- * 4 bytes		paddress	   client's address
- * 
- * 8 bytes		session		   session key
- * 
- * 1 byte		life		   ticket lifetime
- * 
- * 4 bytes		time_sec	   KDC timestamp
- * 
- * string		sname		   service's name
- * 
- * string		sinstance	   service's instance
- * 
- * <=7 bytes		null		   null pad to 8 byte multiple
- *
- */
-static int
-krb524int_krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
-		  session, life, time_sec, sname, sinstance, key)
-    KTEXT   tkt;                /* Gets filled in by the ticket */
-    unsigned int flags;		/* Various Kerberos flags */
-    char    *pname;             /* Principal's name */
-    char    *pinstance;         /* Principal's instance */
-    char    *prealm;            /* Principal's authentication domain */
-    long    paddress;           /* Net address of requesting entity */
-    char    *session;           /* Session key inserted in ticket */
-    int     life;               /* Lifetime of the ticket */
-    long    time_sec;           /* Issue time and date */
-    char    *sname;             /* Service Name */
-    char    *sinstance;         /* Instance Name */
-    C_Block key;                /* Service's secret key */
-{
-    return krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm,
-				    paddress, session, life, time_sec, sname,
-				    sinstance, key, NULL);
-}
-
-static int
-krb524int_krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress,
-			  session, life, time_sec, sname, sinstance, k5key)
-    KTEXT   tkt;                /* Gets filled in by the ticket */
-    unsigned int flags;		/* Various Kerberos flags */
-    char    *pname;             /* Principal's name */
-    char    *pinstance;         /* Principal's instance */
-    char    *prealm;            /* Principal's authentication domain */
-    long    paddress;           /* Net address of requesting entity */
-    char    *session;           /* Session key inserted in ticket */
-    int     life;               /* Lifetime of the ticket */
-    long    time_sec;           /* Issue time and date */
-    char    *sname;             /* Service Name */
-    char    *sinstance;         /* Instance Name */
-    krb5_keyblock *k5key;	/* NULL if not present */
-{
-    C_Block key;
-
-    return krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm,
-				    paddress, session, life, time_sec, sname,
-				    sinstance, key, k5key);
-}
-
-static int
-krb524int_krb_cr_tkt_int(tkt, flags_in, pname, pinstance, prealm, paddress,
-	       session, life, time_sec, sname, sinstance, key, k5key)
-    KTEXT   tkt;                /* Gets filled in by the ticket */
-    unsigned int flags_in;	/* Various Kerberos flags */
-    char    *pname;             /* Principal's name */
-    char    *pinstance;         /* Principal's instance */
-    char    *prealm;            /* Principal's authentication domain */
-    long    paddress;           /* Net address of requesting entity */
-    char    *session;           /* Session key inserted in ticket */
-    int     life;               /* Lifetime of the ticket */
-    long    time_sec;           /* Issue time and date */
-    char    *sname;             /* Service Name */
-    char    *sinstance;         /* Instance Name */
-    C_Block key;                /* Service's secret key */
-    krb5_keyblock *k5key;	/* NULL if not present */
-{
-    Key_schedule key_s;
-    register char *data;        /* running index into ticket */
-
-    unsigned char flags = flags_in & 0xFF; /* This must be one byte */
-
-    tkt->length = 0;            /* Clear previous data  */
-
-    /* Check length of ticket */
-    if (sizeof(tkt->dat) < (sizeof(flags) +
-                            1 + strlen(pname) +
-                            1 + strlen(pinstance) +
-                            1 + strlen(prealm) +
-                            4 +                         /* address */
-			    8 +                         /* session */
-			    1 +                         /* life */
-			    4 +                         /* issue time */
-                            1 + strlen(sname) +
-                            1 + strlen(sinstance) +
-			    7) / 8) {                   /* roundoff */
-        memset(tkt->dat, 0, sizeof(tkt->dat));
-        return KFAILURE /* XXX */;
-    }
-
-    flags |= HOST_BYTE_ORDER;   /* ticket byte order   */
-    memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags));
-    data = ((char *)tkt->dat) + sizeof(flags);
-    (void) strcpy(data, pname);
-    data += 1 + strlen(pname);
-    (void) strcpy(data, pinstance);
-    data += 1 + strlen(pinstance);
-    (void) strcpy(data, prealm);
-    data += 1 + strlen(prealm);
-    memcpy(data, (char *) &paddress, 4);
-    data += 4;
-
-    memcpy(data, (char *) session, 8);
-    data += 8;
-    *(data++) = (char) life;
-    /* issue time */
-    memcpy(data, (char *) &time_sec, 4);
-    data += 4;
-    (void) strcpy(data, sname);
-    data += 1 + strlen(sname);
-    (void) strcpy(data, sinstance);
-    data += 1 + strlen(sinstance);
-
-    /* guarantee null padded ticket to multiple of 8 bytes */
-    memset(data, 0, 7);
-    tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
-
-    /* Check length of ticket */
-    if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
-        memset(tkt->dat, 0, tkt->length);
-        tkt->length = 0;
-        return KFAILURE /* XXX */;
-    }
-
-#ifndef NOENCRYPTION
-    /* Encrypt the ticket in the services key */
-    if (k5key != NULL) {
-	/* block locals */
-	krb5_data in;
-	krb5_enc_data out;
-	krb5_error_code ret;
-	size_t enclen;
-
-	in.length = tkt->length;
-	in.data = tkt->dat;
-	/* XXX assumes context arg is ignored */
-	ret = krb5_c_encrypt_length(NULL, k5key->enctype,
-				    (size_t)in.length, &enclen);
-	if (ret)
-	    return KFAILURE;
-	out.ciphertext.length = enclen;
-	out.ciphertext.data = malloc(enclen);
-	if (out.ciphertext.data == NULL)
-	    return KFAILURE;	/* XXX maybe ENOMEM? */
-
-	/* XXX assumes context arg is ignored */
-	ret = krb5_c_encrypt(NULL, k5key, KRB5_KEYUSAGE_KDC_REP_TICKET,
-			     NULL, &in, &out);
-	if (ret) {
-	    free(out.ciphertext.data);
-	    return KFAILURE;
-	} else {
-	    tkt->length = out.ciphertext.length;
-	    memcpy(tkt->dat, out.ciphertext.data, out.ciphertext.length);
-	    memset(out.ciphertext.data, 0, out.ciphertext.length);
-	    free(out.ciphertext.data);
-	}
-    } else {
-	key_sched(key,key_s);
-	pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,
-		     (long) tkt->length,key_s,(C_Block *)key,1);
-    }
-#endif /* !NOENCRYPTION */
-    return 0;
-}
diff --git a/src/krb524/conv_creds.c b/src/krb524/conv_creds.c
deleted file mode 100644
index ba8daaae4..000000000
--- a/src/krb524/conv_creds.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 1994 by OpenVision Technologies, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "krb5.h"
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include "port-sockets.h"
-#include "socket-utils.h"
-#include <krb.h>
-#include "krb524.h"
-
-#ifdef USE_CCAPI
-#include <CredentialsCache.h>
-#endif
-
-krb5_error_code krb524_convert_creds_plain
-(krb5_context context, krb5_creds *v5creds, 
-		   CREDENTIALS *v4creds);
-
-krb5_error_code
-krb524_convert_creds_kdc(context, v5creds, v4creds)
-     krb5_context context;
-     krb5_creds *v5creds;
-     CREDENTIALS *v4creds;
-{
-     krb5_error_code ret;
-     krb5_data reply;
-     char *p;
-     struct sockaddr_storage ss;
-     socklen_t slen = sizeof(ss);
-
-     ret = krb524_convert_creds_plain(context, v5creds, v4creds);
-     if (ret)
-	 return ret;
-
-     reply.data = NULL;
-     ret = krb524_sendto_kdc(context, &v5creds->ticket,
-			     &v5creds->server->realm, &reply,
-			     ss2sa(&ss), &slen);
-     if (ret)
-	 return ret;
-
-#if TARGET_OS_MAC
-#ifdef USE_CCAPI
-     v4creds->stk_type = cc_v4_stk_des;
-#endif
-     if (slen == sizeof(struct sockaddr_in)
-	 && ss2sa(&ss)->sa_family == AF_INET) {
-	 v4creds->address = ss2sin(&ss)->sin_addr.s_addr;
-     }
-     /* Otherwise, leave it set to all-zero.  */
-#endif
-
-     p = reply.data;
-     ret = ntohl(*((krb5_error_code *) p));
-     p += sizeof(krb5_int32);
-     reply.length -= sizeof(krb5_int32);
-     if (ret)
-	 goto fail;
-
-     v4creds->kvno = ntohl(*((krb5_error_code *) p));
-     p += sizeof(krb5_int32);
-     reply.length -= sizeof(krb5_int32);
-     ret = decode_v4tkt(&v4creds->ticket_st, p, &reply.length);
-
-fail:
-     if (reply.data) 
-	 free(reply.data);
-     reply.data = NULL;
-     return ret;
-}
-
-krb5_error_code
-krb524_convert_creds_plain(context, v5creds, v4creds)
-     krb5_context context;
-     krb5_creds *v5creds;
-     CREDENTIALS *v4creds;
-{
-     int ret;
-     krb5_timestamp endtime;
-     char dummy[REALM_SZ];
-     memset((char *) v4creds, 0, sizeof(CREDENTIALS));
-
-     if ((ret = krb524_convert_princs(context, v5creds->client, 
-				      v5creds->server,
-				      v4creds->pname, v4creds->pinst,
-				      dummy, v4creds->service,
-				      v4creds->instance, v4creds->realm)))
-	  return ret;
-
-     /* Check enctype too */
-     if (v5creds->keyblock.length != sizeof(C_Block)) {
-	  if (krb524_debug)
-	       fprintf(stderr, "v5 session keyblock length %d != C_Block size %d\n",
-		       v5creds->keyblock.length,
-		       (int) sizeof(C_Block));
-	  return KRB524_BADKEY;
-     } else
-	  memcpy(v4creds->session, (char *) v5creds->keyblock.contents,
-		 sizeof(C_Block));
-
-     /* V4 has no concept of authtime or renew_till, so ignore them */
-     v4creds->issue_date = v5creds->times.starttime;
-     v4creds->lifetime = krb_time_to_life(v5creds->times.starttime,
-					  v5creds->times.endtime);
-     endtime = krb_life_to_time(v5creds->times.starttime,
-				v4creds->lifetime);
-     /*
-      * Adjust start time backwards to deal with rounding up in
-      * krb_time_to_life(), to match code on server side.
-      */
-     if (endtime > v5creds->times.endtime)
-	 v4creds->issue_date -= endtime - v5creds->times.endtime;
-
-     return 0;
-}
diff --git a/src/krb524/conv_princ.c b/src/krb524/conv_princ.c
index f52c0dd13..3359981ba 100644
--- a/src/krb524/conv_princ.c
+++ b/src/krb524/conv_princ.c
@@ -22,7 +22,6 @@
 
 #include "krb5.h"
 #include <krb.h>
-#include "krb524.h"
 
 int krb524_convert_princs(context, client, server, pname, pinst, prealm, 
 			  sname, sinst, srealm)
diff --git a/src/krb524/encode.c b/src/krb524/encode.c
deleted file mode 100644
index 00698cfeb..000000000
--- a/src/krb524/encode.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 1994 by OpenVision Technologies, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "krb5.h"
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-
-#ifdef _WIN32
-#include "port-sockets.h"
-#else
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-#endif
-
-#include <krb.h>
-#include "krb524.h"
-
-/*
- * I'm sure that this is reinventing the wheel, but I don't know where
- * the wheel is hidden.
- */
-
-int  encode_v4tkt (KTEXT_ST *, char *, unsigned int *),
-     encode_ktext (char **, int *, KTEXT_ST *),
-     encode_bytes (char **, int *, char *, unsigned int),
-     encode_int32 (char **, int *, krb5_int32 *);
-
-int  decode_v4tkt (KTEXT_ST *, char *, unsigned int *),
-     decode_ktext (char **, int *, KTEXT_ST *),
-     decode_bytes (char **, int *, char *, unsigned int),
-     decode_int32 (char **, int *, krb5_int32 *);
-
-int encode_bytes(out, outlen, in, len)
-     char **out;
-     int *outlen;
-     char *in;
-     unsigned int len;
-{
-     if (len > *outlen)
-	  return KRB524_ENCFULL;
-     memcpy(*out, in, len);
-     *out += len;
-     *outlen -= len;
-     return 0;
-}
-
-int encode_int32(out, outlen, v)
-     char **out;
-     int *outlen;
-     krb5_int32 *v;
-{
-     krb5_int32 nv; /* Must be 4 bytes */
-
-     nv = htonl(*v);
-     return encode_bytes(out, outlen, (char *) &nv, sizeof(nv));
-}
-
-int encode_v4tkt(v4tkt, buf, encoded_len)
-     KTEXT_ST *v4tkt;
-     char *buf;
-     unsigned int *encoded_len;
-{
-     int buflen, ret;
-
-     buflen = *encoded_len;
-
-     if ((ret = encode_int32(&buf, &buflen, &v4tkt->length)))
-	  return ret;
-     if ((ret = encode_bytes(&buf, &buflen, (char *)v4tkt->dat, MAX_KTXT_LEN)))
-	  return ret;
-     if ((ret = encode_int32(&buf, &buflen, (krb5_int32 *) &v4tkt->mbz)))
-	  return ret;
-
-     *encoded_len -= buflen;
-     return 0;
-}
-
-/* decode functions */
-
-int decode_bytes(out, outlen, in, len)
-     char **out;
-     int *outlen;
-     char *in; 
-     unsigned int len;
-{
-     if (len > *outlen)
-	  return KRB524_DECEMPTY;
-     memcpy(in, *out, len);
-     *out += len;
-     *outlen -= len;
-     return 0;
-}
-
-int decode_int32(out, outlen, v)
-     char **out;
-     int *outlen;
-     krb5_int32 *v;
-{
-     int ret;
-     krb5_int32 nv; /* Must be four bytes */
-
-     if ((ret = decode_bytes(out, outlen, (char *) &nv, sizeof(nv))))
-	  return ret;
-     *v = ntohl(nv);
-     return 0;
-}
-
-int decode_v4tkt(v4tkt, buf, encoded_len)
-     KTEXT_ST *v4tkt;
-     char *buf;
-     unsigned int *encoded_len;
-{
-     int buflen, ret;
-
-     buflen = *encoded_len;
-     if ((ret = decode_int32(&buf, &buflen, &v4tkt->length)))
-	  return ret;
-     if ((ret = decode_bytes(&buf, &buflen, (char *)v4tkt->dat, MAX_KTXT_LEN)))
-	  return ret;
-     if ((ret = decode_int32(&buf, &buflen, (krb5_int32 *) &v4tkt->mbz)))
-	  return ret;
-     *encoded_len -= buflen;
-     return 0;
-}
-
diff --git a/src/krb524/getcred.c b/src/krb524/getcred.c
deleted file mode 100644
index ecbb25f10..000000000
--- a/src/krb524/getcred.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 1994 by OpenVision Technologies, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include "krb5.h"
-#include <krb.h>
-
-main(argc, argv)
-     int argc;
-     char **argv;
-{
-     krb5_principal client, server;
-     krb5_ccache cc;
-     krb5_creds v5creds;
-     CREDENTIALS v4creds;
-     int i, ret;
-     krb5_context context;
-     krb5_error_code retval;
-     
-     retval = krb5_init_context(&context);
-     if (retval) {
-	     com_err(argv[0], retval, "while initializing krb5");
-	     exit(1);
-     }
-
-     if (ret = krb5_parse_name(argv[1], &client)) {
-	  com_err("getcred", ret, "parsing client name");
-	  exit(1);
-     }
-     if (ret = krb5_parse_name(argv[2], &server)) {
-	  com_err("getcred", ret, "parsing server name");
-	  exit(1);
-     }
-     if (ret = krb5_cc_default(context, &cc)) {
-	  com_err("getcred", ret, "opening default credentials cache");
-	  exit(1);
-     }
-
-     memset((char *) &v5creds, 0, sizeof(v5creds));
-     v5creds.client = client;
-     v5creds.server = server;
-     v5creds.times.endtime = 0;
-     v5creds.keyblock.enctype = ENCTYPE_DES_CBC_MD5;
-     if (ret = krb5_get_credentials(context, 0, cc, &v5creds)) {
-	  com_err("getcred", ret, "getting V5 credentials");
-	  exit(1);
-     }
-
-     if (ret = krb524_convert_creds_kdc(context, &v5creds, &v4creds)) {
-	  com_err("getcred", ret, "converting to V4 credentials");
-	  exit(1);
-     }
-     
-     return 0;
-}
diff --git a/src/krb524/k524init.c b/src/krb524/k524init.c
index 746fbb938..9a988205f 100644
--- a/src/krb524/k524init.c
+++ b/src/krb524/k524init.c
@@ -37,7 +37,6 @@
 #endif
 
 #include <krb.h>
-#include "krb524.h"
 
 extern int optind;
 extern char *optarg;
@@ -92,8 +91,6 @@ int main(argc, argv)
 	 exit(1);
      }
 
-     krb524_init_ets(context);
-
      if ((code = krb5_cc_default(context, &cc))) {
 	  com_err(prog, code, "opening default credentials cache");
 	  exit(1);
@@ -152,7 +149,7 @@ int main(argc, argv)
 	  exit(1);
      }
 
-     if ((code = krb524_convert_creds_kdc(context, v5creds, &v4creds))) {
+     if ((code = krb5_524_convert_creds(context, v5creds, &v4creds))) {
 	  com_err(prog, code, "converting to V4 credentials");
 	  exit(1);
      }
diff --git a/src/krb524/krb524.c b/src/krb524/krb524.c
new file mode 100644
index 000000000..1eff72f00
--- /dev/null
+++ b/src/krb524/krb524.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2003 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ */
+
+#ifdef _WIN32
+#include "krb5.h"
+
+#ifdef krb524_convert_creds_kdc
+#undef krb524_convert_creds_kdc
+#endif
+#ifdef krb524_init_ets
+#undef krb524_init_ets
+#endif
+
+int KRB5_CALLCONV_WRONG
+krb524_convert_creds_kdc(krb5_context context, krb5_creds *v5creds, struct credentials *v4creds)
+{
+	return(krb5_524_convert_creds(context,v5creds,v4creds));
+}
+
+void KRB5_CALLCONV_WRONG
+krb524_init_ets(krb5_context context)
+{
+	/* no-op */
+}
+#endif /* _WIN32 */
diff --git a/src/krb524/krb524.h b/src/krb524/krb524.h
deleted file mode 100644
index f44a6b4c9..000000000
--- a/src/krb524/krb524.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 1994 by OpenVision Technologies, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef KRB524_H
-#define KRB524_H
-
-#define KRB524_SERVICE "krb524"
-#define KRB524_PORT 4444
-
-#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
-#	include <TargetConditionals.h>
-#    ifndef KRB524_PRIVATE /* Allow e.g. build system to override */
-#		define KRB524_PRIVATE 0
-#	endif
-#else
-#	ifndef KRB524_PRIVATE
-#		define KRB524_PRIVATE 1
-#	endif
-#endif	
-
-#include <krb524_err.h>
-
-#ifndef KRB524INT_BEGIN_DECLS
-#ifdef __cplusplus
-#define KRB524INT_BEGIN_DECLS	extern "C" {
-#define KRB524INT_END_DECLS	}
-#else
-#define KRB524INT_BEGIN_DECLS
-#define KRB524INT_END_DECLS
-#endif
-#endif
-
-#if TARGET_OS_MAC
-#    if defined(__MWERKS__)
-#	pragma import on
-#    endif
-#    pragma options align=mac68k
-#endif
-
-KRB524INT_BEGIN_DECLS
-
-#if KRB524_PRIVATE
-extern int krb524_debug;
-
-struct sockaddr;
-struct sockaddr_in;
-
-int krb524_convert_tkt_skey
-	(krb5_context context, krb5_ticket *v5tkt, KTEXT_ST *v4tkt, 
-		   krb5_keyblock *v5_skey, krb5_keyblock *v4_skey,
-			struct sockaddr_in *saddr);
-
-/* conv_princ.c */
-
-int krb524_convert_princs
-	(krb5_context context, krb5_principal client, krb5_principal server,
-	 char *pname, char *pinst, char *prealm,
-	 char *sname, char *sinst, char *srealm);
-
-/* conv_creds.c */
-
-int krb524_convert_creds_addr
-	(krb5_context context, krb5_creds *v5creds, 
-		   CREDENTIALS *v4creds, struct sockaddr *saddr);
-#endif /* KRB524_PRIVATE */
-
-int krb524_convert_creds_kdc
-	(krb5_context context, krb5_creds *v5creds, 
-		   CREDENTIALS *v4creds);
-
-#if KRB524_PRIVATE
-/* conv_tkt.c */
-
-int krb524_convert_tkt
-	(krb5_principal server, krb5_data *v5tkt, KTEXT_ST *v4tkt,
-		   int *kvno, struct sockaddr_in *saddr);
-
-/* encode.c */
-
-int encode_v4tkt
-	(KTEXT_ST *v4tkt, char *buf, unsigned int *encoded_len);
-
-int decode_v4tkt
-	(KTEXT_ST *v4tkt, char *buf, unsigned int *encoded_len);
-
-
-/* misc.c */
-
-void krb524_init_ets
-	(krb5_context context);
-
-/* sendmsg.c */
-
-#include "port-sockets.h"
-#include "socket-utils.h" /* for socklen_t */
-int krb524_sendto_kdc
-        (krb5_context context, const krb5_data * message, 
-	 const krb5_data * realm, krb5_data * reply,
-	 struct sockaddr *, socklen_t *);
-#endif /* KRB524_PRIVATE */
-
-#if TARGET_OS_MAC
-#    if defined(__MWERKS__)
-#	pragma import reset
-#    endif
-#	pragma options align=reset
-#endif
-
-KRB524INT_END_DECLS
-
-#endif /* KRB524_H */
diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c
index 4995b515f..a5d05c54e 100644
--- a/src/krb524/krb524d.c
+++ b/src/krb524/krb524d.c
@@ -60,7 +60,7 @@
 #include <netinet/in.h>
 
 #include <krb.h>
-#include "krb524.h"
+#include "krb524d.h"
 
 #if defined(NEED_DAEMON_PROTO)
 extern int daemon(int, int);
@@ -76,6 +76,7 @@ static int debug = 0;
 void *handle = NULL;
 
 int use_keytab, use_master;
+int allow_v4_crossrealm = 0;
 char *keytab = NULL;
 krb5_keytab kt;
 
@@ -110,6 +111,8 @@ static RETSIGTYPE request_exit(signo)
      signalled = 1;
 }
 
+int (*encode_v4tkt)(KTEXT, char *, unsigned int *) = 0;
+
 int main(argc, argv)
      int argc;
      char **argv;
@@ -132,12 +135,31 @@ int main(argc, argv)
 	     exit(1);
      }
 
+     {
+	 krb5int_access k5int;
+	 retval = krb5int_accessor(&k5int, KRB5INT_ACCESS_VERSION);
+	 if (retval != 0) {
+	     com_err(whoami, retval,
+		     "while accessing krb5 library internal support");
+	     exit(1);
+	 }
+	 encode_v4tkt = k5int.krb524_encode_v4tkt;
+	 if (encode_v4tkt == NULL) {
+	     com_err(whoami, 0,
+		     "krb4 support disabled in krb5 support library");
+	     exit(1);
+	 }
+     }
+
      argv++; argc--;
      use_master = use_keytab = nofork = 0;
      config_params.mask = 0;
      
      while (argc) {
-	  if (strncmp(*argv, "-k", 2) == 0)
+       if (strncmp(*argv, "-X", 2) == 0) {
+	 allow_v4_crossrealm = 1;
+       }
+       else if (strncmp(*argv, "-k", 2) == 0)
 	       use_keytab = 1;
 	  else if (strncmp(*argv, "-m", 2) == 0)
 	       use_master = 1;
@@ -346,7 +368,7 @@ krb5_error_code do_connection(s, context)
      if (debug)
 	  printf("V5 ticket decoded\n");
      
-     if( v5tkt->server->length >= 1
+     if( krb5_princ_size(context, v5tkt->server) >= 1
 	 &&krb5_princ_component(context, v5tkt->server, 0)->length == 3
 	 &&strncmp(krb5_princ_component(context, v5tkt->server, 0)->data,
 		   "afs", 3) == 0) {
@@ -524,19 +546,7 @@ handle_classic_v4 (krb5_context context, krb5_ticket *v5tkt,
 				   &v5_service_key, NULL)))
 	  goto error;
 
-     if ((ret = lookup_service_key(context, v5tkt->server,
-				   ENCTYPE_DES3_CBC_RAW,
-				   0, /* highest kvno */
-				   &v4_service_key, v4kvno)) &&
-	 (ret = lookup_service_key(context, v5tkt->server,
-				   ENCTYPE_LOCAL_DES3_HMAC_SHA1,
-				   0,
-				   &v4_service_key, v4kvno)) &&
-	 (ret = lookup_service_key(context, v5tkt->server,
-				   ENCTYPE_DES3_CBC_SHA1,
-				   0,
-				   &v4_service_key, v4kvno)) &&
-	 (ret = lookup_service_key(context, v5tkt->server,
+     if ( (ret = lookup_service_key(context, v5tkt->server,
 				   ENCTYPE_DES_CBC_CRC,
 				   0,
 				   &v4_service_key, v4kvno)))
@@ -544,8 +554,19 @@ handle_classic_v4 (krb5_context context, krb5_ticket *v5tkt,
 
      if (debug)
 	  printf("service key retrieved\n");
+     if ((ret = krb5_decrypt_tkt_part(context, &v5_service_key, v5tkt))) {
+       goto error;
+     }
 
-     ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key,
+    if (!(allow_v4_crossrealm || krb5_realm_compare(context, v5tkt->server,
+						    v5tkt->enc_part2->client))) {
+ret =  KRB5KDC_ERR_POLICY ;
+ goto error;
+    }
+    krb5_free_enc_tkt_part(context, v5tkt->enc_part2);
+    v5tkt->enc_part2= NULL;
+
+         ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key,
 				   &v4_service_key,
 				   (struct sockaddr_in *)saddr);
      if (ret)
@@ -561,6 +582,9 @@ handle_classic_v4 (krb5_context context, krb5_ticket *v5tkt,
 	  printf("v4 credentials encoded\n");
 
  error:
+     if (v5tkt->enc_part2)
+	 krb5_free_enc_tkt_part(context, v5tkt->enc_part2);
+
      if(v5_service_key.contents)
        krb5_free_keyblock_contents(context, &v5_service_key);
      if (v4_service_key.contents)
diff --git a/src/krb524/globals.c b/src/krb524/krb524d.h
similarity index 61%
rename from src/krb524/globals.c
rename to src/krb524/krb524d.h
index 0ed868242..33be97157 100644
--- a/src/krb524/globals.c
+++ b/src/krb524/krb524d.h
@@ -20,4 +20,36 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-int krb524_debug = 0;
+#ifndef KRB524INT_H
+#define KRB524INT_H
+
+#include "port-sockets.h"
+#include "kerberosIV/krb.h"
+
+#ifndef KRB524INT_BEGIN_DECLS
+#ifdef __cplusplus
+#define KRB524INT_BEGIN_DECLS	extern "C" {
+#define KRB524INT_END_DECLS	}
+#else
+#define KRB524INT_BEGIN_DECLS
+#define KRB524INT_END_DECLS
+#endif
+#endif
+
+KRB524INT_BEGIN_DECLS
+
+int krb524_convert_tkt_skey
+	(krb5_context context, krb5_ticket *v5tkt, KTEXT_ST *v4tkt, 
+		   krb5_keyblock *v5_skey, krb5_keyblock *v4_skey,
+			struct sockaddr_in *saddr);
+
+/* conv_princ.c */
+
+int krb524_convert_princs
+	(krb5_context context, krb5_principal client, krb5_principal server,
+	 char *pname, char *pinst, char *prealm,
+	 char *sname, char *sinst, char *srealm);
+
+KRB524INT_END_DECLS
+
+#endif /* KRB524INT_H */
diff --git a/src/krb524/test.c b/src/krb524/test.c
index 13189e8cf..d0cb92181 100644
--- a/src/krb524/test.c
+++ b/src/krb524/test.c
@@ -32,7 +32,6 @@
 
 #include <des.h>
 #include <krb.h>
-#include "krb524.h"
 #include "com_err.h"
 
 #define KEYSIZE 8
@@ -223,7 +222,9 @@ int main(argc, argv)
      krb5_context context;
      krb5_error_code retval;
 
+#if 0
      krb524_debug = 1;
+#endif
 
      retval = krb5_init_context(&context);
      if (retval) {
@@ -231,8 +232,6 @@ int main(argc, argv)
 	     exit(1);
      }
 
-     krb524_init_ets(context);
-
      local = 0;
      remote = NULL;
      argc--; argv++;
diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog
index bfa7678b0..2d456bbeb 100644
--- a/src/lib/ChangeLog
+++ b/src/lib/ChangeLog
@@ -1,3 +1,59 @@
+2003-12-18  Jeffrey Altman <jaltman@mit.edu>
+
+        * krb5_32.def: Remove exports added on 2003-12-13.  Moved
+          to krb5int_accessor
+
+2003-12-13  Jeffrey Altman <jaltman@mit.edu>
+   
+        * krb4_32.def: Remove exports from KfM not yet compiled in KfW
+            krb_ad_tkt, krb_pw_tkt, kuserok, tkt_string, FSp_xxx
+        
+        * krb5_32.def: Add exports of private functions necessary for 
+            building new gssapi32.dll:
+              krb5int_c_mandatory_cksumtype   ; PRIVATE GSSAPI k5-int.h
+              krb5_ser_pack_int64             ; PRIVATE GSSAPI k5-int.h
+              krb5_ser_unpack_int64           ; PRIVATE GSSAPI k5-int.h
+
+2003-12-11  Jeffrey Altman <jaltman@mit.edu>
+
+        * Makefile.in: Add secur32.lib to libraries necessary to build 
+          krb5_32.dll.  Necessary to support the new MSLSA ccache type.
+
+2003-12-08  Jeffrey Altman <jaltman@mit.edu>
+
+        * krb4_32.def: Add exports for functions exported by KfM
+
+2003-07-21  Alexandra Ellwood  <lxs@mit.edu>
+
+        * krb5_32.def: Export krb5_principal2salt.
+
+2003-07-18  Jeffrey Altman <jaltman@mit.edu>
+
+    * gssapi32.def: Export GSS OID constants
+
+2003-07-09  Alexandra Ellwood  <lxs@mit.edu>
+
+        * krb5_32.def: Export krb5_get_permitted_enctypes and 
+        krb5_set_real_time for Samba.
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* krb5_32.def: Add krb5_524_convert_creds.
+
+2003-05-08  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5_32.def: Add krb5_c_string_to_key_with_params
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* krb5_32.def: Add krb5_auth_con_getrecvsubkey,
+	krb5_auth_con_getsendsubkey, krb5_auth_con_setrecvsubkey,
+	krb5_auth_con_setsendsubkey.
+
+2003-04-15  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5_32.def: Add krb5_set_password and krb5_set_password_using_ccache
+
 2003-02-10  Tom Yu  <tlyu@mit.edu>
 
 	* Makefile.in (K4LIBS): Revert previous.
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 01a43511d..030beb7bd 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -52,7 +52,7 @@ KRB5RC = krb5.rc
 VERSIONRC = $(BUILDTOP)\windows\version.rc
 
 WINLIBS = kernel32.lib ws2_32.lib user32.lib shell32.lib oldnames.lib \
-	version.lib advapi32.lib gdi32.lib
+	version.lib secur32.lib advapi32.lib gdi32.lib
 WINDLLFLAGS = $(DLL_LINKOPTS) -base:0x1c000000
 
 NO_GLUE=$(OUTPRE)no_glue.obj
diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog
index 6f73ddf62..3c4982f2d 100644
--- a/src/lib/crypto/ChangeLog
+++ b/src/lib/crypto/ChangeLog
@@ -1,3 +1,58 @@
+2004-02-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* t_cts.c (test_cts): Process encryption and decryption IVs
+	separately, make sure they match, and display the value.
+
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* etypes.c (krb5_enctypes_list): Fill in required_ctype field.
+	* mandatory_sumtype.c: New file.
+	* Makefile.in (SRCS, OBJS, STLIBOBJS): Build it.
+
+2003-07-13  Kenneth Raeburn  <raeburn@mit.edu>
+
+	* pbkdf2.c (foo): Never call com_err.
+
+2003-06-25  Ken Raeburn  <raeburn@mit.edu>
+
+	* checksum_length.c (krb5_c_checksum_length): Handle trunc_size.
+
+2003-06-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* cksumtypes.c (krb5_cksumtypes_list): Add aes128/256 hmacs, with
+	new trunc_size field.
+
+	* make_checksum.c (krb5_c_make_checksum): If trunc_size is
+	specified, shrink the computed checksum down to the indicated
+	size.
+
+2003-06-05  Sam Hartman  <hartmans@mit.edu>
+
+	* string_to_key.c (krb5_c_string_to_key_with_params): Only allow
+	AFS s2k  for DES enctypes
+
+2003-05-15  Sam Hartman  <hartmans@mit.edu>
+
+	* combine_keys.c (enctype_ok): new function to determine if we support combine_keys for a particular enctype
+
+2003-05-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* etypes.c (krb5_enctypes_list): Add names aes128-cts and
+	aes256-cts as aliases.
+
+2003-05-08  Sam Hartman  <hartmans@mit.edu>
+
+	* string_to_key.c: Move krb5_c_string_to_key_with_params to krb5.h
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* pbkdf2.c (krb5int_pbkdf2): Provide a temporary buffer for the
+	output from F, if the remaining space in the output buffer isn't
+	big enough.  Free the temporary buffers before returning.
+
+	* etypes.c (krb5_enctypes_list): Use krb5int_aes_encrypt_length,
+	and krb5int_aes_dk_encrypt, and krb5int_aes_dk_decrypt for AES.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * prng.c: use Unix randomness sources on Mac OS X.
diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in
index e571ef777..987945f49 100644
--- a/src/lib/crypto/Makefile.in
+++ b/src/lib/crypto/Makefile.in
@@ -54,6 +54,7 @@ STLIBOBJS=\
 	keyed_checksum_types.o	\
 	make_checksum.o		\
 	make_random_key.o	\
+	mandatory_sumtype.o	\
 	nfold.o			\
 	old_api_glue.o		\
 	pbkdf2.o		\
@@ -86,6 +87,7 @@ OBJS=\
 	$(OUTPRE)keyed_checksum_types.$(OBJEXT)	\
 	$(OUTPRE)make_checksum.$(OBJEXT)	\
 	$(OUTPRE)make_random_key.$(OBJEXT)	\
+	$(OUTPRE)mandatory_sumtype.$(OBJEXT)	\
 	$(OUTPRE)nfold.$(OBJEXT)		\
 	$(OUTPRE)old_api_glue.$(OBJEXT)		\
 	$(OUTPRE)pbkdf2.$(OBJEXT)		\
@@ -118,6 +120,7 @@ SRCS=\
 	$(srcdir)/keyed_checksum_types.c\
 	$(srcdir)/make_checksum.c	\
 	$(srcdir)/make_random_key.c	\
+	$(srcdir)/mandatory_sumtype.c	\
 	$(srcdir)/nfold.c		\
 	$(srcdir)/old_api_glue.c	\
 	$(srcdir)/pbkdf2.c	\
@@ -348,206 +351,224 @@ check-windows::
 #
 block_size.so block_size.po $(OUTPRE)block_size.$(OBJEXT): block_size.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 checksum_length.so checksum_length.po $(OUTPRE)checksum_length.$(OBJEXT): checksum_length.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJEXT): cksumtype_to_string.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): cksumtypes.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/hash_provider/hash_provider.h \
-  $(srcdir)/keyhash_provider/keyhash_provider.h cksumtypes.h
+  $(srcdir)/hash_provider/hash_provider.h $(srcdir)/keyhash_provider/keyhash_provider.h \
+  cksumtypes.h
 coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): coll_proof_cksum.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 combine_keys.so combine_keys.po $(OUTPRE)combine_keys.$(OBJEXT): combine_keys.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h $(srcdir)/dk/dk.h
+  etypes.h $(srcdir)/dk/dk.h
 crypto_libinit.so crypto_libinit.po $(OUTPRE)crypto_libinit.$(OBJEXT): crypto_libinit.c \
   crypto_libinit.h
 default_state.so default_state.po $(OUTPRE)default_state.$(OBJEXT): default_state.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 decrypt.so decrypt.po $(OUTPRE)decrypt.$(OBJEXT): decrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 encrypt.so encrypt.po $(OUTPRE)encrypt.$(OBJEXT): encrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 encrypt_length.so encrypt_length.po $(OUTPRE)encrypt_length.$(OBJEXT): encrypt_length.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
 enctype_compare.so enctype_compare.po $(OUTPRE)enctype_compare.$(OBJEXT): enctype_compare.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
 enctype_to_string.so enctype_to_string.po $(OUTPRE)enctype_to_string.$(OBJEXT): enctype_to_string.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
 etypes.so etypes.po $(OUTPRE)etypes.$(OBJEXT): etypes.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/enc_provider/enc_provider.h \
-  $(srcdir)/hash_provider/hash_provider.h etypes.h $(srcdir)/old/old.h \
-  $(srcdir)/raw/raw.h $(srcdir)/dk/dk.h $(srcdir)/arcfour/arcfour.h \
-  $(srcdir)/aes/aes_s2k.h
+  $(srcdir)/enc_provider/enc_provider.h $(srcdir)/hash_provider/hash_provider.h \
+  etypes.h $(srcdir)/old/old.h $(srcdir)/raw/raw.h $(srcdir)/dk/dk.h \
+  $(srcdir)/arcfour/arcfour.h $(srcdir)/aes/aes_s2k.h
 hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): hmac.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 keyed_cksum.so keyed_cksum.po $(OUTPRE)keyed_cksum.$(OBJEXT): keyed_cksum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cksumtypes.h
+  cksumtypes.h
 keyed_checksum_types.so keyed_checksum_types.po $(OUTPRE)keyed_checksum_types.$(OBJEXT): keyed_checksum_types.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h cksumtypes.h
 make_checksum.so make_checksum.po $(OUTPRE)make_checksum.$(OBJEXT): make_checksum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cksumtypes.h etypes.h \
-  $(srcdir)/dk/dk.h
+  cksumtypes.h etypes.h $(srcdir)/dk/dk.h
 make_random_key.so make_random_key.po $(OUTPRE)make_random_key.$(OBJEXT): make_random_key.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
+mandatory_sumtype.so mandatory_sumtype.po $(OUTPRE)mandatory_sumtype.$(OBJEXT): mandatory_sumtype.c \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
 nfold.so nfold.po $(OUTPRE)nfold.$(OBJEXT): nfold.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 old_api_glue.so old_api_glue.po $(OUTPRE)old_api_glue.$(OBJEXT): old_api_glue.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 pbkdf2.so pbkdf2.po $(OUTPRE)pbkdf2.$(OBJEXT): pbkdf2.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/hash_provider/hash_provider.h
+  $(srcdir)/hash_provider/hash_provider.h
 prng.so prng.po $(OUTPRE)prng.$(OBJEXT): prng.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/enc_provider/enc_provider.h \
-  $(srcdir)/yarrow/yarrow.h $(srcdir)/yarrow/ytypes.h \
-  $(srcdir)/yarrow/yhash.h $(srcdir)/sha1/shs.h $(srcdir)/yarrow/ycipher.h
+  $(srcdir)/enc_provider/enc_provider.h $(srcdir)/yarrow/yarrow.h \
+  $(srcdir)/yarrow/ytypes.h $(srcdir)/yarrow/yhash.h \
+  $(srcdir)/sha1/shs.h $(srcdir)/yarrow/ycipher.h
 state.so state.po $(OUTPRE)state.$(OBJEXT): state.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 string_to_cksumtype.so string_to_cksumtype.po $(OUTPRE)string_to_cksumtype.$(OBJEXT): string_to_cksumtype.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 string_to_enctype.so string_to_enctype.po $(OUTPRE)string_to_enctype.$(OBJEXT): string_to_enctype.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  etypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
 string_to_key.so string_to_key.po $(OUTPRE)string_to_key.$(OBJEXT): string_to_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 valid_cksumtype.so valid_cksumtype.po $(OUTPRE)valid_cksumtype.$(OBJEXT): valid_cksumtype.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 valid_enctype.so valid_enctype.po $(OUTPRE)valid_enctype.$(OBJEXT): valid_enctype.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 verify_checksum.so verify_checksum.po $(OUTPRE)verify_checksum.$(OBJEXT): verify_checksum.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  cksumtypes.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h cksumtypes.h
 t_nfold.so t_nfold.po $(OUTPRE)t_nfold.$(OBJEXT): t_nfold.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_encrypt.so t_encrypt.po $(OUTPRE)t_encrypt.$(OBJEXT): t_encrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h etypes.h
+  etypes.h
 t_prng.so t_prng.po $(OUTPRE)t_prng.$(OBJEXT): t_prng.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_hmac.so t_hmac.po $(OUTPRE)t_hmac.$(OBJEXT): t_hmac.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/hash_provider/hash_provider.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_pkcs5.so t_pkcs5.po $(OUTPRE)t_pkcs5.$(OBJEXT): t_pkcs5.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_cts.so t_cts.po $(OUTPRE)t_cts.$(OBJEXT): t_cts.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/hash_provider/hash_provider.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 vectors.so vectors.po $(OUTPRE)vectors.$(OBJEXT): vectors.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/hash_provider/hash_provider.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/crypto/aes/ChangeLog b/src/lib/crypto/aes/ChangeLog
index 443aabdd9..5852b3bc0 100644
--- a/src/lib/crypto/aes/ChangeLog
+++ b/src/lib/crypto/aes/ChangeLog
@@ -1,3 +1,18 @@
+2003-05-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* aes_s2k.c (DEFAULT_ITERATION_COUNT): New macro; define to 4096.
+	(MAX_ITERATION_COUNT): New macro.
+	(krb5int_aes_string_to_key): Use them.
+
+2003-04-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* uitypes.h: Use inttypes.h if HAVE_INTTYPES_H is defined.
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* aes_s2k.c (krb5int_aes_string_to_key): Return an error if the
+	supplied iteration count is really, really large.
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* aes_s2k.c, aes_s2k.h: New files.
diff --git a/src/lib/crypto/aes/Makefile.in b/src/lib/crypto/aes/Makefile.in
index d14f0f906..4a1064a0b 100644
--- a/src/lib/crypto/aes/Makefile.in
+++ b/src/lib/crypto/aes/Makefile.in
@@ -83,7 +83,8 @@ aeskey.so aeskey.po $(OUTPRE)aeskey.$(OBJEXT): aeskey.c aesopt.h aes.h \
   uitypes.h
 aes_s2k.so aes_s2k.po $(OUTPRE)aes_s2k.$(OBJEXT): aes_s2k.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h aes_s2k.h
+  $(srcdir)/../dk/dk.h aes_s2k.h
 
diff --git a/src/lib/crypto/aes/aes_s2k.c b/src/lib/crypto/aes/aes_s2k.c
index f3670d7d8..9d48bd0cb 100644
--- a/src/lib/crypto/aes/aes_s2k.c
+++ b/src/lib/crypto/aes/aes_s2k.c
@@ -1,9 +1,39 @@
-/* Insert MIT copyright here.  */
+/*
+ * lib/crypto/aes/aes_s2k.c
+ *
+ * Copyright 2003 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * krb5int_aes_string_to_key
+ */
 
 #include "k5-int.h"
 #include "dk.h"
 #include "aes_s2k.h"
 
+#define DEFAULT_ITERATION_COUNT		4096 /* was 0xb000L in earlier drafts */
+#define MAX_ITERATION_COUNT		0x1000000L
+
 krb5_error_code
 krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
 			  const krb5_data *string,
@@ -27,7 +57,13 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
 		return KRB5_ERR_BAD_S2K_PARAMS;
 	}
     } else
-	iter_count = 0xb000L;
+	iter_count = DEFAULT_ITERATION_COUNT;
+
+    /* This is not a protocol specification constraint; this is an
+       implementation limit, which should eventually be controlled by
+       a config file.  */
+    if (iter_count >= MAX_ITERATION_COUNT)
+	return KRB5_ERR_BAD_S2K_PARAMS;
 
     /*
      * Dense key space, no parity bits or anything, so take a shortcut
diff --git a/src/lib/crypto/aes/uitypes.h b/src/lib/crypto/aes/uitypes.h
index 4e50ef7df..02dd3b072 100644
--- a/src/lib/crypto/aes/uitypes.h
+++ b/src/lib/crypto/aes/uitypes.h
@@ -44,7 +44,7 @@
 #endif
 #endif
 
-#if defined HAS_INTTYPES_H
+#if defined HAS_INTTYPES_H || defined HAVE_INTTYPES_H
 #include <inttypes.h>
 #define s_u32     u
 #define s_u64   ull
diff --git a/src/lib/crypto/arcfour/Makefile.in b/src/lib/crypto/arcfour/Makefile.in
index 8c33066b9..329feb47c 100644
--- a/src/lib/crypto/arcfour/Makefile.in
+++ b/src/lib/crypto/arcfour/Makefile.in
@@ -45,13 +45,14 @@ clean-unix:: clean-libobjs
 #
 arcfour.so arcfour.po $(OUTPRE)arcfour.$(OBJEXT): arcfour.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h arcfour-int.h arcfour.h
+  arcfour-int.h arcfour.h
 string_to_key.so string_to_key.po $(OUTPRE)string_to_key.$(OBJEXT): string_to_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../md4/rsa-md4.h \
-  arcfour-int.h arcfour.h
+  $(srcdir)/../md4/rsa-md4.h arcfour-int.h arcfour.h
 
diff --git a/src/lib/crypto/checksum_length.c b/src/lib/crypto/checksum_length.c
index 80040b231..f3886f4a9 100644
--- a/src/lib/crypto/checksum_length.c
+++ b/src/lib/crypto/checksum_length.c
@@ -45,6 +45,8 @@ krb5_c_checksum_length(context, cksumtype, length)
 
     if (krb5_cksumtypes_list[i].keyhash)
 	(*(krb5_cksumtypes_list[i].keyhash->hash_size))(length);
+    else if (krb5_cksumtypes_list[i].trunc_size)
+	*length = krb5_cksumtypes_list[i].trunc_size;
     else
 	(*(krb5_cksumtypes_list[i].hash->hash_size))(length);
 
diff --git a/src/lib/crypto/cksumtypes.c b/src/lib/crypto/cksumtypes.c
index 76882f87d..ae7ed5f87 100644
--- a/src/lib/crypto/cksumtypes.c
+++ b/src/lib/crypto/cksumtypes.c
@@ -84,6 +84,14 @@ const struct krb5_cksumtypes krb5_cksumtypes_list[] = {
       ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
       NULL },
 
+    { CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE,
+      "hmac-sha1-96-aes128", "HMAC-SHA1 AES128 key",
+      0, NULL, 
+      &krb5int_hash_sha1, 12 },
+    { CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE,
+      "hmac-sha1-96-aes256", "HMAC-SHA1 AES256 key",
+      0, NULL, 
+      &krb5int_hash_sha1, 12 },
 };
 
 const int krb5_cksumtypes_length =
diff --git a/src/lib/crypto/combine_keys.c b/src/lib/crypto/combine_keys.c
index 6466a95f3..9aad8f543 100644
--- a/src/lib/crypto/combine_keys.c
+++ b/src/lib/crypto/combine_keys.c
@@ -50,6 +50,25 @@ static krb5_error_code dr
 (const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
 		unsigned char *outdata, const krb5_data *in_constant);
 
+/*
+ * We only support this combine_keys algorithm for des and 3des keys.
+ * Everything else should use the PRF defined in the crypto framework.
+ * We don't implement that yet.
+ */
+
+static krb5_boolean  enctype_ok (krb5_enctype e) 
+{
+    switch (e) {
+    case ENCTYPE_DES_CBC_CRC:
+    case ENCTYPE_DES_CBC_MD4:
+    case ENCTYPE_DES_CBC_MD5:
+    case ENCTYPE_DES3_CBC_SHA1:
+	return 1;
+    default:
+	return 0;
+    }
+}
+
 krb5_error_code krb5int_c_combine_keys
 (krb5_context context, krb5_keyblock *key1, krb5_keyblock *key2, krb5_keyblock *outkey)
 {
@@ -60,6 +79,9 @@ krb5_error_code krb5int_c_combine_keys
     krb5_keyblock tkey;
     krb5_error_code ret;
     int i, myalloc = 0;
+    if (!(enctype_ok(key1->enctype)&&enctype_ok(key2->enctype)))
+	return (KRB5_CRYPTO_INTERNAL);
+    
 
     if (key1->length != key2->length || key1->enctype != key2->enctype)
 	return (KRB5_CRYPTO_INTERNAL);
diff --git a/src/lib/crypto/crc32/Makefile.in b/src/lib/crypto/crc32/Makefile.in
index 09d24047e..29e09391e 100644
--- a/src/lib/crypto/crc32/Makefile.in
+++ b/src/lib/crypto/crc32/Makefile.in
@@ -46,7 +46,8 @@ t_crc: t_crc.o crc32.o
 #
 crc32.so crc32.po $(OUTPRE)crc32.$(OBJEXT): crc32.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h crc-32.h
+  crc-32.h
 
diff --git a/src/lib/crypto/des/Makefile.in b/src/lib/crypto/des/Makefile.in
index f8065d7ef..607cc5f16 100644
--- a/src/lib/crypto/des/Makefile.in
+++ b/src/lib/crypto/des/Makefile.in
@@ -100,61 +100,68 @@ clean-unix:: clean-libobjs
 #
 afsstring2key.so afsstring2key.po $(OUTPRE)afsstring2key.$(OBJEXT): afsstring2key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 d3_cbc.so d3_cbc.po $(OUTPRE)d3_cbc.$(OBJEXT): d3_cbc.c des_int.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h \
-  f_tables.h
+  $(SRCTOP)/include/kerberosIV/des.h f_tables.h
 d3_kysched.so d3_kysched.po $(OUTPRE)d3_kysched.$(OBJEXT): d3_kysched.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 f_cbc.so f_cbc.po $(OUTPRE)f_cbc.$(OBJEXT): f_cbc.c des_int.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h \
-  f_tables.h
+  $(SRCTOP)/include/kerberosIV/des.h f_tables.h
 f_cksum.so f_cksum.po $(OUTPRE)f_cksum.$(OBJEXT): f_cksum.c des_int.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h \
-  f_tables.h
+  $(SRCTOP)/include/kerberosIV/des.h f_tables.h
 f_parity.so f_parity.po $(OUTPRE)f_parity.$(OBJEXT): f_parity.c des_int.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h
+  $(SRCTOP)/include/kerberosIV/des.h
 f_sched.so f_sched.po $(OUTPRE)f_sched.$(OBJEXT): f_sched.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 f_tables.so f_tables.po $(OUTPRE)f_tables.$(OBJEXT): f_tables.c des_int.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/des.h \
-  f_tables.h
+  $(SRCTOP)/include/kerberosIV/des.h f_tables.h
 key_sched.so key_sched.po $(OUTPRE)key_sched.$(OBJEXT): key_sched.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 weak_key.so weak_key.po $(OUTPRE)weak_key.$(OBJEXT): weak_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 string2key.so string2key.po $(OUTPRE)string2key.$(OBJEXT): string2key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h des_int.h $(SRCTOP)/include/kerberosIV/des.h
+  des_int.h $(SRCTOP)/include/kerberosIV/des.h
 
diff --git a/src/lib/crypto/dk/ChangeLog b/src/lib/crypto/dk/ChangeLog
index 9ed3a8de9..e30e76e88 100644
--- a/src/lib/crypto/dk/ChangeLog
+++ b/src/lib/crypto/dk/ChangeLog
@@ -1,3 +1,23 @@
+2003-04-17  Ken Raeburn  <raeburn@mit.edu>
+
+	* dk_encrypt.c (krb5int_aes_dk_encrypt): Set output length
+	properly.
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* dk_decrypt.c (krb5_dk_decrypt_maybe_trunc_hmac): Renamed from
+	krb5_dk_decrypt, made static, added extra HMACSIZE argument to
+	indicate size of HMAC.  Cast byte values to char to silence
+	compiler warning.
+	(krb5_dk_decrypt): Call it.
+	(krb5int_aes_dk_decrypt): New function.
+	* dk_encrypt.c (krb5_dk_encrypt): Cast byte values to char to
+	silence compiler warning.
+	(krb5int_aes_encrypt_length, trunc_hmac, krb5int_aes_dk_encrypt):
+	New functions.
+	* dk.h (krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt,
+	krb5int_aes_dk_decrypt): Declare.
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* stringtokey.c (krb5int_dk_string_to_key): Renamed from
diff --git a/src/lib/crypto/dk/Makefile.in b/src/lib/crypto/dk/Makefile.in
index 3785ad6f8..cfd4821e9 100644
--- a/src/lib/crypto/dk/Makefile.in
+++ b/src/lib/crypto/dk/Makefile.in
@@ -54,28 +54,32 @@ clean-unix:: clean-libobjs
 #
 checksum.so checksum.po $(OUTPRE)checksum.$(OBJEXT): checksum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../etypes.h \
-  dk.h
+  $(srcdir)/../etypes.h dk.h
 dk_decrypt.so dk_decrypt.po $(OUTPRE)dk_decrypt.$(OBJEXT): dk_decrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h dk.h
+  dk.h
 dk_encrypt.so dk_encrypt.po $(OUTPRE)dk_encrypt.$(OBJEXT): dk_encrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h dk.h
+  dk.h
 derive.so derive.po $(OUTPRE)derive.$(OBJEXT): derive.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h dk.h $(srcdir)/../etypes.h
+  dk.h $(srcdir)/../etypes.h
 stringtokey.so stringtokey.po $(OUTPRE)stringtokey.$(OBJEXT): stringtokey.c dk.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/crypto/dk/dk.h b/src/lib/crypto/dk/dk.h
index 017101617..a224167ea 100644
--- a/src/lib/crypto/dk/dk.h
+++ b/src/lib/crypto/dk/dk.h
@@ -38,6 +38,18 @@ krb5_error_code krb5_dk_encrypt
 		const krb5_data *ivec,
 		const krb5_data *input, krb5_data *output);
 
+void krb5int_aes_encrypt_length
+(const struct krb5_enc_provider *enc,
+		const struct krb5_hash_provider *hash,
+		size_t input, size_t *length);
+
+krb5_error_code krb5int_aes_dk_encrypt
+(const struct krb5_enc_provider *enc,
+		const struct krb5_hash_provider *hash,
+		const krb5_keyblock *key, krb5_keyusage usage,
+		const krb5_data *ivec,
+		const krb5_data *input, krb5_data *output);
+
 krb5_error_code krb5_dk_decrypt
 (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
@@ -45,6 +57,13 @@ krb5_error_code krb5_dk_decrypt
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *arg_output);
 
+krb5_error_code krb5int_aes_dk_decrypt
+(const struct krb5_enc_provider *enc,
+		const struct krb5_hash_provider *hash,
+		const krb5_keyblock *key, krb5_keyusage usage,
+		const krb5_data *ivec, const krb5_data *input,
+		krb5_data *arg_output);
+
 krb5_error_code krb5int_dk_string_to_key
 (const struct krb5_enc_provider *enc, 
 		const krb5_data *string, const krb5_data *salt,
diff --git a/src/lib/crypto/dk/dk_decrypt.c b/src/lib/crypto/dk/dk_decrypt.c
index adc4d2348..5f35fa6ac 100644
--- a/src/lib/crypto/dk/dk_decrypt.c
+++ b/src/lib/crypto/dk/dk_decrypt.c
@@ -29,6 +29,16 @@
 
 #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
 
+static krb5_error_code
+krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
+				 const struct krb5_hash_provider *hash,
+				 const krb5_keyblock *key,
+				 krb5_keyusage usage,
+				 const krb5_data *ivec,
+				 const krb5_data *input,
+				 krb5_data *output,
+				 size_t hmacsize);
+
 krb5_error_code
 krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
      const struct krb5_enc_provider *enc;
@@ -38,6 +48,36 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
      const krb5_data *ivec;
      const krb5_data *input;
      krb5_data *output;
+{
+    return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
+					    ivec, input, output, 0);
+}
+
+krb5_error_code
+krb5int_aes_dk_decrypt(enc, hash, key, usage, ivec, input, output)
+     const struct krb5_enc_provider *enc;
+     const struct krb5_hash_provider *hash;
+     const krb5_keyblock *key;
+     krb5_keyusage usage;
+     const krb5_data *ivec;
+     const krb5_data *input;
+     krb5_data *output;
+{
+    return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
+					    ivec, input, output, 96 / 8);
+}
+
+static krb5_error_code
+krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage, ivec, input, output,
+				 hmacsize)
+     const struct krb5_enc_provider *enc;
+     const struct krb5_hash_provider *hash;
+     const krb5_keyblock *key;
+     krb5_keyusage usage;
+     const krb5_data *ivec;
+     const krb5_data *input;
+     krb5_data *output;
+     size_t hmacsize;
 {
     krb5_error_code ret;
     size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
@@ -52,7 +92,12 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
     (*(enc->block_size))(&blocksize);
     (*(enc->keysize))(&keybytes, &keylength);
 
-    enclen = input->length - hashsize;
+    if (hmacsize == 0)
+	hmacsize = hashsize;
+    else if (hmacsize > hashsize)
+	return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+
+    enclen = input->length - hmacsize;
 
     if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
 	return(ENOMEM);
@@ -87,7 +132,7 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
     d1.data[2] = (usage>>8)&0xff;
     d1.data[3] = usage&0xff;
 
-    d1.data[4] = 0xAA;
+    d1.data[4] = (char) 0xAA;
 
     if ((ret = krb5_derive_key(enc, key, &ke, &d1)) != 0)
 	goto cleanup;
@@ -121,7 +166,7 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
     if ((ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) != 0)
 	goto cleanup;
 
-    if (memcmp(cksum, input->data+enclen, hashsize) != 0) {
+    if (memcmp(cksum, input->data+enclen, hmacsize) != 0) {
 	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
 	goto cleanup;
     }
diff --git a/src/lib/crypto/dk/dk_encrypt.c b/src/lib/crypto/dk/dk_encrypt.c
index eb9fe5fa3..9de05fc02 100644
--- a/src/lib/crypto/dk/dk_encrypt.c
+++ b/src/lib/crypto/dk/dk_encrypt.c
@@ -108,7 +108,7 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
     d1.data[2] = (usage>>8)&0xff;
     d1.data[3] = usage&0xff;
 
-    d1.data[4] = 0xAA;
+    d1.data[4] = (char) 0xAA;
 
     if ((ret = krb5_derive_key(enc, key, &ke, &d1)))
 	goto cleanup;
@@ -177,6 +177,178 @@ cleanup:
     return(ret);
 }
 
+/* Not necessarily "AES", per se, but "a CBC+CTS mode block cipher
+   with a 96-bit truncated HMAC".  */
+void
+krb5int_aes_encrypt_length(enc, hash, inputlen, length)
+     const struct krb5_enc_provider *enc;
+     const struct krb5_hash_provider *hash;
+     size_t inputlen;
+     size_t *length;
+{
+    size_t blocksize, hashsize;
+
+    (*(enc->block_size))(&blocksize);
+    hashsize = 96 / 8;
+
+    /* No roundup, since CTS requires no padding once we've hit the
+       block size.  */
+    *length = blocksize+inputlen + hashsize;
+}
+
+static krb5_error_code
+trunc_hmac (const struct krb5_hash_provider *hash,
+	    const krb5_keyblock *ki, int num,
+	    const krb5_data *input, const krb5_data *output)
+{
+    size_t hashsize;
+    krb5_data tmp;
+    krb5_error_code ret;
+
+    (hash->hash_size)(&hashsize);
+    if (hashsize < output->length)
+	return KRB5_CRYPTO_INTERNAL;
+    tmp.length = hashsize;
+    tmp.data = malloc(hashsize);
+    if (tmp.data == NULL)
+	return errno;
+    ret = krb5_hmac(hash, ki, num, input, &tmp);
+    if (ret == 0)
+	memcpy(output->data, tmp.data, output->length);
+    memset(tmp.data, 0, hashsize);
+    free(tmp.data);
+    return ret;
+}
+
+krb5_error_code
+krb5int_aes_dk_encrypt(enc, hash, key, usage, ivec, input, output)
+     const struct krb5_enc_provider *enc;
+     const struct krb5_hash_provider *hash;
+     const krb5_keyblock *key;
+     krb5_keyusage usage;
+     const krb5_data *ivec;
+     const krb5_data *input;
+     krb5_data *output;
+{
+    size_t blocksize, keybytes, keylength, plainlen, enclen;
+    krb5_error_code ret;
+    unsigned char constantdata[K5CLENGTH];
+    krb5_data d1, d2;
+    unsigned char *plaintext, *kedata, *kidata, *cn;
+    krb5_keyblock ke, ki;
+
+    /* allocate and set up plaintext and to-be-derived keys */
+
+    (*(enc->block_size))(&blocksize);
+    (*(enc->keysize))(&keybytes, &keylength);
+    plainlen = blocksize+input->length;
+
+    krb5int_aes_encrypt_length(enc, hash, input->length, &enclen);
+
+    /* key->length, ivec will be tested in enc->encrypt */
+
+    if (output->length < enclen)
+	return(KRB5_BAD_MSIZE);
+
+    if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
+	return(ENOMEM);
+    if ((kidata = (unsigned char *) malloc(keylength)) == NULL) {
+	free(kedata);
+	return(ENOMEM);
+    }
+    if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) {
+	free(kidata);
+	free(kedata);
+	return(ENOMEM);
+    }
+
+    ke.contents = kedata;
+    ke.length = keylength;
+    ki.contents = kidata;
+    ki.length = keylength;
+
+    /* derive the keys */
+
+    d1.data = constantdata;
+    d1.length = K5CLENGTH;
+
+    d1.data[0] = (usage>>24)&0xff;
+    d1.data[1] = (usage>>16)&0xff;
+    d1.data[2] = (usage>>8)&0xff;
+    d1.data[3] = usage&0xff;
+
+    d1.data[4] = (char) 0xAA;
+
+    if ((ret = krb5_derive_key(enc, key, &ke, &d1)))
+	goto cleanup;
+
+    d1.data[4] = 0x55;
+
+    if ((ret = krb5_derive_key(enc, key, &ki, &d1)))
+	goto cleanup;
+
+    /* put together the plaintext */
+
+    d1.length = blocksize;
+    d1.data = plaintext;
+
+    if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &d1)))
+	goto cleanup;
+
+    memcpy(plaintext+blocksize, input->data, input->length);
+
+    /* Ciphertext stealing; there should be no more.  */
+    if (plainlen != blocksize + input->length)
+	abort();
+
+    /* encrypt the plaintext */
+
+    d1.length = plainlen;
+    d1.data = plaintext;
+
+    d2.length = plainlen;
+    d2.data = output->data;
+
+    if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
+	goto cleanup;
+
+    if (ivec != NULL && ivec->length == blocksize)
+	cn = d2.data + d2.length - blocksize;
+    else
+	cn = NULL;
+
+    /* hash the plaintext */
+
+    d2.length = enclen - plainlen;
+    d2.data = output->data+plainlen;
+    if (d2.length != 96 / 8)
+	abort();
+
+    if ((ret = trunc_hmac(hash, &ki, 1, &d1, &d2))) {
+	memset(d2.data, 0, d2.length);
+	goto cleanup;
+    }
+
+    output->length = enclen;
+
+    /* update ivec */
+    if (cn != NULL)
+	memcpy(ivec->data, cn, blocksize);
+
+    /* ret is set correctly by the prior call */
+
+cleanup:
+    memset(kedata, 0, keylength);
+    memset(kidata, 0, keylength);
+    memset(plaintext, 0, plainlen);
+
+    free(plaintext);
+    free(kidata);
+    free(kedata);
+
+    return(ret);
+}
+
 #ifdef ATHENA_DES3_KLUDGE
 void
 krb5_marc_dk_encrypt_length(enc, hash, inputlen, length)
diff --git a/src/lib/crypto/enc_provider/ChangeLog b/src/lib/crypto/enc_provider/ChangeLog
index 08a614e96..c40be6a70 100644
--- a/src/lib/crypto/enc_provider/ChangeLog
+++ b/src/lib/crypto/enc_provider/ChangeLog
@@ -1,3 +1,19 @@
+2004-02-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* aes.c (krb5int_aes_encrypt, krb5int_aes_decrypt): Copy out value
+	for new IV.
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* aes.c (enc): Replaced function with a macro.
+	(dec): New macro.
+	(krb5int_aes_encrypt): Use enc and dec.  Delete unused variable
+	OFFSET.
+	(krb5int_aes_decrypt): Renamed from k5_aes_dencrypt, implemented
+	decryption, made non-static.
+	(krb5int_enc_aes128, krb5int_enc_aes256): Use new name for
+	krb5int_aes_decrypt.
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* aes.c (krb5int_aes_init_state): Implement.
diff --git a/src/lib/crypto/enc_provider/Makefile.in b/src/lib/crypto/enc_provider/Makefile.in
index dbc4f64cc..743f4ee6e 100644
--- a/src/lib/crypto/enc_provider/Makefile.in
+++ b/src/lib/crypto/enc_provider/Makefile.in
@@ -47,26 +47,28 @@ clean-unix:: clean-libobjs
 #
 des.so des.po $(OUTPRE)des.$(OBJEXT): des.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h enc_provider.h
+  $(srcdir)/../des/des_int.h $(SRCTOP)/include/kerberosIV/des.h \
+  enc_provider.h
 des3.so des3.po $(OUTPRE)des3.$(OBJEXT): des3.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(srcdir)/../des/des_int.h $(SRCTOP)/include/kerberosIV/des.h
 aes.so aes.po $(OUTPRE)aes.$(OBJEXT): aes.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h enc_provider.h $(srcdir)/../aes/aes.h \
-  $(srcdir)/../aes/uitypes.h
+  enc_provider.h $(srcdir)/../aes/aes.h $(srcdir)/../aes/uitypes.h
 arcfour.so arcfour.po $(OUTPRE)arcfour.$(OBJEXT): arcfour.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../arcfour/arcfour-int.h \
-  $(srcdir)/../arcfour/arcfour.h enc_provider.h
+  $(srcdir)/../arcfour/arcfour-int.h $(srcdir)/../arcfour/arcfour.h \
+  enc_provider.h
 
diff --git a/src/lib/crypto/enc_provider/aes.c b/src/lib/crypto/enc_provider/aes.c
index d3dc2a5a7..1fc7abca7 100644
--- a/src/lib/crypto/enc_provider/aes.c
+++ b/src/lib/crypto/enc_provider/aes.c
@@ -52,23 +52,8 @@ static void printd (const char *descr, krb5_data *d) {
     }
     printf("\n");
 }
-static void enc(char *out, const char *in, aes_ctx *ctx)
-{
-    if (aes_enc_blk(in, out, ctx) != aes_good)
-	abort();
-#if 0
-    {
-	krb5_data e_in, e_out;
-	e_in.data = in;
-	e_out.data = out;
-	e_in.length = e_out.length = BLOCK_SIZE;
-	printf("encrypting [[\n");
-	printd("input block", &e_in);
-	printd("output block", &e_out);
-	printf("]]\n");
-    }
-#endif
-}
+#define enc(OUT, IN, CTX) (aes_enc_blk((IN),(OUT),(CTX)) == aes_good ? (void) 0 : abort())
+#define dec(OUT, IN, CTX) (aes_dec_blk((IN),(OUT),(CTX)) == aes_good ? (void) 0 : abort())
 
 static void xorblock(char *out, const char *in)
 {
@@ -83,7 +68,6 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
 {
     aes_ctx ctx;
     unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
-    int offset;
     int nblocks = 0, blockno;
 
 /*    CHECK_SIZES; */
@@ -100,8 +84,7 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
 
     if (nblocks == 1) {
 	/* XXX Used for DK function.  */
-	if (aes_enc_blk(input->data, output->data, &ctx) != aes_good)
-	    abort();
+	enc(output->data, input->data, &ctx);
     } else {
 	int nleft;
 
@@ -112,7 +95,6 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
 
 	    /* Set up for next block.  */
 	    memcpy(tmp, tmp2, BLOCK_SIZE);
-	    offset += BLOCK_SIZE;
 	}
 	/* Do final CTS step for last two blocks (the second of which
 	   may or may not be incomplete).  */
@@ -127,23 +109,70 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
 	xorblock(tmp, tmp3);
 	enc(tmp2, tmp, &ctx);
 	memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp2, BLOCK_SIZE);
+	if (ivec)
+	    memcpy(ivec->data, tmp2, BLOCK_SIZE);
     }
 
     return 0;
 }
 
-static krb5_error_code
-k5_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
-	       const krb5_data *input, krb5_data *output)
+krb5_error_code
+krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+		    const krb5_data *input, krb5_data *output)
 {
     aes_ctx ctx;
+    unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
+    int nblocks = 0, blockno;
 
     CHECK_SIZES;
 
     if (aes_dec_key(key->contents, key->length, &ctx) != aes_good)
 	abort();
 
-    abort();
+    if (ivec)
+	memcpy(tmp, ivec->data, BLOCK_SIZE);
+    else
+	memset(tmp, 0, BLOCK_SIZE);
+
+    nblocks = (input->length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+    if (nblocks == 1) {
+	if (input->length < BLOCK_SIZE)
+	    abort();
+	dec(output->data, input->data, &ctx);
+    } else {
+	int nleft;
+
+	for (blockno = 0; blockno < nblocks - 2; blockno++) {
+	    dec(tmp2, input->data + blockno * BLOCK_SIZE, &ctx);
+	    xorblock(tmp2, tmp);
+	    memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE);
+	    memcpy(tmp, input->data + blockno * BLOCK_SIZE, BLOCK_SIZE);
+	}
+	/* Do last two blocks, the second of which (next-to-last block
+	   of plaintext) may be incomplete.  */
+	dec(tmp2, input->data + (nblocks - 2) * BLOCK_SIZE, &ctx);
+	/* Set tmp3 to last ciphertext block, padded.  */
+	memset(tmp3, 0, sizeof(tmp3));
+	memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE,
+	       input->length - (nblocks - 1) * BLOCK_SIZE);
+	/* Set tmp2 to last (possibly partial) plaintext block, and
+	   save it.  */
+	xorblock(tmp2, tmp3);
+	memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2,
+	       input->length - (nblocks - 1) * BLOCK_SIZE);
+	/* Maybe keep the trailing part, and copy in the last
+	   ciphertext block.  */
+	memcpy(tmp2, tmp3, input->length - (nblocks - 1) * BLOCK_SIZE);
+	/* Decrypt, to get next to last plaintext block xor previous
+	   ciphertext.  */
+	dec(tmp3, tmp2, &ctx);
+	xorblock(tmp3, tmp);
+	memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp3, BLOCK_SIZE);
+	if (ivec)
+	    memcpy(ivec->data, input->data + (nblocks - 2) * BLOCK_SIZE,
+		   BLOCK_SIZE);
+    }
 
     return 0;
 }
@@ -178,7 +207,7 @@ const struct krb5_enc_provider krb5int_enc_aes128 = {
     aes_block_size,
     aes128_keysize,
     krb5int_aes_encrypt,
-    k5_aes_decrypt,
+    krb5int_aes_decrypt,
     k5_aes_make_key,
     krb5int_aes_init_state,
     krb5int_default_free_state
@@ -188,7 +217,7 @@ const struct krb5_enc_provider krb5int_enc_aes256 = {
     aes_block_size,
     aes256_keysize,
     krb5int_aes_encrypt,
-    k5_aes_decrypt,
+    krb5int_aes_decrypt,
     k5_aes_make_key,
     krb5int_aes_init_state,
     krb5int_default_free_state
diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c
index 1cc570cd8..6dcf02643 100644
--- a/src/lib/crypto/etypes.c
+++ b/src/lib/crypto/etypes.c
@@ -45,93 +45,109 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       "des-cbc-crc", "DES cbc mode with CRC-32",
       &krb5int_enc_des, &krb5int_hash_crc32,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
-      krb5int_des_string_to_key },
+      krb5int_des_string_to_key, CKSUMTYPE_RSA_MD5 },
     { ENCTYPE_DES_CBC_MD4,
       "des-cbc-md4", "DES cbc mode with RSA-MD4",
       &krb5int_enc_des, &krb5int_hash_md4,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
-      krb5int_des_string_to_key },
+      krb5int_des_string_to_key, CKSUMTYPE_RSA_MD4 },
     { ENCTYPE_DES_CBC_MD5,
       "des-cbc-md5", "DES cbc mode with RSA-MD5",
       &krb5int_enc_des, &krb5int_hash_md5,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
-      krb5int_des_string_to_key },
+      krb5int_des_string_to_key, CKSUMTYPE_RSA_MD5 },
     { ENCTYPE_DES_CBC_MD5,
       "des", "DES cbc mode with RSA-MD5", /* alias */
       &krb5int_enc_des, &krb5int_hash_md5,
       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
-      krb5int_des_string_to_key },
+      krb5int_des_string_to_key, CKSUMTYPE_RSA_MD5 },
 
     { ENCTYPE_DES_CBC_RAW,
       "des-cbc-raw", "DES cbc mode raw",
       &krb5int_enc_des, NULL,
       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
-      krb5int_des_string_to_key },
+      krb5int_des_string_to_key, 0 },
     { ENCTYPE_DES3_CBC_RAW,
       "des3-cbc-raw", "Triple DES cbc mode raw",
       &krb5int_enc_des3, NULL,
       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, 0 },
 
     { ENCTYPE_DES3_CBC_SHA1,
       "des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
       &krb5int_enc_des3, &krb5int_hash_sha1,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, CKSUMTYPE_HMAC_SHA1_DES3 },
     { ENCTYPE_DES3_CBC_SHA1,	/* alias */
       "des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
       &krb5int_enc_des3, &krb5int_hash_sha1,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, CKSUMTYPE_HMAC_SHA1_DES3 },
     { ENCTYPE_DES3_CBC_SHA1,	/* alias */
       "des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
       &krb5int_enc_des3, &krb5int_hash_sha1,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, CKSUMTYPE_HMAC_SHA1_DES3 },
 
     { ENCTYPE_DES_HMAC_SHA1,
       "des-hmac-sha1", "DES with HMAC/sha1",
       &krb5int_enc_des, &krb5int_hash_sha1,
       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, 0 },
     { ENCTYPE_ARCFOUR_HMAC, 
       "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
       "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
       "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
     { ENCTYPE_ARCFOUR_HMAC_EXP, 
       "arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
       "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
       "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
-      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key },
+      krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
+      CKSUMTYPE_HMAC_MD5_ARCFOUR },
 
     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
       "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
       &krb5int_enc_aes128, &krb5int_hash_sha1,
-      krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_aes_string_to_key },
+      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+      krb5int_aes_string_to_key, CKSUMTYPE_HMAC_SHA1_96_AES128 },
+    { ENCTYPE_AES128_CTS_HMAC_SHA1_96, /* alias */
+      "aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
+      &krb5int_enc_aes128, &krb5int_hash_sha1,
+      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+      krb5int_aes_string_to_key, CKSUMTYPE_HMAC_SHA1_96_AES128 },
     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
       "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
       &krb5int_enc_aes256, &krb5int_hash_sha1,
-      krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
-      krb5int_aes_string_to_key },
+      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+      krb5int_aes_string_to_key, CKSUMTYPE_HMAC_SHA1_96_AES256 },
+    { ENCTYPE_AES256_CTS_HMAC_SHA1_96, /* alias */
+      "aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
+      &krb5int_enc_aes256, &krb5int_hash_sha1,
+      krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+      krb5int_aes_string_to_key, CKSUMTYPE_HMAC_SHA1_96_AES256 },
 
 #ifdef ATHENA_DES3_KLUDGE
     /*
@@ -143,7 +159,7 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
       "Triple DES with HMAC/sha1 and 32-bit length code",
       &krb5int_enc_des3, &krb5int_hash_sha1,
       krb5_marc_dk_encrypt_length, krb5_marc_dk_encrypt, krb5_marc_dk_decrypt,
-      krb5int_dk_string_to_key },
+      krb5int_dk_string_to_key, CKSUMTYPE_HMAC_SHA1_DES3 },
 #endif
 };
 
diff --git a/src/lib/crypto/hash_provider/Makefile.in b/src/lib/crypto/hash_provider/Makefile.in
index 55aa8922e..b9e6ba778 100644
--- a/src/lib/crypto/hash_provider/Makefile.in
+++ b/src/lib/crypto/hash_provider/Makefile.in
@@ -42,26 +42,26 @@ clean-unix:: clean-libobjs
 #
 hash_crc32.so hash_crc32.po $(OUTPRE)hash_crc32.$(OBJEXT): hash_crc32.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../crc32/crc-32.h \
-  hash_provider.h
+  $(srcdir)/../crc32/crc-32.h hash_provider.h
 hash_md4.so hash_md4.po $(OUTPRE)hash_md4.$(OBJEXT): hash_md4.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../md4/rsa-md4.h \
-  hash_provider.h
+  $(srcdir)/../md4/rsa-md4.h hash_provider.h
 hash_md5.so hash_md5.po $(OUTPRE)hash_md5.$(OBJEXT): hash_md5.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../md5/rsa-md5.h \
-  hash_provider.h
+  $(srcdir)/../md5/rsa-md5.h hash_provider.h
 hash_sha1.so hash_sha1.po $(OUTPRE)hash_sha1.$(OBJEXT): hash_sha1.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../sha1/shs.h \
-  hash_provider.h
+  $(srcdir)/../sha1/shs.h hash_provider.h
 
diff --git a/src/lib/crypto/keyhash_provider/Makefile.in b/src/lib/crypto/keyhash_provider/Makefile.in
index 27c3821fd..d134fd870 100644
--- a/src/lib/crypto/keyhash_provider/Makefile.in
+++ b/src/lib/crypto/keyhash_provider/Makefile.in
@@ -61,29 +61,31 @@ clean-unix:: clean-libobjs
 #
 descbc.so descbc.po $(OUTPRE)descbc.$(OBJEXT): descbc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h keyhash_provider.h
+  $(srcdir)/../des/des_int.h $(SRCTOP)/include/kerberosIV/des.h \
+  keyhash_provider.h
 k5_md4des.so k5_md4des.po $(OUTPRE)k5_md4des.$(OBJEXT): k5_md4des.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(srcdir)/../md4/rsa-md4.h \
-  keyhash_provider.h
+  $(srcdir)/../des/des_int.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(srcdir)/../md4/rsa-md4.h keyhash_provider.h
 k5_md5des.so k5_md5des.po $(OUTPRE)k5_md5des.$(OBJEXT): k5_md5des.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(srcdir)/../md5/rsa-md5.h \
-  keyhash_provider.h
+  $(srcdir)/../des/des_int.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(srcdir)/../md5/rsa-md5.h keyhash_provider.h
 hmac_md5.so hmac_md5.po $(OUTPRE)hmac_md5.$(OBJEXT): hmac_md5.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h keyhash_provider.h $(srcdir)/../arcfour/arcfour-int.h \
+  keyhash_provider.h $(srcdir)/../arcfour/arcfour-int.h \
   $(srcdir)/../arcfour/arcfour.h $(srcdir)/../md5/rsa-md5.h \
   $(srcdir)/../hash_provider/hash_provider.h
 
diff --git a/src/lib/crypto/make_checksum.c b/src/lib/crypto/make_checksum.c
index 5d7be934b..8a384e710 100644
--- a/src/lib/crypto/make_checksum.c
+++ b/src/lib/crypto/make_checksum.c
@@ -108,6 +108,13 @@ krb5_c_make_checksum(context, cksumtype, key, usage, input, cksum)
     if (!ret) {
 	cksum->magic = KV5M_CHECKSUM;
 	cksum->checksum_type = cksumtype;
+	if (krb5_cksumtypes_list[i].trunc_size) {
+	    krb5_octet *trunc;
+	    cksum->length = krb5_cksumtypes_list[i].trunc_size;
+	    trunc = (krb5_octet *) realloc(cksum->contents, cksum->length);
+	    if (trunc)
+		cksum->contents = trunc;
+	}
     }
 
 cleanup:
diff --git a/src/lib/crypto/mandatory_sumtype.c b/src/lib/crypto/mandatory_sumtype.c
new file mode 100644
index 000000000..f9322ff3f
--- /dev/null
+++ b/src/lib/crypto/mandatory_sumtype.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2003 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "k5-int.h"
+#include "etypes.h"
+
+krb5_error_code
+krb5int_c_mandatory_cksumtype (krb5_context ctx, krb5_enctype etype,
+			       krb5_cksumtype *cksumtype)
+{
+    int i;
+
+    for (i = 0; i < krb5_enctypes_length; i++)
+	if (krb5_enctypes_list[i].etype == etype) {
+	    *cksumtype = krb5_enctypes_list[i].required_ctype;
+	    return 0;
+	}
+
+    return KRB5_BAD_ENCTYPE;
+}
diff --git a/src/lib/crypto/md4/Makefile.in b/src/lib/crypto/md4/Makefile.in
index af0593526..57341c6a7 100644
--- a/src/lib/crypto/md4/Makefile.in
+++ b/src/lib/crypto/md4/Makefile.in
@@ -63,7 +63,8 @@ clean-unix:: clean-libobjs
 #
 md4.so md4.po $(OUTPRE)md4.$(OBJEXT): md4.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h rsa-md4.h
+  rsa-md4.h
 
diff --git a/src/lib/crypto/md5/Makefile.in b/src/lib/crypto/md5/Makefile.in
index b7838934f..d5e3a2244 100644
--- a/src/lib/crypto/md5/Makefile.in
+++ b/src/lib/crypto/md5/Makefile.in
@@ -53,7 +53,8 @@ clean-unix:: clean-libobjs
 #
 md5.so md5.po $(OUTPRE)md5.$(OBJEXT): md5.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h rsa-md5.h
+  rsa-md5.h
 
diff --git a/src/lib/crypto/old/ChangeLog b/src/lib/crypto/old/ChangeLog
index c23b40371..bab270489 100644
--- a/src/lib/crypto/old/ChangeLog
+++ b/src/lib/crypto/old/ChangeLog
@@ -1,3 +1,9 @@
+2003-05-23  Sam Hartman  <hartmans@mit.edu>
+
+	* des_stringtokey.c (krb5int_des_string_to_key): If param has  one
+	byte, treat it as a type.   Type 0 is normal, type 1 is AFS
+	string2key. 
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* des_stringtokey.c (krb5int_des_string_to_key): Renamed from
diff --git a/src/lib/crypto/old/Makefile.in b/src/lib/crypto/old/Makefile.in
index 8fc8390e5..acc2cdd71 100644
--- a/src/lib/crypto/old/Makefile.in
+++ b/src/lib/crypto/old/Makefile.in
@@ -40,18 +40,21 @@ clean-unix:: clean-libobjs
 #
 des_stringtokey.so des_stringtokey.po $(OUTPRE)des_stringtokey.$(OBJEXT): des_stringtokey.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  old.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h old.h $(srcdir)/../des/des_int.h \
+  $(SRCTOP)/include/kerberosIV/des.h
 old_decrypt.so old_decrypt.po $(OUTPRE)old_decrypt.$(OBJEXT): old_decrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h old.h
+  old.h
 old_encrypt.so old_encrypt.po $(OUTPRE)old_encrypt.$(OBJEXT): old_encrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h old.h
+  old.h
 
diff --git a/src/lib/crypto/old/des_stringtokey.c b/src/lib/crypto/old/des_stringtokey.c
index fd3440bda..20f2f053a 100644
--- a/src/lib/crypto/old/des_stringtokey.c
+++ b/src/lib/crypto/old/des_stringtokey.c
@@ -26,6 +26,7 @@
 
 #include "k5-int.h"
 #include "old.h"
+#include <des_int.h>
 
 /* XXX */
 extern krb5_error_code mit_des_string_to_key_int
@@ -41,7 +42,19 @@ krb5int_des_string_to_key(enc, string, salt, parm, key)
      const krb5_data *parm;
      krb5_keyblock *key;
 {
-    if (parm != NULL)
-	return KRB5_ERR_BAD_S2K_PARAMS;
+    int type;
+    if (parm ) {
+	if (parm->length != 1)
+	    return KRB5_ERR_BAD_S2K_PARAMS;
+	type = parm->data[0];
+    }
+    else type = 0;
+    switch(type) {
+    case 0:
     return(mit_des_string_to_key_int(key, string, salt));
+    case 1:
+	return mit_afs_string_to_key(key, string, salt);
+    default:
+	return KRB5_ERR_BAD_S2K_PARAMS;
+    }
 }
diff --git a/src/lib/crypto/pbkdf2.c b/src/lib/crypto/pbkdf2.c
index d8a3f8b58..ce9f215fa 100644
--- a/src/lib/crypto/pbkdf2.c
+++ b/src/lib/crypto/pbkdf2.c
@@ -158,6 +158,7 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
 {
     int l, r, i;
     char *utmp1, *utmp2;
+    char utmp3[20];		/* XXX length shouldn't be hardcoded! */
 
     if (output->length == 0 || hlen == 0)
 	abort();
@@ -169,7 +170,13 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
     r = output->length - (l - 1) * hlen;
 
     utmp1 = /*output + dklen; */ malloc(hlen);
+    if (utmp1 == NULL)
+	return errno;
     utmp2 = /*utmp1 + hlen; */ malloc(salt->length + 4 + hlen);
+    if (utmp2 == NULL) {
+	free(utmp1);
+	return errno;
+    }
 
     /* Step 3.  */
     for (i = 1; i <= l; i++) {
@@ -177,11 +184,21 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
 	int j;
 #endif
 	krb5_error_code err;
+	char *out;
 
-	err = F(output->data + (i-1) * hlen, utmp1, utmp2, prf, hlen,
-		pass, salt, count, i);
-	if (err)
+	if (i == l)
+	    out = utmp3;
+	else
+	    out = output->data + (i-1) * hlen;
+	err = F(out, utmp1, utmp2, prf, hlen, pass, salt, count, i);
+	if (err) {
+	    free(utmp1);
+	    free(utmp2);
 	    return err;
+	}
+	if (i == l)
+	    memcpy(output->data + (i-1) * hlen, utmp3,
+		   output->length - (i-1) * hlen);
 
 #if 0
 	printf("after F(%d), @%p:\n", i, output->data);
@@ -190,6 +207,8 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
 	printf ("\n");
 #endif
     }
+    free(utmp1);
+    free(utmp2);
     return 0;
 }
 
@@ -235,8 +254,6 @@ foo(krb5_keyblock *pass, krb5_data *salt, krb5_data *out)
 
     memset(out->data, 0, out->length);
     err = hmac1 (&krb5int_hash_sha1, pass, salt, out);
-    if (err)
-	com_err("foo", err, "computing hmac");
     return err;
 }
 
diff --git a/src/lib/crypto/raw/Makefile.in b/src/lib/crypto/raw/Makefile.in
index d94112b6a..490d2c78b 100644
--- a/src/lib/crypto/raw/Makefile.in
+++ b/src/lib/crypto/raw/Makefile.in
@@ -38,12 +38,14 @@ clean-unix:: clean-libobjs
 #
 raw_decrypt.so raw_decrypt.po $(OUTPRE)raw_decrypt.$(OBJEXT): raw_decrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h raw.h
+  raw.h
 raw_encrypt.so raw_encrypt.po $(OUTPRE)raw_encrypt.$(OBJEXT): raw_encrypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h raw.h
+  raw.h
 
diff --git a/src/lib/crypto/sha1/Makefile.in b/src/lib/crypto/sha1/Makefile.in
index da3e70fa3..f796eaace 100644
--- a/src/lib/crypto/sha1/Makefile.in
+++ b/src/lib/crypto/sha1/Makefile.in
@@ -58,7 +58,7 @@ t_shs3: t_shs3.o shs.o
 #
 shs.so shs.po $(OUTPRE)shs.$(OBJEXT): shs.c shs.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/crypto/string_to_key.c b/src/lib/crypto/string_to_key.c
index c9434e08d..412583185 100644
--- a/src/lib/crypto/string_to_key.c
+++ b/src/lib/crypto/string_to_key.c
@@ -27,7 +27,6 @@
 #include "k5-int.h"
 #include "etypes.h"
 
-/* Eventually this declaration should move to krb5.h.  */
 krb5_error_code KRB5_CALLCONV
 krb5_c_string_to_key_with_params(krb5_context context,
 				 krb5_enctype enctype,
@@ -72,7 +71,21 @@ krb5_c_string_to_key_with_params(context, enctype, string, salt, params, key)
 	return(KRB5_BAD_ENCTYPE);
 
     enc = krb5_enctypes_list[i].enc;
+/* xxx AFS string2key function is indicated by a special length  in
+ * the salt in much of the code.  However only the DES enctypes can
+ * deal with this.  Using s2kparams would be a much better solution.*/
+    if (salt && salt->length == SALT_TYPE_AFS_LENGTH) {
+	switch (enctype) {
+	case ENCTYPE_DES_CBC_CRC:
+	case ENCTYPE_DES_CBC_MD4:
+	case ENCTYPE_DES_CBC_MD5:
+	    break;
+	default:
+	    return (KRB5_CRYPTO_INTERNAL);
+	}
+    }
 
+	
     (*(enc->keysize))(&keybytes, &keylength);
 
     if ((key->contents = (krb5_octet *) malloc(keylength)) == NULL)
diff --git a/src/lib/crypto/t_cts.c b/src/lib/crypto/t_cts.c
index 5bf1ecba9..b105bd275 100644
--- a/src/lib/crypto/t_cts.c
+++ b/src/lib/crypto/t_cts.c
@@ -120,27 +120,52 @@ static void test_cts()
 					       krb5_data *);
 
     int i;
-    char outbuf[64];
-    krb5_data in, out;
+    char outbuf[64], encivbuf[16], decivbuf[16], outbuf2[64];
+    krb5_data in, out, enciv, deciv, out2;
     krb5_keyblock key;
     krb5_error_code err;
 
     in.data = input;
     out.data = outbuf;
+    out2.data = outbuf2;
+    enciv.length = deciv.length = 16;
+    enciv.data = encivbuf;
+    deciv.data = decivbuf;
     key.contents = aeskey;
     key.length = 16;
 
+    memset(enciv.data, 0, 16);
     printk("AES 128-bit key", &key);
     for (i = 0; i < sizeof(lengths)/sizeof(lengths[0]); i++) {
+    memset(enciv.data, 0, 16);
+    memset(deciv.data, 0, 16);
+
 	printf("\n");
 	in.length = out.length = lengths[i];
-	err = krb5int_aes_encrypt(&key, 0, &in, &out);
+	printd("IV", &enciv);
+	err = krb5int_aes_encrypt(&key, &enciv, &in, &out);
 	if (err) {
 	    printf("error %ld from krb5int_aes_encrypt\n", (long)err);
 	    exit(1);
 	}
 	printd("Input", &in);
 	printd("Output", &out);
+	printd("Next IV", &enciv);
+	out2.length = out.length;
+	err = krb5int_aes_decrypt(&key, &deciv, &out, &out2);
+	if (err) {
+	    printf("error %ld from krb5int_aes_decrypt\n", (long)err);
+	    exit(1);
+	}
+	if (out2.length != in.length
+	    || memcmp(in.data, out2.data, in.length)) {
+	    printd("Decryption result DOESN'T MATCH", &out2);
+	    exit(1);
+	}
+	if (memcmp(enciv.data, deciv.data, 16)) {
+	    printd("Decryption IV result DOESN'T MATCH", &deciv);
+	    exit(1);
+	}
     }
 }
 
diff --git a/src/lib/crypto/yarrow/Makefile.in b/src/lib/crypto/yarrow/Makefile.in
index efae36364..535727249 100644
--- a/src/lib/crypto/yarrow/Makefile.in
+++ b/src/lib/crypto/yarrow/Makefile.in
@@ -44,15 +44,16 @@ clean-unix:: clean-libobjs
 #
 yarrow.so yarrow.po $(OUTPRE)yarrow.$(OBJEXT): yarrow.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h yarrow.h ytypes.h yhash.h \
-  $(srcdir)/../sha1/shs.h ycipher.h ylock.h ystate.h \
-  yexcep.h
+  yarrow.h ytypes.h yhash.h $(srcdir)/../sha1/shs.h ycipher.h \
+  ylock.h ystate.h yexcep.h
 ycipher.so ycipher.po $(OUTPRE)ycipher.$(OBJEXT): ycipher.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h yarrow.h ytypes.h yhash.h \
-  $(srcdir)/../sha1/shs.h ycipher.h $(srcdir)/../enc_provider/enc_provider.h
+  yarrow.h ytypes.h yhash.h $(srcdir)/../sha1/shs.h ycipher.h \
+  $(srcdir)/../enc_provider/enc_provider.h
 
diff --git a/src/lib/des425/ChangeLog b/src/lib/des425/ChangeLog
index acd4ea66e..9ab878a94 100644
--- a/src/lib/des425/ChangeLog
+++ b/src/lib/des425/ChangeLog
@@ -1,3 +1,8 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* quad_cksum.c, t_pcbc.c, t_quad.c, verify.c: Don't declare errno
+	or errmsg.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * mac_des_glue.c, des.c, enc_dec.c, key_sched.c, str_to_key.c: 
diff --git a/src/lib/des425/Makefile.in b/src/lib/des425/Makefile.in
index dc486f32b..54960fee7 100644
--- a/src/lib/des425/Makefile.in
+++ b/src/lib/des425/Makefile.in
@@ -119,85 +119,86 @@ install-unix:: install-libs
 #
 cksum.so cksum.po $(OUTPRE)cksum.$(OBJEXT): cksum.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 des.so des.po $(OUTPRE)des.$(OBJEXT): des.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 enc_dec.so enc_dec.po $(OUTPRE)enc_dec.$(OBJEXT): enc_dec.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 key_parity.so key_parity.po $(OUTPRE)key_parity.$(OBJEXT): key_parity.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 key_sched.so key_sched.po $(OUTPRE)key_sched.$(OBJEXT): key_sched.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 new_rnd_key.so new_rnd_key.po $(OUTPRE)new_rnd_key.$(OBJEXT): new_rnd_key.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 pcbc_encrypt.so pcbc_encrypt.po $(OUTPRE)pcbc_encrypt.$(OBJEXT): pcbc_encrypt.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(srcdir)/../crypto/des/f_tables.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(srcdir)/../crypto/des/f_tables.h
 quad_cksum.so quad_cksum.po $(OUTPRE)quad_cksum.$(OBJEXT): quad_cksum.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 random_key.so random_key.po $(OUTPRE)random_key.$(OBJEXT): random_key.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 read_passwd.so read_passwd.po $(OUTPRE)read_passwd.$(OBJEXT): read_passwd.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 str_to_key.so str_to_key.po $(OUTPRE)str_to_key.$(OBJEXT): str_to_key.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 unix_time.so unix_time.po $(OUTPRE)unix_time.$(OBJEXT): unix_time.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 util.so util.po $(OUTPRE)util.$(OBJEXT): util.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(srcdir)/../crypto/des/des_int.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(srcdir)/../crypto/des/des_int.h $(SRCTOP)/include/kerberosIV/des.h
 weak_key.so weak_key.po $(OUTPRE)weak_key.$(OBJEXT): weak_key.c $(srcdir)/../crypto/des/des_int.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(SRCTOP)/include/kerberosIV/des.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/kerberosIV/des.h
 
diff --git a/src/lib/des425/quad_cksum.c b/src/lib/des425/quad_cksum.c
index b9ef031ef..2a7b78cfd 100644
--- a/src/lib/des425/quad_cksum.c
+++ b/src/lib/des425/quad_cksum.c
@@ -119,10 +119,6 @@
 #define vaxtohs(x) two_bytes_vax_to_nets(((const unsigned char *)(x)))
 
 /* Externals */
-extern char *errmsg();
-#ifndef HAVE_ERRNO
-extern int errno;
-#endif
 extern int des_debug;
 
 /*** Routines ***************************************************** */
diff --git a/src/lib/des425/t_pcbc.c b/src/lib/des425/t_pcbc.c
index 8bd6a08bc..2932148b7 100644
--- a/src/lib/des425/t_pcbc.c
+++ b/src/lib/des425/t_pcbc.c
@@ -30,8 +30,6 @@
 #include "des_int.h"
 #include "des.h"
 
-extern char *errmsg();
-extern int errno;
 char *progname;
 int des_debug;
 
diff --git a/src/lib/des425/t_quad.c b/src/lib/des425/t_quad.c
index 421a55584..b9299fd20 100644
--- a/src/lib/des425/t_quad.c
+++ b/src/lib/des425/t_quad.c
@@ -30,8 +30,6 @@
 #include "des_int.h"
 #include "des.h"
 
-extern char *errmsg();
-extern int errno;
 extern unsigned long quad_cksum();
 char *progname;
 int des_debug;
diff --git a/src/lib/des425/verify.c b/src/lib/des425/verify.c
index 91718e350..653730a2f 100644
--- a/src/lib/des425/verify.c
+++ b/src/lib/des425/verify.c
@@ -37,8 +37,6 @@
 #include "des_int.h"
 #include "des.h"
 
-extern char *errmsg();
-extern int errno;
 char *progname;
 int nflag = 2;
 int vflag;
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 26747104b..27fc2d9a9 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,8 @@
+2003-07-17  Tom Yu  <tlyu@mit.edu>
+
+	* gss_libinit.c (gssint_initialize_library): Don't call
+	kg_release_defcred(); it doesn't exist any more.
+
 2003-03-08  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.in ($(BUILDTOP)/include/gssapi/gssapi.h,
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in
index baa776e5b..3df77c8b7 100644
--- a/src/lib/gssapi/Makefile.in
+++ b/src/lib/gssapi/Makefile.in
@@ -122,5 +122,6 @@ gss_libinit.so gss_libinit.po $(OUTPRE)gss_libinit.$(OBJEXT): gss_libinit.c gene
   $(COM_ERR_DEPS) krb5/gssapi_err_krb5.h $(srcdir)/krb5/gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(srcdir)/generic/gssapiP_generic.h \
   $(srcdir)/generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   $(srcdir)/krb5/gssapi_krb5.h gss_libinit.h generic/gssapi.h
 
diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog
index bd58e5ae7..531b30992 100644
--- a/src/lib/gssapi/generic/ChangeLog
+++ b/src/lib/gssapi/generic/ChangeLog
@@ -1,3 +1,25 @@
+2004-02-08  Ken Raeburn  <raeburn@mit.edu>
+
+	* util_ordering.c (g_queue_externalize, g_queue_internalize):
+	Check for sufficient buffer space.
+
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* gssapiP_generic.h: Include k5-platform.h.
+	(gssint_uint64): New typedef.
+	(g_order_init, g_order_check): Update decls.
+	* util_ordering.c (struct _queue): Change sequence number fields
+	to gssint_uint64.  Add mask field.
+	(queue_insert): Change sequence number to gssint_uint64.
+	(g_order_init): Change sequence numbers to gssint_uint64.  Add
+	"wide_nums" argument; initialize the queue mask field based on
+	it; all callers changed.  Store a -1 as the first element.
+	(g_order_check): Store and check elements as offsets from
+	firstnum.  Mask to 32 bits if desired.
+	* util_token.c (g_verify_token_header): Add new argument
+	indicating whether the pseudo-ASN.1 wrapper is required; all
+	callers changed.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * disp_com_err_status.c, gssapi_generic.h:  
diff --git a/src/lib/gssapi/generic/Makefile.in b/src/lib/gssapi/generic/Makefile.in
index 8ac282f37..b55a6e241 100644
--- a/src/lib/gssapi/generic/Makefile.in
+++ b/src/lib/gssapi/generic/Makefile.in
@@ -147,40 +147,52 @@ depend:: $(ETSRCS)
 #
 disp_com_err_status.so disp_com_err_status.po $(OUTPRE)disp_com_err_status.$(OBJEXT): disp_com_err_status.c \
   gssapiP_generic.h gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 disp_major_status.so disp_major_status.po $(OUTPRE)disp_major_status.$(OBJEXT): disp_major_status.c \
   gssapiP_generic.h gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 gssapi_generic.so gssapi_generic.po $(OUTPRE)gssapi_generic.$(OBJEXT): gssapi_generic.c \
   gssapiP_generic.h gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 oid_ops.so oid_ops.po $(OUTPRE)oid_ops.$(OBJEXT): oid_ops.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 rel_buffer.so rel_buffer.po $(OUTPRE)rel_buffer.$(OBJEXT): rel_buffer.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 rel_oid_set.so rel_oid_set.po $(OUTPRE)rel_oid_set.$(OBJEXT): rel_oid_set.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_buffer.so util_buffer.po $(OUTPRE)util_buffer.$(OBJEXT): util_buffer.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_oid.so util_oid.po $(OUTPRE)util_oid.$(OBJEXT): util_oid.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_ordering.so util_ordering.po $(OUTPRE)util_ordering.$(OBJEXT): util_ordering.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_set.so util_set.po $(OUTPRE)util_set.$(OBJEXT): util_set.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_token.so util_token.po $(OUTPRE)util_token.$(OBJEXT): util_token.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 util_validate.so util_validate.po $(OUTPRE)util_validate.$(OBJEXT): util_validate.c gssapiP_generic.h \
   gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  gssapi_err_generic.h $(COM_ERR_DEPS)
+  gssapi_err_generic.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h
 gssapi_err_generic.so gssapi_err_generic.po $(OUTPRE)gssapi_err_generic.$(OBJEXT): gssapi_err_generic.c \
   $(COM_ERR_DEPS)
 
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index 102ba699e..24d51d0d5 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -40,6 +40,9 @@
 #include "gssapi_err_generic.h"
 #include <errno.h>
 
+#include "k5-platform.h"
+typedef UINT64_TYPE gssint_uint64;
+
 /** helper macros **/
 
 #define g_OID_equal(o1,o2) \
@@ -159,8 +162,9 @@ void g_make_token_header (gss_OID mech, unsigned int body_size,
 			  unsigned char **buf, int tok_type);
 
 gss_int32 g_verify_token_header (gss_OID mech, unsigned int *body_size,
-			  unsigned char **buf, int tok_type, 
-				 unsigned int toksize_in);
+				 unsigned char **buf, int tok_type, 
+				 unsigned int toksize_in,
+				 int wrapper_required);
 
 OM_uint32 g_display_major_status (OM_uint32 *minor_status,
 				 OM_uint32 status_value,
@@ -171,10 +175,10 @@ OM_uint32 g_display_com_err_status (OM_uint32 *minor_status,
 				   OM_uint32 status_value,
 				   gss_buffer_t status_string);
 
-gss_int32 g_order_init (void **queue, OM_uint32 seqnum,
-				  int do_replay, int do_sequence);
+gss_int32 g_order_init (void **queue, gssint_uint64 seqnum,
+				  int do_replay, int do_sequence, int wide);
 
-gss_int32 g_order_check (void **queue, OM_uint32 seqnum);
+gss_int32 g_order_check (void **queue, gssint_uint64 seqnum);
 
 void g_order_free (void **queue);
 
diff --git a/src/lib/gssapi/generic/util_ordering.c b/src/lib/gssapi/generic/util_ordering.c
index 21a8b0641..f7cf66678 100644
--- a/src/lib/gssapi/generic/util_ordering.c
+++ b/src/lib/gssapi/generic/util_ordering.c
@@ -38,8 +38,14 @@ typedef struct _queue {
    int do_sequence;
    int start;
    int length;
-   unsigned int firstnum;
-   unsigned int elem[QUEUE_LENGTH];
+   gssint_uint64 firstnum;
+   /* Stored as deltas from firstnum.  This way, the high bit won't
+      overflow unless we've actually gone through 2**n messages, or
+      gotten something *way* out of sequence.  */
+   gssint_uint64 elem[QUEUE_LENGTH];
+   /* All ones for 64-bit sequence numbers; 32 ones for 32-bit
+      sequence numbers.  */
+   gssint_uint64 mask;
 } queue;
 
 /* rep invariant:
@@ -51,7 +57,7 @@ typedef struct _queue {
 #define QELEM(q,i) ((q)->elem[(i)%QSIZE(q)])
 
 static void
-queue_insert(queue *q, int after, unsigned int seqnum)
+queue_insert(queue *q, int after, gssint_uint64 seqnum)
 {
    /* insert.  this is not the fastest way, but it's easy, and it's
       optimized for insert at end, which is the common case */
@@ -80,10 +86,10 @@ queue_insert(queue *q, int after, unsigned int seqnum)
       q->length++;
    }
 }
-   
+
 gss_int32
-g_order_init(void **vqueue, OM_uint32 seqnum,
-	     int do_replay, int do_sequence)
+g_order_init(void **vqueue, gssint_uint64 seqnum,
+	     int do_replay, int do_sequence, int wide_nums)
 {
    queue *q;
 
@@ -92,38 +98,49 @@ g_order_init(void **vqueue, OM_uint32 seqnum,
 
    q->do_replay = do_replay;
    q->do_sequence = do_sequence;
+   q->mask = wide_nums ? ~(gssint_uint64)0 : 0xffffffffUL;
 
    q->start = 0;
    q->length = 1;
    q->firstnum = seqnum;
-   q->elem[q->start] = seqnum-1;
+   q->elem[q->start] = ((gssint_uint64)0 - 1) & q->mask;
 
    *vqueue = (void *) q;
    return(0);
 }
 
 gss_int32
-g_order_check(void **vqueue, OM_uint32 seqnum)
+g_order_check(void **vqueue, gssint_uint64 seqnum)
 {
    queue *q;
    int i;
-   
+   gssint_uint64 expected;
+
    q = (queue *) (*vqueue);
 
    if (!q->do_replay && !q->do_sequence)
       return(GSS_S_COMPLETE);
 
+   /* All checks are done relative to the initial sequence number, to
+      avoid (or at least put off) the pain of wrapping.  */
+   seqnum -= q->firstnum;
+   /* If we're only doing 32-bit values, adjust for that again.
+
+      Note that this will probably be the wrong thing to if we get
+      2**32 messages sent with 32-bit sequence numbers.  */
+   seqnum &= q->mask;
+
    /* rule 1: expected sequence number */
 
-   if (seqnum == QELEM(q,q->start+q->length-1)+1) { 
+   expected = (QELEM(q,q->start+q->length-1)+1) & q->mask;
+   if (seqnum == expected) { 
       queue_insert(q, q->start+q->length-1, seqnum);
       return(GSS_S_COMPLETE);
    }
 
    /* rule 2: > expected sequence number */
 
-   if ((seqnum > QELEM(q,q->start+q->length-1)+1) ||
-       (seqnum < q->firstnum)) {
+   if ((seqnum > expected)) {
       queue_insert(q, q->start+q->length-1, seqnum);
       if (q->do_replay && !q->do_sequence)
 	 return(GSS_S_COMPLETE);
@@ -134,7 +151,20 @@ g_order_check(void **vqueue, OM_uint32 seqnum)
    /* rule 3: seqnum < seqnum(first) */
 
    if ((seqnum < QELEM(q,q->start)) &&
-       (seqnum >= q->firstnum)) {
+       /* Is top bit of whatever width we're using set?
+
+	  We used to check for greater than or equal to firstnum, but
+	  (1) we've since switched to compute values relative to
+	  firstnum, so the lowest we can have is 0, and (2) the effect
+	  of the original scheme was highly dependent on whether
+	  firstnum was close to either side of 0.  (Consider
+	  firstnum==0xFFFFFFFE and we miss three packets; the next
+	  packet is *new* but would look old.)
+
+          This check should give us 2**31 or 2**63 messages "new", and
+          just as many "old".  That's not quite right either.  */
+       (seqnum & (1 + (q->mask >> 1)))
+       ) {
       if (q->do_replay && !q->do_sequence)
 	 return(GSS_S_OLD_TOKEN);
       else
@@ -189,6 +219,8 @@ g_queue_size(void *vqueue, size_t *sizep)
 gss_uint32
 g_queue_externalize(void *vqueue, unsigned char **buf, size_t *lenremain)
 {
+    if (*lenremain < sizeof(queue))
+	return ENOMEM;
     memcpy(*buf, vqueue, sizeof(queue));
     *buf += sizeof(queue);
     *lenremain -= sizeof(queue);
@@ -201,6 +233,8 @@ g_queue_internalize(void **vqueue, unsigned char **buf, size_t *lenremain)
 {
     void *q;
 
+    if (*lenremain < sizeof(queue))
+	return EINVAL;
     if ((q = malloc(sizeof(queue))) == 0)
 	return ENOMEM;
     memcpy(q, *buf, sizeof(queue));
diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c
index 30ae0698c..97a788c09 100644
--- a/src/lib/gssapi/generic/util_token.c
+++ b/src/lib/gssapi/generic/util_token.c
@@ -168,12 +168,15 @@ void g_make_token_header(mech, body_size, buf, tok_type)
  * mechanism in the token does not match the mech argument.  buf and
  * *body_size are left unmodified on error.
  */
-gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
+
+gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in,
+				wrapper_required)
      gss_OID mech;
      unsigned int *body_size;
      unsigned char **buf_in;
      int tok_type;
      unsigned int toksize_in;
+     int wrapper_required;
 {
    unsigned char *buf = *buf_in;
    int seqsize;
@@ -182,8 +185,13 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
 
    if ((toksize-=1) < 0)
       return(G_BAD_TOK_HEADER);
-   if (*buf++ != 0x60)
-      return(G_BAD_TOK_HEADER);
+   if (*buf++ != 0x60) {
+       if (wrapper_required)
+	   return(G_BAD_TOK_HEADER);
+       buf--;
+       toksize++;
+       goto skip_wrapper;
+   }
 
    if ((seqsize = der_read_length(&buf, &toksize)) < 0)
       return(G_BAD_TOK_HEADER);
@@ -207,16 +215,17 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
 
    if (! g_OID_equal(&toid, mech)) 
        return  G_WRONG_MECH;
+skip_wrapper:
    if (tok_type != -1) {
        if ((toksize-=2) < 0)
 	   return(G_BAD_TOK_HEADER);
 
        if ((*buf++ != ((tok_type>>8)&0xff)) ||
-	   (*buf++ != (tok_type&0xff))) 
+	   (*buf++ != (tok_type&0xff)))
 	   return(G_WRONG_TOKID);
    }
-	*buf_in = buf;
-	*body_size = toksize;
+   *buf_in = buf;
+   *body_size = toksize;
 
-	return 0;
-	}
+   return 0;
+}
diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c
index 7906786e9..0568f2964 100644
--- a/src/lib/gssapi/gss_libinit.c
+++ b/src/lib/gssapi/gss_libinit.c
@@ -33,12 +33,9 @@ OM_uint32 gssint_initialize_library (void)
 
 void gssint_cleanup_library (void)
 {
-	OM_uint32 min_stat;
 
 	assert (initialized);
 	
-	(void) kg_release_defcred (&min_stat);
-	
 #if !USE_BUNDLE_ERROR_STRINGS
 	remove_error_table(&et_k5g_error_table);
 	remove_error_table(&et_ggss_error_table);
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index 7424a251d..5224721ab 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,3 +1,202 @@
+2004-02-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* ser_sctx.c (kg_oid_externalize): Check for errors.
+	(kg_oid_internalize): Check for errors.  Free allocated storage on
+	error.
+	(kg_queue_externalize): Check for errorrs.
+	(kg_queue_internalize): Check for errors.  Free allocated storage
+	on error.
+	(kg_ctx_size): Update for new context data.
+	(kg_ctx_externalize): Update for new context data.  Check for
+	error storing trailer.
+	(kg_ctx_internalize): Update for new context data.  Check for
+	errors in a few more cases.
+
+2004-02-05  Jeffrey Altman <jaltman@mit.edu>
+
+    * gssapiP_krb5.h:  remove KG_IMPLFLAGS macro
+
+    * init_sec_context.c (init_sec_context): Expand KG_IMPLFLAGS
+      macro with previous macro definition
+
+    * accept_sec_context.c (accept_sec_context): Replace KG_IMPLFLAGS
+      macro with new definition.  As per 1964 the INTEG and CONF flags
+      are supposed to indicate the availability of the services in 
+      the client.  By applying the previous definition of KG_IMPLFLAGS
+      the INTEG and CONF flags are always on.  This can be a problem
+      because some clients such as Microsoft's Kerberos SSPI allow
+      CONF and INTEG to be used independently.  By forcing the flags
+      on, we would end up with inconsist state with the client.
+
+2004-01-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* init_sec_context.c (make_gss_checksum) [CFX_EXERCISE]: Don't
+	crash on null pointer in debugging code.
+	(new_connection): Disable CFX_EXERCISE unknown-token-id case
+	detection.
+
+	* accept_sec_context.c (krb5_gss_accept_sec_context)
+	[CFX_EXERCISE]: Log to /tmp/gsslog whether delegation or extra
+	option bytes were present.
+
+2004-01-05  Ken Raeburn  <raeburn@mit.edu>
+
+	* init_sec_context.c: Include auth_con.h if CFX_EXERCISE is
+	defined.
+	(make_gss_checksum) [CFX_EXERCISE]: If the key enctype is aes256,
+	insert some stuff after the delegation slot.
+	(new_connection) [CFX_EXERCISE]: Don't send messages with bogus
+	token ids.
+
+	* accept_sec_context.c (krb5_gss_accept_sec_context): Don't
+	discard the delegation flag; only look for a delegation if the
+	flag is set, and only look for delegation, not other options.
+	Ignore any other data there.
+
+2003-12-19  Tom Yu  <tlyu@mit.edu>
+
+	* init_sec_context.c: Include k5-int.h for accessor.
+
+2003-12-18  Jeffrey Altman <jaltman@mit.edu>
+
+   * accept_sec_context.c, init_sec_context.c, ser_sctx.c:
+     Implement use of krb5int_accessor() for krb5int_c_mandatory_cksumtype,
+     krb5_ser_pack_int64, and krb5_ser_unpack_int64
+
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+	    Sam Hartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* k5sealv3.c: New file, implements Wrap and MIC tokens for CFX
+	extensions.
+	* gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Added acceptor
+	subkey, 64-bit sequence numbers, checksum type, and hooks for
+	sending a bogus initial token for CFX testing.  Changed some flags
+	into bitfields.
+	(gss_krb5int_make_seal_token_v3): Declare.
+	* Makefile.in (SRCS, OBJS, STLIBOBJS): Build it.
+	* accept_sec_context.c (krb5_gss_accept_sec_context): Add CFX
+	support.  For G_WRONG_TOKID, send back an error token with
+	AP_ERR_MSG_TYPE code and return a CONTINUE_NEEDED indication.
+	Initialize new fields in context.
+	* delete_sec_context.c (krb5_gss_delete_sec_context): Free
+	acceptor subkey field.
+	* init_sec_context.c (get_credentials): Drop enctypes argument;
+	callers changed.
+	(get_requested_enctypes): Deleted.
+	(setup_enc): Combine some common sections.  Do CFX initialization
+	for newer enctypes.
+	(new_connection) [CFX_EXERCISE]: If doing CFX, send a bogus
+	token.  Delete the enctype list manipulation.
+	(mutual_auth): If CFX, save acceptor's subkey.
+	* k5seal.c (make_seal_token_v1): Sequence number is now 64 bits.
+	(kg_seal): Call out to _v3 code for CFX.
+	* k5unseal.c (kg_unseal): For CFX, adjust token id numbers and
+	call out to _v3 code.
+	* wrap_size_limit.c (krb5_gss_wrap_size_limit): Implement CFX
+	support.
+
+	* gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Deleted fields
+	ctypes and nctypes.
+	* delete_sec_context.c, init_sec_context.c, ser_sctx.c: Removed
+	references.
+
+2003-12-11  Alexandra Ellwood <lxs@mit.edu>
+
+	* acquire_cred.c, gssapi_krb5.c, gssapiP_krb5.h, set_ccache.c:
+        Added kg_sync_ccache_name(), kg_get_ccache_name, and 
+        kg_set_ccache_name() and rewrote gss_krb5_ccache_name() and
+        added a call to kg_sync_ccache_name() to acquire_init_cred()
+        to fix a bug where on systems with multiple ccaches that GSSAPI
+        gets stuck on the ccache that was default when it launched.
+
+2003-07-19  Ezra Peisach  <epeisach@mit.edu>
+
+	* acquire_cred.c (krb5_gss_register_acceptor_identity): Allocate
+	enough memory to include the null at the end of the keytab char *.
+
+2003-07-17  Tom Yu  <tlyu@mit.edu>
+
+	* gssapiP_krb5.h: Delete kg_release_defcred(); it's no longer
+	used.
+
+	* gssapi_krb5.c: Delete defcred; it's no longer cached.
+	(kg_get_defcred): Don't cache.
+	(kg_release_defcred): Delete; it's no longer used.
+
+	* init_sec_context.c (krb5_gss_init_sec_context): Break into more
+	manageable pieces.  Clean up a few error condition memory leaks
+	previously obscured by the sheer size of this function.
+	(setup_enc): New function; used to be part of
+	krb5_gss_init_sec_context() responsible for setting up enctypes,
+	keyblocks, related nastiness.
+	(get_requested_enctypes): New function; used to be part of
+	krb5_gss_init_sec_context() responsible for pruning the krb5
+	library's default enctype list to the limited set of enctypes
+	usable with GSSAPI.
+	(new_connection): New function; used to be part of
+	krb5_gss_init_sec_context() responsible for initial gss_ctx setup
+	and creating the AP-REQ.
+	(mutual_auth): New function; used to be part of
+	krb5_gss_init_sec_context() responsible for reading the AP-REP if
+	mutual auth was requested.
+
+	* inq_cred.c (krb5_gss_inquire_cred): Rearrange due to removal of
+	kg_release_defcred(), particularly to explicitly release the
+	defcred once it's obtained.
+
+	* rel_cred.c (krb5_gss_release_cred): Remove call to
+	kg_release_defcred(), and always succeed in releasing the null
+	credential.
+
+	* set_ccache.c (gss_krb5_ccache_name): Remove call to
+	kg_release_defcred().
+
+2003-07-14  Tom Yu  <tlyu@mit.edu>
+
+	* accept_sec_context.c (krb5_gss_accept_sec_context): Call
+	TREAD_STR with correct arguments.  Patch from Emily Ratliff.
+
+2003-07-10  Tom Yu  <tlyu@mit.edu>
+
+	* acquire_cred.c (acquire_init_cred): Close the ccache if
+	krb5_cc_set_flags() fails, as krb5int_cc_default succeeds even if
+	the file is not there, but krb5_cc_set_flags will fail in turning
+	off OPENCLOSE mode if the file can't be opened.  Thanks to Kent Wu.
+
+2003-06-13  Tom Yu  <tlyu@mit.edu>
+
+	* init_sec_context.c (make_ap_req_v1): Free checksum_data if
+	needed, to avoid leaking memory.  Found by Kent Wu.
+	(krb5_gss_init_sec_context): Free default_enctypes to avoid
+	leaking returned value from krb5_get_tgs_ktypes.
+
+	* k5unseal.c (kg_unseal_v1): Explicitly set token.value to NULL if
+	token.length == 0, to avoid spurious uninitialized memory
+	references when calling memcpy() with a zero length.
+
+2003-05-13  Tom Yu  <tlyu@mit.edu>
+
+	* gssapi_krb5.h: Remove check for GSS_RFC_COMPLIANT_OIDS.
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* accept_sec_context.c (krb5_gss_accept_sec_context): Rename
+	remote_subkey -> recv_subkey.
+
+	* init_sec_context.c (krb5_gss_init_sec_context): Rename
+	local_subkey -> send_subkey.
+
+2003-03-14  Sam Hartman  <hartmans@mit.edu>
+
+	* accept_sec_context.c (krb5_gss_accept_sec_context): Set
+	prot_ready here
+
+	* init_sec_context.c (krb5_gss_init_sec_context):  Set prot_ready
+	after context established
+
+	* gssapiP_krb5.h (KG_IMPLFLAGS): Don't claim prot_ready until the
+	context is established  because we don't currently support it.  
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * disp_status.c, gssapi_krb5.h, gssapiP_krb5.h: 
diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in
index c0d2660ee..0bdc117de 100644
--- a/src/lib/gssapi/krb5/Makefile.in
+++ b/src/lib/gssapi/krb5/Makefile.in
@@ -43,6 +43,7 @@ SRCS = \
 	$(srcdir)/inq_cred.c \
 	$(srcdir)/inq_names.c \
 	$(srcdir)/k5seal.c \
+	$(srcdir)/k5sealv3.c \
 	$(srcdir)/k5unseal.c \
 	$(srcdir)/krb5_gss_glue.c \
 	$(srcdir)/process_context_token.c \
@@ -90,6 +91,7 @@ OBJS = \
 	$(OUTPRE)inq_cred.$(OBJEXT) \
 	$(OUTPRE)inq_names.$(OBJEXT) \
 	$(OUTPRE)k5seal.$(OBJEXT) \
+	$(OUTPRE)k5sealv3.$(OBJEXT) \
 	$(OUTPRE)k5unseal.$(OBJEXT) \
 	$(OUTPRE)krb5_gss_glue.$(OBJEXT) \
 	$(OUTPRE)process_context_token.$(OBJEXT) \
@@ -137,6 +139,7 @@ STLIBOBJS = \
 	inq_cred.o \
 	inq_names.o \
 	k5seal.o \
+	k5sealv3.o \
 	k5unseal.o \
 	krb5_gss_glue.o \
 	process_context_token.o \
@@ -215,195 +218,244 @@ install::
 #
 accept_sec_context.so accept_sec_context.po $(OUTPRE)accept_sec_context.$(OBJEXT): accept_sec_context.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 acquire_cred.so acquire_cred.po $(OUTPRE)acquire_cred.$(OBJEXT): acquire_cred.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 add_cred.so add_cred.po $(OUTPRE)add_cred.$(OBJEXT): add_cred.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 canon_name.so canon_name.po $(OUTPRE)canon_name.$(OBJEXT): canon_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 compare_name.so compare_name.po $(OUTPRE)compare_name.$(OBJEXT): compare_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 context_time.so context_time.po $(OUTPRE)context_time.$(OBJEXT): context_time.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 copy_ccache.so copy_ccache.po $(OUTPRE)copy_ccache.$(OBJEXT): copy_ccache.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 delete_sec_context.so delete_sec_context.po $(OUTPRE)delete_sec_context.$(OBJEXT): delete_sec_context.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 disp_name.so disp_name.po $(OUTPRE)disp_name.$(OBJEXT): disp_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 disp_status.so disp_status.po $(OUTPRE)disp_status.$(OBJEXT): disp_status.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 duplicate_name.so duplicate_name.po $(OUTPRE)duplicate_name.$(OBJEXT): duplicate_name.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 export_name.so export_name.po $(OUTPRE)export_name.$(OBJEXT): export_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 export_sec_context.so export_sec_context.po $(OUTPRE)export_sec_context.$(OBJEXT): export_sec_context.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 get_tkt_flags.so get_tkt_flags.po $(OUTPRE)get_tkt_flags.$(OBJEXT): get_tkt_flags.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 gssapi_krb5.so gssapi_krb5.po $(OUTPRE)gssapi_krb5.$(OBJEXT): gssapi_krb5.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 import_name.so import_name.po $(OUTPRE)import_name.$(OBJEXT): import_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 import_sec_context.so import_sec_context.po $(OUTPRE)import_sec_context.$(OBJEXT): import_sec_context.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 indicate_mechs.so indicate_mechs.po $(OUTPRE)indicate_mechs.$(OBJEXT): indicate_mechs.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 init_sec_context.so init_sec_context.po $(OUTPRE)init_sec_context.$(OBJEXT): init_sec_context.c \
-  gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
-  $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
-  $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
-  gssapi_krb5.h gssapi_err_krb5.h
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
+  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 inq_context.so inq_context.po $(OUTPRE)inq_context.$(OBJEXT): inq_context.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 inq_cred.so inq_cred.po $(OUTPRE)inq_cred.$(OBJEXT): inq_cred.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 inq_names.so inq_names.po $(OUTPRE)inq_names.$(OBJEXT): inq_names.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 k5seal.so k5seal.po $(OUTPRE)k5seal.$(OBJEXT): k5seal.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
+k5sealv3.so k5sealv3.po $(OUTPRE)k5sealv3.$(OBJEXT): k5sealv3.c $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
+  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 k5unseal.so k5unseal.po $(OUTPRE)k5unseal.$(OBJEXT): k5unseal.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 krb5_gss_glue.so krb5_gss_glue.po $(OUTPRE)krb5_gss_glue.$(OBJEXT): krb5_gss_glue.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 process_context_token.so process_context_token.po $(OUTPRE)process_context_token.$(OBJEXT): process_context_token.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 rel_cred.so rel_cred.po $(OUTPRE)rel_cred.$(OBJEXT): rel_cred.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 rel_oid.so rel_oid.po $(OUTPRE)rel_oid.$(OBJEXT): rel_oid.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 rel_name.so rel_name.po $(OUTPRE)rel_name.$(OBJEXT): rel_name.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 seal.so seal.po $(OUTPRE)seal.$(OBJEXT): seal.c gssapiP_krb5.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 ser_sctx.so ser_sctx.po $(OUTPRE)ser_sctx.$(OBJEXT): ser_sctx.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 set_ccache.so set_ccache.po $(OUTPRE)set_ccache.$(OBJEXT): set_ccache.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 sign.so sign.po $(OUTPRE)sign.$(OBJEXT): sign.c gssapiP_krb5.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 unseal.so unseal.po $(OUTPRE)unseal.$(OBJEXT): unseal.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 util_cksum.so util_cksum.po $(OUTPRE)util_cksum.$(OBJEXT): util_cksum.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 util_crypt.so util_crypt.po $(OUTPRE)util_crypt.$(OBJEXT): util_crypt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
+  gssapiP_krb5.h $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
 util_seed.so util_seed.po $(OUTPRE)util_seed.$(OBJEXT): util_seed.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 util_seqnum.so util_seqnum.po $(OUTPRE)util_seqnum.$(OBJEXT): util_seqnum.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h \
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 val_cred.so val_cred.po $(OUTPRE)val_cred.$(OBJEXT): val_cred.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 verify.so verify.po $(OUTPRE)verify.$(OBJEXT): verify.c gssapiP_krb5.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
   $(srcdir)/../generic/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
-  ../generic/gssapi_err_generic.h gssapi_krb5.h gssapi_err_krb5.h
+  ../generic/gssapi_err_generic.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5/autoconf.h gssapi_krb5.h gssapi_err_krb5.h
 wrap_size_limit.so wrap_size_limit.po $(OUTPRE)wrap_size_limit.$(OBJEXT): wrap_size_limit.c \
   gssapiP_krb5.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(BUILDTOP)/include/gssapi/gssapi.h ../generic/gssapi_err_generic.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \
   gssapi_krb5.h gssapi_err_krb5.h
 gssapi_err_krb5.so gssapi_err_krb5.po $(OUTPRE)gssapi_err_krb5.$(OBJEXT): gssapi_err_krb5.c \
   $(COM_ERR_DEPS)
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 5ff6146ea..daff47ffb 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -77,6 +77,12 @@
 #endif
 #include <assert.h>
 
+#ifdef CFX_EXERCISE
+#define CFX_ACCEPTOR_SUBKEY (time(0) & 1)
+#else
+#define CFX_ACCEPTOR_SUBKEY 1
+#endif
+
 /* Decode, decrypt and store the forwarded creds in the local ccache. */
 static krb5_error_code
 rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
@@ -101,8 +107,8 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
 	 * By the time krb5_rd_cred is called here (after krb5_rd_req has been
 	 * called in krb5_gss_accept_sec_context), the "keyblock" field of
 	 * auth_context contains a pointer to the session key, and the
-	 * "remote_subkey" field might contain a session subkey.  Either of
-	 * these (the "remote_subkey" if it isn't NULL, otherwise the
+	 * "recv_subkey" field might contain a session subkey.  Either of
+	 * these (the "recv_subkey" if it isn't NULL, otherwise the
 	 * "keyblock") might have been used to encrypt the encrypted part of
 	 * the KRB_CRED message that contains the forwarded credentials.  (The
 	 * Java Crypto and Security Implementation from the DSTC in Australia
@@ -122,7 +128,8 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
 		if ((retval = krb5_auth_con_init(context, &new_auth_ctx)))
 			goto cleanup;
 		krb5_auth_con_setflags(context, new_auth_ctx, 0);
-		if ((retval = krb5_rd_cred(context, new_auth_ctx, inbuf, &creds, NULL)))
+		if ((retval = krb5_rd_cred(context, new_auth_ctx, inbuf,
+					   &creds, NULL)))
 			goto cleanup;
 		}
 
@@ -241,7 +248,14 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    krb5_data scratch;
    gss_cred_id_t cred_handle = NULL;
    krb5_gss_cred_id_t deleg_cred = NULL;
+   krb5int_access kaccess;
 
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    if (code) {
+        *minor_status = code;
+        return(GSS_S_FAILURE);
+    }
+       
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
 
@@ -312,13 +326,13 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    if (!(code = g_verify_token_header((gss_OID) gss_mech_krb5,
 				      &(ap_req.length),
 				      &ptr, KG_TOK_CTX_AP_REQ,
-				      input_token->length))) {
+				      input_token->length, 1))) {
        mech_used = gss_mech_krb5;
    } else if ((code == G_WRONG_MECH) &&
 	      !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old,
 					     &(ap_req.length), 
 					     &ptr, KG_TOK_CTX_AP_REQ,
-					     input_token->length))) {
+					     input_token->length, 1))) {
        /*
 	* Previous versions of this library used the old mech_id
 	* and some broken behavior (wrong IV on checksum
@@ -327,6 +341,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 	* old behavior.
 	*/
        mech_used = gss_mech_krb5_old;
+   } else if (code == G_WRONG_TOKID) {
+       major_status = GSS_S_CONTINUE_NEEDED;
+       code = KRB5KRB_AP_ERR_MSG_TYPE;
+       mech_used = gss_mech_krb5;
+       goto fail;
    } else {
        major_status = GSS_S_DEFECTIVE_TOKEN;
        goto fail;
@@ -496,18 +515,20 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        reqcksum.contents = 0;
 
        TREAD_INT(ptr, gss_flags, bigend);
+#if 0
        gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; if
 					  there's a delegation, we'll set
 					  it below */
+#endif
        decode_req_message = 0;
 
        /* if the checksum length > 24, there are options to process */
 
-       if(authdat->checksum->length > 24) {
+       if(authdat->checksum->length > 24 && (gss_flags & GSS_C_DELEG_FLAG)) {
 
 	   i = authdat->checksum->length - 24;
 
-	   while (i >= 4) {
+	   if (i >= 4) {
 
 	       TREAD_INT16(ptr, option_id, bigend);
 
@@ -515,23 +536,24 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 
 	       i -= 4;
 
-	       /* have to use ptr2, since option.data is wrong type and
-		  macro uses ptr as both lvalue and rvalue */
-
 	       if (i < option.length || option.length < 0) {
 		   code = KG_BAD_LENGTH;
 		   major_status = GSS_S_FAILURE;
 		   goto fail;
 	       }
 
-	       TREAD_STR(ptr, ptr2, bigend);
+	       /* have to use ptr2, since option.data is wrong type and
+		  macro uses ptr as both lvalue and rvalue */
+
+	       TREAD_STR(ptr, ptr2, option.length);
 	       option.data = (char *) ptr2;
 
 	       i -= option.length;
 
-	       switch(option_id) {
-
-	       case KRB5_GSS_FOR_CREDS_OPTION:
+	       if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
+		   major_status = GSS_S_FAILURE;
+		   goto fail;
+	       }
 
 		   /* store the delegated credential */
 
@@ -543,16 +565,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 		       goto fail;
 		   }
 
-		   gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
-
-		   break;
-
-		   /* default: */
-		   /* unknown options aren't an error */
-
-	       } /* switch */
-	   } /* while */
-       } /* if */
+	   } /* if i >= 4 */
+	   /* ignore any additional trailing data, for now */
+#ifdef CFX_EXERCISE
+	   {
+	       FILE *f = fopen("/tmp/gsslog", "a");
+	       if (f) {
+		   fprintf(f,
+			   "initial context token with delegation, %d extra bytes\n",
+			   i);
+		   fclose(f);
+	       }
+	   }
+#endif
+       } else {
+#ifdef CFX_EXERCISE
+	   {
+	       FILE *f = fopen("/tmp/gsslog", "a");
+	       if (f) {
+		   if (gss_flags & GSS_C_DELEG_FLAG)
+		       fprintf(f,
+			       "initial context token, delegation flag but too small\n");
+		   else
+		       /* no deleg flag, length might still be too big */
+		       fprintf(f,
+			       "initial context token, %d extra bytes\n",
+			       authdat->checksum->length - 24);
+		   fclose(f);
+	       }
+	   }
+#endif
+       }
    }
 
    /* create the ctx struct and start filling it in */
@@ -568,7 +611,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    ctx->mech_used = (gss_OID) mech_used;
    ctx->auth_context = auth_context;
    ctx->initiate = 0;
-   ctx->gss_flags = KG_IMPLFLAGS(gss_flags);
+   ctx->gss_flags = (GSS_C_TRANS_FLAG |
+                    ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
+                            GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+                            GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
    ctx->seed_init = 0;
    ctx->big_endian = bigend;
 
@@ -592,8 +638,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        goto fail;
    }
 
-   if ((code = krb5_auth_con_getremotesubkey(context, auth_context,
-					     &ctx->subkey))) { 
+   if ((code = krb5_auth_con_getrecvsubkey(context, auth_context,
+					   &ctx->subkey))) { 
        major_status = GSS_S_FAILURE;      
        goto fail;
    }
@@ -616,6 +662,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        goto fail;
    }
 
+   ctx->proto = 0;
    switch(ctx->subkey->enctype) {
    case ENCTYPE_DES_CBC_MD5:
    case ENCTYPE_DES_CBC_CRC:
@@ -635,12 +682,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 	   /*SUPPRESS 113*/
 	   ctx->enc->contents[i] ^= 0xf0;
 
-       if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
-	   major_status = GSS_S_FAILURE;
-	   goto fail;
-       }
-
-       break;
+       goto copy_subkey_to_seq;
 
    case ENCTYPE_DES3_CBC_SHA1:
        ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
@@ -649,36 +691,38 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        ctx->sealalg = SEAL_ALG_DES3KD;
 
        /* fill in the encryption descriptors */
-
+   copy_subkey:
        if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
 	   major_status = GSS_S_FAILURE;
 	   goto fail;
        }
-
+   copy_subkey_to_seq:
        if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
 	   major_status = GSS_S_FAILURE;
 	   goto fail;
        }
-
        break;
-	  case ENCTYPE_ARCFOUR_HMAC:
-	    ctx->signalg = SGN_ALG_HMAC_MD5 ;
-	    ctx->cksum_size = 8;
-	    ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
-
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
-	      if (code)
-		  goto fail;
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
-	      if (code) {
-		  krb5_free_keyblock (context, ctx->enc);
-		  goto fail;
-	      }
-	      break;	    
+
+   case ENCTYPE_ARCFOUR_HMAC:
+       ctx->signalg = SGN_ALG_HMAC_MD5 ;
+       ctx->cksum_size = 8;
+       ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+       goto copy_subkey;
 
    default:
-       code = KRB5_BAD_ENCTYPE;
-       goto fail;
+       ctx->signalg = -1;
+       ctx->sealalg = -1;
+       ctx->proto = 1;
+       code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
+					    &ctx->cksumtype);
+       if (code)
+	   goto fail;
+       code = krb5_c_checksum_length(context, ctx->cksumtype,
+				     &ctx->cksum_size);
+       if (code)
+	   goto fail;
+       ctx->have_acceptor_subkey = 0;
+       goto copy_subkey;
    }
 
    ctx->endtime = ticket->enc_part2->times.endtime;
@@ -686,7 +730,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 
    krb5_free_ticket(context, ticket); /* Done with ticket */
 
-   krb5_auth_con_getremoteseqnumber(context, auth_context, &ctx->seq_recv);
+   {
+       krb5_ui_4 seq_temp;
+       krb5_auth_con_getremoteseqnumber(context, auth_context, &seq_temp);
+       ctx->seq_recv = seq_temp;
+   }
 
    if ((code = krb5_timeofday(context, &now))) {
        major_status = GSS_S_FAILURE;
@@ -701,7 +749,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 
    g_order_init(&(ctx->seqstate), ctx->seq_recv,
 		(ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-		(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0);
+		(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
 
    /* at this point, the entire context structure is filled in, 
       so it can be released.  */
@@ -710,15 +758,56 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 
    if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
        unsigned char * ptr3;
+       krb5_ui_4 seq_temp;
+       int cfx_generate_subkey;
+
+       if (ctx->proto == 1)
+	   cfx_generate_subkey = CFX_ACCEPTOR_SUBKEY;
+       else
+	   cfx_generate_subkey = 0;
+
+       if (cfx_generate_subkey) {
+	   krb5_int32 acflags;
+	   code = krb5_auth_con_getflags(context, auth_context, &acflags);
+	   if (code == 0) {
+	       acflags |= KRB5_AUTH_CONTEXT_USE_SUBKEY;
+	       code = krb5_auth_con_setflags(context, auth_context, acflags);
+	   }
+	   if (code) {
+	       major_status = GSS_S_FAILURE;
+	       goto fail;
+	   }
+       }
+
        if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) {
 	   major_status = GSS_S_FAILURE;
 	   goto fail;
        }
 
-       krb5_auth_con_getlocalseqnumber(context, auth_context,
-				       &ctx->seq_send);
+       krb5_auth_con_getlocalseqnumber(context, auth_context, &seq_temp);
+       ctx->seq_send = seq_temp & 0xffffffffL;
+
+       if (cfx_generate_subkey) {
+	   /* Get the new acceptor subkey.  With the code above, there
+	      should always be one if we make it to this point.  */
+	   code = krb5_auth_con_getsendsubkey(context, auth_context,
+					      &ctx->acceptor_subkey);
+	   if (code != 0) {
+	       major_status = GSS_S_FAILURE;
+	       goto fail;
+	   }
+	   code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+						ctx->acceptor_subkey->enctype,
+						&ctx->acceptor_subkey_cksumtype);
+	   if (code) {
+	       major_status = GSS_S_FAILURE;
+	       goto fail;
+	   }
+	   ctx->have_acceptor_subkey = 1;
+       }
 
        /* the reply token hasn't been sent yet, but that's ok. */
+       ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
        ctx->established = 1;
 
        token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
@@ -803,7 +892,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    if (ap_rep.data)
        krb5_free_data_contents(context, &ap_rep);
 
-   if (!GSS_ERROR(major_status))
+   if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED)
        return(major_status);
 
    /* from here on is the real "fail" code */
@@ -843,7 +932,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        krb5_free_ap_req(context, request);
    }
 
-   if (cred && (gss_flags & GSS_C_MUTUAL_FLAG)) {
+   if (cred
+       && ((gss_flags & GSS_C_MUTUAL_FLAG)
+	   || (major_status == GSS_S_CONTINUE_NEEDED))) {
        unsigned int tmsglen;
        int toktype;
 
@@ -853,7 +944,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 	*/
        memset(&krb_error_data, 0, sizeof(krb_error_data));
 
-       code  -= ERROR_TABLE_BASE_krb5;
+       code -= ERROR_TABLE_BASE_krb5;
        if (code < 0 || code > 128)
 	   code = 60 /* KRB_ERR_GENERIC */;
 
@@ -861,7 +952,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
        (void) krb5_us_timeofday(context, &krb_error_data.stime,
 				&krb_error_data.susec);
        krb_error_data.server = cred->princ;
-	   
+
        code = krb5_mk_error(context, &krb_error_data, &scratch);
        if (code)
 	   return (major_status);
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 2c620b940..513abe552 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -92,7 +92,7 @@ krb5_gss_register_acceptor_identity(const char *keytab)
 	free(krb5_gss_keytab);
 
     len = strlen(keytab);
-    krb5_gss_keytab = malloc(len);
+    krb5_gss_keytab = malloc(len + 1);
     if (krb5_gss_keytab == NULL)
 	return GSS_S_FAILURE;
 
@@ -190,8 +190,13 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
 
    cred->ccache = NULL;
 
-   /* open the default credential cache */
+   /* load the GSS ccache name into the kg_context */
+   
+   if (GSS_ERROR(kg_sync_ccache_name(minor_status)))
+       return(GSS_S_FAILURE);
 
+   /* open the default credential cache */
+   
    if ((code = krb5int_cc_default(context, &ccache))) {
       *minor_status = code;
       return(GSS_S_CRED_UNAVAIL);
@@ -201,6 +206,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
 
    flags = 0;		/* turns off OPENCLOSE mode */
    if ((code = krb5_cc_set_flags(context, ccache, flags))) {
+      (void)krb5_cc_close(context, ccache);
       *minor_status = code;
       return(GSS_S_CRED_UNAVAIL);
    }
diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c
index 28c235890..94702b862 100644
--- a/src/lib/gssapi/krb5/delete_sec_context.c
+++ b/src/lib/gssapi/krb5/delete_sec_context.c
@@ -92,6 +92,8 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token)
       krb5_free_principal(context, ctx->there);
    if (ctx->subkey)
       krb5_free_keyblock(context, ctx->subkey);
+   if (ctx->acceptor_subkey)
+       krb5_free_keyblock(context, ctx->acceptor_subkey);
 
    if (ctx->auth_context) {
        (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL);
@@ -101,9 +103,6 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token)
    if (ctx->mech_used)
        gss_release_oid(minor_status, &ctx->mech_used);
    
-   if (ctx->ctypes)
-       xfree(ctx->ctypes);
-
    /* Zero out context */
    memset(ctx, 0, sizeof(*ctx));
    xfree(ctx);
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 325108612..514c82147 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -69,6 +69,9 @@
 #include "gssapi_krb5.h"
 #include "gssapi_err_krb5.h"
 
+/* for debugging */
+#undef CFX_EXERCISE
+
 /** constants **/
 
 #define CKSUMTYPE_KG_CB		0x8003
@@ -82,11 +85,6 @@
 #define	KG_TOK_WRAP_MSG		0x0201
 #define KG_TOK_DEL_CTX		0x0102
 
-#define KG_IMPLFLAGS(x) (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | \
-			 GSS_C_TRANS_FLAG | GSS_C_PROT_READY_FLAG | \
-			 ((x) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \
-				 GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)))
-
 #define KG2_TOK_INITIAL		0x0101
 #define KG2_TOK_RESPONSE	0x0202
 #define KG2_TOK_MIC		0x0303
@@ -116,10 +114,17 @@ enum seal_alg {
   SEAL_ALG_DES3KD          = 0x0002
 };
 
+/* for 3DES */
 #define KG_USAGE_SEAL 22
 #define KG_USAGE_SIGN 23
 #define KG_USAGE_SEQ  24
 
+/* for draft-ietf-krb-wg-gssapi-cfx-01 */
+#define KG_USAGE_ACCEPTOR_SEAL	22
+#define KG_USAGE_ACCEPTOR_SIGN	23
+#define KG_USAGE_INITIATOR_SEAL	24
+#define KG_USAGE_INITIATOR_SIGN	25
+
 enum qop {
   GSS_KRB5_INTEG_C_QOP_MD5       = 0x0001, /* *partial* MD5 = "MD2.5" */
   GSS_KRB5_INTEG_C_QOP_DES_MD5   = 0x0002,
@@ -152,15 +157,21 @@ typedef struct _krb5_gss_cred_id_rec {
 } krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; 
 
 typedef struct _krb5_gss_ctx_id_rec {
-   int initiate;	/* nonzero if initiating, zero if accepting */
+   unsigned int initiate : 1;	/* nonzero if initiating, zero if accepting */
+   unsigned int established : 1;
+   unsigned int big_endian : 1;
+   unsigned int have_acceptor_subkey : 1;
+   unsigned int seed_init : 1;	/* XXX tested but never actually set */
+#ifdef CFX_EXERCISE
+   unsigned int testing_unknown_tokid : 1; /* for testing only */
+#endif
    OM_uint32 gss_flags;
-   int seed_init;
    unsigned char seed[16];
    krb5_principal here;
    krb5_principal there;
    krb5_keyblock *subkey;
    int signalg;
-   int cksum_size;
+   size_t cksum_size;
    int sealalg;
    krb5_keyblock *enc;
    krb5_keyblock *seq;
@@ -169,15 +180,22 @@ typedef struct _krb5_gss_ctx_id_rec {
    /* XXX these used to be signed.  the old spec is inspecific, and
       the new spec specifies unsigned.  I don't believe that the change
       affects the wire encoding. */
-   krb5_ui_4 seq_send;
-   krb5_ui_4 seq_recv;
+   gssint_uint64 seq_send;
+   gssint_uint64 seq_recv;
    void *seqstate;
-   int established;
-   int big_endian;
    krb5_auth_context auth_context;
    gss_OID_desc *mech_used;
-   int nctypes;
-   krb5_cksumtype *ctypes;
+    /* Protocol spec revision
+       0 => RFC 1964 with 3DES and RC4 enhancements
+       1 => draft-ietf-krb-wg-gssapi-cfx-01
+       No others defined so far.  */
+   int proto;
+   krb5_cksumtype cksumtype;	/* for "main" subkey */
+   krb5_keyblock *acceptor_subkey; /* CFX only */
+   krb5_cksumtype acceptor_subkey_cksumtype;
+#ifdef CFX_EXERCISE
+    gss_buffer_desc init_token;
+#endif
 } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
 
 extern void *kg_vdb;
@@ -202,8 +220,6 @@ OM_uint32 kg_get_defcred
 	(OM_uint32 *minor_status, 
 		   gss_cred_id_t *cred);
 
-OM_uint32 kg_release_defcred (OM_uint32 *minor_status);
-
 krb5_error_code kg_checksum_channel_bindings
          (krb5_context context, gss_channel_bindings_t cb,
 					     krb5_checksum *cksum,
@@ -290,7 +306,15 @@ krb5_error_code kg_ctx_internalize (krb5_context kcontext,
 
 OM_uint32 kg_get_context (OM_uint32 *minor_status,
 				    krb5_context *context);
-	
+
+OM_uint32 kg_sync_ccache_name (OM_uint32 *minor_status);
+
+OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, 
+                              const char **out_name);
+
+OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, 
+                              const char *name);
+
 /** declarations of internal name mechanism functions **/
 
 OM_uint32 krb5_gss_acquire_cred
@@ -589,4 +613,10 @@ gss_OID krb5_gss_convert_static_mech_oid
 (gss_OID oid
 	 );
 	
+krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context,
+					       krb5_gss_ctx_id_rec *,
+					       const gss_buffer_desc *,
+					       gss_buffer_t,
+					       int, int);
+
 #endif /* _GSSAPIP_KRB5_H_ */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index db6eabd5d..be750a749 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -125,13 +125,10 @@ const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1;
 const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2;
 
 void *kg_vdb = NULL;
+static char *kg_ccache_name = NULL;
 
 /** default credential support */
 
-/* default credentials */
-
-static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
-
 /*
  * init_sec_context() will explicitly re-acquire default credentials,
  * so handling the expiration/invalidation condition here isn't needed.
@@ -141,36 +138,18 @@ kg_get_defcred(minor_status, cred)
      OM_uint32 *minor_status;
      gss_cred_id_t *cred;
 {
-   if (defcred == GSS_C_NO_CREDENTIAL) {
-      OM_uint32 major;
-
-      if ((major = krb5_gss_acquire_cred(minor_status, 
-					 (gss_name_t) NULL, GSS_C_INDEFINITE, 
-					 GSS_C_NULL_OID_SET, GSS_C_INITIATE, 
-					 &defcred, NULL, NULL)) &&
-	  GSS_ERROR(major)) {
-	 defcred = GSS_C_NO_CREDENTIAL;
-	 return(major);
-      }
+    OM_uint32 major;
+    
+    if ((major = krb5_gss_acquire_cred(minor_status, 
+				      (gss_name_t) NULL, GSS_C_INDEFINITE, 
+				      GSS_C_NULL_OID_SET, GSS_C_INITIATE, 
+				      cred, NULL, NULL)) && GSS_ERROR(major)) {
+      return(major);
    }
-
-   *cred = defcred;
    *minor_status = 0;
    return(GSS_S_COMPLETE);
 }
 
-OM_uint32
-kg_release_defcred(minor_status)
-     OM_uint32 *minor_status;
-{
-   if (defcred == GSS_C_NO_CREDENTIAL) {
-      *minor_status = 0;
-      return(GSS_S_COMPLETE);
-   }
-
-   return(krb5_gss_release_cred(minor_status, &defcred));
-}
-
 OM_uint32
 kg_get_context(minor_status, context)
    OM_uint32 *minor_status;
@@ -203,3 +182,103 @@ fail:
    *minor_status = (OM_uint32) code;
    return GSS_S_FAILURE;
 }
+
+OM_uint32
+kg_sync_ccache_name (OM_uint32 *minor_status)
+{
+    krb5_context context = NULL;
+    OM_uint32 err = 0;
+    OM_uint32 minor;
+    
+    /* 
+     * Sync up the kg_context ccache name with the GSSAPI ccache name.
+     * If kg_ccache_name is NULL -- normal unless someone has called 
+     * gss_krb5_ccache_name() -- then the system default ccache will 
+     * be picked up and used by resetting the context default ccache.
+     * This is needed for platforms which support multiple ccaches.
+     */
+    
+    if (!err) {
+        if (GSS_ERROR(kg_get_context (&minor, &context))) {
+            err = minor;
+        }
+    }
+    
+    if (!err) {
+        /* kg_ccache_name == NULL resets the context default ccache */
+        err = krb5_cc_set_default_name(context, kg_ccache_name);
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
+OM_uint32
+kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
+{
+    krb5_context context = NULL;
+    const char *name = NULL;
+    OM_uint32 err = 0;
+    OM_uint32 minor;
+    
+    if (!err) {
+        if (GSS_ERROR(kg_get_context (&minor, &context))) {
+            err = minor;
+        }
+    }
+    
+    if (!err) {
+        if (kg_ccache_name != NULL) {
+            name = kg_ccache_name;
+        } else {
+            /* reset the context default ccache (see text above) */
+            err = krb5_cc_set_default_name (context, NULL);
+            if (!err) {
+                name = krb5_cc_default_name(context);
+            }
+        }
+    }
+
+    if (!err) {
+        if (out_name) {
+            *out_name = name;
+        }
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
+OM_uint32
+kg_set_ccache_name (OM_uint32 *minor_status, const char *name)
+{
+    char *new_name = NULL;
+    OM_uint32 err = 0;
+    
+    if (!err) {
+        if (name) {
+            new_name = malloc(strlen(name) + 1);
+            if (new_name == NULL) {
+                err = ENOMEM;
+            } else {
+                strcpy(new_name, name);
+            }
+        }
+    }
+    
+    if (!err) {
+        char *swap = NULL;
+        
+        swap = kg_ccache_name;
+        kg_ccache_name = new_name;
+        new_name = swap;
+    }
+    
+    if (new_name != NULL) {
+        free (new_name);
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
index c142802e4..3007a0fd8 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.h
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -31,7 +31,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#if GSS_RFC_COMPLIANT_OIDS
 /* Reserved static storage for GSS_oids.  See rfc 1964 for more details. */
 
 /* 2.1.1. Kerberos Principal Name Form: */
@@ -71,8 +70,6 @@ GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME;
  * generic(1) string_uid_name(3)}.  The recommended symbolic name for
  * this type is "GSS_KRB5_NT_STRING_UID_NAME". */ 
 
-#endif /* GSS_RFC_COMPLIANT_OIDS */
-
 extern const gss_OID_desc * const gss_mech_krb5;
 extern const gss_OID_desc * const gss_mech_krb5_old;
 extern const gss_OID_set_desc * const gss_mech_set_krb5;
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 8877052ba..544316e0a 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -70,6 +70,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include "k5-int.h"
 #include "gssapiP_krb5.h"
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
@@ -90,13 +91,12 @@ int krb5_gss_dbg_client_expcreds = 0;
  * ccache.
  */
 static krb5_error_code get_credentials(context, cred, server, now,
-				       endtime, enctypes, out_creds)
+				       endtime, out_creds)
     krb5_context context;
     krb5_gss_cred_id_t cred;
     krb5_principal server;
     krb5_timestamp now;
     krb5_timestamp endtime;
-    const krb5_enctype *enctypes;
     krb5_creds **out_creds;
 {
     krb5_error_code	code;
@@ -112,10 +112,7 @@ static krb5_error_code get_credentials(context, cred, server, now,
 
     in_creds.keyblock.enctype = 0;
 
-    code = krb5_set_default_tgs_enctypes (context, enctypes);
-    if (code)
-      goto cleanup;
-        code = krb5_get_credentials(context, 0, cred->ccache,
+    code = krb5_get_credentials(context, 0, cred->ccache,
 				&in_creds, out_creds);
     if (code)
 	goto cleanup;
@@ -145,6 +142,9 @@ struct gss_checksum_data {
     krb5_data checksum_data;
 };
 
+#ifdef CFX_EXERCISE
+#include "../../krb5/krb/auth_con.h"
+#endif
 static krb5_error_code KRB5_CALLCONV
 make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
 		   void *cksum_data, krb5_data **out)
@@ -154,6 +154,8 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
     unsigned char *ptr;
     struct gss_checksum_data *data = cksum_data;
     krb5_data credmsg;
+    int junk;
+
     data->checksum_data.data = 0;
     credmsg.data = 0;
     /* build the checksum field */
@@ -191,6 +193,21 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
     } else {
 	data->checksum_data.length = 24;
     }
+#ifdef CFX_EXERCISE
+    if (data->ctx->auth_context->keyblock != NULL
+	&& data->ctx->auth_context->keyblock->enctype == 18) {
+	srand(time(0) ^ getpid());
+	/* Our ftp client code stupidly assumes a base64-encoded
+	   version of the token will fit in 10K, so don't make this
+	   too big.  */
+	junk = rand() & 0xff;
+    } else
+	junk = 0;
+#else
+    junk = 0;
+#endif
+
+    data->checksum_data.length += junk;
 
     /* now allocate a buffer to hold the checksum data and
        (maybe) KRB_CRED msg */
@@ -219,6 +236,8 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
 	/* free credmsg data */
 	krb5_free_data_contents(context, &credmsg);
     }
+    if (junk)
+	memset(ptr, 'i', junk);
     *out = &data->checksum_data;
     return 0;
 }
@@ -316,12 +335,529 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
    code = 0;
     
  cleanup:
+   if (checksum_data && checksum_data->data)
+       krb5_free_data_contents(context, checksum_data);
    if (ap_req.data)
        krb5_free_data_contents(context, &ap_req);
 
    return (code);
 }
 
+/*
+ * setup_enc
+ *
+ * Fill in the encryption descriptors.  Called after AP-REQ is made.
+ */
+static OM_uint32
+setup_enc(
+   OM_uint32 *minor_status,
+   krb5_gss_ctx_id_rec *ctx,
+   krb5_context context)
+{
+   krb5_error_code code;
+   int i;
+   krb5int_access kaccess;
+
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+   if (code)
+       goto fail;
+
+   ctx->have_acceptor_subkey = 0;
+   ctx->proto = 0;
+   ctx->cksumtype = 0;
+   switch(ctx->subkey->enctype) {
+   case ENCTYPE_DES_CBC_MD5:
+   case ENCTYPE_DES_CBC_MD4:
+   case ENCTYPE_DES_CBC_CRC:
+      ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+      ctx->signalg = SGN_ALG_DES_MAC_MD5;
+      ctx->cksum_size = 8;
+      ctx->sealalg = SEAL_ALG_DES;
+
+      /* The encryption key is the session key XOR
+	 0xf0f0f0f0f0f0f0f0.  */
+      if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+	 goto fail;
+
+      for (i=0; i<ctx->enc->length; i++)
+	 ctx->enc->contents[i] ^= 0xf0;
+
+      goto copy_subkey_to_seq;
+
+   case ENCTYPE_DES3_CBC_SHA1:
+       /* MIT extension */
+      ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+      ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+      ctx->cksum_size = 20;
+      ctx->sealalg = SEAL_ALG_DES3KD;
+
+   copy_subkey:
+      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+      if (code)
+	 goto fail;
+   copy_subkey_to_seq:
+      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+      if (code) {
+	 krb5_free_keyblock (context, ctx->enc);
+	 goto fail;
+      }
+      break;
+
+   case ENCTYPE_ARCFOUR_HMAC:
+       /* Microsoft extension */
+      ctx->signalg = SGN_ALG_HMAC_MD5 ;
+      ctx->cksum_size = 8;
+      ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+
+      goto copy_subkey;
+
+   default:
+       /* Fill some fields we shouldn't be using on this path
+	  with garbage.  */
+       ctx->signalg = -10;
+       ctx->sealalg = -10;
+
+       ctx->proto = 1;
+       code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
+					    &ctx->cksumtype);
+       if (code)
+	   goto fail;
+       code = krb5_c_checksum_length(context, ctx->cksumtype,
+				     &ctx->cksum_size);
+       if (code)
+	   goto fail;
+       goto copy_subkey;
+   }
+fail:
+   *minor_status = code;
+   return GSS_S_FAILURE;
+}
+
+/*
+ * new_connection
+ *
+ * Do the grunt work of setting up a new context.
+ */
+static OM_uint32
+new_connection(
+   OM_uint32 *minor_status,
+   krb5_gss_cred_id_t cred,
+   gss_ctx_id_t *context_handle,
+   gss_name_t target_name,
+   gss_OID mech_type,
+   OM_uint32 req_flags,
+   OM_uint32 time_req,
+   gss_channel_bindings_t input_chan_bindings,
+   gss_buffer_t input_token,
+   gss_OID *actual_mech_type,
+   gss_buffer_t output_token,
+   OM_uint32 *ret_flags,
+   OM_uint32 *time_rec,
+   krb5_context context,
+   int default_mech)
+{
+   OM_uint32 major_status;
+   krb5_error_code code;
+   krb5_creds *k_cred;
+   krb5_gss_ctx_id_rec *ctx, *ctx_free;
+   krb5_timestamp now;
+   gss_buffer_desc token;
+
+   major_status = GSS_S_FAILURE;
+   token.length = 0;
+   token.value = NULL;
+
+   /* make sure the cred is usable for init */
+
+   if ((cred->usage != GSS_C_INITIATE) &&
+       (cred->usage != GSS_C_BOTH)) {
+      *minor_status = 0;
+      return(GSS_S_NO_CRED);
+   }
+
+   /* complain if the input token is non-null */
+
+   if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
+#if 0 /* def CFX_EXERCISE */
+       if (*context_handle != GSS_C_NO_CONTEXT
+	   && ((krb5_gss_ctx_id_t)*context_handle)->testing_unknown_tokid) {
+	   /* XXX Should check for a KRB_ERROR message that we can
+	      parse, and which contains the expected error code.  */
+	   ctx = (krb5_gss_ctx_id_t)*context_handle;
+	   goto resume_after_testing;
+       }
+#endif
+       *minor_status = 0;
+       return(GSS_S_DEFECTIVE_TOKEN);
+   }
+
+   /* create the ctx */
+
+   if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+       == NULL) {
+      *minor_status = ENOMEM;
+      return(GSS_S_FAILURE);
+   }
+
+   /* fill in the ctx */
+   memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
+   ctx_free = ctx;
+   if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
+      goto fail;
+   krb5_auth_con_setflags(context, ctx->auth_context,
+			  KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+   ctx->initiate = 1;
+   ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
+                     GSS_C_TRANS_FLAG | 
+                     ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+                                     GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
+   ctx->seed_init = 0;
+   ctx->big_endian = 0;  /* all initiators do little-endian, as per spec */
+   ctx->seqstate = 0;
+
+   if ((code = krb5_timeofday(context, &now)))
+      goto fail;
+
+   if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
+      ctx->endtime = 0;
+   } else {
+      ctx->endtime = now + time_req;
+   }
+
+   if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
+      goto fail;
+      
+   if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
+				   &ctx->there)))
+      goto fail;
+
+   code = get_credentials(context, cred, ctx->there, now,
+			  ctx->endtime, &k_cred);
+   if (code)
+      goto fail;
+
+   if (default_mech) {
+      mech_type = (gss_OID) gss_mech_krb5;
+   }
+
+   if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
+       != GSS_S_COMPLETE) {
+      code = *minor_status;
+      goto fail;
+   }
+   /*
+    * Now try to make it static if at all possible....
+    */
+   ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
+
+   {
+      /* gsskrb5 v1 */
+      krb5_ui_4 seq_temp;
+      if ((code = make_ap_req_v1(context, ctx,
+				 cred, k_cred, input_chan_bindings, 
+				 mech_type, &token))) {
+	 if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
+	     (code == KG_EMPTY_CCACHE))
+	    major_status = GSS_S_NO_CRED;
+	 if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
+	    major_status = GSS_S_CREDENTIALS_EXPIRED;
+	 goto fail;
+      }
+
+      krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp);
+      ctx->seq_send = seq_temp;
+      krb5_auth_con_getsendsubkey(context, ctx->auth_context,
+				  &ctx->subkey);
+   }
+
+   major_status = setup_enc(minor_status, ctx, context);
+
+   if (k_cred) {
+      krb5_free_creds(context, k_cred);
+      k_cred = 0;
+   }
+      
+   /* at this point, the context is constructed and valid,
+      hence, releaseable */
+
+   /* intern the context handle */
+
+   if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+      code = G_VALIDATE_FAILED;
+      goto fail;
+   }
+   *context_handle = (gss_ctx_id_t) ctx;
+   ctx_free = 0;
+
+#if 0 /* Sigh.  We're changing the spec again.  */
+#ifdef CFX_EXERCISE
+   if (ctx->proto == 1
+       /* I think the RPC code may be broken.  Don't mess around
+	  if we're authenticating to "kadmin/whatever".  */
+       && ctx->there->data[0].data[0] != 'k'
+       /* I *know* the FTP server code is broken.  */
+       && ctx->there->data[0].data[0] != 'f'
+       ) {
+       /* Create a bogus token and return it, with status
+	  GSS_S_CONTINUE_NEEDED.  Save enough data that we can resume
+	  on the next call.  */
+       static const unsigned char hack_token[20] = {
+	   0x60, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+	   0xf7, 0x12, 0x01, 0x02, 0x02, 0x12, 0x34, 0x68,
+	   0x65, 0x6c, 0x6c, 0x6f
+       };
+       ctx->testing_unknown_tokid = 1;
+       ctx->init_token = token;
+       token.value = malloc(20);
+       token.length = 20;
+       if (token.value == NULL) {
+	   /* Skip testing.  We'll probably die soon enough, but let's
+	      not do it because we couldn't exercise this code
+	      path.  */
+	   goto resume_after_testing;
+       }
+       memcpy(token.value, hack_token, sizeof(hack_token));
+       /* Can just fall through into the normal return path, because
+	  it'll always return GSS_S_CONTINUE_NEEDED because we're
+	  doing mutual authentication.  */
+   }
+   if (0) {
+   resume_after_testing:
+       token = ctx->init_token;
+       ctx->init_token.value = 0;
+       ctx->init_token.length = 0;
+       ctx->testing_unknown_tokid = 0;
+       ctx_free = 0;
+   }
+#endif /* CFX_EXERCISE */
+#endif /* 0 */
+
+   /* compute time_rec */
+   if (time_rec) {
+      if ((code = krb5_timeofday(context, &now)))
+	 goto fail;
+      *time_rec = ctx->endtime - now;
+   }
+
+   /* set the other returns */
+   *output_token = token;
+
+   if (ret_flags)
+      *ret_flags = ctx->gss_flags;
+
+   if (actual_mech_type)
+      *actual_mech_type = mech_type;
+
+   /* return successfully */
+
+   *minor_status = 0;
+   if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
+      ctx->established = 0;
+      return(GSS_S_CONTINUE_NEEDED);
+   } else {
+      ctx->seq_recv = ctx->seq_send;
+      g_order_init(&(ctx->seqstate), ctx->seq_recv,
+		   (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, 
+		   (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
+      ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
+      ctx->established = 1;
+      return(GSS_S_COMPLETE);
+   }
+
+fail:
+   if (ctx_free) {
+       if (ctx_free->auth_context)
+	   krb5_auth_con_free(context, ctx_free->auth_context);
+       if (ctx_free->here)
+	   krb5_free_principal(context, ctx_free->here);
+       if (ctx_free->there)
+	   krb5_free_principal(context, ctx_free->there);
+       if (ctx_free->subkey)
+	   krb5_free_keyblock(context, ctx_free->subkey);
+       xfree(ctx_free);
+   } else
+	(void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+
+   *minor_status = code;
+   return (major_status);
+}
+
+/*
+ * mutual_auth
+ *
+ * Handle the reply from the acceptor, if we're doing mutual auth.
+ */
+static OM_uint32
+mutual_auth(
+   OM_uint32 *minor_status,
+   krb5_gss_cred_id_t cred,
+   gss_ctx_id_t *context_handle,
+   gss_name_t target_name,
+   gss_OID mech_type,
+   OM_uint32 req_flags,
+   OM_uint32 time_req,
+   gss_channel_bindings_t input_chan_bindings,
+   gss_buffer_t input_token,
+   gss_OID *actual_mech_type,
+   gss_buffer_t output_token,
+   OM_uint32 *ret_flags,
+   OM_uint32 *time_rec,
+   krb5_context context)
+{
+   OM_uint32 major_status;
+   unsigned char *ptr;
+   char *sptr;
+   krb5_data ap_rep;
+   krb5_ap_rep_enc_part *ap_rep_data;
+   krb5_timestamp now;
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_error *krb_error;
+   krb5_error_code code;
+   krb5int_access kaccess;
+
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+   if (code)
+       goto fail;
+
+   major_status = GSS_S_FAILURE;
+
+   /* validate the context handle */
+   /*SUPPRESS 29*/
+   if (! kg_validate_ctx_id(*context_handle)) {
+      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (gss_ctx_id_t) *context_handle;
+
+   /* make sure the context is non-established, and that certain
+      arguments are unchanged */
+
+   if ((ctx->established) ||
+       ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
+      code = KG_CONTEXT_ESTABLISHED;
+      goto fail;
+   }
+
+   if (! krb5_principal_compare(context, ctx->there, 
+				(krb5_principal) target_name)) {
+      (void)krb5_gss_delete_sec_context(minor_status, 
+					context_handle, NULL);
+      code = 0;
+      major_status = GSS_S_BAD_NAME;
+      goto fail;
+   }
+
+   /* verify the token and leave the AP_REP message in ap_rep */
+
+   if (input_token == GSS_C_NO_BUFFER) {
+      (void)krb5_gss_delete_sec_context(minor_status, 
+					context_handle, NULL);
+      code = 0;
+      major_status = GSS_S_DEFECTIVE_TOKEN;
+      goto fail;
+   }
+
+   ptr = (unsigned char *) input_token->value;
+
+   if (g_verify_token_header((gss_OID) ctx->mech_used,
+			     &(ap_rep.length),
+			     &ptr, KG_TOK_CTX_AP_REP,
+			     input_token->length, 1)) {
+      if (g_verify_token_header((gss_OID) ctx->mech_used,
+				&(ap_rep.length),
+				&ptr, KG_TOK_CTX_ERROR,
+				input_token->length, 1) == 0) {
+
+	 /* Handle a KRB_ERROR message from the server */
+
+	 sptr = (char *) ptr;           /* PC compiler bug */
+	 TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+		      
+	 code = krb5_rd_error(context, &ap_rep, &krb_error);
+	 if (code)
+	    goto fail;
+	 if (krb_error->error)
+	    code = krb_error->error + ERROR_TABLE_BASE_krb5;
+	 else
+	    code = 0;
+	 krb5_free_error(context, krb_error);
+	 goto fail;
+      } else {
+	 *minor_status = 0;
+	 return(GSS_S_DEFECTIVE_TOKEN);
+      }
+   }
+
+   sptr = (char *) ptr;                      /* PC compiler bug */
+   TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+   /* decode the ap_rep */
+   if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+			   &ap_rep_data))) {
+      /*
+       * XXX A hack for backwards compatiblity.
+       * To be removed in 1999 -- proven 
+       */
+      krb5_auth_con_setuseruserkey(context, ctx->auth_context,
+				   ctx->subkey);
+      if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+		       &ap_rep_data)))
+	 goto fail;
+   }
+
+   /* store away the sequence number */
+   ctx->seq_recv = ap_rep_data->seq_number;
+   g_order_init(&(ctx->seqstate), ctx->seq_recv,
+		(ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+		(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
+
+   if (ctx->proto == 1 && ap_rep_data->subkey) {
+       /* Keep acceptor's subkey.  */
+       ctx->have_acceptor_subkey = 1;
+       code = krb5_copy_keyblock(context, ap_rep_data->subkey,
+				 &ctx->acceptor_subkey);
+       if (code)
+	   goto fail;
+       code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+					    ctx->acceptor_subkey->enctype,
+					    &ctx->acceptor_subkey_cksumtype);
+       if (code)
+	   goto fail;
+   }
+
+   /* free the ap_rep_data */
+   krb5_free_ap_rep_enc_part(context, ap_rep_data);
+
+   /* set established */
+   ctx->established = 1;
+
+   /* set returns */
+
+   if (time_rec) {
+      if ((code = krb5_timeofday(context, &now)))
+	 goto fail;
+      *time_rec = ctx->endtime - now;
+   }
+
+   if (ret_flags)
+      *ret_flags = ctx->gss_flags;
+
+   if (actual_mech_type)
+      *actual_mech_type = mech_type;
+
+   /* success */
+
+   *minor_status = 0;
+   return GSS_S_COMPLETE;
+
+fail:
+   (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+
+   *minor_status = code;
+   return (major_status);
+}
+
 OM_uint32
 krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
 			  context_handle, target_name, mech_type,
@@ -344,25 +880,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
 {
    krb5_context context;
    krb5_gss_cred_id_t cred;
-   krb5_creds *k_cred = 0;
-   static const krb5_enctype wanted_enctypes[] = {
-#if 1
-     ENCTYPE_DES3_CBC_SHA1,
-#endif
-     ENCTYPE_ARCFOUR_HMAC,
-     ENCTYPE_DES_CBC_CRC,
-     ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
-   };
-#define N_WANTED_ENCTYPES (sizeof(wanted_enctypes)/sizeof(wanted_enctypes[0]))
-   krb5_enctype requested_enctypes[N_WANTED_ENCTYPES + 1];
-   krb5_enctype *default_enctypes = 0;
-   krb5_error_code code; 
-   krb5_gss_ctx_id_rec *ctx, *ctx_free;
-   krb5_timestamp now;
-   gss_buffer_desc token;
-   int i, j, k, err;
+   int err;
    int default_mech = 0;
    OM_uint32 major_status;
+   OM_uint32 tmp_min_stat;
 
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
@@ -374,35 +895,28 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
    output_token->value = NULL;
    if (actual_mech_type)
       *actual_mech_type = NULL;
-   token.value = 0;
-   ctx_free = 0;
+
+   /* verify that the target_name is valid and usable */
+
+   if (! kg_validate_name(target_name)) {
+      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
 
    /* verify the credential, or use the default */
    /*SUPPRESS 29*/
    if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
-      OM_uint32 major;
-
-      /*
-       * Release default cred prior to re-acquiring it, to notice when
-       * the ccache has changed.
-       */
-      major = kg_release_defcred(minor_status);
-      if (GSS_ERROR(major))
-	 return major;
-      if ((major = kg_get_defcred(minor_status, &claimant_cred_handle)) &&
-	  GSS_ERROR(major)) {
-	 return(major);
+      major_status = kg_get_defcred(minor_status, &cred);
+      if (major_status && GSS_ERROR(major_status)) {
+	 return(major_status);
       }
    } else {
-      OM_uint32 major;
-	   
-      major = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
-      if (GSS_ERROR(major))
-	  return(major);
+      major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
+      if (GSS_ERROR(major_status))
+	  return(major_status);
+      cred = (krb5_gss_cred_id_t) claimant_cred_handle;
    }
 
-   cred = (krb5_gss_cred_id_t) claimant_cred_handle;
-
    /* verify the mech_type */
 
    err = 0;
@@ -426,414 +940,37 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
    }
    
    if (err) {
+      if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+	 krb5_gss_release_cred(minor_status, (gss_cred_id_t)cred);
       *minor_status = 0;
       return(GSS_S_BAD_MECH);
    }
 
-   /* verify that the target_name is valid and usable */
-
-   if (! kg_validate_name(target_name)) {
-      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
-   }
-
    /* is this a new connection or not? */
 
    /*SUPPRESS 29*/
-   if (*context_handle == GSS_C_NO_CONTEXT) {
-      /* make sure the cred is usable for init */
-
-      if ((cred->usage != GSS_C_INITIATE) &&
-	  (cred->usage != GSS_C_BOTH)) {
-	 *minor_status = 0;
-	 return(GSS_S_NO_CRED);
-      }
-
-      /* complain if the input token is non-null */
-
-      if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
-	 *minor_status = 0;
-	 return(GSS_S_DEFECTIVE_TOKEN);
-      }
-
-      /* create the ctx */
-
-      if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
-	  == NULL) {
-	 *minor_status = ENOMEM;
-	 return(GSS_S_FAILURE);
-      }
-
-      /* fill in the ctx */
-      memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
-      ctx_free = ctx;
-      if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
-	  goto fail;
-      krb5_auth_con_setflags(context, ctx->auth_context,
-			     KRB5_AUTH_CONTEXT_DO_SEQUENCE);
-      ctx->initiate = 1;
-      ctx->gss_flags = KG_IMPLFLAGS(req_flags);
-      ctx->seed_init = 0;
-      ctx->big_endian = 0;  /* all initiators do little-endian, as per spec */
-      ctx->seqstate = 0;
-      ctx->nctypes = 0;
-      ctx->ctypes = 0;
-
-      if ((code = krb5_timeofday(context, &now)))
-	  goto fail;
-
-      if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
-	 ctx->endtime = 0;
-      } else {
-	 ctx->endtime = now + time_req;
-      }
-
-      if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
-	  goto fail;
-      
-      if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
-				      &ctx->there)))
-	  goto fail;
-
-      code = krb5_get_tgs_ktypes (context, 0, &default_enctypes);
-      if (code)
-	  goto fail;
-      /* "i" denotes *next* slot to fill.  Don't forget to save room
-	 for a trailing zero.  */
-      i = 0;
-      for (j = 0;
-	   (default_enctypes[j] != 0
-	    /* This part should be redundant, but let's be paranoid.  */
-	    && i < N_WANTED_ENCTYPES);
-	   j++) {
-
-	  int is_duplicate_enctype;
-	  int is_wanted_enctype;
-
-	  krb5_enctype e = default_enctypes[j];
-
-	  /* Is this enctype one of the ones we want for GSSAPI?  */
-	  is_wanted_enctype = 0;
-	  for (k = 0; k < N_WANTED_ENCTYPES; k++) {
-	      if (wanted_enctypes[k] == e) {
-		  is_wanted_enctype = 1;
-		  break;
-	      }
-	  }
-	  /* If unwanted, go to the next one. */
-	  if (!is_wanted_enctype)
-	      continue;
-
-	  /* Is this enctype already in the list of enctypes to
-	     request?  (Is it a duplicate?)  */
-	  is_duplicate_enctype = 0;
-	  for (k = 0; k < i; k++) {
-	      if (requested_enctypes[k] == e) {
-		  is_duplicate_enctype = 1;
-		  break;
-	      }
-	  }
-	  /* If it is not a duplicate, add it. */
-	  if (!is_duplicate_enctype)
-	      requested_enctypes[i++] = e;
-      }
-      requested_enctypes[i++] = 0;
-
-      if ((code = get_credentials(context, cred, ctx->there, now,
-				  ctx->endtime, requested_enctypes, &k_cred)))
-	  goto fail;
-
-      if (default_mech) {
-	 mech_type = (gss_OID) gss_mech_krb5;
-      }
-
-      if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
-	  != GSS_S_COMPLETE) {
-	  code = *minor_status;
-	  goto fail;
-      }
-      /*
-       * Now try to make it static if at all possible....
-       */
-      ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
-
-      {
-	  /* gsskrb5 v1 */
-	  if ((code = make_ap_req_v1(context, ctx,
-				     cred, k_cred, input_chan_bindings, 
-				     mech_type, &token))) {
-	      if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
-		  (code == KG_EMPTY_CCACHE))
-		  major_status = GSS_S_NO_CRED;
-	      if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
-		  major_status = GSS_S_CREDENTIALS_EXPIRED;
-	      goto fail;
-	  }
-
-	  krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
-					  &ctx->seq_send);
-	  krb5_auth_con_getlocalsubkey(context, ctx->auth_context,
-				       &ctx->subkey);
-
-	  /* fill in the encryption descriptors */
-
-	  switch(ctx->subkey->enctype) {
-	  case ENCTYPE_DES_CBC_MD5:
-	  case ENCTYPE_DES_CBC_MD4:
-	  case ENCTYPE_DES_CBC_CRC:
-	      ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
-	      ctx->signalg = SGN_ALG_DES_MAC_MD5;
-	      ctx->cksum_size = 8;
-	      ctx->sealalg = SEAL_ALG_DES;
-
-	      /* The encryption key is the session key XOR
-		 0xf0f0f0f0f0f0f0f0.  */
-	      if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
-		  goto fail;
-
-	      for (i=0; i<ctx->enc->length; i++)
-		  /*SUPPRESS 113*/
-		  ctx->enc->contents[i] ^= 0xf0;
-
-	      if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
-		  goto fail;
-
-	      break;
-
-	  case ENCTYPE_DES3_CBC_SHA1:
-	      ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
-	      ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
-	      ctx->cksum_size = 20;
-	      ctx->sealalg = SEAL_ALG_DES3KD;
-
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
-	      if (code)
-		  goto fail;
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
-	      if (code) {
-		  krb5_free_keyblock (context, ctx->enc);
-		  goto fail;
-	      }
-	      break;
-	  case ENCTYPE_ARCFOUR_HMAC:
-	    ctx->signalg = SGN_ALG_HMAC_MD5 ;
-	    ctx->cksum_size = 8;
-	    ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
-
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
-	      if (code)
-		  goto fail;
-	      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
-	      if (code) {
-		  krb5_free_keyblock (context, ctx->enc);
-		  goto fail;
-	      }
-	      break;	    
-#if 0
-	  case ENCTYPE_DES3_CBC_MD5:
-	      enctype = ENCTYPE_DES3_CBC_RAW;
-	      ctx->signalg = 3;
-	      ctx->cksum_size = 16;
-	      ctx->sealalg = 1;
-	      break;
+   if (*context_handle == GSS_C_NO_CONTEXT
+#ifdef CFX_EXERCISE
+       || ((krb5_gss_ctx_id_t)*context_handle)->testing_unknown_tokid
 #endif
-	  default:
-	      *minor_status = KRB5_BAD_ENCTYPE;
-	      return GSS_S_FAILURE;
-	  }
-
-      }
-
-      if (k_cred) {
-          krb5_free_creds(context, k_cred);
-	  k_cred = 0;
-      }
-      
-      /* at this point, the context is constructed and valid,
-	 hence, releaseable */
-
-      /* intern the context handle */
-
-      if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
-	  code = G_VALIDATE_FAILED;
-	  goto fail;
-      }
-      *context_handle = (gss_ctx_id_t) ctx;
-      ctx_free = 0;
-
-      /* compute time_rec */
-      if (time_rec) {
-	 if ((code = krb5_timeofday(context, &now)))
-	     goto fail;
-	 *time_rec = ctx->endtime - now;
-      }
-
-      /* set the other returns */
-      *output_token = token;
-
-      if (ret_flags)
-	 *ret_flags = ctx->gss_flags;
-
-      if (actual_mech_type)
-	 *actual_mech_type = mech_type;
-
-      /* return successfully */
-
-      *minor_status = 0;
-      if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
-	 ctx->established = 0;
-	 return(GSS_S_CONTINUE_NEEDED);
-      } else {
-	 ctx->seq_recv = ctx->seq_send;
-	 g_order_init(&(ctx->seqstate), ctx->seq_recv,
-		      (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, 
-		      (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0);
-	 ctx->established = 1;
-	 /* fall through to GSS_S_COMPLETE */
-      }
+       ) {
+      major_status = new_connection(minor_status, cred, context_handle,
+				    target_name, mech_type, req_flags,
+				    time_req, input_chan_bindings,
+				    input_token, actual_mech_type,
+				    output_token, ret_flags, time_rec,
+				    context, default_mech);
    } else {
-      unsigned char *ptr;
-      char *sptr;
-      krb5_data ap_rep;
-      krb5_ap_rep_enc_part *ap_rep_data;
-      krb5_error *krb_error;
-
-      /* validate the context handle */
-      /*SUPPRESS 29*/
-      if (! kg_validate_ctx_id(*context_handle)) {
-	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	 return(GSS_S_NO_CONTEXT);
-      }
-
-      ctx = (gss_ctx_id_t) *context_handle;
-
-      /* make sure the context is non-established, and that certain
-	 arguments are unchanged */
-
-      if ((ctx->established) ||
-	  (((gss_cred_id_t) cred) != claimant_cred_handle) ||
-	  ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
-	  code = KG_CONTEXT_ESTABLISHED;
-	  goto fail;
-      }
-
-      if (! krb5_principal_compare(context, ctx->there, 
-				   (krb5_principal) target_name)) {
-	 (void)krb5_gss_delete_sec_context(minor_status, 
-					   context_handle, NULL);
-	 code = 0;
-	 major_status = GSS_S_BAD_NAME;
-	 goto fail;
-      }
-
-      /* verify the token and leave the AP_REP message in ap_rep */
-
-      if (input_token == GSS_C_NO_BUFFER) {
-	 (void)krb5_gss_delete_sec_context(minor_status, 
-					   context_handle, NULL);
-	 code = 0;
-	 major_status = GSS_S_DEFECTIVE_TOKEN;
-	 goto fail;
-      }
-
-      ptr = (unsigned char *) input_token->value;
-
-      if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
-				       &(ap_rep.length),
-				       &ptr, KG_TOK_CTX_AP_REP,
-				       input_token->length))) {
-	  if (g_verify_token_header((gss_OID) ctx->mech_used,
-				    &(ap_rep.length),
-				    &ptr, KG_TOK_CTX_ERROR,
-				    input_token->length) == 0) {
-
-	      /* Handle a KRB_ERROR message from the server */
-
-	      sptr = (char *) ptr;           /* PC compiler bug */
-	      TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-		      
-	      code = krb5_rd_error(context, &ap_rep, &krb_error);
-	      if (code)
-		  goto fail;
-	      if (krb_error->error)
-		  code = krb_error->error + ERROR_TABLE_BASE_krb5;
-	      else
-		  code = 0;
-	      krb5_free_error(context, krb_error);
-	      goto fail;
-	  } else {
-	      *minor_status = 0;
-	      return(GSS_S_DEFECTIVE_TOKEN);
-	  }
-      }
-
-      sptr = (char *) ptr;                      /* PC compiler bug */
-      TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
-      /* decode the ap_rep */
-      if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
-			      &ap_rep_data))) {
-	  /*
-	   * XXX A hack for backwards compatiblity.
-	   * To be removed in 1999 -- proven 
-	   */
-	  krb5_auth_con_setuseruserkey(context, ctx->auth_context,
-				       ctx->subkey);
-	  if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
-			   &ap_rep_data)))
-	      goto fail;
-      }
-
-      /* store away the sequence number */
-      ctx->seq_recv = ap_rep_data->seq_number;
-      g_order_init(&(ctx->seqstate), ctx->seq_recv,
-		   (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-		   (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0);
-
-      /* free the ap_rep_data */
-      krb5_free_ap_rep_enc_part(context, ap_rep_data);
-
-      /* set established */
-      ctx->established = 1;
-
-      /* set returns */
-
-      if (time_rec) {
-	 if ((code = krb5_timeofday(context, &now)))
-		 goto fail;
-	 *time_rec = ctx->endtime - now;
-      }
-
-      if (ret_flags)
-	 *ret_flags = ctx->gss_flags;
-
-      if (actual_mech_type)
-	 *actual_mech_type = mech_type;
-
-      /* success */
-
-      *minor_status = 0;
-      /* fall through to GSS_S_COMPLETE */
+      major_status = mutual_auth(minor_status, cred, context_handle,
+				 target_name, mech_type, req_flags,
+				 time_req, input_chan_bindings,
+				 input_token, actual_mech_type,
+				 output_token, ret_flags, time_rec,
+				 context);
    }
 
-   return(GSS_S_COMPLETE);
+   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+      krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t)cred);
 
-fail:
-   if (ctx_free) {
-       if (ctx_free->auth_context)
-	   krb5_auth_con_free(context, ctx_free->auth_context);
-       if (ctx_free->here)
-	   krb5_free_principal(context, ctx_free->here);
-       if (ctx_free->there)
-	   krb5_free_principal(context, ctx_free->there);
-       if (ctx_free->subkey)
-	   krb5_free_keyblock(context, ctx_free->subkey);
-       if (ctx_free->ctypes)
-	   krb5_free_cksumtypes(context, ctx_free->ctypes);
-       xfree(ctx_free);
-   } else
-	(void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
-
-   *minor_status = code;
-   return (major_status);
+   return(major_status);
 }
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index a79034d9e..83782162b 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -91,6 +91,8 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
    gss_OID_set mechs;
    OM_uint32 ret;
 
+   ret = GSS_S_FAILURE;
+
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
 
@@ -102,7 +104,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
    if (cred_handle == GSS_C_NO_CREDENTIAL) {
       OM_uint32 major;
 
-      if ((major = kg_get_defcred(minor_status, &cred_handle)) &&
+      if ((major = kg_get_defcred(minor_status, (gss_cred_id_t)&cred)) &&
 	  GSS_ERROR(major)) {
 	 return(major);
       }
@@ -112,13 +114,13 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
       major = krb5_gss_validate_cred(minor_status, cred_handle);
       if (GSS_ERROR(major))
 	  return(major);
+      cred = (krb5_gss_cred_id_t) cred_handle;
    }
 
-   cred = (krb5_gss_cred_id_t) cred_handle;
-
    if ((code = krb5_timeofday(context, &now))) {
       *minor_status = code;
-      return(GSS_S_FAILURE);
+      ret = GSS_S_FAILURE;
+      goto fail;
    }
 
    if (cred->tgt_expire > 0) {
@@ -132,7 +134,8 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
       if (cred->princ &&
 	  (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
 	 *minor_status = code;
-	 return(GSS_S_FAILURE);
+	 ret = GSS_S_FAILURE;
+	 goto fail;
       }
    }
 
@@ -149,7 +152,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
 							   &mechs)))) {
 	   krb5_free_principal(context, ret_name);
 	   /* *minor_status set above */
-	   return(ret);
+	   goto fail;
        }
    }
 
@@ -172,8 +175,18 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
    if (mechanisms)
       *mechanisms = mechs;
 
+   if (cred_handle == GSS_C_NO_CREDENTIAL)
+       krb5_gss_release_cred(minor_status, (gss_cred_id_t)cred);
+
    *minor_status = 0;
    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
+fail:
+   if (cred_handle == GSS_C_NO_CREDENTIAL) {
+       OM_uint32 tmp_min_stat;
+
+       krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t)cred);
+   }
+   return ret;
 }
 
 /* V2 interface */
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index 3c8702a55..7999a3e15 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -54,7 +54,7 @@ static krb5_error_code
 make_seal_token_v1 (krb5_context context,
 		    krb5_keyblock *enc,
 		    krb5_keyblock *seq,
-		    krb5_ui_4 *seqnum,
+		    gssint_uint64 *seqnum,
 		    int direction,
 		    gss_buffer_t text,
 		    gss_buffer_t token,
@@ -304,6 +304,7 @@ make_seal_token_v1 (krb5_context context,
     /* that's it.  return the token */
 
     (*seqnum)++;
+    *seqnum &= 0xffffffffL;
 
     token->length = tlen;
     token->value = (void *) t;
@@ -334,50 +335,16 @@ kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
     output_message_buffer->length = 0;
     output_message_buffer->value = NULL;
 
-    /* only default qop or matching established cryptosystem is allowed */
-    
-#if 0
-    switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) {
-    case GSS_C_QOP_DEFAULT:
-	break;
-    default:
-    unknown_qop:
-	*minor_status = (OM_uint32) G_UNKNOWN_QOP;
-	return GSS_S_FAILURE;
-    case GSS_KRB5_CONF_C_QOP_DES:
-	if (ctx->sealalg != SEAL_ALG_DES) {
-	bad_qop:
-	    *minor_status = (OM_uint32) G_BAD_QOP;
-	    return GSS_S_FAILURE;
-	}
-	break;
-    case GSS_KRB5_CONF_C_QOP_DES3:
-	if (ctx->sealalg != SEAL_ALG_DES3)
-	    goto bad_qop;
-	break;
-    }
-    switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) {
-    case GSS_C_QOP_DEFAULT:
-	break;
-    default:
-	goto unknown_qop;
-    case GSS_KRB5_INTEG_C_QOP_MD5:
-    case GSS_KRB5_INTEG_C_QOP_DES_MD5:
-    case GSS_KRB5_INTEG_C_QOP_DES_MAC:
-	if (ctx->sealalg != SEAL_ALG_DES)
-	    goto bad_qop;
-	break;
-    case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1:
-	if (ctx->sealalg != SEAL_ALG_DES3KD)
-	    goto bad_qop;
-	break;
-    }
-#else
+    /* Only default qop or matching established cryptosystem is allowed.
+
+       There are NO EXTENSIONS to this set for AES and friends!  The
+       new spec says "just use 0".  The old spec plus extensions would
+       actually allow for certain non-zero values.  Fix this to handle
+       them later.  */
     if (qop_req != 0) {
 	*minor_status = (OM_uint32) G_UNKNOWN_QOP;
 	return GSS_S_FAILURE;
     }
-#endif
 
     /* validate the context handle */
     if (! kg_validate_ctx_id(context_handle)) {
@@ -397,12 +364,26 @@ kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
 	return(GSS_S_FAILURE);
     }
 
-    code = make_seal_token_v1(context, ctx->enc, ctx->seq,
-			      &ctx->seq_send, ctx->initiate,
-			      input_message_buffer, output_message_buffer,
-			      ctx->signalg, ctx->cksum_size, ctx->sealalg,
-			      conf_req_flag, toktype, ctx->big_endian,
-			      ctx->mech_used);
+    switch (ctx->proto)
+    {
+    case 0:
+	code = make_seal_token_v1(context, ctx->enc, ctx->seq,
+				  &ctx->seq_send, ctx->initiate,
+				  input_message_buffer, output_message_buffer,
+				  ctx->signalg, ctx->cksum_size, ctx->sealalg,
+				  conf_req_flag, toktype, ctx->big_endian,
+				  ctx->mech_used);
+	break;
+    case 1:
+	code = gss_krb5int_make_seal_token_v3(context, ctx,
+					      input_message_buffer,
+					      output_message_buffer,
+					      conf_req_flag, toktype);
+	break;
+    default:
+	code = G_UNKNOWN_QOP;	/* XXX */
+	break;
+    }
 
     if (code) {
 	*minor_status = code;
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
new file mode 100644
index 000000000..710c6f59d
--- /dev/null
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -0,0 +1,502 @@
+/*
+ * lib/gssapi/krb5/k5sealv3.c
+ *
+ * Copyright 2003,2004 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ */
+/* draft-ietf-krb-wg-gssapi-cfx-05 */
+
+#include <assert.h>
+#include "k5-platform.h" 	/* for 64-bit support */
+#include "k5-int.h"		/* for zap() */
+#include "gssapiP_krb5.h"
+#include <stdarg.h>
+
+static int
+rotate_left (void *ptr, size_t bufsiz, size_t rc)
+{
+    /* Optimize for receiving.  After some debugging is done, the MIT
+       implementation won't do any rotates on sending, and while
+       debugging, they'll be randomly chosen.
+
+       Return 1 for success, 0 for failure (ENOMEM).  */
+    void *tbuf;
+
+    if (bufsiz == 0)
+	return 1;
+    rc = rc % bufsiz;
+    if (rc == 0)
+	return 1;
+
+    tbuf = malloc(rc);
+    if (tbuf == 0)
+	return 0;
+    memcpy(tbuf, ptr, rc);
+    memmove(ptr, (char *)ptr + rc, bufsiz - rc);
+    memcpy((char *)ptr + bufsiz - rc, tbuf, rc);
+    free(tbuf);
+    return 1;
+}
+
+static const gss_buffer_desc empty_message = { 0, 0 };
+
+#define FLAG_SENDER_IS_ACCEPTOR	0x01
+#define FLAG_WRAP_CONFIDENTIAL	0x02
+#define FLAG_ACCEPTOR_SUBKEY	0x04
+
+krb5_error_code
+gss_krb5int_make_seal_token_v3 (krb5_context context,
+				krb5_gss_ctx_id_rec *ctx,
+				const gss_buffer_desc * message,
+				gss_buffer_t token,
+				int conf_req_flag, int toktype)
+{
+    size_t bufsize = 16;
+    unsigned char *outbuf = 0;
+    krb5_error_code err;
+    int key_usage;
+    unsigned char acceptor_flag;
+    const gss_buffer_desc *message2 = message;
+    size_t rrc, ec;
+    unsigned short tok_id;
+    krb5_checksum sum;
+    krb5_keyblock *key;
+
+    assert(toktype != KG_TOK_SEAL_MSG || ctx->enc != 0);
+    assert(ctx->big_endian == 0);
+
+    acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR;
+    key_usage = (toktype == KG_TOK_WRAP_MSG
+		 ? (ctx->initiate
+		    ? KG_USAGE_INITIATOR_SEAL
+		    : KG_USAGE_ACCEPTOR_SEAL)
+		 : (ctx->initiate
+		    ? KG_USAGE_INITIATOR_SIGN
+		    : KG_USAGE_ACCEPTOR_SIGN));
+    if (ctx->have_acceptor_subkey) {
+	key = ctx->acceptor_subkey;
+    } else {
+	key = ctx->enc;
+    }
+
+#ifdef CFX_EXERCISE
+    {
+	static int initialized = 0;
+	if (!initialized) {
+	    srand(time(0));
+	    initialized = 1;
+	}
+    }
+#endif
+
+    if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) {
+	krb5_data plain;
+	krb5_enc_data cipher;
+	size_t ec_max;
+
+	/* 300: Adds some slop.  */
+	if (SIZE_MAX - 300 < message->length)
+	    return ENOMEM;
+	ec_max = SIZE_MAX - message->length - 300;
+	if (ec_max > 0xffff)
+	    ec_max = 0xffff;
+#ifdef CFX_EXERCISE
+	/* For testing only.  For performance, always set ec = 0.  */
+	ec = ec_max & rand();
+#else
+	ec = 0;
+#endif
+	plain.length = message->length + 16 + ec;
+	plain.data = malloc(message->length + 16 + ec);
+	if (plain.data == NULL)
+	    return ENOMEM;
+
+	/* Get size of ciphertext.  */
+	bufsize = 16 + krb5_encrypt_size (plain.length, ctx->enc->enctype);
+	/* Allocate space for header plus encrypted data.  */
+	outbuf = malloc(bufsize);
+	if (outbuf == NULL) {
+	    free(plain.data);
+	    return ENOMEM;
+	}
+
+	/* TOK_ID */
+	store_16_be(0x0504, outbuf);
+	/* flags */
+	outbuf[2] = (acceptor_flag
+		     | (conf_req_flag ? FLAG_WRAP_CONFIDENTIAL : 0)
+		     | (ctx->have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0));
+	/* filler */
+	outbuf[3] = 0xff;
+	/* EC */
+	store_16_be(ec, outbuf+4);
+	/* RRC */
+	store_16_be(0, outbuf+6);
+	store_64_be(ctx->seq_send, outbuf+8);
+
+	memcpy(plain.data, message->value, message->length);
+	memset(plain.data + message->length, 'x', ec);
+	memcpy(plain.data + message->length + ec, outbuf, 16);
+
+	cipher.ciphertext.data = outbuf + 16;
+	cipher.ciphertext.length = bufsize - 16;
+	cipher.enctype = key->enctype;
+	err = krb5_c_encrypt(context, key, key_usage, 0, &plain, &cipher);
+	zap(plain.data, plain.length);
+	free(plain.data);
+	plain.data = 0;
+	if (err)
+	    goto error;
+
+	/* Now that we know we're returning a valid token....  */
+	ctx->seq_send++;
+
+#ifdef CFX_EXERCISE
+	rrc = rand() & 0xffff;
+	if (rotate_left(outbuf+16, bufsize-16,
+			(bufsize-16) - (rrc % (bufsize - 16))))
+	    store_16_be(rrc, outbuf+6);
+	/* If the rotate fails, don't worry about it.  */
+#endif
+    } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) {
+	krb5_data plain;
+
+	/* Here, message is the application-supplied data; message2 is
+	   what goes into the output token.  They may be the same, or
+	   message2 may be empty (for MIC).  */
+
+	tok_id = 0x0504;
+
+    wrap_with_checksum:
+	plain.length = message->length + 16;
+	plain.data = malloc(message->length + 16);
+	if (plain.data == NULL)
+	    return ENOMEM;
+
+	if (ctx->cksum_size > 0xffff)
+	    abort();
+
+	bufsize = 16 + message2->length + ctx->cksum_size;
+	outbuf = malloc(bufsize);
+	if (outbuf == NULL) {
+	    free(plain.data);
+	    plain.data = 0;
+	    err = ENOMEM;
+	    goto error;
+	}
+
+	/* TOK_ID */
+	store_16_be(tok_id, outbuf);
+	/* flags */
+	outbuf[2] = (acceptor_flag
+		     | (ctx->have_acceptor_subkey ? FLAG_ACCEPTOR_SUBKEY : 0));
+	/* filler */
+	outbuf[3] = 0xff;
+	if (toktype == KG_TOK_WRAP_MSG) {
+	    /* Use 0 for checksum calculation, substitute
+	       checksum length later.  */
+	    /* EC */
+	    store_16_be(0, outbuf+4);
+	    /* RRC */
+	    store_16_be(0, outbuf+6);
+	} else {
+	    /* MIC and DEL store 0xFF in EC and RRC.  */
+	    store_16_be(0xffff, outbuf+4);
+	    store_16_be(0xffff, outbuf+6);
+	}
+	store_64_be(ctx->seq_send, outbuf+8);
+
+	memcpy(plain.data, message->value, message->length);
+	memcpy(plain.data + message->length, outbuf, 16);
+
+	/* Fill in the output token -- data contents, if any, and
+	   space for the checksum.  */
+	if (message2->length)
+	    memcpy(outbuf + 16, message2->value, message2->length);
+
+	sum.contents = outbuf + 16 + message2->length;
+	sum.length = ctx->cksum_size;
+
+	err = krb5_c_make_checksum(context, ctx->cksumtype, key,
+				   key_usage, &plain, &sum);
+	zap(plain.data, plain.length);
+	free(plain.data);
+	plain.data = 0;
+	if (err) {
+	    zap(outbuf,bufsize);
+	    free(outbuf);
+	    goto error;
+	}
+	if (sum.length != ctx->cksum_size)
+	    abort();
+	memcpy(outbuf + 16 + message2->length, sum.contents, ctx->cksum_size);
+	krb5_free_checksum_contents(context, &sum);
+	sum.contents = 0;
+	/* Now that we know we're actually generating the token...  */
+	ctx->seq_send++;
+
+	if (toktype == KG_TOK_WRAP_MSG) {
+#ifdef CFX_EXERCISE
+	    rrc = rand() & 0xffff;
+	    /* If the rotate fails, don't worry about it.  */
+	    if (rotate_left(outbuf+16, bufsize-16,
+			    (bufsize-16) - (rrc % (bufsize - 16))))
+		store_16_be(rrc, outbuf+6);
+#endif
+	    /* Fix up EC field.  */
+	    store_16_be(ctx->cksum_size, outbuf+4);
+	} else {
+	    store_16_be(0xffff, outbuf+6);
+	}
+    } else if (toktype == KG_TOK_MIC_MSG) {
+	tok_id = 0x0404;
+	message2 = &empty_message;
+	goto wrap_with_checksum;
+    } else if (toktype == KG_TOK_DEL_CTX) {
+	tok_id = 0x0405;
+	message = message2 = &empty_message;
+	goto wrap_with_checksum;
+    } else
+	abort();
+
+    token->value = outbuf;
+    token->length = bufsize;
+    return 0;
+
+error:
+    free(outbuf);
+    token->value = NULL;
+    token->length = 0;
+    return err;
+}
+
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+   conf_state is only valid if SEAL. */
+
+OM_uint32
+gss_krb5int_unseal_token_v3(krb5_context *contextptr,
+			    OM_uint32 *minor_status,
+			    krb5_gss_ctx_id_rec *ctx,
+			    unsigned char *ptr, int bodysize,
+			    gss_buffer_t message_buffer,
+			    int *conf_state, int *qop_state, int toktype)
+{
+    krb5_context context = *contextptr;
+    krb5_data plain;
+    gssint_uint64 seqnum;
+    size_t ec, rrc;
+    int key_usage;
+    unsigned char acceptor_flag;
+    krb5_checksum sum;
+    krb5_error_code err;
+    krb5_boolean valid;
+    krb5_keyblock *key;
+
+    assert(toktype != KG_TOK_SEAL_MSG || ctx->enc != 0);
+    assert(ctx->big_endian == 0);
+    assert(ctx->proto == 1);
+
+    if (qop_state)
+	*qop_state = GSS_C_QOP_DEFAULT;
+
+    acceptor_flag = ctx->initiate ? FLAG_SENDER_IS_ACCEPTOR : 0;
+    key_usage = (toktype == KG_TOK_WRAP_MSG
+		 ? (!ctx->initiate
+		    ? KG_USAGE_INITIATOR_SEAL
+		    : KG_USAGE_ACCEPTOR_SEAL)
+		 : (!ctx->initiate
+		    ? KG_USAGE_INITIATOR_SIGN
+		    : KG_USAGE_ACCEPTOR_SIGN));
+
+    /* Oops.  I wrote this code assuming ptr would be at the start of
+       the token header.  */
+    ptr -= 2;
+    bodysize += 2;
+
+    if (bodysize < 16) {
+    defective:
+	*minor_status = 0;
+	return GSS_S_DEFECTIVE_TOKEN;
+    }
+    if ((ptr[2] & FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) {
+	*minor_status = G_BAD_DIRECTION;
+	return GSS_S_BAD_SIG;
+    }
+
+    /* Two things to note here.
+
+       First, we can't really enforce the use of the acceptor's subkey,
+       if we're the acceptor; the initiator may have sent messages
+       before getting the subkey.  We could probably enforce it if
+       we're the initiator.
+
+       Second, if someone tweaks the code to not set the flag telling
+       the krb5 library to generate a new subkey in the AP-REP
+       message, the MIT library may include a subkey anyways --
+       namely, a copy of the AP-REQ subkey, if it was provided.  So
+       the initiator may think we wanted a subkey, and set the flag,
+       even though we weren't trying to set the subkey.  The "other"
+       key, the one not asserted by the acceptor, will have the same
+       value in that case, though, so we can just ignore the flag.  */
+    if (ctx->have_acceptor_subkey && (ptr[2] & FLAG_ACCEPTOR_SUBKEY)) {
+	key = ctx->acceptor_subkey;
+    } else {
+	key = ctx->enc;
+    }
+
+    if (toktype == KG_TOK_WRAP_MSG) {
+	if (load_16_be(ptr) != 0x0504)
+	    goto defective;
+	if (ptr[3] != 0xff)
+	    goto defective;
+	ec = load_16_be(ptr+4);
+	rrc = load_16_be(ptr+6);
+	seqnum = load_64_be(ptr+8);
+	if (!rotate_left(ptr+16, bodysize-16, rrc)) {
+	no_mem:
+	    *minor_status = ENOMEM;
+	    return GSS_S_FAILURE;
+	}
+	if (ptr[2] & FLAG_WRAP_CONFIDENTIAL) {
+	    /* confidentiality */
+	    krb5_enc_data cipher;
+	    unsigned char *althdr;
+
+	    if (conf_state)
+		*conf_state = 1;
+	    /* Do we have no decrypt_size function?
+
+	       For all current cryptosystems, the ciphertext size will
+	       be larger than the plaintext size.  */
+	    cipher.enctype = key->enctype;
+	    cipher.ciphertext.length = bodysize - 16;
+	    cipher.ciphertext.data = ptr + 16;
+	    plain.length = bodysize - 16;
+	    plain.data = malloc(plain.length);
+	    if (plain.data == NULL)
+		goto no_mem;
+	    err = krb5_c_decrypt(context, key, key_usage, 0,
+				 &cipher, &plain);
+	    if (err) {
+		free(plain.data);
+		goto error;
+	    }
+	    /* Don't use bodysize here!  Use the fact that
+	       cipher.ciphertext.length has been adjusted to the
+	       correct length.  */
+	    althdr = plain.data + plain.length - 16;
+	    if (load_16_be(althdr) != 0x0504
+		|| althdr[2] != ptr[2]
+		|| althdr[3] != ptr[3]
+		|| memcmp(althdr+8, ptr+8, 8))
+		goto defective;
+	    message_buffer->value = plain.data;
+	    message_buffer->length = plain.length - ec - 16;
+	} else {
+	    /* no confidentiality */
+	    if (conf_state)
+		*conf_state = 0;
+	    if (ec + 16 < ec)
+		/* overflow check */
+		goto defective;
+	    if (ec + 16 > bodysize)
+		goto defective;
+	    /* We have: header | msg | cksum.
+	       We need cksum(msg | header).
+	       Rotate the first two.  */
+	    store_16_be(0, ptr+4);
+	    store_16_be(0, ptr+6);
+	    plain.length = bodysize-ec;
+	    plain.data = ptr;
+	    if (!rotate_left(ptr, bodysize-ec, 16))
+		goto no_mem;
+	    sum.length = ec;
+	    if (sum.length != ctx->cksum_size) {
+		*minor_status = 0;
+		return GSS_S_BAD_SIG;
+	    }
+	    sum.contents = ptr+bodysize-ec;
+	    sum.checksum_type = ctx->cksumtype;
+	    err = krb5_c_verify_checksum(context, key, key_usage,
+					 &plain, &sum, &valid);
+	    if (err)
+		goto error;
+	    if (!valid) {
+		*minor_status = 0;
+		return GSS_S_BAD_SIG;
+	    }
+	    message_buffer->length = plain.length - 16;
+	    message_buffer->value = malloc(message_buffer->length);
+	    if (message_buffer->value == NULL)
+		goto no_mem;
+	    memcpy(message_buffer->value, plain.data, message_buffer->length);
+	}
+	err = g_order_check(&ctx->seqstate, seqnum);
+	*minor_status = 0;
+	return err;
+    } else if (toktype == KG_TOK_MIC_MSG) {
+	/* wrap token, no confidentiality */
+	if (load_16_be(ptr) != 0x0404)
+	    goto defective;
+    verify_mic_1:
+	if (ptr[3] != 0xff)
+	    goto defective;
+	if (load_32_be(ptr+4) != 0xffffffffL)
+	    goto defective;
+	seqnum = load_64_be(ptr+8);
+	plain.length = message_buffer->length + 16;
+	plain.data = malloc(plain.length);
+	if (plain.data == NULL)
+	    goto no_mem;
+	if (message_buffer->length)
+	    memcpy(plain.data, message_buffer->value, message_buffer->length);
+	memcpy(plain.data + message_buffer->length, ptr, 16);
+	sum.length = bodysize - 16;
+	sum.contents = ptr + 16;
+	sum.checksum_type = ctx->cksumtype;
+	err = krb5_c_verify_checksum(context, key, key_usage,
+				     &plain, &sum, &valid);
+	if (err) {
+	error:
+	    free(plain.data);
+	    *minor_status = err;
+	    return GSS_S_BAD_SIG; /* XXX */
+	}
+	if (!valid) {
+	    free(plain.data);
+	    *minor_status = 0;
+	    return GSS_S_BAD_SIG;
+	}
+	err = g_order_check(&ctx->seqstate, seqnum);
+	*minor_status = 0;
+	return err;
+    } else if (toktype == KG_TOK_DEL_CTX) {
+	if (load_16_be(ptr) != 0x0405)
+	    goto defective;
+	message_buffer = &empty_message;
+	goto verify_mic_1;
+    } else {
+	goto defective;
+    }
+}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 347d6b852..6851352ee 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -224,6 +224,8 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 		return(GSS_S_FAILURE);
 	    }
 	    memcpy(token.value, plain+conflen, token.length);
+	} else {
+	    token.value = NULL;
 	}
     } else if (toktype == KG_TOK_SIGN_MSG) {
 	token = *message_buffer;
@@ -488,6 +490,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer,
     unsigned char *ptr;
     unsigned int bodysize;
     int err;
+    int toktype2;
 
     /* validate the context handle */
     if (! kg_validate_ctx_id(context_handle)) {
@@ -508,14 +511,38 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer,
 
     ptr = (unsigned char *) input_token_buffer->value;
 
-    if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
-				      &bodysize, &ptr, toktype,
-				      input_token_buffer->length))) {
-	return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
-			    message_buffer, conf_state, qop_state,
-			    toktype));
+    if (ctx->proto)
+	switch (toktype) {
+	case KG_TOK_SIGN_MSG:
+	    toktype2 = 0x0404;
+	    break;
+	case KG_TOK_SEAL_MSG:
+	    toktype2 = 0x0504;
+	    break;
+	case KG_TOK_DEL_CTX:
+	    toktype2 = 0x0405;
+	    break;
+	default:
+	    toktype2 = toktype;
+	    break;
+	}
+    else
+	toktype2 = toktype;
+    err = g_verify_token_header((gss_OID) ctx->mech_used,
+				&bodysize, &ptr, toktype2,
+				input_token_buffer->length,
+				!ctx->proto);
+    if (err) {
+	*minor_status = err;
+	return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    *minor_status = err;
-    return(GSS_S_DEFECTIVE_TOKEN);
+    if (ctx->proto == 0)
+	return kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
+			    message_buffer, conf_state, qop_state,
+			    toktype);
+    else
+	return gss_krb5int_unseal_token_v3(context, minor_status, ctx,
+					   ptr, bodysize, message_buffer,
+					   conf_state, qop_state, toktype);
 }
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
index 0d81399af..43d5ca1c2 100644
--- a/src/lib/gssapi/krb5/rel_cred.c
+++ b/src/lib/gssapi/krb5/rel_cred.c
@@ -34,8 +34,10 @@ krb5_gss_release_cred(minor_status, cred_handle)
    if (GSS_ERROR(kg_get_context(minor_status, &context)))
       return(GSS_S_FAILURE);
 
-   if (*cred_handle == GSS_C_NO_CREDENTIAL)
-      return(kg_release_defcred(minor_status));
+   if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+      *minor_status = 0;
+      return(GSS_S_COMPLETE);
+   }
 
    if (! kg_delete_cred_id(*cred_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 8ab9401c3..e0d0ee0af 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -51,14 +51,21 @@ kg_oid_externalize(kcontext, arg, buffer, lenremain)
     size_t		*lenremain;
 {
      gss_OID oid = (gss_OID) arg;
+     krb5_error_code err;
      
-     (void) krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
-     (void) krb5_ser_pack_int32((krb5_int32) oid->length,
-				buffer, lenremain);
-     (void) krb5_ser_pack_bytes((krb5_octet *) oid->elements,
-				oid->length, buffer, lenremain);
-     (void) krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
-     return 0;
+     err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
+     if (err)
+	 return err;
+     err = krb5_ser_pack_int32((krb5_int32) oid->length,
+			       buffer, lenremain);
+     if (err)
+	 return err;
+     err = krb5_ser_pack_bytes((krb5_octet *) oid->elements,
+			       oid->length, buffer, lenremain);
+     if (err)
+	 return err;
+     err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
+     return err;
 }
 
 static krb5_error_code
@@ -86,22 +93,35 @@ kg_oid_internalize(kcontext, argp, buffer, lenremain)
      oid = (gss_OID) malloc(sizeof(gss_OID_desc));
      if (oid == NULL)
 	  return ENOMEM;
-     (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
+	 free(oid);
+	 return EINVAL;
+     }
      oid->length = ibuf;
      oid->elements = malloc(ibuf);
      if (oid->elements == 0) {
 	     free(oid);
 	     return ENOMEM;
      }
-     (void) krb5_ser_unpack_bytes((krb5_octet *) oid->elements,
-				  oid->length, &bp, &remain);
+     if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements,
+			       oid->length, &bp, &remain)) {
+	 free(oid->elements);
+	 free(oid);
+	 return EINVAL;
+     }
      
      /* Read in and check our trailing magic number */
-     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
-	return (EINVAL);
+     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
+	 free(oid->elements);
+	 free(oid);
+	 return (EINVAL);
+     }
 
-     if (ibuf != KV5M_GSS_OID)
+     if (ibuf != KV5M_GSS_OID) {
+	 free(oid->elements);
+	 free(oid);
 	 return (EINVAL);
+     }
 
      *buffer = bp;
      *lenremain = remain;
@@ -140,10 +160,13 @@ kg_queue_externalize(kcontext, arg, buffer, lenremain)
     krb5_octet		**buffer;
     size_t		*lenremain;
 {
-     (void) krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
-     g_queue_externalize(arg, buffer, lenremain);
-     (void) krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
-     return 0;
+    krb5_error_code err;
+    err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
+    if (err == 0)
+	err = g_queue_externalize(arg, buffer, lenremain);
+    if (err == 0)
+	err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
+    return err;
 }
 
 static krb5_error_code
@@ -156,6 +179,7 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain)
      krb5_int32 ibuf;
      krb5_octet		*bp;
      size_t		remain;
+     krb5_error_code	err;
 
      bp = *buffer;
      remain = *lenremain;
@@ -167,14 +191,20 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain)
      if (ibuf != KV5M_GSS_QUEUE)
 	 return (EINVAL);
 
-     g_queue_internalize(argp, &bp, &remain);
+     err = g_queue_internalize(argp, &bp, &remain);
+     if (err)
+	  return err;
 
      /* Read in and check our trailing magic number */
-     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
-	return (EINVAL);
+     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
+	 g_order_free(argp);
+	 return (EINVAL);
+     }
 
-     if (ibuf != KV5M_GSS_QUEUE)
+     if (ibuf != KV5M_GSS_QUEUE) {
+	 g_order_free(argp);
 	 return (EINVAL);
+     }
 
      *buffer = bp;
      *lenremain = remain;
@@ -218,26 +248,38 @@ kg_ctx_size(kcontext, arg, sizep)
      * krb5_gss_ctx_id_rec requires:
      *	krb5_int32	for KG_CONTEXT
      *	krb5_int32	for initiate.
-     *	krb5_int32	for mutual.
+     *	krb5_int32	for established.
+     *	krb5_int32	for big_endian.
+     *	krb5_int32	for have_acceptor_subkey.
      *	krb5_int32	for seed_init.
+     *	krb5_int32	for gss_flags.
      *	sizeof(seed)	for seed
+     *	...		for here
+     *	...		for there
+     *	...		for subkey
      *  krb5_int32	for signalg.
      *  krb5_int32	for cksum_size.
      *  krb5_int32	for sealalg.
+     *	...		for enc
+     *	...		for seq
      *	krb5_int32	for endtime.
      *	krb5_int32	for flags.
-     *	krb5_int32	for seq_send.
-     *	krb5_int32	for seq_recv.
-     *	krb5_int32	for established.
-     *	krb5_int32	for big_endian.
-     *	krb5_int32	for nctypes.
+     *	krb5_int64	for seq_send.
+     *	krb5_int64	for seq_recv.
+     *	...		for seqstate
+     *	...		for auth_context
+     *	...		for mech_used
+     *	krb5_int32	for proto
+     *	krb5_int32	for cksumtype
+     *	...		for acceptor_subkey
+     *	krb5_int32	for acceptor_key_cksumtype
      *	krb5_int32	for trailer.
      */
     kret = EINVAL;
     if ((ctx = (krb5_gss_ctx_id_rec *) arg)) {
 	required = 16*sizeof(krb5_int32);
+	required += 2*sizeof(krb5_int64);
 	required += sizeof(ctx->seed);
-	required += ctx->nctypes*sizeof(krb5_int32);
 
 	kret = 0;
 	if (!kret && ctx->here)
@@ -283,6 +325,11 @@ kg_ctx_size(kcontext, arg, sizep)
 				    KV5M_AUTH_CONTEXT,
 				    (krb5_pointer) ctx->auth_context,
 				    &required);
+	if (!kret && ctx->acceptor_subkey)
+	    kret = krb5_size_opaque(kcontext,
+				    KV5M_KEYBLOCK,
+				    (krb5_pointer) ctx->acceptor_subkey,
+				    &required);
 	if (!kret)
 	    *sizep += required;
     }
@@ -304,7 +351,11 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
     size_t		required;
     krb5_octet		*bp;
     size_t		remain;
-    int			i;
+    krb5int_access kaccess;
+
+    kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    if (kret) 
+        return(kret);
 
     required = 0;
     bp = *buffer;
@@ -320,10 +371,16 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
 	    /* Now static data */
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate,
 				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags,
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->established,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey,
 				       &bp, &remain);
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init,
 				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags,
+				       &bp, &remain);
 	    (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed,
 				       sizeof(ctx->seed),
 				       &bp, &remain);
@@ -337,15 +394,9 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
 				       &bp, &remain);
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags,
 				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->seq_send,
+	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_send,
 				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->seq_recv,
-				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->established,
-				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
-				       &bp, &remain);
-	    (void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes,
+	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv,
 				       &bp, &remain);
 
 	    /* Now dynamic data */
@@ -395,15 +446,25 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
 					       (krb5_pointer) ctx->auth_context,
 					       &bp, &remain);
 
-	    for (i=0; i<ctx->nctypes; i++) {
-		if (!kret) {
-		    kret = krb5_ser_pack_int32((krb5_int32) ctx->ctypes[i],
+	    if (!kret)
+		kret = krb5_ser_pack_int32((krb5_int32) ctx->proto,
+					   &bp, &remain);
+	    if (!kret)
+		kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype,
+					   &bp, &remain);
+	    if (!kret && ctx->acceptor_subkey)
+		kret = krb5_externalize_opaque(kcontext,
+					       KV5M_KEYBLOCK,
+					       (krb5_pointer) ctx->acceptor_subkey,
 					       &bp, &remain);
-		}
-	    }
-	    
+	    if (!kret)
+		kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype,
+					   &bp, &remain);
+
+	    /* trailer */
+	    if (!kret)
+		kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
 	    if (!kret) {
-		(void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
 		*buffer = bp;
 		*lenremain = remain;
 	    }
@@ -427,7 +488,11 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
     krb5_int32		ibuf;
     krb5_octet		*bp;
     size_t		remain;
-    int			i;
+    krb5int_access kaccess;
+
+    kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    if (kret)
+        return(kret);
 
     bp = *buffer;
     remain = *lenremain;
@@ -439,7 +504,9 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
 	kret = ENOMEM;
 
 	/* Get a context */
-	if ((remain >= ((10*sizeof(krb5_int32))+sizeof(ctx->seed))) &&
+	if ((remain >= (16*sizeof(krb5_int32)
+			+ 2*sizeof(krb5_int64)
+			+ sizeof(ctx->seed))) &&
 	    (ctx = (krb5_gss_ctx_id_rec *)
 	     xmalloc(sizeof(krb5_gss_ctx_id_rec)))) {
 	    memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
@@ -448,9 +515,15 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
 	    ctx->initiate = (int) ibuf;
 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-	    ctx->gss_flags = (int) ibuf;
+	    ctx->established = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->big_endian = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->have_acceptor_subkey = (int) ibuf;
 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
 	    ctx->seed_init = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->gss_flags = (int) ibuf;
 	    (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed,
 					 sizeof(ctx->seed),
 					 &bp, &remain);
@@ -464,14 +537,12 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
 	    ctx->endtime = (krb5_timestamp) ibuf;
 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
 	    ctx->krb_flags = (krb5_flags) ibuf;
-	    (void) krb5_ser_unpack_int32(&ctx->seq_send, &bp, &remain);
-	    (void) krb5_ser_unpack_int32(&ctx->seq_recv, &bp, &remain);
-	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-	    ctx->established = (int) ibuf;
-	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-	    ctx->big_endian = (int) ibuf;
-	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-	    ctx->nctypes = (int) ibuf;
+	    (void) (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_send, &bp, &remain);
+	    kret = (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_recv, &bp, &remain);
+	    if (kret) {
+		free(ctx);
+		return kret;
+	    }
 
 	    if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp,
 					   &remain))) {
@@ -531,34 +602,36 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
 					       KV5M_AUTH_CONTEXT,
 				       (krb5_pointer *) &ctx->auth_context,
 					       &bp, &remain);
-		
-	    if (!kret) {
-		if (ctx->nctypes) {
-		    if ((ctx->ctypes = (krb5_cksumtype *)
-			 malloc(ctx->nctypes*sizeof(krb5_cksumtype))) == NULL){
-			kret = ENOMEM;
-		    }
-
-		    for (i=0; i<ctx->nctypes; i++) {
-			if (!kret) {
-			    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-			    ctx->ctypes[i] = (krb5_cksumtype) ibuf;
-			}
-		    }
-		}
+
+	    if (!kret)
+		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->proto = ibuf;
+	    if (!kret)
+		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->cksumtype = ibuf;
+	    if (!kret &&
+		(kret = krb5_internalize_opaque(kcontext,
+						KV5M_KEYBLOCK,
+						(krb5_pointer *) &ctx->acceptor_subkey,
+						&bp, &remain))) {
+		if (kret == EINVAL)
+		    kret = 0;
 	    }
+	    if (!kret)
+		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->acceptor_subkey_cksumtype = ibuf;
 
 	    /* Get trailer */
-	    if (!kret &&
-		!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
-		(ibuf == KG_CONTEXT)) {
+	    if (!kret)
+		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    if (!kret && ibuf != KG_CONTEXT)
+		kret = EINVAL;
+
+	    if (!kret) {
 		*buffer = bp;
 		*lenremain = remain;
 		*argp = (krb5_pointer) ctx;
-	    }
-	    else {
-		if (!kret && (ibuf != KG_CONTEXT))
-		    kret = EINVAL;
+	    } else {
 		if (ctx->seq)
 		    krb5_free_keyblock(kcontext, ctx->seq);
 		if (ctx->enc)
diff --git a/src/lib/gssapi/krb5/set_ccache.c b/src/lib/gssapi/krb5/set_ccache.c
index 9a612201b..9a6cdda70 100644
--- a/src/lib/gssapi/krb5/set_ccache.c
+++ b/src/lib/gssapi/krb5/set_ccache.c
@@ -36,36 +36,55 @@ gss_krb5_ccache_name(minor_status, name, out_name)
 	const char *name;
 	const char **out_name;
 {
-	krb5_context context;
-	krb5_error_code retval;
-	OM_uint32 foo_stat;
-	static char *oldname = NULL;
-	const char *tmpname = NULL;
+    static char *gss_out_name = NULL;
+    
+    char *old_name = NULL;
+    OM_uint32 err = 0;
+    OM_uint32 minor = 0;
 
-	if (GSS_ERROR(kg_get_context(minor_status, &context)))
-		return (GSS_S_FAILURE);
+    if (out_name) {
+        const char *tmp_name = NULL;
 
-	if (out_name) {
-		if (oldname != NULL)
-			free(oldname);
-		/*
-		 * Save copy of previous default ccname, since
-		 * cc_set_default_name will free it and we don't want
-		 * to hang on to a pointer to freed memory.
-		 */
-		tmpname = krb5_cc_default_name(context);
-		oldname = malloc(strlen(tmpname) + 1);
-		if (oldname == NULL)
-			return GSS_S_FAILURE;
-		strcpy(oldname, tmpname);
-		*out_name = oldname;
-	}
-
-	retval = krb5_cc_set_default_name(context, name);
-	if (retval) {
-		*minor_status = retval;
-		return GSS_S_FAILURE;
-	}
-	kg_release_defcred(&foo_stat);
-	return GSS_S_COMPLETE;
+        if (!err) {
+            if (GSS_ERROR(kg_get_ccache_name (&minor, &tmp_name))) {
+                err = minor;
+            }
+        }
+        
+        if (!err) {
+            old_name = malloc(strlen(tmp_name) + 1);
+            if (old_name == NULL) {
+                err = ENOMEM;
+            } else {
+                strcpy(old_name, tmp_name);
+            }
+        }
+        
+        if (!err) {
+            char *swap = NULL;
+            
+            swap = gss_out_name;
+            gss_out_name = old_name;
+            old_name = swap;
+        }            
+    }
+    
+    if (!err) {
+        if (GSS_ERROR(kg_set_ccache_name (&minor, name))) {
+            err = minor;
+        }
+    }
+    
+    if (!err) {
+        if (out_name) {
+            *out_name = gss_out_name;
+        }
+    }
+    
+    if (old_name != NULL) {
+        free (old_name);
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
 }
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index 43ccc6415..59bf30e4c 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -110,6 +110,32 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
 	return(GSS_S_NO_CONTEXT);
     }
 
+    if (ctx->proto == 1) {
+	/* No pseudo-ASN.1 wrapper overhead, so no sequence length and
+	   OID.  */
+	OM_uint32 sz = req_output_size;
+	/* Token header: 16 octets.  */
+	if (conf_req_flag) {
+	    while (sz > 0 && krb5_encrypt_size(sz, ctx->enc->enctype) + 16 > req_output_size)
+		sz--;
+	} else {
+	    if (sz < 16 + ctx->cksum_size)
+		sz = 0;
+	    else
+		sz -= (16 + ctx->cksum_size);
+	}
+
+	/* While testing only!  */
+	if (sz < 65536)
+	    sz = 0;
+	else
+	    sz -= 65535;
+
+	*max_input_size = sz;
+	*minor_status = 0;
+	return GSS_S_COMPLETE;
+    }
+
     /* Calculate the token size and subtract that from the output size */
     overhead = 7 + ctx->mech_used->length;
     data_size = req_output_size;
diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def
index 3a43be2ba..e951cb931 100644
--- a/src/lib/gssapi32.def
+++ b/src/lib/gssapi32.def
@@ -72,7 +72,14 @@ EXPORTS
 ;
 ; GSS-API variables
 ;
-	gss_nt_user_name	DATA
-	gss_nt_machine_uid_name	DATA
-	gss_nt_string_uid_name	DATA
-	gss_nt_service_name	DATA
+	gss_nt_user_name	           DATA
+	gss_nt_machine_uid_name	       DATA
+	gss_nt_string_uid_name	       DATA
+	gss_nt_service_name	           DATA
+    GSS_C_NT_USER_NAME             DATA
+    GSS_C_NT_MACHINE_UID_NAME      DATA
+    GSS_C_NT_STRING_UID_NAME       DATA
+    GSS_C_NT_HOSTBASED_SERVICE     DATA
+    GSS_C_NT_HOSTBASED_SERVICE_X   DATA
+    GSS_C_NT_ANONYMOUS             DATA
+    GSS_C_NT_EXPORT_NAME           DATA
diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog
index d663d7f9b..75cf06025 100644
--- a/src/lib/kadm5/ChangeLog
+++ b/src/lib/kadm5/ChangeLog
@@ -1,3 +1,23 @@
+2003-06-03  Tom Yu  <tlyu@mit.edu>
+
+	* alt_prof.c (krb5_read_realm_params): Don't bother reading in
+	realm_keysalts or realm_num_keysalts, as they're no longer used.
+
+2003-05-30  Ken Raeburn  <raeburn@mit.edu>
+
+	* alt_prof.c (kadm5_get_config_params): Change default max_life to
+	one day.
+
+2003-05-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* alt_prof.c (kadm5_get_config_params): Remove aes256 from the
+	default supported enctypes list for now.
+
+2003-04-18  Ken Raeburn  <raeburn@mit.edu>
+
+	* alt_prof.c (kadm5_get_config_params): Add aes256 to the default
+	supported enctypes list.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
 	* configure.in: Don't explicitly invoke AC_PROG_ARCHIVE,
diff --git a/src/lib/kadm5/Makefile.in b/src/lib/kadm5/Makefile.in
index 9546a6b22..50bdfb6f7 100644
--- a/src/lib/kadm5/Makefile.in
+++ b/src/lib/kadm5/Makefile.in
@@ -122,10 +122,11 @@ ovsec_glue.so ovsec_glue.po $(OUTPRE)ovsec_glue.$(OBJEXT): ovsec_glue.c $(BUILDT
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h
 misc_free.so misc_free.po $(OUTPRE)misc_free.$(OBJEXT): misc_free.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -133,11 +134,12 @@ misc_free.so misc_free.po $(OUTPRE)misc_free.$(OBJEXT): misc_free.c $(BUILDTOP)/
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  server_internal.h admin_internal.h adb.h $(DB_DEPS)
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h server_internal.h \
+  admin_internal.h adb.h $(DB_DEPS)
 kadm_rpc_xdr.so kadm_rpc_xdr.po $(OUTPRE)kadm_rpc_xdr.$(OBJEXT): kadm_rpc_xdr.c $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
   $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
@@ -145,11 +147,12 @@ kadm_rpc_xdr.so kadm_rpc_xdr.po $(OUTPRE)kadm_rpc_xdr.$(OBJEXT): kadm_rpc_xdr.c
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/admin_xdr.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
+  $(BUILDTOP)/include/kadm5/admin_xdr.h
 chpass_util.so chpass_util.po $(OUTPRE)chpass_util.$(OBJEXT): chpass_util.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -157,28 +160,29 @@ chpass_util.so chpass_util.po $(OUTPRE)chpass_util.$(OBJEXT): chpass_util.c $(BU
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  admin_internal.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h admin_internal.h
 alt_prof.so alt_prof.po $(OUTPRE)alt_prof.$(OBJEXT): alt_prof.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
-  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
-  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
-  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
-  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(SRCTOP)/include/krb5/adm_proto.h
+  $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
+  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
+  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
+  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h
 str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): str_conv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h admin_internal.h $(BUILDTOP)/include/kadm5/admin.h \
+  admin_internal.h $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
   $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
@@ -188,8 +192,8 @@ str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): str_conv.c $(SRCTOP)/includ
   $(SRCTOP)/include/krb5/adm_proto.h
 logger.so logger.po $(OUTPRE)logger.$(OBJEXT): logger.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/adm_proto.h \
-  $(SRCTOP)/include/syslog.h
+  $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h
 
diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c
index 758c8857d..659068bad 100644
--- a/src/lib/kadm5/alt_prof.c
+++ b/src/lib/kadm5/alt_prof.c
@@ -605,7 +605,7 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
 	 params.max_life = dtvalue;
 	 params.mask |= KADM5_CONFIG_MAX_LIFE;
     } else {
-	 params.max_life = 36000; /* 10 hours */
+	 params.max_life = 24 * 60 * 60; /* 1 day */
 	 params.mask |= KADM5_CONFIG_MAX_LIFE;
     }	 
 	    
@@ -702,7 +702,7 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
 	 if (aprofile)
 	      krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
 	 if (svalue == NULL)
-	      svalue = strdup("des3-hmac-sha1:normal des-cbc-crc:normal");
+	     svalue = strdup("des3-hmac-sha1:normal des-cbc-crc:normal");
 
 	 params.keysalts = NULL;
 	 params.num_keysalts = 0;
@@ -936,27 +936,8 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
 	krb5_xfree(svalue);
     }
 
-    /* Get the value for the supported enctype/salttype matrix */
-    /* XXX This is so that the kdc will search a different
-       enctype list than kadmind */
-    if (!kret) {
-	hierarchy[2] = "kdc_supported_enctypes";
-	kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
-	if (kret) {
-	    hierarchy[2] = "supported_enctypes";
-	    kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
-	}
-	if (!kret) {
-	    krb5_string_to_keysalts(svalue,
-				    ", \t",	/* Tuple separators	*/
-				    ":.-",	/* Key/salt separators	*/
-				    0,		/* No duplicates	*/
-				    &rparams->realm_keysalts,
-				    &rparams->realm_num_keysalts);
-	    krb5_xfree(svalue);
-	}
-	kret = 0;
-    }
+    rparams->realm_keysalts = NULL;
+    rparams->realm_num_keysalts = 0;
 
 cleanup:
     if (aprofile)
diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in
index daf317a8d..2f0949210 100644
--- a/src/lib/kadm5/clnt/Makefile.in
+++ b/src/lib/kadm5/clnt/Makefile.in
@@ -84,12 +84,12 @@ clnt_policy.so clnt_policy.po $(OUTPRE)clnt_policy.$(OBJEXT): clnt_policy.c $(BU
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
+  client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h
 client_rpc.so client_rpc.po $(OUTPRE)client_rpc.$(OBJEXT): client_rpc.c $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
   $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
@@ -98,10 +98,10 @@ client_rpc.so client_rpc.po $(OUTPRE)client_rpc.$(OBJEXT): client_rpc.c $(BUILDT
   $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h
 client_principal.so client_principal.po $(OUTPRE)client_principal.$(OBJEXT): client_principal.c \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -110,26 +110,27 @@ client_principal.so client_principal.po $(OUTPRE)client_principal.$(OBJEXT): cli
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
-  client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \
+  $(BUILDTOP)/include/kadm5/admin_internal.h
 client_init.so client_init.po $(OUTPRE)client_init.$(OBJEXT): client_init.c $(COM_ERR_DEPS) \
   $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
-  $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
-  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
-  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
-  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
-  client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \
-  $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
-  $(BUILDTOP)/include/gssrpc/auth_gssapi.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin.h \
+  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
+  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
+  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
+  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
+  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \
+  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/gssapi/gssapi.h \
+  $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/gssrpc/auth_gssapi.h
 clnt_privs.so clnt_privs.po $(OUTPRE)clnt_privs.$(OBJEXT): clnt_privs.c $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
   $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
@@ -137,12 +138,12 @@ clnt_privs.so clnt_privs.po $(OUTPRE)clnt_privs.$(OBJEXT): clnt_privs.c $(BUILDT
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
+  client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h
 clnt_chpass_util.so clnt_chpass_util.po $(OUTPRE)clnt_chpass_util.$(OBJEXT): clnt_chpass_util.c \
   $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
@@ -151,9 +152,9 @@ clnt_chpass_util.so clnt_chpass_util.po $(OUTPRE)clnt_chpass_util.$(OBJEXT): cln
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h client_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h
 
diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog
index 6d3e3de5b..eea698794 100644
--- a/src/lib/kadm5/srv/ChangeLog
+++ b/src/lib/kadm5/srv/ChangeLog
@@ -1,3 +1,19 @@
+2003-09-02  Alexandra Ellwood  <lxs@mit.edu>
+
+	* svr_principal.c: Added Apple password server support.
+
+2003-06-13  Tom Yu  <tlyu@mit.edu>
+
+	* server_kdb.c (kdb_init_hist): Force history principal's key to
+	be of the same enctype as the master key, as searches for it later
+	on explicitly specify the enctype.
+
+2003-04-01  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in: Remove $(SHLIB_DBLIB_DEPS) and related variables.
+	(SHLIB_EXPDEPS): Remove $(SHLIB_DBLIB_DEPS).
+	(SHLIB_EXPLIBS): Change $(DB_LIB) to $(KDB5_DB_LIB).
+
 2003-01-12  Ezra Peisach  <epeisach@bu.edu>
 
 	* svr_iters.c (kadm5_get_either): For POSIX_REGEXPS
diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in
index db61a8c57..d46216ccf 100644
--- a/src/lib/kadm5/srv/Makefile.in
+++ b/src/lib/kadm5/srv/Makefile.in
@@ -13,18 +13,14 @@ LIBMAJOR=5
 LIBMINOR=1
 STOBJLISTS=../OBJS.ST OBJS.ST
 
-SHLIB_DBLIB_DEPS = $(SHLIB_DBLIB-@DB_VERSION@)
-SHLIB_DBLIB-k5	 = $(TOPLIBD)/libdb$(SHLIBEXT)
-SHLIB_DBLIB-sys	 = 
-
 SHLIB_EXPDEPS=\
 	$(TOPLIBD)/libgssrpc$(SHLIBEXT) \
 	$(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \
-	$(TOPLIBD)/libkdb5$(SHLIBEXT) $(SHLIB_DBLIB_DEPS) \
+	$(TOPLIBD)/libkdb5$(SHLIBEXT) \
 	$(TOPLIBD)/libkrb5$(SHLIBEXT) \
 	$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
 	$(COM_ERR_DEPLIB)
-SHLIB_EXPLIBS =	-lgssrpc -lgssapi_krb5 -lkdb5 $(DB_LIB) \
+SHLIB_EXPLIBS =	-lgssrpc -lgssapi_krb5 -lkdb5 $(KDB5_DB_LIB) \
 		-lkrb5 -lk5crypto -lcom_err @GEN_LIB@
 SHLIB_DIRS=-L$(TOPLIBD)
 SHLIB_RDIRS=$(KRB5_LIBDIR)
@@ -113,11 +109,12 @@ svr_policy.so svr_policy.po $(OUTPRE)svr_policy.$(OBJEXT): svr_policy.c $(BUILDT
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/adb.h \
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
   $(BUILDTOP)/include/kadm5/admin_internal.h
 svr_principal.so svr_principal.po $(OUTPRE)svr_principal.$(OBJEXT): svr_principal.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
@@ -126,53 +123,56 @@ svr_principal.so svr_principal.po $(OUTPRE)svr_principal.$(OBJEXT): svr_principa
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/adb.h \
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
   $(BUILDTOP)/include/kadm5/admin_internal.h
 server_acl.so server_acl.po $(OUTPRE)server_acl.$(OBJEXT): server_acl.c $(SRCTOP)/include/syslog.h \
   $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
-  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
-  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
-  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
-  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \
-  $(DB_DEPS) $(SRCTOP)/include/krb5/adm_proto.h server_acl.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/server_internal.h \
+  $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
+  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
+  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
+  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/admin_internal.h \
+  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) $(SRCTOP)/include/krb5/adm_proto.h \
+  server_acl.h
 server_kdb.so server_kdb.po $(OUTPRE)server_kdb.$(OBJEXT): server_kdb.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
-  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
-  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
-  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
-  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \
-  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS)
-server_misc.so server_misc.po $(OUTPRE)server_misc.$(OBJEXT): server_misc.c $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/adb.h \
-  $(BUILDTOP)/include/gssrpc/types.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/xdr.h \
+  $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
   $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
   $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
   $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h
+  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \
+  $(DB_DEPS)
+server_misc.so server_misc.po $(OUTPRE)server_misc.$(OBJEXT): server_misc.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
+  $(BUILDTOP)/include/kadm5/adb.h $(BUILDTOP)/include/gssrpc/types.h \
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
+  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
+  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
+  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h
 server_init.so server_init.po $(OUTPRE)server_init.$(OBJEXT): server_init.c $(COM_ERR_DEPS) \
   $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
   $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/xdr.h \
@@ -181,12 +181,12 @@ server_init.so server_init.po $(OUTPRE)server_init.$(OBJEXT): server_init.c $(CO
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \
-  $(DB_DEPS)
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \
+  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS)
 server_dict.so server_dict.po $(OUTPRE)server_dict.$(OBJEXT): server_dict.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -194,13 +194,14 @@ server_dict.so server_dict.po $(OUTPRE)server_dict.$(OBJEXT): server_dict.c $(BU
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h \
-  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \
-  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS)
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h \
+  $(SRCTOP)/include/syslog.h $(BUILDTOP)/include/kadm5/server_internal.h \
+  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \
+  $(DB_DEPS)
 svr_iters.so svr_iters.po $(OUTPRE)svr_iters.$(OBJEXT): svr_iters.c $(BUILDTOP)/include/kadm5/admin.h \
   $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -208,11 +209,12 @@ svr_iters.so svr_iters.po $(OUTPRE)svr_iters.$(OBJEXT): svr_iters.c $(BUILDTOP)/
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/kadm5/kadm_err.h \
-  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
-  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
+  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
+  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/adb.h \
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \
   $(BUILDTOP)/include/kadm5/admin_internal.h
 svr_chpass_util.so svr_chpass_util.po $(OUTPRE)svr_chpass_util.$(OBJEXT): svr_chpass_util.c \
   $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
@@ -222,12 +224,12 @@ svr_chpass_util.so svr_chpass_util.po $(OUTPRE)svr_chpass_util.$(OBJEXT): svr_ch
   $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \
-  $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \
-  $(DB_DEPS)
+  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \
+  $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS)
 adb_xdr.so adb_xdr.po $(OUTPRE)adb_xdr.$(OBJEXT): adb_xdr.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \
   $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
@@ -235,46 +237,46 @@ adb_xdr.so adb_xdr.po $(OUTPRE)adb_xdr.$(OBJEXT): adb_xdr.c $(BUILDTOP)/include/
   $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
   $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/adb.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/admin_xdr.h \
-  $(BUILDTOP)/include/kadm5/kadm_rpc.h
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+  $(BUILDTOP)/include/kadm5/admin_xdr.h $(BUILDTOP)/include/kadm5/kadm_rpc.h
 adb_policy.so adb_policy.po $(OUTPRE)adb_policy.$(OBJEXT): adb_policy.c $(BUILDTOP)/include/kadm5/adb.h \
   $(BUILDTOP)/include/gssrpc/types.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/xdr.h \
-  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
-  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
-  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
+  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
+  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
+  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h
 adb_free.so adb_free.po $(OUTPRE)adb_free.$(OBJEXT): adb_free.c $(BUILDTOP)/include/kadm5/adb.h \
   $(BUILDTOP)/include/gssrpc/types.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/xdr.h \
-  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
-  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
-  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
+  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
+  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
+  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h
 adb_openclose.so adb_openclose.po $(OUTPRE)adb_openclose.$(OBJEXT): adb_openclose.c $(BUILDTOP)/include/kadm5/adb.h \
   $(BUILDTOP)/include/gssrpc/types.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \
-  $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/xdr.h \
-  $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \
-  $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \
-  $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \
-  $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \
-  $(BUILDTOP)/include/kadm5/chpass_util_strings.h
+  $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \
+  $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \
+  $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \
+  $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/svc_auth.h \
+  $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+  $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h
 
diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c
index 231fcb3ef..97d38c7b6 100644
--- a/src/lib/kadm5/srv/server_kdb.c
+++ b/src/lib/kadm5/srv/server_kdb.c
@@ -107,6 +107,7 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r)
     int	    ret = 0;
     char    *realm, *hist_name;
     krb5_key_data *key_data;
+    krb5_key_salt_tuple ks[1];
 
     if (r == NULL)  {
 	if ((ret = krb5_get_default_realm(handle->context, &realm)))
@@ -144,11 +145,13 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r)
 	   history principal, anyway. */
 
 	hist_kvno = 2;
-
-	ret = kadm5_create_principal(handle, &ent,
-				     (KADM5_PRINCIPAL | KADM5_MAX_LIFE |
-				      KADM5_ATTRIBUTES),
-				     "to-be-random");
+	ks[0].ks_enctype = handle->params.enctype;
+	ks[0].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
+	ret = kadm5_create_principal_3(handle, &ent,
+				       (KADM5_PRINCIPAL | KADM5_MAX_LIFE |
+					KADM5_ATTRIBUTES),
+				       1, ks,
+				       "to-be-random");
 	if (ret)
 	    goto done;
 
@@ -156,7 +159,8 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r)
 
 	hist_princ = NULL;
 
-	ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL);
+	ret = kadm5_randkey_principal_3(handle, ent.principal, 0, 1, ks,
+					NULL, NULL);
 
 	hist_princ = ent.principal;
 
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index c1b8bc59c..c567f8369 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -19,6 +19,9 @@ static char *rcsid = "$Header$";
 #include	"server_internal.h"
 #include	<stdarg.h>
 #include	<stdlib.h>
+#ifdef USE_PASSWORD_SERVER
+#include	<sys/wait.h>
+#endif
 
 extern	krb5_principal	    master_princ;
 extern	krb5_principal	    hist_princ;
@@ -1065,6 +1068,105 @@ static kadm5_ret_t add_to_history(krb5_context context,
 }
 #undef KADM_MOD
 
+#ifdef USE_PASSWORD_SERVER
+
+/* FIXME: don't use global variable for this */
+krb5_boolean use_password_server = 0;
+
+static krb5_boolean
+kadm5_use_password_server (void)
+{
+    return use_password_server;
+}
+
+void
+kadm5_set_use_password_server (void)
+{
+    use_password_server = 1;
+}
+
+/*
+ * kadm5_launch_task () runs a program (task_path) to synchronize the 
+ * Apple password server with the Kerberos database.  Password server
+ * programs can receive arguments on the command line (task_argv)
+ * and a block of data via stdin (data_buffer).
+ *
+ * Because a failure to communicate with the tool results in the
+ * password server falling out of sync with the database,
+ * kadm5_launch_task() always fails if it can't talk to the tool.
+ */
+
+static kadm5_ret_t
+kadm5_launch_task (krb5_context context,
+                   const char *task_path, char * const task_argv[],
+                   const char *data_buffer) 
+{
+    kadm5_ret_t ret = 0;
+    int data_pipe[2];
+    
+    if (data_buffer != NULL) {
+        ret = pipe (data_pipe);
+        if (ret) { ret = errno; }
+    }
+
+    if (!ret) {
+        pid_t pid = fork ();
+        if (pid == -1) {
+            ret = errno;
+        } else if (pid == 0) {
+            /* The child: */
+            
+            if (data_buffer != NULL) {
+                if (dup2 (data_pipe[0], STDIN_FILENO) == -1) {
+                    _exit (1);
+                }
+            } else {
+                close (data_pipe[0]);
+            }
+
+            close (data_pipe[1]);
+            
+            execv (task_path, task_argv);
+            
+            _exit (1); /* Fail if execv fails */
+        } else {
+            /* The parent: */
+            int status;
+                       
+            if (data_buffer != NULL) {
+                /* Write out the buffer to the child */
+                if (krb5_net_write (context, data_pipe[1],
+                                    data_buffer, strlen (data_buffer)) < 0) {
+                    /* kill the child to make sure waitpid() won't hang later */
+                    ret = errno;
+                    kill (pid, SIGKILL);
+                }
+            }
+
+            close (data_buffer[0]);
+            close (data_buffer[1]);
+
+            waitpid (pid, &status, 0);
+
+            if (!ret) {
+                if (WIFEXITED (status)) {
+                    /* child read password and exited.  Check the return value. */
+                    if ((WEXITSTATUS (status) != 0) && (WEXITSTATUS (status) != 252)) {
+                       ret = KRB5KDC_ERR_POLICY; /* password change rejected */
+                    }
+                } else {
+                    /* child read password but crashed or was killed */
+                    ret = KRB5KRB_ERR_GENERIC; /* FIXME: better error */
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+#endif
+
 kadm5_ret_t
 kadm5_chpass_principal(void *server_handle,
 			    krb5_principal principal, char *password)
@@ -1193,6 +1295,42 @@ kadm5_chpass_principal_3(void *server_handle,
 	kdb.pw_expiration = 0;
     }
 
+#ifdef USE_PASSWORD_SERVER
+    if (kadm5_use_password_server () &&
+        (krb5_princ_size (handle->context, principal) == 1)) {
+        krb5_data *princ = krb5_princ_component (handle->context, principal, 0);
+        const char *path = "/usr/sbin/mkpassdb";
+        char *argv[] = { "mkpassdb", "-setpassword", NULL, NULL };
+        char *pstring = NULL;
+        char pwbuf[256];
+        int pwlen = strlen (password);
+
+        if (pwlen > 254) pwlen = 254;
+        strncpy (pwbuf, password, pwlen);
+        pwbuf[pwlen] = '\n';
+        pwbuf[pwlen + 1] = '\0';
+
+        if (!ret) {
+            pstring = malloc ((princ->length + 1) * sizeof (char));
+            if (pstring == NULL) { ret = errno; }
+        }
+
+        if (!ret) {
+            memcpy (pstring, princ->data, princ->length);
+            pstring [princ->length] = '\0';
+            argv[2] = pstring;
+
+            ret = kadm5_launch_task (handle->context, path, argv, pwbuf);
+        }
+        
+        if (pstring != NULL)
+            free (pstring);
+        
+        if (ret)
+            goto done;
+    }
+#endif
+
     ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now);
     if (ret)
 	goto done;
diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog
index f4da36de4..d1cd62047 100644
--- a/src/lib/kadm5/unit-test/ChangeLog
+++ b/src/lib/kadm5/unit-test/ChangeLog
@@ -1,3 +1,26 @@
+2003-10-16  Tom Yu  <tlyu@mit.edu>
+
+	* api.1/lock.exp: Work around a race condition in the Solaris 9
+	pty implementation: output sent to a pty slave immediately before
+	last close/exit can get lost on the way to the master.  This is
+	Sun bug #4927647.  The workaround consists of changing the tests
+	to always make lock-test wait to read a character prior to
+	exiting, so any output prior to the "wait" directive will not get
+	lost.
+
+2003-06-02  Ken Raeburn  <raeburn@mit.edu>
+
+	* api.2/init-v2.exp (test117): Update lifetime expected for new
+	defaults.
+
+2003-05-21  Tom Yu  <tlyu@mit.edu>
+
+	* api.0/init.exp (test6, test7): Be slightly more lenient about
+	matching password prompt.
+
+	* api.2/init.exp (test6, test7): Be slightly more lenient about
+	matching password prompt.
+
 2003-01-07  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.ov: Deleted.
diff --git a/src/lib/kadm5/unit-test/api.0/init.exp b/src/lib/kadm5/unit-test/api.0/init.exp
index f232d23d0..d39ecce07 100644
--- a/src/lib/kadm5/unit-test/api.0/init.exp
+++ b/src/lib/kadm5/unit-test/api.0/init.exp
@@ -77,7 +77,7 @@ proc test6 {} {
     send "ovsec_kadm_init admin null \$OVSEC_KADM_ADMIN_SERVICE null \$OVSEC_KADM_STRUCT_VERSION \$OVSEC_KADM_API_VERSION_1 server_handle\n"
 
     expect {
-	{Enter password:} { }
+	-re "assword\[^\r\n\]*: *" { }
 	eof {
 		fail "$test: eof instead of password prompt"
 		api_exit
@@ -103,7 +103,7 @@ proc test7 {} {
     send "ovsec_kadm_init admin \"\" \$OVSEC_KADM_ADMIN_SERVICE null \$OVSEC_KADM_STRUCT_VERSION \$OVSEC_KADM_API_VERSION_1 server_handle\n"
 
     expect {
-	{Enter password:} { }
+	-re "assword\[^\r\n\]*: *" { }
 	-re "\n\[^\n\]+key:\[^\n\]*$" { }
 	eof {
 		fail "$test: eof instead of password prompt"
diff --git a/src/lib/kadm5/unit-test/api.1/lock.exp b/src/lib/kadm5/unit-test/api.1/lock.exp
index e61a28f8d..6adef5981 100644
--- a/src/lib/kadm5/unit-test/api.1/lock.exp
+++ b/src/lib/kadm5/unit-test/api.1/lock.exp
@@ -137,60 +137,78 @@ proc lock_test_continue {test my_spawn_id test_failed fail_output cont cmds} {
     return {}
 }
 
-lock_test 1 [list \
+set lock1 [lock_test_start 1 [list \
 	[list shared	"shared"] \
 	[list release	"released"] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock1
 
-lock_test 2 [list \
+set lock2 [lock_test_start 2 [list \
 	[list exclusive	exclusive] \
 	[list release	released] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock2
 
-lock_test 3 [list \
+set lock3 [lock_test_start 5 [list \
 	[list permanent	permanent] \
 	[list release	released] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock3
 
-lock_test 4 [list \
+set lock4 [lock_test_start 4 [list \
 	[list release	"Database not locked"] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock4
 
 set lock5 [lock_test_start 5 [list \
 	[list shared	shared] \
 	[list wait	""] \
 	[list eof	0]]]
-lock_test 5.1 [list \
+set lock5_1 [lock_test_start 5.1 [list \
 	[list shared	shared] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock5_1
 eval lock_test_continue $lock5
 
 set lock6 [lock_test_start 6 [list \
 	[list exclusive exclusive] \
 	[list wait	""] \
 	[list eof	0]]]
-lock_test 6.1 [list \
+set lock6_1 [lock_test_start 6.1 [list \
 	[list shared	"Cannot lock database"] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock6_1
 eval lock_test_continue $lock6
 
 set lock7 [lock_test_start 7 [list \
 	[list shared	shared] \
 	[list wait	""] \
 	[list eof	0]]]
-lock_test 7.1 [list \
+set lock7_1 [lock_test_start 7.1 [list \
 	[list exclusive	"Cannot lock database"] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock7_1
 eval lock_test_continue $lock7
 
 set lock8 [lock_test_start 8 [list \
 	[list permanent	permanent] \
 	[list wait	""] \
 	[list release	"released" ] \
+	[list wait	""] \
 	[list eof	0]]]
-lock_test 8.1 [list \
+set lock8_1 [lock_test_start 8.1 [list \
 	[list "" "administration database lock file missing while opening database" ] \
-	[list eof	1]]
+	[list wait	""] \
+	[list eof	1]]]
+eval lock_test_continue $lock8_1
+eval set lock8 \[lock_test_continue $lock8\]
 eval lock_test_continue $lock8
 
 set lock9 [lock_test_start 9 [list \
@@ -198,13 +216,17 @@ set lock9 [lock_test_start 9 [list \
 	[list release released] \
 	[list wait	""] \
 	[list exclusive	"database lock file missing while getting exclusive"] \
+	[list wait	""] \
 	[list eof	0]]]
 set lock9_1 [lock_test_start 9.1 [list \
 	[list permanent	permanent] \
 	[list wait	""] \
 	[list release	released] \
+	[list wait	""] \
 	[list eof	0]]]
+eval set lock9 \[lock_test_continue $lock9\]
 eval lock_test_continue $lock9
+eval set lock9_1 \[lock_test_continue $lock9_1\]
 eval lock_test_continue $lock9_1
 
 if {! [file exists $lockfile]} {
@@ -214,10 +236,12 @@ set lock10 [lock_test_start 10 [list \
 	[list permanent	permanent] \
 	[list wait	""] \
 	[list release	released] \
+	[list wait	""] \
 	[list eof	0]]]
 if {[file exists $lockfile]} {
     fail "test 10: lock file exists"
 }
+eval set lock10 \[lock_test_continue $lock10\]
 eval lock_test_continue $lock10
 if {[file exists $lockfile]} {
     pass "test 11: lock file exists"
@@ -229,15 +253,18 @@ set lock12 [lock_test_start 12 [list \
 	[list shared	shared] \
 	[list wait	""] \
 	[list eof	0]]]
-lock_test 12.1 [list \
+set lock12_1 [lock_test_start 12.1 [list \
 	[list "get test-pol"	retrieved] \
-	[list eof	0]]
+	[list wait	""] \
+	[list eof	0]]]
+eval lock_test_continue $lock12_1
 eval lock_test_continue $lock12
 
 set lock13 [lock_test_start 13 [list \
 	[list "get lock13"	"Principal or policy does not exist"] \
 	[list wait	""] \
 	[list "get lock13"	retrieved] \
+	[list wait	""] \
 	[list eof	0]]]
 set test13_spawn_id $spawn_id
 # create_policy could call api_exit immediately when it starts up.
@@ -248,6 +275,7 @@ api_start
 create_policy lock13
 set api_spawn_id $spawn_id
 set spawn_id $test13_spawn_id
+eval set lock13 \[lock_test_continue $lock13\]
 eval lock_test_continue $lock13
 set spawn_id $api_spawn_id
 delete_policy lock13
diff --git a/src/lib/kadm5/unit-test/api.2/init-v2.exp b/src/lib/kadm5/unit-test/api.2/init-v2.exp
index 58fe1a8b9..089300939 100644
--- a/src/lib/kadm5/unit-test/api.2/init-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/init-v2.exp
@@ -532,10 +532,10 @@ proc test117 {} {
 	}
     }
     
-    if {$max_life == 36000} {
+    if {$max_life == 86400} {
 	pass "$test"
     } else {
-	fail "$test: max_life $max_life should be 36000"
+	fail "$test: max_life $max_life should be 86400"
     }
 
     if {! [cmd {kadm5_destroy $server_handle}]} {
diff --git a/src/lib/kadm5/unit-test/api.2/init.exp b/src/lib/kadm5/unit-test/api.2/init.exp
index a1a2bc5ea..335f6e041 100644
--- a/src/lib/kadm5/unit-test/api.2/init.exp
+++ b/src/lib/kadm5/unit-test/api.2/init.exp
@@ -80,7 +80,7 @@ proc test6 {} {
     send "kadm5_init admin null \$KADM5_ADMIN_SERVICE null \$KADM5_STRUCT_VERSION \$KADM5_API_VERSION_2 server_handle\n"
 
     expect {
-	{Enter password:} { }
+	-re "assword\[^\r\n\]*:" { }
 	eof {
 		fail "$test: eof instead of password prompt"
 		api_exit
@@ -106,7 +106,7 @@ proc test7 {} {
     send "kadm5_init admin \"\" \$KADM5_ADMIN_SERVICE null \$KADM5_STRUCT_VERSION \$KADM5_API_VERSION_2 server_handle\n"
 
     expect {
-	{Enter password:} { }
+	-re "assword\[^\r\n\]*:" { }
 	-re "key:$" { }
 	eof {
 		fail "$test: eof instead of password prompt"
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog
index d685be6d9..87f60aad9 100644
--- a/src/lib/kdb/ChangeLog
+++ b/src/lib/kdb/ChangeLog
@@ -1,3 +1,31 @@
+2003-05-22  Ezra Peisach  <epeisach@mit.edu>
+
+	* keytab.c (is_xrealm_tgt): Use strncmp instead of strcmp - as
+	principal and realm name do not need to be null terminated.
+
+2003-04-01  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in: Remove $(SHLIB_DBLIB_DEPS) and related variables.
+	(SHLIB_EXPDEPS): Remove $(SHLIB_DBLIB_DEPS).
+	(SHLIB_EXPLIBS): Change $(DB_LIB) to $(KDB5_DB_LIB).
+	(DBOBJLISTS, STOBJLISTS): Pull in object lists of in-tree libdb so
+	we don't need to install libdb.  Don't do this if building with
+	system libdb, though, since we need to explicitly link against the
+	system libdb in that case.
+
+2003-03-18  Tom Yu  <tlyu@mit.edu>
+
+	* keytab.c (krb5_ktkdb_get_entry): Do not perform the enctype
+	comparison if the requested enctype is a wildcard.
+
+2003-03-16  Sam Hartman  <hartmans@mit.edu>
+
+	* keytab.c (krb5_ktkdb_get_entry):  Match only against the first
+	enctype  for non-cross-realm tickets so we will only accept
+	tickets that the current configuration would have issued.  For
+	cross-realm tickets be liberal and match against the specified
+	enctype. 
+
 2003-03-05  Tom Yu  <tlyu@mit.edu>
 
 	* kdb_xdr.c (krb5_dbe_search_enctype): Check for ktype > 0 rather
diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in
index ea80b7652..4ca36b0a1 100644
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -12,17 +12,20 @@ LIBMAJOR=4
 LIBMINOR=0
 RELDIR=kdb
 # Depends on libk5crypto and libkrb5
-SHLIB_DBLIB_DEPS = $(SHLIB_DBLIB-@DB_VERSION@)
-SHLIB_DBLIB-k5	 = $(TOPLIBD)/libdb$(SHLIBEXT)
-SHLIB_DBLIB-sys	 = 
 
 SHLIB_EXPDEPS = \
 	$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
-	$(TOPLIBD)/libkrb5$(SHLIBEXT) $(SHLIB_DBLIB_DEPS)
-SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto $(DB_LIB) $(LIBS)
+	$(TOPLIBD)/libkrb5$(SHLIBEXT)
+SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto $(KDB5_DB_LIB) $(LIBS)
 SHLIB_DIRS=-L$(TOPLIBD)
 SHLIB_RDIRS=$(KRB5_LIBDIR)
 
+DBDIR = $(BUILDTOP)/util/db2
+DBOBJLISTS = $(DBOBJLISTS-@DB_VERSION@)
+DBOBJLISTS-sys =
+DBOBJLISTS-k5 = $(DBDIR)/hash/OBJS.ST $(DBDIR)/btree/OBJS.ST \
+	$(DBDIR)/db/OBJS.ST $(DBDIR)/mpool/OBJS.ST $(DBDIR)/recno/OBJS.ST \
+	$(DBDIR)/clib/OBJS.ST
 
 all:: 
 
@@ -38,7 +41,7 @@ SRCS= \
 	$(srcdir)/setup_mkey.c \
 	$(srcdir)/store_mkey.c
 
-STOBJLISTS=OBJS.ST
+STOBJLISTS=OBJS.ST $(DBOBJLISTS)
 STLIBOBJS= \
 	keytab.o \
 	encrypt_key.o \
@@ -77,53 +80,55 @@ clean::
 #
 keytab.so keytab.po $(OUTPRE)keytab.$(OBJEXT): keytab.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/kdb_kt.h
+  $(SRCTOP)/include/krb5/kdb_kt.h
 encrypt_key.so encrypt_key.po $(OUTPRE)encrypt_key.$(OBJEXT): encrypt_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 decrypt_key.so decrypt_key.po $(OUTPRE)decrypt_key.$(OBJEXT): decrypt_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kdb_cpw.so kdb_cpw.po $(OUTPRE)kdb_cpw.$(OBJEXT): kdb_cpw.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/krb5/adm.h
+  $(SRCTOP)/include/krb5/adm.h
 kdb_db2.so kdb_db2.po $(OUTPRE)kdb_db2.$(OBJEXT): kdb_db2.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(DB_DEPS) kdb_compat.h \
-  kdb_db2.h
+  $(DB_DEPS) kdb_compat.h kdb_db2.h
 kdb_xdr.so kdb_xdr.po $(OUTPRE)kdb_xdr.$(OBJEXT): kdb_xdr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 verify_mky.so verify_mky.po $(OUTPRE)verify_mky.$(OBJEXT): verify_mky.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 fetch_mkey.so fetch_mkey.po $(OUTPRE)fetch_mkey.$(OBJEXT): fetch_mkey.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 setup_mkey.so setup_mkey.po $(OUTPRE)setup_mkey.$(OBJEXT): setup_mkey.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 store_mkey.so store_mkey.po $(OUTPRE)store_mkey.$(OBJEXT): store_mkey.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c
index 6ec375ac2..5db382cc2 100644
--- a/src/lib/kdb/keytab.c
+++ b/src/lib/kdb/keytab.c
@@ -24,10 +24,14 @@
  * or implied warranty.
  * 
  */
+#include <string.h>
 
 #include "k5-int.h"
 #include "kdb_kt.h"
 
+static int
+is_xrealm_tgt(krb5_context, krb5_const_principal);
+
 krb5_error_code krb5_ktkdb_close (krb5_context, krb5_keytab);
 
 krb5_error_code krb5_ktkdb_get_entry (krb5_context, krb5_keytab, krb5_const_principal,
@@ -116,6 +120,8 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry)
     krb5_db_entry 	  db_entry;
     krb5_boolean 	  more = 0;
     int 	 	  n = 0;
+    int xrealm_tgt = is_xrealm_tgt(context, principal);
+    int similar;
 
     if (ktkdb_ctx)
 	context = ktkdb_ctx;
@@ -150,16 +156,33 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry)
     if (kerror)
 	goto error;
 
+    /* For cross realm tgts, we match whatever enctype is provided;
+     * for other principals, we only match the first enctype that is
+     * found.  Since the TGS and AS code do the same thing, then we
+     * will only successfully decrypt  tickets we have issued.*/
     kerror = krb5_dbe_find_enctype(context, &db_entry,
-				   enctype, -1, kvno, &key_data);
+				   xrealm_tgt?enctype:-1,
+				   -1, kvno, &key_data);
     if (kerror)
 	goto error;
 
+
     kerror = krb5_dbekd_decrypt_key_data(context, master_key,
 					 key_data, &entry->key, NULL);
     if (kerror)
 	goto error;
 
+    if (enctype > 0) {	
+	kerror = krb5_c_enctype_compare(context, enctype,
+					entry->key.enctype, &similar);
+	if (kerror)
+	    goto error;
+
+	if (!similar) {
+	    kerror = KRB5_KDB_NO_PERMITTED_KEY;
+	    goto error;
+	}
+    }
     /*
      * Coerce the enctype of the output keyblock in case we got an
      * inexact match on the enctype.
@@ -176,3 +199,27 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry)
     krb5_db_close_database(context);
     return(kerror);
 }
+
+/*
+ * is_xrealm_tgt: Returns true if the principal is a cross-realm  TGT
+ * principal-- a principal with first component  krbtgt and second
+ * component not equal to realm.
+ */
+static int
+is_xrealm_tgt(krb5_context context, krb5_const_principal princ)
+{
+    krb5_data *dat;
+    if (krb5_princ_size(context, princ) != 2)
+	return 0;
+    dat = krb5_princ_component(context, princ, 0);
+    if (strncmp("krbtgt", dat->data, dat->length) != 0)
+	return 0;
+    dat = krb5_princ_component(context, princ, 1);
+    if (dat->length != princ->realm.length)
+	return 1;
+    if (strncmp(dat->data, princ->realm.data, dat->length) == 0)
+	return 0;
+    return 1;
+
+}
+
diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog
index 9c53ca17b..084283176 100644
--- a/src/lib/krb4/ChangeLog
+++ b/src/lib/krb4/ChangeLog
@@ -1,3 +1,132 @@
+2003-08-15  Alexandra Ellwood  <lxs@mit.edu>
+
+        * mk_auth.c: krb_check_auth clears the return value for the 
+        schedule parameter with a memset.  This prevents callers 
+        from using the key schedule, which breaks code.
+
+2003-08-06  Alexandra Ellwood  <lxs@mit.edu>
+
+        * configure.in: Don't assume all darwin boxes are powerpc.
+        (eg: OpenDarwin/x86).
+
+2003-07-11  Alexandra Ellwood  <lxs@mit.edu>
+
+        * RealmsConfig-glue.c: Check for NULL realm argument and n
+        not equal to 1.  Fill in realm with an empty string on error 
+        in case the caller doesn't check the return value.
+
+2003-07-11  Alexandra Ellwood  <lxs@mit.edu>
+
+        * RealmsConfig-glue.c: Don't fail when krb5.conf is valid
+        and krb.conf isn't.  Also, don't assert v4 realm is in profile
+        unless that realm is a valid v4 realm.
+
+2003-07-07  Alexandra Ellwood  <lxs@mit.edu>
+
+        * RealmsConfig-glue.c: krb_prof_get_nth() no longer assumes that
+        its retlen argument is correct (call strcpy instead of strncpy)
+        because this argument is a guess for some callers 
+        (eg: krb_get_admhst())
+
+2003-06-11  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in (KRB_ERR_C): New variable; Darwin needs err_txt.o to
+	have a dependency on krb_err.c so that krb_err.c will be generated
+	first.
+
+	* configure.in: Set KRB_ERR_C to krb_err.c on Darwin.
+
+2003-06-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* RealmsConfig-glue.c (krb_get_krbhst): Don't fall back to DNS if
+	entries were found in krb.conf, and just not enough to fill the
+	request.
+
+2003-06-06  Ken Raeburn  <raeburn@mit.edu>
+
+	* RealmsConfig-glue.c: Include k5-int.h.
+	(dnscache): New variable.
+	(DNS_CACHE_TIMEOUT): New macro.
+	(krb_get_krbhst) [KRB5_DNS_LOOKUP]: If no krb.conf info is found,
+	try DNS SRV records for "kerberos-iv".  Cache results in case
+	they're immediately requested again.
+
+2003-06-06  Tom Yu  <tlyu@mit.edu>
+
+	* g_cnffile.c (krb__get_srvtabname): Make retname be a static
+	array rather than a static pointer, to avoid callers' possible
+	retention of free()d pointers.  Yes, this may cause difficulty
+	with making this function thread-safe.
+
+2003-06-04  Tom Yu  <tlyu@mit.edu>
+
+	* password_to_key.c (mit_passwd_to_key, afs_passwd_to_key): Delete
+	spurious space from prompt.
+
+2003-06-03  Ken Raeburn  <raeburn@mit.edu>
+
+	* RealmsConfig-glue.c (get_krbhst_default): Deleted.
+	(krb_get_krbhst): Don't call it.
+
+2003-06-03  Sam Hartman  <hartmans@mit.edu>
+
+	* g_pw_in_tkt.c (passwd_to_key): Fix password prompt
+
+	* password_to_key.c (mit_passwd_to_key): Fix password prompt
+	(afs_passwd_to_key): Fix password prompt
+
+	* g_in_tkt.c (krb_get_in_tkt_preauth_creds): Keep copy of
+	ciphertext while trying different keyprocs 
+
+2003-06-02  Tom Yu  <tlyu@mit.edu>
+
+	* change_password.c (krb_change_password): Explicitly zero the
+	session key.  Zero the key derived from the new password.
+
+	* mk_req.c (krb_mk_req): Explicitly zero the session key.
+	(krb_mk_req_creds_prealm): Don't zero the session key, in case the
+	caller wants to make use of it.
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* lifetime.c (krb_life_to_time, krb_time_to_life): Rewrite to use
+	support functions in the krb5 library via krb5int_accessor.  Moved
+	old implementation into krb5 library.
+
+2003-05-12  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in: Add setting of KRB_ERR on Windows.
+
+2003-05-11  Sam Hartman  <hartmans@mit.edu>
+
+	* Makefile.in: Build krb_err.c when appropriate.
+
+	* configure.in: Set KRB_ERR to be the object file generated by
+	krb_err.c on non-Darwin
+
+	* err_txt.c :  Don't include krb_err.c on non-Darwin UNIX.  Doing
+	so may break with some compile_et implementations.  Also not
+	included on Windows.
+
+2003-05-01  Alexandra Ellwood  <lxs@mit.edu>
+ ÊÊ
+    * kadm_stream.c: Fixed vts_long() and vts_short() so they return a
+    pointer to the beginning of the memory they allocate and place 
+    their data at the end of the buffer which was passed in.
+
+2003-04-15  Alexandra Ellwood  <lxs@mit.edu>
+ ÊÊ
+    * g_ad_tkt.c: accidentally checked a non-space character into
+    the USE_LOGIN_LIBRARY part of get_ad_tkt so it doesn't build
+    on the Mac.  Oops.
+    
+2003-04-14  Alexandra Ellwood  <lxs@mit.edu>
+ ÊÊ
+    * g_ad_tkt.c: Added support for login library to get_ad_tkt.
+    Support is copied from Mac Kerberos4 library and conditionalized
+    for USE_LOGIN_LIBRARY to avoid changing get_ad_tkt's behavior for
+    non-Kerberos Login Library builds.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
 
     * CCache-glue.c: Added prototypes for deprecated functions.
diff --git a/src/lib/krb4/Makefile.in b/src/lib/krb4/Makefile.in
index 0a8ecff3e..572a3ad0f 100644
--- a/src/lib/krb4/Makefile.in
+++ b/src/lib/krb4/Makefile.in
@@ -29,6 +29,12 @@ SHLIB_DIRS=-L$(TOPLIBD)
 SHLIB_RDIRS=$(KRB5_LIBDIR)
 
 EHDRDIR=$(BUILDTOP)$(S)include$(S)kerberosIV
+KRB_ERR=@KRB_ERR@
+##DOS##KRB_ERR=$(OUTPRE)krb_err.$(OBJEXT)
+
+# Name of generated krb_err.c, needed for err_txt.* dependency on Darwin.
+KRB_ERR_C=@KRB_ERR_C@
+##DOS##KRB_ERR_C=
 
 OBJS	= \
 	$(OUTPRE)change_password.$(OBJEXT) \
@@ -72,7 +78,7 @@ OBJS	= \
 	$(OUTPRE)rd_preauth.$(OBJEXT) \
 	$(OUTPRE)mk_preauth.$(OBJEXT) \
 	$(OSOBJS) $(CACHEOBJS) $(SETENVOBJS) $(STRCASEOBJS) $(SHMOBJS) \
-	$(LIB_KRB_HOSTOBJS) $(SERVER_KRB_OBJS) $(NETIO_OBJS) $(REALMDBOBJS)
+	$(LIB_KRB_HOSTOBJS) $(SERVER_KRB_OBJS) $(NETIO_OBJS) $(REALMDBOBJS) $(KRB_ERR)
 
 SRCS = \
 	change_password.c \
@@ -217,7 +223,7 @@ krb_err_txt.c: krb_err.et $(srcdir)$(S)et_errtxt.awk
 # Will be empty on Darwin, krb_err_txt.c elsewhere.
 KRB_ERR_TXT=@KRB_ERR_TXT@
 ##DOS##KRB_ERR_TXT=krb_err_txt.c
-err_txt.so err_txt.po $(OUTPRE)err_txt.$(OBJEXT): err_txt.c $(KRB_ERR_TXT)
+err_txt.so err_txt.po $(OUTPRE)err_txt.$(OBJEXT): err_txt.c $(KRB_ERR_C) $(KRB_ERR_TXT)
 
 depend-dependencies: krb_err.h $(EHDRDIR)$(S)krb_err.h \
 	kadm_err.h $(EHDRDIR)$(S)kadm_err.h \
@@ -335,11 +341,14 @@ kname_parse.so kname_parse.po $(OUTPRE)kname_parse.$(OBJEXT): kname_parse.c $(SR
 err_txt.so err_txt.po $(OUTPRE)err_txt.$(OBJEXT): err_txt.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h krb4int.h \
-  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  krb_err.c
+  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h
 lifetime.so lifetime.po $(OUTPRE)lifetime.$(OBJEXT): lifetime.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
-  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h
 g_in_tkt.so g_in_tkt.po $(OUTPRE)g_in_tkt.$(OBJEXT): g_in_tkt.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h krb4int.h \
@@ -409,9 +418,10 @@ send_to_kdc.so send_to_kdc.po $(OUTPRE)send_to_kdc.$(OBJEXT): send_to_kdc.c $(SR
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/krbports.h \
   $(SRCTOP)/include/kerberosIV/prot.h $(BUILDTOP)/include/krb5/autoconf.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
-  $(SRCTOP)/include/krb5/kdb.h krb4int.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/krb5/kdb.h \
+  krb4int.h
 stime.so stime.po $(OUTPRE)stime.$(OBJEXT): stime.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h krb4int.h \
@@ -434,9 +444,9 @@ tf_util.so tf_util.po $(OUTPRE)tf_util.$(OBJEXT): tf_util.c $(SRCTOP)/include/ke
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  krb4int.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krb4int.h
 dest_tkt.so dest_tkt.po $(OUTPRE)dest_tkt.$(OBJEXT): dest_tkt.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-util.h \
@@ -489,9 +499,9 @@ rd_svc_key.so rd_svc_key.po $(OUTPRE)rd_svc_key.$(OBJEXT): rd_svc_key.c $(SRCTOP
   $(KRB_ERR_H_DEP) $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
   krb4int.h $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb54proto.h \
-  $(SRCTOP)/include/kerberosIV/prot.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
+  $(SRCTOP)/include/krb54proto.h $(SRCTOP)/include/kerberosIV/prot.h
 cr_err_repl.so cr_err_repl.po $(OUTPRE)cr_err_repl.$(OBJEXT): cr_err_repl.c $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/prot.h
@@ -538,12 +548,14 @@ g_cnffile.so g_cnffile.po $(OUTPRE)g_cnffile.$(OBJEXT): g_cnffile.c $(SRCTOP)/in
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  krb4int.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krb4int.h
 RealmsConfig-glue.so RealmsConfig-glue.po $(OUTPRE)RealmsConfig-glue.$(OBJEXT): RealmsConfig-glue.c \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   krb4int.h $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb4/RealmsConfig-glue.c b/src/lib/krb4/RealmsConfig-glue.c
index 52437ee98..0635284c0 100644
--- a/src/lib/krb4/RealmsConfig-glue.c
+++ b/src/lib/krb4/RealmsConfig-glue.c
@@ -37,6 +37,7 @@
 #include "profile.h"
 #include "krb.h"
 #include "krb4int.h"
+#include "k5-int.h"		/* for accessor, addrlist stuff */
 #include "port-sockets.h"
 
 #define KRB5_PRIVATE 1
@@ -142,10 +143,11 @@ krb_prof_get_nth(
     }
     if (result == KSUCCESS) {
 	/* Return error rather than truncating. */
+	/* Don't strncpy because retlen is a guess for some callers */
 	if (strlen(value) >= retlen)
 	    result = KFAILURE;
 	else
-	    strncpy(ret, value, retlen);
+	    strcpy(ret, value);
     }
 cleanup:
     if (name != NULL)
@@ -188,76 +190,112 @@ krb_get_lrealm(
     char	*realm,
     int		n)
 {
-    long	profErr = 0;
-    char	*realmString = NULL;
-    char	*realmStringV4 = NULL;
-    profile_t	profile = NULL;
-    int		result;
-    FILE	*cnffile = NULL;
-    char	scratch[SCRATCHSZ];
-
-    if (n != 1 || realm == NULL)
-	return KFAILURE;
+    int         result = KSUCCESS;
+    profile_t   profile = NULL;
+    char       *profileDefaultRealm = NULL;
+    char      **profileV4Realms = NULL;
+    int         profileHasDefaultRealm = 0;
+    int         profileDefaultRealmIsV4RealmInProfile = 0;
+    char        krbConfLocalRealm[REALM_SZ];
+    int         krbConfHasLocalRealm = 0;
 
-    result = KFAILURE;		/* Start out with failure. */
-
-    profErr = krb_get_profile(&profile);
-    if (profErr)
-	goto cleanup;
+    if ((realm == NULL) || (n != 1)) { result = KFAILURE; }
 
-    profErr = profile_get_string(profile, REALMS_V4_PROF_LIBDEFAULTS_SECTION,
-				 REALMS_V4_DEFAULT_REALM, NULL, NULL,
-				 &realmString);
-    if (profErr || realmString == NULL)
-	goto cleanup;
+    if (result == KSUCCESS) {
+        /* Some callers don't check the return value so we initialize
+         * to an empty string in case it never gets filled in. */
+        realm [0] = '\0';  
+    }
+    
+    if (result == KSUCCESS) {
+        int profileErr = krb_get_profile (&profile);
+
+        if (!profileErr) {
+            /* Get the default realm from the profile */
+            profileErr = profile_get_string(profile, REALMS_V4_PROF_LIBDEFAULTS_SECTION,
+                                            REALMS_V4_DEFAULT_REALM, NULL, NULL,
+                                            &profileDefaultRealm);
+            if (profileDefaultRealm == NULL) { profileErr = KFAILURE; }
+        }
+
+        if (!profileErr) {
+            /* If there is an equivalent v4 realm to the default realm, use that instead */
+            char *profileV4EquivalentRealm = NULL;
+
+            if (profile_get_string (profile, "realms", profileDefaultRealm, "v4_realm", NULL,
+                                    &profileV4EquivalentRealm) == 0 &&
+                profileV4EquivalentRealm != NULL) {
+
+                profile_release_string (profileDefaultRealm);
+                profileDefaultRealm = profileV4EquivalentRealm;
+            }
+        }
+
+        if (!profileErr) {
+            if (strlen (profileDefaultRealm) < REALM_SZ) {
+                profileHasDefaultRealm = 1;  /* a reasonable default realm */
+            } else {
+                profileErr = KFAILURE;
+            }
+        }
+
+        if (!profileErr) {
+            /* Walk through the v4 realms list looking for the default realm */
+            const char *profileV4RealmsList[] = { REALMS_V4_PROF_REALMS_SECTION, NULL };
+
+            if (profile_get_subsection_names (profile, profileV4RealmsList,
+                                              &profileV4Realms) == 0 &&
+                profileV4Realms != NULL) {
+
+                char **profileRealm;
+                for (profileRealm = profileV4Realms; *profileRealm != NULL; profileRealm++) {
+                    if (strcmp (*profileRealm, profileDefaultRealm) == 0) {
+                        /* default realm is a v4 realm */
+                        profileDefaultRealmIsV4RealmInProfile = 1;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    
+    if (result == KSUCCESS) {
+        /* Try to get old-style config file lookup for fallback. */
+        FILE	*cnffile = NULL;
+        char	scratch[SCRATCHSZ];
+
+        cnffile = krb__get_cnffile();
+        if (cnffile != NULL) {
+            if (fscanf(cnffile, SCNSCRATCH, scratch) == 1) {
+                if (strlen(scratch) < REALM_SZ) {
+                    strncpy(krbConfLocalRealm, scratch, REALM_SZ);
+                    krbConfHasLocalRealm = 1;
+                }
+            }
+            fclose(cnffile);
+        }
+    }
 
-    if (strlen(realmString) >= REALM_SZ)
-	goto cleanup;
-    strncpy(realm, realmString, REALM_SZ);
-    /*
-     * Step 2: the default realm is actually v5 realm, so we have to
-     * check for the case where v4 and v5 realms are different.
-     */
-    profErr = profile_get_string(profile, "realms", realm, "v4_realm",
-				 NULL, &realmStringV4);
-    if (profErr || realmStringV4 == NULL)
-	goto cleanup;
+    if (result == KSUCCESS) {
+        /*
+         * We want to favor the profile value over the krb.conf value
+         * but not stop suppporting its use with a v5-only profile. 
+         * So we only use the krb.conf realm when the default profile
+         * realm doesn't exist in the v4 realm section of the profile.
+         */
+        if (krbConfHasLocalRealm && !profileDefaultRealmIsV4RealmInProfile) {
+            strncpy (realm, krbConfLocalRealm, REALM_SZ);
+        } else if (profileHasDefaultRealm) {
+            strncpy (realm, profileDefaultRealm, REALM_SZ);
+        } else {
+            result = KFAILURE;  /* No default realm */
+        }
+    }
 
-    if (strlen(realmStringV4) >= REALM_SZ)
-	goto cleanup;
-    strncpy(realm, realmStringV4, REALM_SZ);
-    result = KSUCCESS;
-cleanup:
-    if (realmString != NULL)
-	profile_release_string(realmString);
-    if (realmStringV4 != NULL)
-	profile_release_string(realmStringV4);
-    if (profile != NULL)
-	profile_abandon(profile);
+    if (profileDefaultRealm != NULL) { profile_release_string (profileDefaultRealm); }
+    if (profileV4Realms     != NULL) { profile_free_list (profileV4Realms); }
+    if (profile             != NULL) { profile_abandon (profile); }
 
-    if (result == KSUCCESS)
-	return result;
-    /*
-     * Do old-style config file lookup.
-     */
-    do {
-	cnffile = krb__get_cnffile();
-	if (cnffile == NULL)
-	    break;
-	if (fscanf(cnffile, SCNSCRATCH, scratch) == 1) {
-	    if (strlen(scratch) >= REALM_SZ)
-		result = KFAILURE;
-	    else {
-		strncpy(realm, scratch, REALM_SZ);
-		result = KSUCCESS;
-	    }
-	}
-	fclose(cnffile);
-    } while (0);
-    if (result == KFAILURE && strlen(KRB_REALM) < REALM_SZ) {
-	strncpy(realm, KRB_REALM, REALM_SZ);
-	result = KSUCCESS;
-    }
     return result;
 }
 
@@ -359,23 +397,6 @@ krb_get_kpasswdhst(
 			    REALMS_V4_PROF_KPASSWD_KDC);
 }
 
-static int
-get_krbhst_default(h, r, n)
-    char *h;
-    char *r;
-    int n;
-{
-    if (n != 1)
-	return KFAILURE;
-    if (strlen(KRB_HOST) + 1 + strlen(r) >= MAXHOSTNAMELEN)
-	return KFAILURE;
-    /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
-    strcpy(h, KRB_HOST);
-    strcat(h, ".");
-    strcat(h, r);
-    return KSUCCESS;
-}
-
 /*
  * Realm, index -> KDC mapping
  *
@@ -411,6 +432,15 @@ get_krbhst_default(h, r, n)
  * kerberos.  In the long run, this functionality will be provided by a
  * nameserver.
  */
+#ifdef KRB5_DNS_LOOKUP
+static struct {
+    time_t when;
+    char realm[REALM_SZ+1];
+    struct srv_dns_entry *srv;
+} dnscache = { 0, { 0 }, 0 };
+#define DNS_CACHE_TIMEOUT	60 /* seconds */
+#endif
+
 int KRB5_CALLCONV
 krb_get_krbhst(
     char	*host,
@@ -423,10 +453,36 @@ krb_get_krbhst(
     char	linebuf[BUFSIZ];
     char	tr[SCRATCHSZ];
     char	scratch[SCRATCHSZ];
+#ifdef KRB5_DNS_LOOKUP
+    time_t now;
+#endif
 
     if (n < 1 || host == NULL || realm == NULL)
 	return KFAILURE;
 
+#ifdef KRB5_DNS_LOOKUP
+    /* We'll only have this realm's info in the DNS cache if there is
+       no data in the local config files.
+
+       XXX The files could've been updated in the last few seconds.
+       Do we care?  */
+    if (!strncmp(dnscache.realm, realm, REALM_SZ)
+	&& (time(&now), abs(dnscache.when - now) < DNS_CACHE_TIMEOUT)) {
+	struct srv_dns_entry *entry;
+
+    get_from_dnscache:
+	/* n starts at 1, addrs indices run 0..naddrs */
+	for (i = 1, entry = dnscache.srv; i < n && entry; i++)
+	    entry = entry->next;
+	if (entry == NULL)
+	    return KFAILURE;
+	if (strlen(entry->host) + 6 >= MAXHOSTNAMELEN)
+	    return KFAILURE;
+	sprintf(host, "%s:%d", entry->host, entry->port);
+	return KSUCCESS;
+    }
+#endif
+
     result = krb_prof_get_nth(host, MAXHOSTNAMELEN, realm, n,
 			      REALMS_V4_PROF_REALMS_SECTION,
 			      REALMS_V4_PROF_KDC);
@@ -461,14 +517,43 @@ krb_get_krbhst(
 		i++;
 	}
 	fclose(cnffile);
-	if (result == KSUCCESS && strlen(scratch) < MAXHOSTNAMELEN)
+	if (result == KSUCCESS && strlen(scratch) < MAXHOSTNAMELEN) {
 	    strcpy(host, scratch);
-	else
-	    result = KFAILURE;
+	    return KSUCCESS;
+	}
+	if (i > 0)
+	    /* Found some, but not as many as requested.  */
+	    return KFAILURE;
     } while (0);
-    if (result == KFAILURE)
-	result = get_krbhst_default(host, realm, n);
-    return result;
+#ifdef KRB5_DNS_LOOKUP
+    do {
+	krb5int_access k5;
+	krb5_error_code err;
+	krb5_data realmdat;
+	struct srv_dns_entry *srv;
+
+	err = krb5int_accessor(&k5, KRB5INT_ACCESS_VERSION);
+	if (err)
+	    break;
+
+	realmdat.data = realm;
+	realmdat.length = strlen(realm);
+	err = k5.make_srv_query_realm(&realmdat, "_kerberos-iv", "_udp", &srv);
+	if (err)
+	    break;
+
+	if (srv == 0)
+	    break;
+
+	if (dnscache.srv)
+	    k5.free_srv_dns_data(dnscache.srv);
+	dnscache.srv = srv;
+	strncpy(dnscache.realm, realm, REALM_SZ);
+	dnscache.when = now;
+	goto get_from_dnscache;
+    } while (0);
+#endif
+    return KFAILURE;
 }
 
 /*
diff --git a/src/lib/krb4/change_password.c b/src/lib/krb4/change_password.c
index a6e4d7b29..7c3bcd01d 100644
--- a/src/lib/krb4/change_password.c
+++ b/src/lib/krb4/change_password.c
@@ -100,6 +100,7 @@ krb_change_password(char *principal, char *instance, char *realm,
     p = key;
     KRB4_GET32BE(tempKey, p);
     sendSize += vts_long(tempKey, &sendStream, (int)sendSize);
+    tempKey = 0;
 
     if (newPassword) {
 	sendSize += vts_string(newPassword, &sendStream, (int)sendSize);
@@ -120,5 +121,7 @@ disconnect:
     kadm_cli_disconn(&client_parm);
 
 cleanup:
+    memset(&client_parm.creds.session, 0, sizeof(client_parm.creds.session));
+    memset(&key, 0, sizeof(key));
     return err;
 }
diff --git a/src/lib/krb4/configure.in b/src/lib/krb4/configure.in
index 87aeebccf..d4286567b 100644
--- a/src/lib/krb4/configure.in
+++ b/src/lib/krb4/configure.in
@@ -3,14 +3,20 @@ CONFIG_RULES
 AC_TYPE_MODE_T
 AC_TYPE_UID_T
 case $krb5_cv_host in
-     powerpc-apple-darwin*)
+     *-apple-darwin*)
      KRB_ERR_TXT=
+     KRB_ERR=
+     KRB_ERR_C=krb_err.c
      ;;
      *)
+     KRB_ERR='$(OUTPRE)krb_err.$(OBJEXT)'
      KRB_ERR_TXT=krb_err_txt.c
+     KRB_ERR_C=
      ;;
 esac
 AC_SUBST([KRB_ERR_TXT])
+AC_SUBST([KRB_ERR])
+AC_SUBST([KRB_ERR_C])
 AC_PROG_AWK
 KRB5_BUILD_LIBOBJS
 KRB5_BUILD_LIBRARY_WITH_DEPS
diff --git a/src/lib/krb4/err_txt.c b/src/lib/krb4/err_txt.c
index 9d942a071..a7a290c94 100644
--- a/src/lib/krb4/err_txt.c
+++ b/src/lib/krb4/err_txt.c
@@ -31,17 +31,14 @@
  * This is gross.  We want krb_err_txt to match the contents of the
  * com_err error table, but the text is static in krb_err.c.  We can't
  * alias it by making a pointer to it, either, so we have to suck in
- * another copy of it that is named differently.  Also, to avoid
- * multiple registrations of the error table, we want to override
- * initialize_krb_error_table() in case someone decides to call it.
- */
+ * another copy of it that is named differently.   */
+#if TARGET_OS_MAC
 #undef initialize_krb_error_table
 #define initialize_krb_error_table	krb4int_init_krb_err_tbl
 void krb4int_init_krb_err_tbl(void);
 #include "krb_err.c"
 #undef initialize_krb_error_table
 
-#if TARGET_OS_MAC
 /*
  * Depends on the name of the static table generated by compile_et,
  * but since this is only on Darwin, where we will always use a
@@ -68,12 +65,6 @@ krb4int_et_init(void)
     inited = 1;\
 }
 
-void
-initialize_krb_error_table(void)
-{
-    krb4int_et_init();
-}
-
 void
 krb4int_et_fini(void)
 {
diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c
index daae7515f..353fdcee5 100644
--- a/src/lib/krb4/g_ad_tkt.c
+++ b/src/lib/krb4/g_ad_tkt.c
@@ -256,6 +256,15 @@ get_ad_tkt(service, sinstance, realm, lifetime)
     size_t snamelen, sinstlen;
 
     kerror = krb_get_tf_realm(TKT_FILE, lrealm);
+#if USE_LOGIN_LIBRARY
+    if (kerror == GC_NOTKT) {
+        /* No tickets... call krb_get_cred (KLL will prompt) and try again. */
+        if ((kerror = krb_get_cred ("krbtgt", realm, realm, &cr)) == KSUCCESS) {
+            /* Now get the realm again. */
+            kerror = krb_get_tf_realm (TKT_FILE, lrealm);
+        }
+    }
+#endif
     if (kerror != KSUCCESS)
 	return kerror;
 
diff --git a/src/lib/krb4/g_cnffile.c b/src/lib/krb4/g_cnffile.c
index 8d61f5056..dd5ed5c60 100644
--- a/src/lib/krb4/g_cnffile.c
+++ b/src/lib/krb4/g_cnffile.c
@@ -56,7 +56,7 @@ krb__get_srvtabname(default_srvtabname)
 	const char* names[3];
 	char **full_name = 0, **cpp;
 	krb5_error_code retval;
-	static char *retname;
+	static char retname[MAXPATHLEN];
 
 	if (!krb5__krb4_context)
 		krb5_init_context(&krb5__krb4_context);
@@ -67,18 +67,16 @@ krb__get_srvtabname(default_srvtabname)
 	    retval = profile_get_values(krb5__krb4_context->profile, names, 
 					&full_name);
 	    if (retval == 0 && full_name && full_name[0]) {
-		if (retname != NULL)
-		    free(retname);
-		retname = strdup(full_name[0]);
+		retname[0] = '\0';
+		strncat(retname, full_name[0], sizeof(retname));
 		for (cpp = full_name; *cpp; cpp++) 
 		    krb5_xfree(*cpp);
 		krb5_xfree(full_name);
 		return retname;
 	    }
 	}
-	if (retname != NULL)
-	    free(retname);
-	retname = strdup(default_srvtabname);
+	retname[0] = '\0';
+	strncat(retname, default_srvtabname, sizeof(retname));
 	return retname;
 }
 
diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c
index 4d5286a98..58a91b00d 100644
--- a/src/lib/krb4/g_in_tkt.c
+++ b/src/lib/krb4/g_in_tkt.c
@@ -424,6 +424,9 @@ krb_get_in_tkt_preauth_creds(user, instance, realm, service, sinstance, life,
     /* Attempt to decrypt the reply.  Loop trying password_to_key algorithms 
        until we succeed or we get an error other than "bad password" */
     do {
+	KTEXT_ST cip_copy_st;
+	memcpy(&cip_copy_st, &cip_st, sizeof(cip_st));
+	cip = &cip_copy_st;
         if (decrypt_proc == NULL) {
             decrypt_tkt (user, instance, realm, arg, keyprocs[i], &cip);
         } else {
@@ -432,6 +435,7 @@ krb_get_in_tkt_preauth_creds(user, instance, realm, service, sinstance, life,
         kerror = krb_parse_in_tkt_creds(user, instance, realm,
                     service, sinstance, life, cip, byteorder, creds);
     } while ((keyprocs [++i] != NULL) && (kerror == INTK_BADPW));
+    cip = &cip_st;
 
     /* Fill in the local address if the caller wants it */
     if (laddrp != NULL) {
diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c
index 494a05951..d68781857 100644
--- a/src/lib/krb4/g_pw_in_tkt.c
+++ b/src/lib/krb4/g_pw_in_tkt.c
@@ -79,7 +79,7 @@ passwd_to_key(user,instance,realm,passwd,key)
     if (passwd)
         string_to_key(passwd, key);
     else {
-        des_read_password((des_cblock *)key, "Password: ", 0);
+        des_read_password((des_cblock *)key, "Password", 0);
     }
 #endif /* NOENCRYPTION */
 #endif /* unix */
diff --git a/src/lib/krb4/kadm_stream.c b/src/lib/krb4/kadm_stream.c
index 3a9861eda..dc9fef110 100644
--- a/src/lib/krb4/kadm_stream.c
+++ b/src/lib/krb4/kadm_stream.c
@@ -129,8 +129,11 @@ vts_short(KRB_UINT32 dat, u_char **st, int loc)
     if (p == NULL)
 	return -1;
 
+    *st = p; /* KRB4_PUT32BE will modify p */
+
+    p += loc; /* place bytes at the end */
     KRB4_PUT16BE(p, dat);
-    *st = p;
+
     return 2;
 }
 
@@ -145,8 +148,11 @@ vts_long(KRB_UINT32 dat, u_char **st, int loc)
     if (p == NULL)
 	return -1;
 
+    *st = p; /* KRB4_PUT32BE will modify p */
+
+    p += loc; /* place bytes at the end */
     KRB4_PUT32BE(p, dat);
-    *st = p;
+
     return 4;
 }
 
diff --git a/src/lib/krb4/lifetime.c b/src/lib/krb4/lifetime.c
index b43ed4523..826e090df 100644
--- a/src/lib/krb4/lifetime.c
+++ b/src/lib/krb4/lifetime.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000, 2001 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2001, 2003 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -24,72 +24,7 @@
  */
 
 #include "krb.h"
-
-/*
- * Only lifetime bytes values less than 128 are on a linear scale.
- * The following table contains an exponential scale that covers the
- * lifetime values 128 to 191 inclusive (a total of 64 values).
- * Values greater than 191 get interpreted the same as 191, but they
- * will never be generated by the functions in this file.
- *
- * The ratio is approximately 1.069144898 (actually exactly
- * exp(log(67.5)/63), where 67.5 = 2592000/38400, and 259200 = 30
- * days, and 38400 = 128*5 minutes.  This allows a lifetime byte of
- * 191 to correspond to a ticket life of exactly 30 days and a
- * lifetime byte of 128 to correspond to exactly 128*5 minutes, with
- * the other values spread on an exponential curve fit in between
- * them.  This table should correspond exactly to the set of extended
- * ticket lifetime values used by AFS and CMU.
- *
- * The following awk script is sufficient to reproduce the table:
- * BEGIN {
- *     r = exp(log(2592000/38400)/63);
- *     x = 38400;
- *     for (i=0;i<64;i++) {
- *         printf("%d\n",x+0.5);
- *         x *= r;
- *     }
- * }
- */
-#ifndef SHORT_LIFETIME
-#define NLIFETIMES 64
-static const KRB4_32 lifetimes[NLIFETIMES] = {
-    38400, 41055,		/* 00:10:40:00, 00:11:24:15 */
-    43894, 46929,		/* 00:12:11:34, 00:13:02:09 */
-    50174, 53643,		/* 00:13:56:14, 00:14:54:03 */
-    57352, 61318,		/* 00:15:55:52, 00:17:01:58 */
-    65558, 70091,		/* 00:18:12:38, 00:19:28:11 */
-    74937, 80119,		/* 00:20:48:57, 00:22:15:19 */
-    85658, 91581,		/* 00:23:47:38, 01:01:26:21 */
-    97914, 104684,		/* 01:03:11:54, 01:05:04:44 */
-    111922, 119661,		/* 01:07:05:22, 01:09:14:21 */
-    127935, 136781,		/* 01:11:32:15, 01:13:59:41 */
-    146239, 156350,		/* 01:16:37:19, 01:19:25:50 */
-    167161, 178720,		/* 01:22:26:01, 02:01:38:40 */
-    191077, 204289,		/* 02:05:04:37, 02:08:44:49 */
-    218415, 233517,		/* 02:12:40:15, 02:16:51:57 */
-    249664, 266926,		/* 02:21:21:04, 03:02:08:46 */
-    285383, 305116,		/* 03:07:16:23, 03:12:45:16 */
-    326213, 348769,		/* 03:18:36:53, 04:00:52:49 */
-    372885, 398668,		/* 04:07:34:45, 04:14:44:28 */
-    426234, 455705,		/* 04:22:23:54, 05:06:35:05 */
-    487215, 520904,		/* 05:15:20:15, 06:00:41:44 */
-    556921, 595430,		/* 06:10:42:01, 06:21:23:50 */
-    636601, 680618,		/* 07:08:50:01, 07:21:03:38 */
-    727680, 777995,		/* 08:10:08:00, 09:00:06:35 */
-    831789, 889303,		/* 09:15:03:09, 10:07:01:43 */
-    950794, 1016537,		/* 11:00:06:34, 11:18:22:17 */
-    1086825, 1161973,		/* 12:13:53:45, 13:10:46:13 */
-    1242318, 1328218,		/* 14:09:05:18, 15:08:56:58 */
-    1420057, 1518247,		/* 16:10:27:37, 17:13:44:07 */
-    1623226, 1735464,		/* 18:18:53:46, 20:02:04:24 */
-    1855462, 1983758,		/* 21:11:24:22, 22:23:02:38 */
-    2120925, 2267576,		/* 24:13:08:45, 26:05:52:56 */
-    2424367, 2592000		/* 28:01:26:07, 30:00:00:00 */
-};
-#define MINFIXED 0x80
-#define MAXFIXED (MINFIXED + NLIFETIMES - 1)
-#endif /* !SHORT_LIFETIME */
+#include "k5-int.h"
 
 /*
  * krb_life_to_time
@@ -100,17 +35,12 @@ static const KRB4_32 lifetimes[NLIFETIMES] = {
 KRB4_32 KRB5_CALLCONV
 krb_life_to_time(KRB4_32 start, int life)
 {
-    if (life < 0 || life > 255)	/* possibly sign botch in caller */
+    krb5int_access k5internals;
+
+    if (krb5int_accessor(&k5internals, KRB5INT_ACCESS_VERSION)
+	|| k5internals.krb_life_to_time == NULL)
 	return start;
-#ifndef SHORT_LIFETIME
-    if (life < MINFIXED)
-	return start + life * 5 * 60;
-    if (life > MAXFIXED)
-	return start + lifetimes[NLIFETIMES - 1];
-    return start + lifetimes[life - MINFIXED];
-#else  /* SHORT_LIFETIME */
-    return start + life * 5 * 60;
-#endif /* SHORT_LIFETIME */
+    return k5internals.krb_life_to_time(start, life);
 }
 
 /*
@@ -123,27 +53,10 @@ krb_life_to_time(KRB4_32 start, int life)
 int KRB5_CALLCONV
 krb_time_to_life(KRB4_32 start, KRB4_32 end)
 {
-    KRB4_32 dt;
-#ifndef SHORT_LIFETIME
-    int i;
-#endif
+    krb5int_access k5internals;
 
-    dt = end - start;
-    if (dt <= 0)
+    if (krb5int_accessor(&k5internals, KRB5INT_ACCESS_VERSION)
+	|| k5internals.krb_time_to_life == NULL)
 	return 0;
-#ifndef SHORT_LIFETIME
-    if (dt < lifetimes[0])
-	return (dt + 5 * 60 - 1) / (5 * 60);
-    /* This depends on the array being ordered. */
-    for (i = 0; i < NLIFETIMES; i++) {
-	if (lifetimes[i] >= dt)
-	    return i + MINFIXED;
-    }
-    return MAXFIXED;
-#else  /* SHORT_LIFETIME */
-    if (dt > 5 * 60 * 255)
-	return 255;
-    else
-	return (dt + 5 * 60 - 1) / (5 * 60);
-#endif /* SHORT_LIFETIME */
+    return k5internals.krb_time_to_life(start, end);
 }
diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c
index 9159ce177..cf85ea2f8 100644
--- a/src/lib/krb4/mk_auth.c
+++ b/src/lib/krb4/mk_auth.c
@@ -230,7 +230,6 @@ krb_check_auth (buf, checksum, msg_data, session, schedule, laddr, faddr)
 	return KFAILURE;
     cc = krb_rd_priv(buf->dat, (unsigned KRB4_32)buf->length, schedule,
 		     (C_Block *)session, faddr, laddr, msg_data);
-    memset(schedule, 0, sizeof(schedule));
     if (cc)
 	return cc;
 
diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c
index 698d2c2ad..3066f43d7 100644
--- a/src/lib/krb4/mk_req.c
+++ b/src/lib/krb4/mk_req.c
@@ -114,7 +114,6 @@ krb_mk_req_creds_prealm(authent, creds, checksum, myrealm)
 				+ 1 + 1 + ticket->length)
 	|| ticket->length < 0 || ticket->length > 255) {
 	authent->length = 0;
-	memset(creds->session, 0, sizeof(creds->session));
 	return KFAILURE;
     }
 
@@ -150,7 +149,6 @@ krb_mk_req_creds_prealm(authent, creds, checksum, myrealm)
     myrealmlen = strlen(myrealm) + 1;
     if (sizeof(req_id->dat) / 8 < (pnamelen + pinstlen + myrealmlen
 				   + 4 + 1 + 4 + 7) / 8) {
-	memset(creds->session, 0, sizeof(creds->session));
 	return KFAILURE;
     }
 
@@ -185,7 +183,6 @@ krb_mk_req_creds_prealm(authent, creds, checksum, myrealm)
                  (long)req_id->length, key_s, &creds->session, 1);
     /* clean up */
     memset(key_s, 0, sizeof(key_s));
-    memset(creds->session, 0, sizeof(creds->session));
 #endif /* NOENCRYPTION */
 
     /* Copy it into the authenticator */
@@ -252,7 +249,9 @@ krb_mk_req(authent, service, instance, realm, checksum)
     if (retval != KSUCCESS)
 	return retval;
 
-    return krb_mk_req_creds_prealm(authent, &creds, checksum, myrealm);
+    retval = krb_mk_req_creds_prealm(authent, &creds, checksum, myrealm);
+    memset(&creds.session, 0, sizeof(creds.session));
+    return retval;
 }
 
 int KRB5_CALLCONV
diff --git a/src/lib/krb4/password_to_key.c b/src/lib/krb4/password_to_key.c
index 56b5f8e04..c6e60d98c 100644
--- a/src/lib/krb4/password_to_key.c
+++ b/src/lib/krb4/password_to_key.c
@@ -90,7 +90,7 @@ mit_passwd_to_key(
         des_string_to_key(passwd, key);
     } else {
 #if !(defined(_WIN32) || defined(USE_LOGIN_LIBRARY))
-        des_read_password((des_cblock *)key, "Password: ", 0);
+        des_read_password((des_cblock *)key, "Password", 0);
 #else
         return (-1);
 #endif
@@ -143,7 +143,7 @@ afs_passwd_to_key(
         afs_string_to_key(passwd, realm, key);
     } else {
 #if !(defined(_WIN32) || defined(USE_LOGIN_LIBRARY))
-        des_read_password((des_cblock *)key, "Password: ", 0);
+        des_read_password((des_cblock *)key, "Password", 0);
 #else
         return (-1);
 #endif
diff --git a/src/lib/krb4_32.def b/src/lib/krb4_32.def
index d5a3c33f5..11814cebd 100644
--- a/src/lib/krb4_32.def
+++ b/src/lib/krb4_32.def
@@ -54,3 +54,33 @@ EXPORTS
 ;	kstream_destroy
 ;	kstream_set_buffer_mode
 	krb_in_tkt
+
+; Added to match exports from KfM
+    krb_change_password
+    decomp_ticket
+    krb_err_txt
+    ;krb_ad_tkt
+    krb_get_in_tkt
+    krb_get_in_tkt_creds
+    krb_get_pw_in_tkt_creds
+    ;krb_pw_tkt
+    k_isrealm
+    k_isinst
+    k_isname
+    kname_unparse
+    ;kuserok
+    krb_set_lifetime
+    krb_rd_req_int
+    krb_sendauth
+    ;tkt_string
+    krb_set_tkt_string
+    krb_get_num_cred
+    krb_get_nth_cred
+    krb_delete_cred
+    dest_all_tkts
+    krb_get_profile 
+    ;FSp_krb_get_svc_in_tkt
+    ;FSp_put_svc_key
+    ;FSp_read_service_key
+    krb_time_to_life
+    krb_life_to_time
diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
index dc5c7b9df..96efb5628 100644
--- a/src/lib/krb5/Makefile.in
+++ b/src/lib/krb5/Makefile.in
@@ -130,8 +130,8 @@ install-unix:: install-libs
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-krb5_libinit.so krb5_libinit.po $(OUTPRE)krb5_libinit.$(OBJEXT): krb5_libinit.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(BUILDTOP)/include/krb5_err.h $(BUILDTOP)/include/kv5m_err.h \
-  $(BUILDTOP)/include/asn1_err.h $(BUILDTOP)/include/kdb5_err.h \
-  krb5_libinit.h
+krb5_libinit.so krb5_libinit.po $(OUTPRE)krb5_libinit.$(OBJEXT): krb5_libinit.c $(COM_ERR_DEPS) \
+  $(BUILDTOP)/include/krb5.h $(BUILDTOP)/include/krb5_err.h \
+  $(BUILDTOP)/include/kv5m_err.h $(BUILDTOP)/include/asn1_err.h \
+  $(BUILDTOP)/include/kdb5_err.h krb5_libinit.h
 
diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog
index b1ff161c4..18e4c073d 100644
--- a/src/lib/krb5/asn.1/ChangeLog
+++ b/src/lib/krb5/asn.1/ChangeLog
@@ -1,3 +1,103 @@
+2003-10-08  Tom Yu  <tlyu@mit.edu>
+
+	* asn1_k_encode.c (asn1_encode_krb_saved_safe_body): New function;
+	kludge to insert a raw pre-encoded KRB-SAFE-BODY.
+
+	* asn1_k_encode.h (asn1_encode_krb_saved_safe_body): Add
+	prototype.
+
+	* krb5_decode.c (decode_krb5_safe_with_body): New function; saves
+	a copy of the encoding of the KRB-SAFE-BODY to avoid problems
+	caused by re-encoding it during verification.
+
+	* krb5_encode.c (encode_krb5_safe_with_body): New function;
+	re-encode a KRB-SAFE using a saved KRB-SAFE-BODY encoding, to
+	avoid trouble with re-encoding a KRB-SAFE-BODY.
+
+2003-07-22  Sam Hartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* asn1_k_decode.c (asn1_decode_etype_info2_entry_1_3): Decoder for
+	the broken 1.3 ASN.1 behavior for  etype_info2; see bug 1681.
+
+	* asn1_k_decode.h (asn1_decode_etype_info2): Add v1_3_behavior
+	flag for parsing the broken 1.3 behavior  of using an octetString
+	instead of generalString
+
+	* asn1_k_decode.c (asn1_decode_etype_info2_entry):  Expect etype_info2 as generalstring not octetstring
+
+2003-06-20  Sam Hartman  <hartmans@mit.edu>
+
+	* asn1_k_decode.h (asn1_decode_etype_info2): Prototype.  Also
+	deleted prototype for asn1_decode_etype_info_entry as that is not
+	used outside asn1_k_decode.c
+
+	* krb5_decode.c (decode_krb5_etype_info2): Call etype_info2 decoder
+
+	* asn1_k_decode.c (asn1_decode_etype_info_entry): Split out
+	etype_info2 and etype_info decoder  so we ignore tag 2 in the
+	heimdal encoder
+	(asn1_decode_etype_info2): new function
+
+2003-05-23  Sam Hartman  <hartmans@mit.edu>
+
+	* asn1_k_decode.c (asn1_decode_etype_info_entry): Fix logic error
+	that incorrectly set up s2kparams.data 
+
+2003-05-20  Ezra Peisach  <epeisach@bu.edu>
+
+	* asn1_k_encode.c (asn1_encode_krb_safe_body): Use
+	asn1_encode_unsigned_integer for sequence number.
+
+	* asn1_k_decode.c (asn1_decode_krb_safe_body): Use
+	asn1_decode_seqnum to decode sequence number.
+	
+
+2003-05-18  Tom Yu  <tlyu@mit.edu>
+
+	* asn1_decode.c (asn1_decode_maybe_unsigned): New function; decode
+	negative 32-bit numbers into positive unsigned numbers for the
+	sake of backwards compatibility with old code.
+
+	* asn1_decode.h: Add prototype for asn1_decode_maybe_unsigned.
+
+	* asn1_k_decode.c (asn1_decode_seqnum): New function; wrapper
+	around asn1_decode_maybe_unsigned.
+
+	* asn1_k_decode.h: Add prototype for asn1_decode_seqnum.
+
+	* krb5_decode.c (decode_krb5_authenticator) 
+	(decode_krb5_ap_rep_enc_part, decode_krb5_enc_priv_part): Sequence
+	numbers are now unsigned.  Use asn1_decode_seqnum to handle
+	backwards compat with negative sequence numbers.
+
+	* krb5_encode.c (encode_krb5_authenticator) 
+	(encode_krb5_ap_rep_enc_part, encode_krb5_enc_priv_part): Sequence
+	numbers are now unsigned.
+
+2003-05-06  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5_decode.c (decode_krb5_etype_info2): New function; currently
+	the same code as decode_krb5_etype_info.  This means that we can
+	manage to accept s2kparams in etype_info which is wrong but
+	probably harmless.
+
+	* asn1_k_decode.c (asn1_decode_etype_info_entry): Add etype_info2
+	support 
+
+	* asn1_k_encode.c (asn1_encode_etype_info_entry):  Add support for
+	etype-info2 
+
+	* krb5_encode.c (encode_krb5_etype_info2): New function
+
+2003-04-15  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5_encode.c (encode_krb5_setpw_req): new function
+
+2003-04-13  Ezra Peisach  <epeisach@mit.edu>
+
+	* asn1_k_decode.c (asn1_decode_kdc_req_body): Fix memory leak if
+	optional server field is lacking,
+
 2003-03-11  Ken Raeburn  <raeburn@mit.edu>
 
 	* asn1_get.c (asn1_get_tag): Deleted.
diff --git a/src/lib/krb5/asn.1/Makefile.in b/src/lib/krb5/asn.1/Makefile.in
index 6757046cb..8de97f0e4 100644
--- a/src/lib/krb5/asn.1/Makefile.in
+++ b/src/lib/krb5/asn.1/Makefile.in
@@ -61,61 +61,66 @@ clean-unix:: clean-libobjs
 #
 asn1_decode.so asn1_decode.po $(OUTPRE)asn1_decode.$(OBJEXT): asn1_decode.c asn1_decode.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h asn1buf.h asn1_get.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_get.h
 asn1_k_decode.so asn1_k_decode.po $(OUTPRE)asn1_k_decode.$(OBJEXT): asn1_k_decode.c asn1_k_decode.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h asn1buf.h asn1_decode.h asn1_get.h asn1_misc.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_decode.h \
+  asn1_get.h asn1_misc.h
 asn1_encode.so asn1_encode.po $(OUTPRE)asn1_encode.$(OBJEXT): asn1_encode.c asn1_encode.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h asn1buf.h asn1_make.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_make.h
 asn1_get.so asn1_get.po $(OUTPRE)asn1_get.$(OBJEXT): asn1_get.c asn1_get.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h asn1buf.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h
 asn1_make.so asn1_make.po $(OUTPRE)asn1_make.$(OBJEXT): asn1_make.c asn1_make.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h asn1buf.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h
 asn1buf.so asn1buf.po $(OUTPRE)asn1buf.$(OBJEXT): asn1buf.c asn1buf.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h krbasn1.h asn1_get.h
+  krbasn1.h asn1_get.h
 krb5_decode.so krb5_decode.po $(OUTPRE)krb5_decode.$(OBJEXT): krb5_decode.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) krbasn1.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  asn1_k_decode.h asn1buf.h asn1_decode.h asn1_get.h
+  $(SRCTOP)/include/krb5/kdb.h asn1_k_decode.h asn1buf.h \
+  asn1_decode.h asn1_get.h
 krb5_encode.so krb5_encode.po $(OUTPRE)krb5_encode.$(OBJEXT): krb5_encode.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) asn1_k_encode.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  asn1buf.h krbasn1.h asn1_encode.h asn1_make.h
+  $(SRCTOP)/include/krb5/kdb.h asn1buf.h krbasn1.h asn1_encode.h \
+  asn1_make.h
 asn1_k_encode.so asn1_k_encode.po $(OUTPRE)asn1_k_encode.$(OBJEXT): asn1_k_encode.c asn1_k_encode.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  asn1buf.h krbasn1.h asn1_make.h asn1_encode.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h asn1buf.h krbasn1.h asn1_make.h \
+  asn1_encode.h
 asn1_misc.so asn1_misc.po $(OUTPRE)asn1_misc.$(OBJEXT): asn1_misc.c asn1_misc.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  krbasn1.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h krbasn1.h
 
diff --git a/src/lib/krb5/asn.1/asn1_decode.c b/src/lib/krb5/asn.1/asn1_decode.c
index 56904c5ee..65863202a 100644
--- a/src/lib/krb5/asn.1/asn1_decode.c
+++ b/src/lib/krb5/asn.1/asn1_decode.c
@@ -1,7 +1,7 @@
 /*
  * src/lib/krb5/asn.1/asn1_decode.c
  * 
- * Copyright 1994 by the Massachusetts Institute of Technology.
+ * Copyright 1994, 2003 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -106,6 +106,50 @@ asn1_error_code asn1_decode_unsigned_integer(asn1buf *buf, long unsigned int *va
   cleanup();
 }
 
+/*
+ * asn1_decode_maybe_unsigned
+ *
+ * This is needed because older releases of MIT krb5 have signed
+ * sequence numbers.  We want to accept both signed and unsigned
+ * sequence numbers, in the range -2^31..2^32-1, mapping negative
+ * numbers into their positive equivalents in the same way that C's
+ * normal integer conversions do, i.e., would preserve bits on a
+ * two's-complement architecture.
+ */
+asn1_error_code asn1_decode_maybe_unsigned(asn1buf *buf, unsigned long *val)
+{
+  setup();
+  asn1_octet o;
+  unsigned long n, bitsremain;
+  unsigned int i;
+
+  tag(ASN1_INTEGER);
+  o = 0;
+  n = 0;
+  bitsremain = ~0UL;
+  for (i = 0; i < length; i++) {
+    /* Accounts for u_long width not being a multiple of 8. */
+    if (bitsremain < 0xff) return ASN1_OVERFLOW;
+    retval = asn1buf_remove_octet(buf, &o);
+    if (retval) return retval;
+    if (bitsremain == ~0UL) {
+      if (i == 0)
+	n = (o & 0x80) ? ~0UL : 0UL; /* grab sign bit */
+      /*
+       * Skip leading zero or 0xFF octets to humor non-compliant encoders.
+       */
+      if (n == 0 && o == 0)
+	continue;
+      if (n == ~0UL && o == 0xff)
+	continue;
+    }
+    n = (n << 8) | o;
+    bitsremain >>= 8;
+  }
+  *val = n;
+  cleanup();
+}
+
 asn1_error_code asn1_decode_oid(asn1buf *buf, unsigned int *retlen, asn1_octet **val)
 {
   setup();
diff --git a/src/lib/krb5/asn.1/asn1_decode.h b/src/lib/krb5/asn.1/asn1_decode.h
index 449a58900..cafbf3fd3 100644
--- a/src/lib/krb5/asn.1/asn1_decode.h
+++ b/src/lib/krb5/asn.1/asn1_decode.h
@@ -62,6 +62,8 @@ asn1_error_code asn1_decode_integer
 	(asn1buf *buf, long *val);
 asn1_error_code asn1_decode_unsigned_integer
 	(asn1buf *buf, unsigned long *val);
+asn1_error_code asn1_decode_maybe_unsigned
+	(asn1buf *buf, unsigned long *val);
 asn1_error_code asn1_decode_null
 	(asn1buf *buf);
 
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c
index c64ebb84e..3ffb701fe 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.c
+++ b/src/lib/krb5/asn.1/asn1_k_decode.c
@@ -320,6 +320,17 @@ integer_convert(asn1_decode_authdatatype,krb5_authdatatype)
 unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2)
 unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4)
 
+asn1_error_code asn1_decode_seqnum(asn1buf *buf, krb5_ui_4 *val)
+{
+  asn1_error_code retval;
+  unsigned long n;
+
+  retval = asn1_decode_maybe_unsigned(buf, &n);
+  if (retval) return retval;
+  *val = (krb5_ui_4)n & 0xffffffff;
+  return 0;
+}
+
 asn1_error_code asn1_decode_msgtype(asn1buf *buf, krb5_msgtype *val)
 {
   asn1_error_code retval;
@@ -541,7 +552,9 @@ asn1_error_code asn1_decode_kdc_req(asn1buf *buf, krb5_kdc_req *val)
 asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val)
 {
   setup();
-  { begin_structure();
+  { 
+    krb5_principal psave;
+    begin_structure();
     get_field(val->kdc_options,0,asn1_decode_kdc_options);
     if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); }
     opt_field(val->client,1,asn1_decode_principal_name,NULL);
@@ -550,7 +563,19 @@ asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val)
     if(val->client != NULL){
       retval = asn1_krb5_realm_copy(val->client,val->server);
       if(retval) return retval; }
+
+    /* If opt_field server is missing, memory reference to server is
+       lost and results in memory leak */
+    psave = val->server;
     opt_field(val->server,3,asn1_decode_principal_name,NULL);
+    if(val->server == NULL){
+      if(psave->realm.data) {
+	free(psave->realm.data);
+	psave->realm.data = NULL;
+	psave->realm.length=0;
+      }
+      free(psave);
+    }
     opt_field(val->from,4,asn1_decode_kerberos_time,0);
     get_field(val->till,5,asn1_decode_kerberos_time);
     opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
@@ -580,7 +605,7 @@ asn1_error_code asn1_decode_krb_safe_body(asn1buf *buf, krb5_safe *val)
     get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
     opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
     opt_field(val->usec,2,asn1_decode_int32,0);
-    opt_field(val->seq_number,3,asn1_decode_int32,0);
+    opt_field(val->seq_number,3,asn1_decode_seqnum,0);
     alloc_field(val->s_address,krb5_address);
     get_field(*(val->s_address),4,asn1_decode_host_address);
     if(tagnum == 5){
@@ -782,7 +807,33 @@ asn1_error_code asn1_decode_sequence_of_checksum(asn1buf *buf, krb5_checksum ***
   decode_array_body(krb5_checksum, asn1_decode_checksum);
 }
 
-asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val)
+static asn1_error_code asn1_decode_etype_info2_entry(asn1buf *buf, krb5_etype_info_entry *val )
+{
+  setup();
+  { begin_structure();
+    get_field(val->etype,0,asn1_decode_enctype);
+    if (tagnum == 1) {
+	    get_lenfield(val->length,val->salt,1,asn1_decode_generalstring);
+    } else {
+	    val->length = KRB5_ETYPE_NO_SALT;
+	    val->salt = 0;
+    }
+    if ( tagnum ==2) {
+      krb5_octet *params ;
+      get_lenfield( val->s2kparams.length, params,
+		      2, asn1_decode_octetstring);
+      val->s2kparams.data = ( char *) params;
+    } else {
+	val->s2kparams.data = NULL;
+	val->s2kparams.length = 0;
+    }
+    end_structure();
+    val->magic = KV5M_ETYPE_INFO_ENTRY;
+  }
+  cleanup();
+}
+
+static asn1_error_code asn1_decode_etype_info2_entry_1_3(asn1buf *buf, krb5_etype_info_entry *val )
 {
   setup();
   { begin_structure();
@@ -793,17 +844,59 @@ asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry
 	    val->length = KRB5_ETYPE_NO_SALT;
 	    val->salt = 0;
     }
+    if ( tagnum ==2) {
+      krb5_octet *params ;
+      get_lenfield( val->s2kparams.length, params,
+		      2, asn1_decode_octetstring);
+      val->s2kparams.data = ( char *) params;
+    } else {
+	val->s2kparams.data = NULL;
+	val->s2kparams.length = 0;
+    }
     end_structure();
     val->magic = KV5M_ETYPE_INFO_ENTRY;
   }
   cleanup();
 }
 
-asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val)
+
+static asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val )
+{
+  setup();
+  { begin_structure();
+    get_field(val->etype,0,asn1_decode_enctype);
+    if (tagnum == 1) {
+	    get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
+    } else {
+	    val->length = KRB5_ETYPE_NO_SALT;
+	    val->salt = 0;
+    }
+    val->s2kparams.data = NULL;
+    val->s2kparams.length = 0;
+    
+    end_structure();
+    val->magic = KV5M_ETYPE_INFO_ENTRY;
+  }
+  cleanup();
+}
+
+asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val )
 {
   decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry);
 }
 
+asn1_error_code asn1_decode_etype_info2(asn1buf *buf, krb5_etype_info_entry ***val ,
+					krb5_boolean v1_3_behavior)
+{
+    if (v1_3_behavior) {
+	decode_array_body(krb5_etype_info_entry,
+			  asn1_decode_etype_info2_entry_1_3);
+    } else {
+	decode_array_body(krb5_etype_info_entry,
+			  asn1_decode_etype_info2_entry);
+    }
+}
+
 asn1_error_code asn1_decode_passwdsequence(asn1buf *buf, passwd_phrase_element *val)
 {
   setup();
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.h b/src/lib/krb5/asn.1/asn1_k_decode.h
index 8f8b0bcff..1852e762f 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.h
+++ b/src/lib/krb5/asn.1/asn1_k_decode.h
@@ -89,6 +89,8 @@ asn1_error_code asn1_decode_ui_2
 	(asn1buf *buf, krb5_ui_2 *val);
 asn1_error_code asn1_decode_ui_4
 	(asn1buf *buf, krb5_ui_4 *val);
+asn1_error_code asn1_decode_seqnum
+	(asn1buf *buf, krb5_ui_4 *val);
 asn1_error_code asn1_decode_kerberos_time
 	(asn1buf *buf, krb5_timestamp *val);
 asn1_error_code asn1_decode_sam_flags
@@ -185,6 +187,8 @@ asn1_error_code asn1_decode_sequence_of_passwdsequence
 
 asn1_error_code asn1_decode_etype_info
 	(asn1buf *buf, krb5_etype_info_entry ***val);
+asn1_error_code asn1_decode_etype_info2
+	(asn1buf *buf, krb5_etype_info_entry ***val, krb5_boolean v1_3_behavior);
 
 
 #endif
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 9226f7ca2..00cfab032 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -27,6 +27,7 @@
 #include "asn1_k_encode.h"
 #include "asn1_make.h"
 #include "asn1_encode.h"
+#include <assert.h>
 
 /**** asn1 macros ****/
 #if 0
@@ -643,7 +644,7 @@ asn1_error_code asn1_encode_krb_safe_body(asn1buf *buf, const krb5_safe *val, un
     asn1_addfield(val->r_address,5,asn1_encode_host_address);
   asn1_addfield(val->s_address,4,asn1_encode_host_address);
   if(val->seq_number)
-    asn1_addfield(val->seq_number,3,asn1_encode_integer);
+    asn1_addfield(val->seq_number,3,asn1_encode_unsigned_integer);
   if(val->timestamp){
     asn1_addfield(val->usec,2,asn1_encode_integer);
     asn1_addfield(val->timestamp,1,asn1_encode_kerberos_time);
@@ -708,24 +709,33 @@ asn1_error_code asn1_encode_krb_cred_info(asn1buf *buf, const krb5_cred_info *va
   asn1_cleanup();
 }
 
-asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info_entry *val, unsigned int *retlen)
+asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info_entry *val,
+					     unsigned int *retlen, int etype_info2)
 {
   asn1_setup();
 
+  assert(val->s2kparams.data == NULL || etype_info2);
   if(val == NULL || (val->length > 0 && val->length != KRB5_ETYPE_NO_SALT &&
 		     val->salt == NULL))
      return ASN1_MISSING_FIELD;
-
-  if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT)
+  if(val->s2kparams.data != NULL)
+      asn1_addlenfield(val->s2kparams.length, val->s2kparams.data, 2,
+		       asn1_encode_octetstring);
+  if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT){
+      if (etype_info2)
 	  asn1_addlenfield(val->length,val->salt,1,
-			   asn1_encode_octetstring);
-  asn1_addfield(val->etype,0,asn1_encode_integer);
+			   asn1_encode_generalstring)
+      else 	  asn1_addlenfield(val->length,val->salt,1,
+				   asn1_encode_octetstring);
+  }
+asn1_addfield(val->etype,0,asn1_encode_integer);
   asn1_makeseq();
 
   asn1_cleanup();
 }
 
-asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry **val, unsigned int *retlen)
+asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry **val,
+				       unsigned int *retlen, int etype_info2)
 {
     asn1_setup();
     int i;
@@ -734,7 +744,7 @@ asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry
   
     for(i=0; val[i] != NULL; i++); /* get to the end of the array */
     for(i--; i>=0; i--){
-	retval = asn1_encode_etype_info_entry(buf,val[i],&length);
+	retval = asn1_encode_etype_info_entry(buf,val[i],&length, etype_info2);
 	if(retval) return retval;
 	sum += length;
     }
@@ -932,3 +942,20 @@ asn1_error_code asn1_encode_predicted_sam_response(asn1buf *buf, const krb5_pred
 
   asn1_cleanup();
 }
+
+/*
+ * Do some ugliness to insert a raw pre-encoded KRB-SAFE-BODY.
+ */
+asn1_error_code asn1_encode_krb_saved_safe_body(asn1buf *buf, const krb5_data *body, unsigned int *retlen)
+{
+  asn1_error_code retval;
+
+  retval = asn1buf_insert_octetstring(buf, body->length,
+				      (krb5_octet *)body->data);
+  if (retval){
+    asn1buf_destroy(&buf);
+    return retval; 
+  }
+  *retlen = body->length;
+  return 0;
+}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.h b/src/lib/krb5/asn.1/asn1_k_encode.h
index 5914e0981..caa46c570 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.h
+++ b/src/lib/krb5/asn.1/asn1_k_encode.h
@@ -219,11 +219,11 @@ asn1_error_code asn1_encode_alt_method
 
 asn1_error_code asn1_encode_etype_info_entry
 	(asn1buf *buf, const krb5_etype_info_entry *val,
-		   unsigned int *retlen);
+		   unsigned int *retlen, int etype_info2);
 
 asn1_error_code asn1_encode_etype_info
 	(asn1buf *buf, const krb5_etype_info_entry **val,
-		   unsigned int *retlen);
+		   unsigned int *retlen, int etype_info2);
 
 asn1_error_code asn1_encode_passwdsequence
 	(asn1buf *buf, const passwd_phrase_element *val, unsigned int *retlen);
@@ -266,4 +266,7 @@ asn1_error_code asn1_encode_predicted_sam_response
 	(asn1buf *buf, const krb5_predicted_sam_response *val, 
 		   unsigned int *retlen);
 
+asn1_error_code asn1_encode_krb_saved_safe_body
+	(asn1buf *buf, const krb5_data *body, unsigned int *retlen);
+
 #endif
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index 03a30295b..596997fe9 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -90,6 +90,7 @@ if((var) == NULL) clean_return(ENOMEM)
   construction = t2.construction;		\
   tagnum = t2.tagnum;				\
   indef = t2.indef;				\
+  taglen = t2.length;				\
 }
 
 #define get_eoc()						\
@@ -107,6 +108,7 @@ if((var) == NULL) clean_return(ENOMEM)
 
 /* decode sequence header and initialize tagnum with the first field */
 #define begin_structure()\
+unsigned int taglen;\
 asn1buf subbuf;\
 int seqindef;\
 int indef;\
@@ -219,7 +221,7 @@ krb5_error_code decode_krb5_authenticator(const krb5_data *code, krb5_authentica
     get_field((*rep)->ctime,5,asn1_decode_kerberos_time);
     if(tagnum == 6){ alloc_field((*rep)->subkey,krb5_keyblock); }
     opt_field(*((*rep)->subkey),6,asn1_decode_encryption_key);
-    opt_field((*rep)->seq_number,7,asn1_decode_int32);
+    opt_field((*rep)->seq_number,7,asn1_decode_seqnum);
     opt_field((*rep)->authorization_data,8,asn1_decode_authorization_data);
     (*rep)->magic = KV5M_AUTHENTICATOR;
     end_structure();
@@ -440,7 +442,7 @@ krb5_error_code decode_krb5_ap_rep_enc_part(const krb5_data *code, krb5_ap_rep_e
     get_field((*rep)->cusec,1,asn1_decode_int32);
     if(tagnum == 2){ alloc_field((*rep)->subkey,krb5_keyblock); }
     opt_field(*((*rep)->subkey),2,asn1_decode_encryption_key);
-    opt_field((*rep)->seq_number,3,asn1_decode_int32);
+    opt_field((*rep)->seq_number,3,asn1_decode_seqnum);
     end_structure();
     (*rep)->magic = KV5M_AP_REP_ENC_PART;
   }
@@ -494,8 +496,26 @@ krb5_error_code decode_krb5_kdc_req_body(const krb5_data *code, krb5_kdc_req **r
   cleanup(free);
 }
 
-krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
+/*
+ * decode_krb5_safe_with_body
+ *
+ * Like decode_krb5_safe(), but grabs the encoding of the
+ * KRB-SAFE-BODY as well, in case re-encoding would produce a
+ * different encoding.  (Yes, we're using DER, but there's this
+ * annoying problem with pre-1.3.x code using signed sequence numbers,
+ * which we permissively decode and cram into unsigned 32-bit numbers.
+ * When they're re-encoded, they're no longer negative if they started
+ * out negative, so checksum verification fails.)
+ *
+ * This does *not* perform any copying; the returned pointer to the
+ * encoded KRB-SAFE-BODY points into the input buffer.
+ */
+krb5_error_code decode_krb5_safe_with_body(
+  const krb5_data *code,
+  krb5_safe **rep,
+  krb5_data *body)
 {
+  krb5_data tmpbody;
   setup();
   alloc_field(*rep,krb5_safe);
   clear_field(rep,checksum);
@@ -511,12 +531,26 @@ krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
       if(msg_type != KRB5_SAFE) clean_return(KRB5_BADMSGTYPE);
 #endif
     }
+    /*
+     * Gross kludge to extract pointer to encoded safe-body.  Relies
+     * on tag prefetch done by next_tag().  Don't handle indefinite
+     * encoding, as it's too much work.
+     */
+    if (!indef) {
+      tmpbody.length = taglen;
+      tmpbody.data = subbuf.next;
+    } else {
+      tmpbody.length = 0;
+      tmpbody.data = NULL;
+    }
     get_field(**rep,2,asn1_decode_krb_safe_body);
     alloc_field((*rep)->checksum,krb5_checksum);
     get_field(*((*rep)->checksum),3,asn1_decode_checksum);
   (*rep)->magic = KV5M_SAFE;
     end_structure();
   }
+  if (body != NULL)
+    *body = tmpbody;
   cleanup_manual();
 error_out:
   if (rep && *rep) {
@@ -526,6 +560,11 @@ error_out:
   return retval;
 }
 
+krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
+{
+  return decode_krb5_safe_with_body(code, rep, NULL);
+}
+
 krb5_error_code decode_krb5_priv(const krb5_data *code, krb5_priv **rep)
 {
   setup();
@@ -561,7 +600,7 @@ krb5_error_code decode_krb5_enc_priv_part(const krb5_data *code, krb5_priv_enc_p
     get_lenfield((*rep)->user_data.length,(*rep)->user_data.data,0,asn1_decode_charstring);
     opt_field((*rep)->timestamp,1,asn1_decode_kerberos_time);
     opt_field((*rep)->usec,2,asn1_decode_int32);
-    opt_field((*rep)->seq_number,3,asn1_decode_int32);
+    opt_field((*rep)->seq_number,3,asn1_decode_seqnum);
     alloc_field((*rep)->s_address,krb5_address);
     get_field(*((*rep)->s_address),4,asn1_decode_host_address);
     if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); }
@@ -744,6 +783,21 @@ krb5_error_code decode_krb5_etype_info(const krb5_data *code, krb5_etype_info_en
   cleanup_none();		/* we're not allocating anything here */
 }
 
+krb5_error_code decode_krb5_etype_info2(const krb5_data *code, krb5_etype_info_entry ***rep)
+{
+    setup_buf_only();
+    *rep = 0;
+    retval = asn1_decode_etype_info2(&buf,rep, 0);
+    if (retval == ASN1_BAD_ID) {
+	retval = asn1buf_wrap_data(&buf,code);
+	if(retval) clean_return(retval);
+	retval = asn1_decode_etype_info2(&buf, rep, 1);
+    }
+    if(retval) clean_return(retval);
+    cleanup_none();		/* we're not allocating anything here */
+}
+
+
 krb5_error_code decode_krb5_enc_data(const krb5_data *code, krb5_enc_data **rep)
 {
   setup_buf_only();
diff --git a/src/lib/krb5/asn.1/krb5_encode.c b/src/lib/krb5/asn.1/krb5_encode.c
index 2a4f7bb14..ecdfa1878 100644
--- a/src/lib/krb5/asn.1/krb5_encode.c
+++ b/src/lib/krb5/asn.1/krb5_encode.c
@@ -166,7 +166,7 @@ krb5_error_code encode_krb5_authenticator(const krb5_authenticator *rep, krb5_da
 
   /* seq-number[7]		INTEGER OPTIONAL */
   if(rep->seq_number != 0)
-    krb5_addfield(rep->seq_number,7,asn1_encode_integer);
+    krb5_addfield(rep->seq_number,7,asn1_encode_unsigned_integer);
 
   /* subkey[6]			EncryptionKey OPTIONAL */
   if(rep->subkey != NULL)
@@ -305,6 +305,7 @@ krb5_error_code encode_krb5_enc_kdc_rep_part(const krb5_enc_kdc_rep_part *rep, k
 #ifdef KRB5_ENCKRB5KDCREPPART_COMPAT
   krb5_apptag(26);
 #else
+  /* XXX WRONG!!! Should use 25 || 26, not the outer KDC_REP tags! */
   if (rep->msg_type == KRB5_AS_REP) { krb5_apptag(ASN1_KRB_AS_REP); }
   else if (rep->msg_type == KRB5_TGS_REP) { krb5_apptag(ASN1_KRB_TGS_REP); }
   else return KRB5_BADMSGTYPE;
@@ -395,7 +396,7 @@ krb5_error_code encode_krb5_ap_rep_enc_part(const krb5_ap_rep_enc_part *rep, krb
 
   /* seq-number[3]	INTEGER OPTIONAL */
   if(rep->seq_number)
-    krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+    krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
 
   /* subkey[2]		EncryptionKey OPTIONAL */
   if(rep->subkey != NULL)
@@ -477,6 +478,43 @@ krb5_error_code encode_krb5_safe(const krb5_safe *rep, krb5_data **code)
   krb5_cleanup();
 }
 
+/*
+ * encode_krb5_safe_with_body
+ *
+ * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY
+ * encoding to avoid problems with re-encoding.
+ */
+krb5_error_code encode_krb5_safe_with_body(
+  const krb5_safe *rep,
+  const krb5_data *body,
+  krb5_data **code)
+{
+  krb5_setup();
+
+  if (body == NULL) {
+      asn1buf_destroy(&buf);
+      return ASN1_MISSING_FIELD;
+  }
+
+  /* cksum[3]		Checksum */
+  krb5_addfield(rep->checksum,3,asn1_encode_checksum);
+
+  /* safe-body[2]	KRB-SAFE-BODY */
+  krb5_addfield(body,2,asn1_encode_krb_saved_safe_body);
+
+  /* msg-type[1]	INTEGER */
+  krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
+
+  /* pvno[0]		INTEGER */
+  krb5_addfield(KVNO,0,asn1_encode_integer);
+
+  /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
+  krb5_makeseq();
+  krb5_apptag(20);
+
+  krb5_cleanup();
+}
+
 krb5_error_code encode_krb5_priv(const krb5_priv *rep, krb5_data **code)
 {
   krb5_setup();
@@ -510,7 +548,7 @@ krb5_error_code encode_krb5_enc_priv_part(const krb5_priv_enc_part *rep, krb5_da
 
   /* seq-number[3]	INTEGER OPTIONAL */
   if(rep->seq_number)
-    krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+    krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
 
   /* usec[2]		INTEGER OPTIONAL */
   if(rep->timestamp){
@@ -678,11 +716,21 @@ krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **c
 krb5_error_code encode_krb5_etype_info(const krb5_etype_info_entry **rep, krb5_data **code)
 {
   krb5_setup();
-  retval = asn1_encode_etype_info(buf,rep,&length);
+  retval = asn1_encode_etype_info(buf,rep,&length, 0);
+  if(retval) return retval;
+  sum += length;
+  krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_etype_info2(const krb5_etype_info_entry **rep, krb5_data **code)
+{
+  krb5_setup();
+  retval = asn1_encode_etype_info(buf,rep,&length, 1);
   if(retval) return retval;
   sum += length;
   krb5_cleanup();
 }
+  
 
 krb5_error_code encode_krb5_enc_data(const krb5_enc_data *rep, krb5_data **code)
 {
@@ -822,3 +870,20 @@ krb5_error_code encode_krb5_predicted_sam_response(const krb5_predicted_sam_resp
   sum += length;
   krb5_cleanup();
 }
+
+krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
+				      char *password, krb5_data **code)
+{
+  /* Macros really want us to have a variable called rep which we do not need*/
+  const char *rep = "dummy string";
+
+  krb5_setup();
+
+  krb5_addfield(target,2,asn1_encode_realm);
+  krb5_addfield(target,1,asn1_encode_principal_name);
+  krb5_addlenfield(strlen(password), password,0,asn1_encode_octetstring);
+  krb5_makeseq();
+
+
+  krb5_cleanup();
+}
diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog
index 0b44b4d54..0f50b1d39 100644
--- a/src/lib/krb5/ccache/ChangeLog
+++ b/src/lib/krb5/ccache/ChangeLog
@@ -1,3 +1,158 @@
+2004-02-04  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c:
+     Remove reference to <ntstatus.h> as it is not present in the August 2001
+     Platform SDK used by Pismere.  Instead copy the error value.
+
+2004-02-02  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_msla.c: 
+     GetMSCacheTicketFromCacheInfo() uses the tktinfo->TicketFlags as the
+     value to assign to TicketRequest->TicketFlags.  This field is blindly
+     inserted into the kdc-options[0] field of the TGS_REQ.  If there are
+     bits such as TRANSIT_POLICY_CHECKED in the TicketFlags, this will result
+     in an unknown TGS_OPTION being processed by the KDC.
+
+     This has been fixed by mapping the Ticket Flags to KDC options.
+     We only map Forwardable, Forwarded, Proxiable, and Renewable.  The others
+     should not be used.
+
+2004-02-02  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c: the MSLSA code was crashing on Pismere machines when 
+     logging on with cross realm credentials.  On these machines there are
+     8 tickets within the LSA cache from two different realms.  One of the
+     krbtgt/CLIENT-REALM@CLIENT-REALM tickets (not the Initial ticket but
+     a Forwarded ticket) is inaccessible to the ms2mit.exe and leash32.exe
+     processes.  The attempt to access the ticket returns a SubStatus code
+     of STATUS_LOGON_FAILURE (0xC000006DL) which is supposed to mean that
+     the logon attempt was invalid due to bad authentication information.
+     kerbtray has no problem listing this ticket.  The other seven tickets
+     in the cache including the Initial Ticket are accessible.  Modified 
+     krb5_lcc_next_cred() to skip to the next ticket if an attempt to read
+     a single ticket fails.
+
+2004-01-31  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c: Optimize the get next logic by storing a handle to
+     the MS TGT in the lcc_cursor data structure
+
+2004-01-31  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c: Do not return tickets to the caller if they contain
+     NULL session keys.  This is to prevent useless TGTs from being
+     placed into the MIT credential cache.
+
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c: As per extensive conversations with Doug Engert we have
+     concluded that MS is not specifying a complete set of domain information
+     when it comes to service tickets other than the initial TGT.  What happens
+     is the client principal domain cannot be derived from the fields they
+     export.  Code has now been added to obtain the domain from the initial
+     TGT and use that when constructing the client principals for all tickets.
+
+     This behavior can be turned off by setting a registry either on a per-user
+     or a system-wide basis:
+
+        {HKCU,HKLM}\Software\MIT\Kerberos5
+            PreserveInitialTicketIdentity = 0x0 (DWORD)
+           
+
+2004-01-06  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_file.c, cc_memory.c:
+     Add stub implementations for unimplemented krb5_cc_remove_cred()
+     Returns KRB5_CC_NOSUPP
+
+   * cc_mslsa.c:
+     Add implementation for krb5_cc_remove_cred().  Returns KRB5_CC_READONLY.
+
+2003-12-18  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_retr.c:  Extract the test to determine if a credential matches
+     a requested credential according to the specified fields into 
+     a private function: krb5int_cc_creds_match_request()
+
+   * cc_mslsa.c: Extend the functionality of krb5_lcc_retrieve() to
+     perform a MS Kerberos LSA ticket request if there is no matching
+     credential in the cache.  The MS Kerberos LSA places the following
+     restriction on what tickets it will place into the LSA cache:
+         tickets obtained by an application request for a specific
+         set of kerberos flags or enctype will not be cached.
+     Therefore, we first make a request with no flags or enctype in 
+     the hope that we will be lucky and get the right ones anyway.
+     If not, we make the application's request and return that ticket
+     if it matches the other criteria.
+
+     Implemented a similar technique for krb5_lcc_store().  Since we
+     can not write to the cache, when a store request is made we 
+     instead perform a ticket request through the lsa for a matching
+     credential.  If we receive one, we return success.  Otherwise,
+     we return the KRB5_CC_READONLY error.
+
+   With these changes I am now able to operate entirely with the MSLSA
+   ccache as the default cache provided the MS LSA credentials are
+   for the principal I wish to use.  Obviously, one cannot change
+   principals while the MSLSA ccache is the default.
+
+2003-12-15  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_msla.c:   Enable purging of the MS Kerberos LSA cache when the TGT
+     has expired.  This will force the LSA to get a new TGT instead of 
+     returning the expired version.
+
+2003-12-15  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c:  Perform a GetMSTGT() call as part of krb5_lcc_start_seq_get
+     to ensure that the tgt is refreshed
+
+2003-12-13  Jeffrey Altman <jaltman@mit.edu>
+
+   * Makefile.in: Remove extranenous spaces in ##WIN32## constructs
+     defining MSLSA_SRC MSLSA_OBJ
+
+2003-12-12  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in: Move ##WIN32## constructs from inside
+	backslash-continued lists, as it was breaking them.  Move explicit
+	dependency information from under automatic dependencies.
+
+2003-12-11  Jeffrey Altman <jaltman@mit.edu>
+
+    * Makefile.in, ccbase.c, cc_mslsa.c (new)
+
+    Remove all of the code which was duplicated between ms2mit.c
+    and the KfW Leash libraries (and who knows how many applications
+    shipped by third parties) and use it as the basis for a new
+    krb5_ccache type, "MSLSA:".  The "MSLSA:" ccache type is a
+    read-only ccache which can be used either as a monitor of the
+    contents of the Microsoft LSA cache or as a source for copying
+    the contents to another ccache type.  The purpose of migrating
+    this code to the krb5_32.dll is to avoid the need for applications
+    to be consistently updated each time Microsoft makes a change
+    to the behavior of the LSA cache.  Changes have occurred with
+    the release of 2000, XP, and 2003 so far.  Also, the code for
+    working with the MS LSA cache is not well documented and many
+    mistakes were made in the original versions of the ms2mit.c
+    code base.  Unfortunately, the ms2mit.c code has been copied
+    into many other applications.  
+
+    With access to this new ccache type, the ms2mit.c source file
+    is reduced from 890 lines to 80 lines including the copyright
+    banner.
+
+2003-11-26  Jeffrey Altman <jaltman@mit.edu>
+
+    * cc_default.c: Add support for Leash Kinit Dialog on Windows to
+            krb5int_c_default()
+
+2003-07-22  Sam Hartman  <hartmans@mit.edu>
+
+	* ccbase.c: Always register the file credentials cache type.  If
+	we do not, then when USE_CCAPI is defined, it will not be
+	available. 
+
 2003-03-06  Alexandra Ellwood <lxs@mit.edu>
 
     * ccdefault.c: Remove Mac header goober and include
diff --git a/src/lib/krb5/ccache/Makefile.in b/src/lib/krb5/ccache/Makefile.in
index bbf61bebb..01e654462 100644
--- a/src/lib/krb5/ccache/Makefile.in
+++ b/src/lib/krb5/ccache/Makefile.in
@@ -17,6 +17,9 @@ LOCALINCLUDES = -I$(srcdir)$(S)ccapi $(WIN_INCLUDES)
 ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst
 ##WIN16##LIBNAME=..\krb5.lib
 
+##WIN32##MSLSA_OBJ = $(OUTPRE)cc_mslsa.$(OBJEXT)
+##WIN32##MSLSA_SRC = $(srcdir)/cc_mslsa.c
+
 MAC_SUBDIRS = ccapi
 
 STLIBOBJS= \
@@ -37,7 +40,7 @@ OBJS=	$(OUTPRE)ccbase.$(OBJEXT) \
 	$(OUTPRE)cc_file.$(OBJEXT) \
 	$(OUTPRE)cc_memory.$(OBJEXT) \
 	$(OUTPRE)ccfns.$(OBJEXT) \
-	$(OUTPRE)ser_cc.$(OBJEXT)
+	$(OUTPRE)ser_cc.$(OBJEXT) $(MSLSA_OBJ)
 
 SRCS=	$(srcdir)/ccbase.c \
 	$(srcdir)/cccopy.c \
@@ -47,7 +50,7 @@ SRCS=	$(srcdir)/ccbase.c \
 	$(srcdir)/cc_file.c \
 	$(srcdir)/cc_memory.c \
 	$(srcdir)/ccfns.c \
-	$(srcdir)/ser_cc.c
+	$(srcdir)/ser_cc.c $(MSLSA_SRC)
 
 ##DOS##OBJS=$(OBJS) $(OUTPRE)ccfns.$(OBJEXT)
 
@@ -97,7 +100,7 @@ check-unix:: t_cc
 clean-unix::
 	$(RM) t_cc t_cc.o
 
-
+##WIN32## $(OUTPRE)cc_mslsa.$(OBJEXT): cc_mslsa.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS)
 
 # @libobj_frag@
 
@@ -108,47 +111,49 @@ clean-unix::
 #
 ccbase.so ccbase.po $(OUTPRE)ccbase.$(OBJEXT): ccbase.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  fcc.h
 cccopy.so cccopy.po $(OUTPRE)cccopy.$(OBJEXT): cccopy.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ccdefault.so ccdefault.po $(OUTPRE)ccdefault.$(OBJEXT): ccdefault.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ccdefops.so ccdefops.po $(OUTPRE)ccdefops.$(OBJEXT): ccdefops.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h fcc.h
+  fcc.h
 cc_retr.so cc_retr.po $(OUTPRE)cc_retr.$(OBJEXT): cc_retr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 cc_file.so cc_file.po $(OUTPRE)cc_file.$(OBJEXT): cc_file.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 cc_memory.so cc_memory.po $(OUTPRE)cc_memory.$(OBJEXT): cc_memory.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ccfns.so ccfns.po $(OUTPRE)ccfns.$(OBJEXT): ccfns.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ser_cc.so ser_cc.po $(OUTPRE)ser_cc.$(OBJEXT): ser_cc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index eb051c150..dff3038bd 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -2305,6 +2305,18 @@ lose:
 #undef TCHECK
 }
 
+/* 
+ * Non-functional stub implementation for krb5_fcc_remove
+ * 
+ * Errors:
+ *    KRB5_CC_NOSUPP - not implemented
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_fcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
+                     krb5_creds *creds)
+{
+    return KRB5_CC_NOSUPP;
+}
 
 /*
  * Requires:
@@ -2413,7 +2425,7 @@ const krb5_cc_ops krb5_fcc_ops = {
      krb5_fcc_start_seq_get,
      krb5_fcc_next_cred,
      krb5_fcc_end_seq_get,
-     NULL, /* XXX krb5_fcc_remove, */
+     krb5_fcc_remove_cred,
      krb5_fcc_set_flags,
 };
 
@@ -2473,6 +2485,6 @@ const krb5_cc_ops krb5_cc_file_ops = {
      krb5_fcc_start_seq_get,
      krb5_fcc_next_cred,
      krb5_fcc_end_seq_get,
-     NULL, /* XXX krb5_fcc_remove, */
+     krb5_fcc_remove_cred,
      krb5_fcc_set_flags,
 };
diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c
index 97ec32752..c3aeb1e8b 100644
--- a/src/lib/krb5/ccache/cc_memory.c
+++ b/src/lib/krb5/ccache/cc_memory.c
@@ -519,6 +519,20 @@ krb5_mcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
      return ret;
 }
 
+/* 
+ * Non-functional stub implementation for krb5_mcc_remove
+ * 
+ * Errors:
+ *    KRB5_CC_NOSUPP - not implemented
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_mcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
+                     krb5_creds *creds)
+{
+    return KRB5_CC_NOSUPP;
+}
+
+
 /*
  * Requires:
  * id is a cred cache returned by krb5_mcc_resolve or
@@ -553,6 +567,6 @@ const krb5_cc_ops krb5_mcc_ops = {
      krb5_mcc_start_seq_get,
      krb5_mcc_next_cred,
      krb5_mcc_end_seq_get,
-     NULL, /* XXX krb5_mcc_remove, */
+     krb5_mcc_remove_cred,
      krb5_mcc_set_flags,
 };
diff --git a/src/lib/krb5/ccache/cc_mslsa.c b/src/lib/krb5/ccache/cc_mslsa.c
new file mode 100644
index 000000000..29648b8b3
--- /dev/null
+++ b/src/lib/krb5/ccache/cc_mslsa.c
@@ -0,0 +1,1525 @@
+/*
+ * lib/krb5/ccache/cc_mslsa.c
+ *
+ * Copyright 2003 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ * Copyright 2000 by Carnegie Mellon University
+ *
+ * All Rights Reserved
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Carnegie Mellon
+ * University not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.
+ * 
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
+ * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Implementation of read-only microsoft windows lsa credentials cache
+ */
+
+#ifdef _WIN32
+#define UNICODE
+#define _UNICODE
+
+#include "k5-int.h"
+#include "com_err.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <conio.h>
+#include <time.h>
+#define SECURITY_WIN32
+#include <security.h>
+#include <ntsecapi.h>
+
+#define MAX_MSG_SIZE 256
+#define MAX_MSPRINC_SIZE 1024
+
+static VOID
+ShowWinError(LPSTR szAPI, DWORD dwError)
+{
+
+    // TODO - Write errors to event log so that scripts that don't
+    // check for errors will still get something in the event log
+
+    WCHAR szMsgBuf[MAX_MSG_SIZE];
+    DWORD dwRes;
+
+    printf("Error calling function %s: %lu\n", szAPI, dwError);
+
+    dwRes = FormatMessage (
+        FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        dwError,
+        MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
+        szMsgBuf,
+        MAX_MSG_SIZE,
+        NULL);
+    if (0 == dwRes) {
+        printf("FormatMessage failed with %d\n", GetLastError());
+        ExitProcess(EXIT_FAILURE);
+    }
+
+    printf("%S",szMsgBuf);
+}
+
+static VOID
+ShowLsaError(LPSTR szAPI, NTSTATUS Status)
+{
+    //
+    // Convert the NTSTATUS to Winerror. Then call ShowWinError().
+    //
+    ShowWinError(szAPI, LsaNtStatusToWinError(Status));
+}
+
+
+
+static BOOL
+WINAPI
+UnicodeToANSI(LPTSTR lpInputString, LPSTR lpszOutputString, int nOutStringLen)
+{
+    CPINFO CodePageInfo;
+
+    GetCPInfo(CP_ACP, &CodePageInfo);
+
+    if (CodePageInfo.MaxCharSize > 1)
+        // Only supporting non-Unicode strings
+        return FALSE;
+    else if (((LPBYTE) lpInputString)[1] == '\0')
+    {
+        // Looks like unicode, better translate it
+        WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) lpInputString, -1,
+                            lpszOutputString, nOutStringLen, NULL, NULL);
+    }
+    else
+        lstrcpyA(lpszOutputString, (LPSTR) lpInputString);
+    return TRUE;
+}  // UnicodeToANSI
+
+static VOID
+WINAPI
+ANSIToUnicode(LPSTR  lpInputString, LPTSTR lpszOutputString, int nOutStringLen)
+{
+
+    CPINFO CodePageInfo;
+
+    lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
+
+    GetCPInfo(CP_ACP, &CodePageInfo);
+
+    if (CodePageInfo.MaxCharSize > 1)
+        // It must already be a Unicode string
+        return;
+    else if (((LPBYTE) lpInputString)[1] != '\0')
+    {
+        // Looks like ANSI, better translate it
+        MultiByteToWideChar(CP_ACP, 0, (LPCSTR) lpInputString, -1,
+                            (LPWSTR) lpszOutputString, nOutStringLen);
+    }
+    else
+        lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
+}  // ANSIToUnicode
+
+
+static void
+MITPrincToMSPrinc(krb5_context context, krb5_principal principal, UNICODE_STRING * msprinc)
+{
+    char *aname = NULL;
+
+    if (!krb5_unparse_name(context, principal, &aname)) {
+        msprinc->Length = strlen(aname) * sizeof(WCHAR);
+        ANSIToUnicode(aname, msprinc->Buffer, msprinc->MaximumLength);
+        krb5_free_unparsed_name(context,aname);
+    }
+}
+
+static void
+MSPrincToMITPrinc(KERB_EXTERNAL_NAME *msprinc, WCHAR *realm, krb5_context context, krb5_principal *principal)
+{
+    WCHAR princbuf[512],tmpbuf[128];
+    char aname[512];
+    USHORT i;
+    princbuf[0]=0;
+    for (i=0;i<msprinc->NameCount;i++) {
+        wcsncpy(tmpbuf, msprinc->Names[i].Buffer,
+                msprinc->Names[i].Length/sizeof(WCHAR));
+        tmpbuf[msprinc->Names[i].Length/sizeof(WCHAR)]=0;
+        if (princbuf[0])
+            wcscat(princbuf, L"/");
+        wcscat(princbuf, tmpbuf);
+    }
+    wcscat(princbuf, L"@");
+    wcscat(princbuf, realm);
+    UnicodeToANSI(princbuf, aname, sizeof(aname));
+    krb5_parse_name(context, aname, principal);
+}
+
+
+static time_t
+FileTimeToUnixTime(LARGE_INTEGER *ltime)
+{
+    FILETIME filetime, localfiletime;
+    SYSTEMTIME systime;
+    struct tm utime;
+    filetime.dwLowDateTime=ltime->LowPart;
+    filetime.dwHighDateTime=ltime->HighPart;
+    FileTimeToLocalFileTime(&filetime, &localfiletime);
+    FileTimeToSystemTime(&localfiletime, &systime);
+    utime.tm_sec=systime.wSecond;
+    utime.tm_min=systime.wMinute;
+    utime.tm_hour=systime.wHour;
+    utime.tm_mday=systime.wDay;
+    utime.tm_mon=systime.wMonth-1;
+    utime.tm_year=systime.wYear-1900;
+    utime.tm_isdst=-1;
+    return(mktime(&utime));
+}
+
+static void
+MSSessionKeyToMITKeyblock(KERB_CRYPTO_KEY *mskey, krb5_context context, krb5_keyblock *keyblock)
+{
+    krb5_keyblock tmpblock;
+    tmpblock.magic=KV5M_KEYBLOCK;
+    tmpblock.enctype=mskey->KeyType;
+    tmpblock.length=mskey->Length;
+    tmpblock.contents=mskey->Value;
+    krb5_copy_keyblock_contents(context, &tmpblock, keyblock);
+}
+
+
+static void
+MSFlagsToMITFlags(ULONG msflags, ULONG *mitflags)
+{
+    *mitflags=msflags;
+}
+
+static void
+MSTicketToMITTicket(KERB_EXTERNAL_TICKET *msticket, krb5_context context, krb5_data *ticket)
+{
+    krb5_data tmpdata, *newdata;
+    tmpdata.magic=KV5M_DATA;
+    tmpdata.length=msticket->EncodedTicketSize;
+    tmpdata.data=msticket->EncodedTicket;
+
+    // TODO: fix this up a little. this is ugly and will break krb5_free_data()
+    krb5_copy_data(context, &tmpdata, &newdata);
+    memcpy(ticket, newdata, sizeof(krb5_data));
+}
+
+/*
+ * PreserveInitialTicketIdentity()
+ *
+ * This will find the "PreserveInitialTicketIdentity" key in the registry.  
+ * Returns 1 to preserve and 0 to not.
+ */
+
+static DWORD
+PreserveInitialTicketIdentity(void)
+{
+    HKEY hKey;
+    DWORD size = sizeof(DWORD);
+    DWORD type = REG_DWORD;
+    const char *key_path = "Software\\MIT\\Kerberos5";
+    const char *value_name = "PreserveInitialTicketIdentity";
+    DWORD retval = 1;     /* default to Preserve */
+
+    if (RegOpenKeyExA(HKEY_CURRENT_USER, key_path, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+        goto syskey;
+    if (RegQueryValueExA(hKey, value_name, 0, &type, (LPBYTE)&retval, &size) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hKey);
+        goto syskey;
+    }
+    RegCloseKey(hKey);
+    goto done;
+
+  syskey:
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_path, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+        goto done;
+    if (RegQueryValueExA(hKey, value_name, 0, &type, (LPBYTE)&retval, &size) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hKey);
+        goto done;
+    }
+    RegCloseKey(hKey);
+
+  done:
+    return retval;
+}
+
+
+static void
+MSCredToMITCred(KERB_EXTERNAL_TICKET *msticket, UNICODE_STRING InitialTicketDomain, 
+                krb5_context context, krb5_creds *creds)
+{
+    WCHAR wrealm[128];
+    ZeroMemory(creds, sizeof(krb5_creds));
+    creds->magic=KV5M_CREDS;
+
+    // construct Client Principal
+    if ( PreserveInitialTicketIdentity() ) {
+        wcsncpy(wrealm, InitialTicketDomain.Buffer, InitialTicketDomain.Length/sizeof(WCHAR));
+        wrealm[InitialTicketDomain.Length/sizeof(WCHAR)]=0;
+    } else {
+        wcsncpy(wrealm, msticket->DomainName.Buffer, msticket->DomainName.Length/sizeof(WCHAR));
+        wrealm[msticket->DomainName.Length/sizeof(WCHAR)]=0;
+    }
+    MSPrincToMITPrinc(msticket->ClientName, wrealm, context, &creds->client);
+
+    // construct Service Principal
+    wcsncpy(wrealm, msticket->DomainName.Buffer,
+            msticket->DomainName.Length/sizeof(WCHAR));
+    wrealm[msticket->DomainName.Length/sizeof(WCHAR)]=0;
+    MSPrincToMITPrinc(msticket->ServiceName, wrealm, context, &creds->server);
+
+    MSSessionKeyToMITKeyblock(&msticket->SessionKey, context, 
+                              &creds->keyblock);
+    MSFlagsToMITFlags(msticket->TicketFlags, &creds->ticket_flags);
+    creds->times.starttime=FileTimeToUnixTime(&msticket->StartTime);
+    creds->times.endtime=FileTimeToUnixTime(&msticket->EndTime);
+    creds->times.renew_till=FileTimeToUnixTime(&msticket->RenewUntil);
+
+    /* MS Tickets are addressless.  MIT requires an empty address
+     * not a NULL list of addresses.
+     */
+    creds->addresses = (krb5_address **)malloc(sizeof(krb5_address *));
+    memset(creds->addresses, 0, sizeof(krb5_address *));
+
+    MSTicketToMITTicket(msticket, context, &creds->ticket);
+}
+
+static BOOL
+PackageConnectLookup(HANDLE *pLogonHandle, ULONG *pPackageId)
+{
+    LSA_STRING Name;
+    NTSTATUS Status;
+
+    Status = LsaConnectUntrusted(
+        pLogonHandle
+        );
+
+    if (FAILED(Status))
+    {
+        ShowLsaError("LsaConnectUntrusted", Status);
+        return FALSE;
+    }
+
+    Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
+    Name.Length = strlen(Name.Buffer);
+    Name.MaximumLength = Name.Length + 1;
+
+    Status = LsaLookupAuthenticationPackage(
+        *pLogonHandle,
+        &Name,
+        pPackageId
+        );
+
+    if (FAILED(Status))
+    {
+        ShowLsaError("LsaLookupAuthenticationPackage", Status);
+        return FALSE;
+    }
+
+    return TRUE;
+
+}
+
+
+static DWORD
+ConcatenateUnicodeStrings(UNICODE_STRING *pTarget, UNICODE_STRING Source1, UNICODE_STRING Source2)
+{
+    //
+    // The buffers for Source1 and Source2 cannot overlap pTarget's
+    // buffer.  Source1.Length + Source2.Length must be <= 0xFFFF,
+    // otherwise we overflow...
+    //
+
+    USHORT TotalSize = Source1.Length + Source2.Length;
+    PBYTE buffer = (PBYTE) pTarget->Buffer;
+
+    if (TotalSize > pTarget->MaximumLength)
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    if ( pTarget->Buffer != Source1.Buffer )
+        memcpy(buffer, Source1.Buffer, Source1.Length);
+    memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
+
+    pTarget->Length = TotalSize;
+    return ERROR_SUCCESS;
+}
+
+static 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 = RegOpenKeyExA(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
+    if (rc)
+        return FALSE;
+
+    dwCount = outlen;
+    rc = RegQueryValueExA(hKey, value, 0, 0, (LPBYTE) outbuf, &dwCount);
+    RegCloseKey(hKey);
+
+    return rc?FALSE:TRUE;
+}
+
+static BOOL
+GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+{
+    NTSTATUS Status = 0;
+    HANDLE  TokenHandle;
+    TOKEN_STATISTICS Stats;
+    DWORD   ReqLen;
+    BOOL    Success;
+
+    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 = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
+    if ( FAILED(Status) || !ppSessionData )
+        return FALSE;
+
+    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.
+
+static 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)
+            {
+                lstrcpyn (buffer, usBuffer, usLength);
+                lstrcat (buffer,L"");
+                if ( !lstrcmp(L"Kerberos",buffer) )
+                    Success = TRUE;
+            }
+        }
+        LsaFreeReturnBuffer(pSessionData);
+    }
+    return Success;
+}
+
+static NTSTATUS
+ConstructTicketRequest(UNICODE_STRING DomainName, PKERB_RETRIEVE_TKT_REQUEST * outRequest, ULONG * outSize)
+{
+    NTSTATUS Status;
+    UNICODE_STRING TargetPrefix;
+    USHORT TargetSize;
+    ULONG RequestSize;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
+
+    *outRequest = NULL;
+    *outSize = 0;
+
+    //
+    // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
+    // can easily concatenate it later.
+    //
+
+    TargetPrefix.Buffer = L"krbtgt/";
+    TargetPrefix.Length = wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
+    TargetPrefix.MaximumLength = TargetPrefix.Length;
+
+    //
+    // We will need to concatenate the "krbtgt/" prefix and the 
+    // Logon Session's DnsDomainName into our request's target name.
+    //
+    // Therefore, first compute the necessary buffer size for that.
+    //
+    // Note that we might theoretically have integer overflow.
+    //
+
+    TargetSize = TargetPrefix.Length + DomainName.Length;
+
+    //
+    // The ticket request buffer needs to be a single buffer.  That buffer
+    // needs to include the buffer for the target name.
+    //
+
+    RequestSize = sizeof(*pTicketRequest) + TargetSize;
+
+    //
+    // Allocate the request buffer and make sure it's zero-filled.
+    //
+
+    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize);
+    if (!pTicketRequest)
+        return GetLastError();
+
+    //
+    // Concatenate the target prefix with the previous reponse's
+    // target domain.
+    //
+
+    pTicketRequest->TargetName.Length = 0;
+    pTicketRequest->TargetName.MaximumLength = TargetSize;
+    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
+    Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
+                                        TargetPrefix,
+                                        DomainName);
+    *outRequest = pTicketRequest;
+    *outSize    = RequestSize;
+    return Status;
+}
+
+static BOOL
+PurgeMSTGT(HANDLE LogonHandle, ULONG  PackageId)
+{
+    NTSTATUS Status = 0;
+    NTSTATUS SubStatus = 0;
+    KERB_PURGE_TKT_CACHE_REQUEST PurgeRequest;
+
+    PurgeRequest.MessageType = KerbPurgeTicketCacheMessage;
+    PurgeRequest.LogonId.LowPart = 0;
+    PurgeRequest.LogonId.HighPart = 0;
+    PurgeRequest.ServerName.Buffer = L"";
+    PurgeRequest.ServerName.Length = 0;
+    PurgeRequest.ServerName.MaximumLength = 0;
+    PurgeRequest.RealmName.Buffer = L"";
+    PurgeRequest.RealmName.Length = 0;
+    PurgeRequest.RealmName.MaximumLength = 0;
+    Status = LsaCallAuthenticationPackage(LogonHandle,
+                                           PackageId,
+                                           &PurgeRequest,
+                                           sizeof(PurgeRequest),
+                                           NULL,
+                                           NULL,
+                                           &SubStatus
+                                           );
+    if (FAILED(Status) || FAILED(SubStatus))
+        return FALSE;
+    return TRUE;
+}
+
+#define ENABLE_PURGING 1
+// to allow the purging of expired tickets from LSA cache.  This is necessary
+// to force the retrieval of new TGTs.  Microsoft does not appear to retrieve
+// new tickets when they expire.  Instead they continue to accept the expired
+// tickets.  This is safe to do because the LSA purges its cache when it 
+// retrieves a new TGT (ms calls this renew) but not when it renews the TGT
+// (ms calls this refresh).
+
+static BOOL
+GetMSTGT(HANDLE LogonHandle, ULONG PackageId,KERB_EXTERNAL_TICKET **ticket)
+{
+    //
+    // INVARIANTS:
+    //
+    //   (FAILED(Status) || FAILED(SubStatus)) ==> error
+    //   bIsLsaError ==> LsaCallAuthenticationPackage() error
+    //
+
+    BOOL bIsLsaError = FALSE;
+    NTSTATUS Status = 0;
+    NTSTATUS SubStatus = 0;
+
+    KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest;
+    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
+    ULONG RequestSize;
+    ULONG ResponseSize;
+#ifdef ENABLE_PURGING
+    int    purge_cache = 0;
+#endif /* ENABLE_PURGING */
+    int    ignore_cache = 0;
+
+    CacheRequest.MessageType = KerbRetrieveTicketMessage;
+    CacheRequest.LogonId.LowPart = 0;
+    CacheRequest.LogonId.HighPart = 0;
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        &CacheRequest,
+        sizeof(CacheRequest),
+        &pTicketResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    if (FAILED(Status))
+    {
+        // if the call to LsaCallAuthenticationPackage failed we cannot
+        // perform any queries most likely because the Kerberos package 
+        // is not available or we do not have access
+        bIsLsaError = TRUE;
+        goto cleanup;
+    }
+
+    if (FAILED(SubStatus)) {
+        PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
+        BOOL    Success = FALSE;
+        OSVERSIONINFOEX verinfo;
+        int supported = 0;
+
+        // SubStatus 0x8009030E is not documented.  However, it appears
+        // to mean there is no TGT
+        if (SubStatus != 0x8009030E) {
+            bIsLsaError = TRUE;
+            goto cleanup;
+        }
+
+        verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+        GetVersionEx((OSVERSIONINFO *)&verinfo);
+        supported = (verinfo.dwMajorVersion > 5) || 
+            (verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion >= 1);
+
+        // If we could not get a TGT from the cache we won't know what the
+        // Kerberos Domain should have been.  On Windows XP and 2003 Server
+        // we can extract it from the Security Logon Session Data.  However,
+        // the required fields are not supported on Windows 2000.  :(
+        if ( supported && GetSecurityLogonSessionData(&pSessionData) ) {
+            if ( pSessionData->DnsDomainName.Buffer ) {
+                Status = ConstructTicketRequest(pSessionData->DnsDomainName,
+                                                &pTicketRequest, &RequestSize);
+                if ( FAILED(Status) ) {
+                    goto cleanup;
+                }
+            } else {
+                bIsLsaError = TRUE;
+                goto cleanup;
+            }
+            LsaFreeReturnBuffer(pSessionData);
+        } else {
+            CHAR  UserDnsDomain[256];
+            WCHAR UnicodeUserDnsDomain[256];
+            UNICODE_STRING wrapper;
+            if ( !get_STRING_from_registry(HKEY_CURRENT_USER,
+                                          "Volatile Environment",
+                                          "USERDNSDOMAIN",
+                                           UserDnsDomain,
+                                           sizeof(UserDnsDomain)
+                                           ) )
+            {
+                goto cleanup;
+            }
+
+            ANSIToUnicode(UserDnsDomain,UnicodeUserDnsDomain,256);
+            wrapper.Buffer = UnicodeUserDnsDomain;
+            wrapper.Length = wcslen(UnicodeUserDnsDomain) * sizeof(WCHAR);
+            wrapper.MaximumLength = 256;
+
+            Status = ConstructTicketRequest(wrapper,
+                                             &pTicketRequest, &RequestSize);
+            if ( FAILED(Status) ) {
+                goto cleanup;
+            }
+        }
+    } else {
+#ifdef PURGE_ALL
+        purge_cache = 1;
+#else
+        switch (pTicketResponse->Ticket.SessionKey.KeyType) {
+        case KERB_ETYPE_DES_CBC_CRC:
+        case KERB_ETYPE_DES_CBC_MD4:
+        case KERB_ETYPE_DES_CBC_MD5:
+        case KERB_ETYPE_NULL:
+        case KERB_ETYPE_RC4_HMAC_NT: {
+            FILETIME Now, MinLife, EndTime, LocalEndTime;
+            __int64  temp;
+            // FILETIME is in units of 100 nano-seconds
+            // If obtained tickets are either expired or have a lifetime
+            // less than 20 minutes, retry ...
+            GetSystemTimeAsFileTime(&Now);
+            EndTime.dwLowDateTime=pTicketResponse->Ticket.EndTime.LowPart;
+            EndTime.dwHighDateTime=pTicketResponse->Ticket.EndTime.HighPart;
+            FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
+            temp = Now.dwHighDateTime;
+            temp <<= 32;
+            temp = Now.dwLowDateTime;
+            temp += 1200 * 10000;
+            MinLife.dwHighDateTime = (DWORD)((temp >> 32) & 0xFFFFFFFF);
+            MinLife.dwLowDateTime = (DWORD)(temp & 0xFFFFFFFF);
+            if (CompareFileTime(&MinLife, &LocalEndTime) >= 0) {
+#ifdef ENABLE_PURGING
+                purge_cache = 1;
+#else
+                ignore_cache = 1;
+#endif /* ENABLE_PURGING */
+                break;
+            }
+            if (pTicketResponse->Ticket.TicketFlags & KERB_TICKET_FLAGS_invalid) {
+                ignore_cache = 1;
+                break;      // invalid, need to attempt a TGT request
+            }
+            goto cleanup;   // all done
+        }
+        case KERB_ETYPE_RC4_MD4:
+        default:
+            // not supported
+            ignore_cache = 1;
+            break;
+        }
+#endif /* PURGE_ALL */
+
+        Status = ConstructTicketRequest(pTicketResponse->Ticket.TargetDomainName,
+                                        &pTicketRequest, &RequestSize);
+        if ( FAILED(Status) ) {
+            goto cleanup;
+        }
+
+        //
+        // Free the previous response buffer so we can get the new response.
+        //
+
+        if ( pTicketResponse ) {
+            memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE));
+            LsaFreeReturnBuffer(pTicketResponse);
+            pTicketResponse = NULL;
+        }
+
+#ifdef ENABLE_PURGING
+        if ( purge_cache ) {
+            //
+            // Purge the existing tickets which we cannot use so new ones can 
+            // be requested.  It is not possible to purge just the TGT.  All
+            // service tickets must be purged.
+            //
+            PurgeMSTGT(LogonHandle, PackageId);
+        }
+#endif /* ENABLE_PURGING */
+    }
+    
+    //
+    // Intialize the request of the request.
+    //
+
+    pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
+    pTicketRequest->LogonId.LowPart = 0;
+    pTicketRequest->LogonId.HighPart = 0;
+    // Note: pTicketRequest->TargetName set up above
+#ifdef ENABLE_PURGING
+    pTicketRequest->CacheOptions = ((ignore_cache || !purge_cache) ? 
+                                     KERB_RETRIEVE_TICKET_DONT_USE_CACHE : 0L);
+#else
+    pTicketRequest->CacheOptions = (ignore_cache ? KERB_RETRIEVE_TICKET_DONT_USE_CACHE : 0L);
+#endif /* ENABLE_PURGING */
+    pTicketRequest->TicketFlags = 0L;
+    pTicketRequest->EncryptionType = 0L;
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        pTicketRequest,
+        RequestSize,
+        &pTicketResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    if (FAILED(Status) || FAILED(SubStatus))
+    {
+        bIsLsaError = TRUE;
+        goto cleanup;
+    }
+
+    //
+    // Check to make sure the new tickets we received are of a type we support
+    //
+
+    switch (pTicketResponse->Ticket.SessionKey.KeyType) {
+    case KERB_ETYPE_DES_CBC_CRC:
+    case KERB_ETYPE_DES_CBC_MD4:
+    case KERB_ETYPE_DES_CBC_MD5:
+    case KERB_ETYPE_NULL:
+    case KERB_ETYPE_RC4_HMAC_NT:
+        goto cleanup;   // all done
+    case KERB_ETYPE_RC4_MD4:
+    default:
+        // not supported
+        break;
+    }
+
+
+    //
+    // Try once more but this time specify the Encryption Type
+    // (This will not store the retrieved tickets in the LSA cache)
+    //
+    pTicketRequest->EncryptionType = ENCTYPE_DES_CBC_CRC;
+    pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;
+
+    if ( pTicketResponse ) {
+        memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE));
+        LsaFreeReturnBuffer(pTicketResponse);
+        pTicketResponse = NULL;
+    }
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        pTicketRequest,
+        RequestSize,
+        &pTicketResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    if (FAILED(Status) || FAILED(SubStatus))
+    {
+        bIsLsaError = TRUE;
+        goto cleanup;
+    }
+
+  cleanup:
+    if ( pTicketRequest )
+        LsaFreeReturnBuffer(pTicketRequest);
+
+    if (FAILED(Status) || FAILED(SubStatus))
+    {
+        if (bIsLsaError)
+        {
+            // XXX - Will be fixed later
+            if (FAILED(Status))
+                ShowLsaError("LsaCallAuthenticationPackage", Status);
+            if (FAILED(SubStatus))
+                ShowLsaError("LsaCallAuthenticationPackage", SubStatus);
+        }
+        else
+        {
+            ShowWinError("GetMSTGT", Status);
+        }
+
+        if (pTicketResponse) {
+            memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE));
+            LsaFreeReturnBuffer(pTicketResponse);
+            pTicketResponse = NULL;
+        }
+        return(FALSE);
+    }
+
+    *ticket = &(pTicketResponse->Ticket);
+    return(TRUE);
+}
+
+static BOOL
+GetQueryTktCacheResponse( HANDLE LogonHandle, ULONG PackageId,
+                          PKERB_QUERY_TKT_CACHE_RESPONSE * ppResponse)
+{
+    NTSTATUS Status = 0;
+    NTSTATUS SubStatus = 0;
+
+    KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
+    PKERB_QUERY_TKT_CACHE_RESPONSE pQueryResponse = NULL;
+    ULONG ResponseSize;
+    
+    CacheRequest.MessageType = KerbQueryTicketCacheMessage;
+    CacheRequest.LogonId.LowPart = 0;
+    CacheRequest.LogonId.HighPart = 0;
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        &CacheRequest,
+        sizeof(CacheRequest),
+        &pQueryResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    if ( !(FAILED(Status) || FAILED(SubStatus)) ) {
+        *ppResponse = pQueryResponse;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void
+FreeQueryResponse(PKERB_QUERY_TKT_CACHE_RESPONSE  pResponse)
+{
+    LsaFreeReturnBuffer(pResponse);
+}
+
+
+static BOOL
+GetMSCacheTicketFromMITCred( HANDLE LogonHandle, ULONG PackageId,
+                  krb5_context context, krb5_creds *creds, PKERB_EXTERNAL_TICKET *ticket)
+{
+    NTSTATUS Status = 0;
+    NTSTATUS SubStatus = 0;
+    ULONG RequestSize;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
+    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
+    ULONG ResponseSize;
+
+    RequestSize = sizeof(*pTicketRequest) + MAX_MSPRINC_SIZE;
+
+    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize);
+    if (!pTicketRequest)
+        return FALSE;
+
+    pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
+    pTicketRequest->LogonId.LowPart = 0;
+    pTicketRequest->LogonId.HighPart = 0;
+
+    pTicketRequest->TargetName.Length = 0;
+    pTicketRequest->TargetName.MaximumLength = MAX_MSPRINC_SIZE;
+    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
+    MITPrincToMSPrinc(context, creds->server, &pTicketRequest->TargetName);
+    pTicketRequest->CacheOptions = 0;
+    pTicketRequest->TicketFlags = creds->ticket_flags;
+    pTicketRequest->EncryptionType = creds->keyblock.enctype;
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        pTicketRequest,
+        RequestSize,
+        &pTicketResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    LocalFree(pTicketRequest);
+
+    if (FAILED(Status) || FAILED(SubStatus))
+        return(FALSE);
+    
+    /* otherwise return ticket */
+    *ticket = &(pTicketResponse->Ticket);
+    return(TRUE);
+
+}
+
+static BOOL
+GetMSCacheTicketFromCacheInfo( HANDLE LogonHandle, ULONG PackageId,
+                  PKERB_TICKET_CACHE_INFO tktinfo, PKERB_EXTERNAL_TICKET *ticket)
+{
+    NTSTATUS Status = 0;
+    NTSTATUS SubStatus = 0;
+    ULONG RequestSize;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
+    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
+    ULONG ResponseSize;
+
+    RequestSize = sizeof(*pTicketRequest) + tktinfo->ServerName.Length;
+
+    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize);
+    if (!pTicketRequest)
+        return FALSE;
+
+    pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
+    pTicketRequest->LogonId.LowPart = 0;
+    pTicketRequest->LogonId.HighPart = 0;
+    pTicketRequest->TargetName.Length = tktinfo->ServerName.Length;
+    pTicketRequest->TargetName.MaximumLength = tktinfo->ServerName.Length;
+    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
+    memcpy(pTicketRequest->TargetName.Buffer,tktinfo->ServerName.Buffer, tktinfo->ServerName.Length);
+    pTicketRequest->CacheOptions = 0;
+    pTicketRequest->EncryptionType = tktinfo->EncryptionType;
+    pTicketRequest->TicketFlags = 0;
+    if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwardable )
+        pTicketRequest->TicketFlags |= KDC_OPT_FORWARDABLE;
+    if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwarded )
+        pTicketRequest->TicketFlags |= KDC_OPT_FORWARDED;
+    if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_proxiable )
+        pTicketRequest->TicketFlags |= KDC_OPT_PROXIABLE;
+    if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_renewable )
+        pTicketRequest->TicketFlags |= KDC_OPT_RENEWABLE;
+
+    Status = LsaCallAuthenticationPackage(
+        LogonHandle,
+        PackageId,
+        pTicketRequest,
+        RequestSize,
+        &pTicketResponse,
+        &ResponseSize,
+        &SubStatus
+        );
+
+    LocalFree(pTicketRequest);
+
+    if (FAILED(Status) || FAILED(SubStatus))
+        return(FALSE);
+    
+    /* otherwise return ticket */
+    *ticket = &(pTicketResponse->Ticket);
+    return(TRUE);
+
+}
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_close
+        (krb5_context, krb5_ccache id);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_destroy
+        (krb5_context, krb5_ccache id);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_end_seq_get
+        (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_generate_new
+        (krb5_context, krb5_ccache *id);
+
+static const char * KRB5_CALLCONV krb5_lcc_get_name
+        (krb5_context, krb5_ccache id);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_get_principal
+        (krb5_context, krb5_ccache id, krb5_principal *princ);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_initialize
+        (krb5_context, krb5_ccache id, krb5_principal princ);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_next_cred
+        (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor,
+	 krb5_creds *creds);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_resolve
+        (krb5_context, krb5_ccache *id, const char *residual);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_retrieve
+        (krb5_context, krb5_ccache id, krb5_flags whichfields,
+	 krb5_creds *mcreds, krb5_creds *creds);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_start_seq_get
+        (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_store
+        (krb5_context, krb5_ccache id, krb5_creds *creds);
+
+static krb5_error_code KRB5_CALLCONV krb5_lcc_set_flags
+        (krb5_context, krb5_ccache id, krb5_flags flags);
+
+extern const krb5_cc_ops krb5_lcc_ops;
+
+krb5_error_code krb5_change_cache (void);
+
+krb5_boolean
+krb5int_cc_creds_match_request(krb5_context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds);
+
+#define KRB5_OK 0
+
+typedef struct _krb5_lcc_data {
+    HANDLE LogonHandle;
+    ULONG  PackageId;
+    char * cc_name;
+    krb5_principal princ;
+} krb5_lcc_data;
+
+typedef struct _krb5_lcc_cursor {
+    PKERB_QUERY_TKT_CACHE_RESPONSE  response;
+    int                             index;
+    PKERB_EXTERNAL_TICKET mstgt;
+} krb5_lcc_cursor;
+
+
+/*
+ * Requires:
+ * residual is ignored
+ *
+ * Modifies:
+ * id
+ * 
+ * Effects:
+ * Acccess the MS Kerberos LSA cache in the current logon session
+ * Ignore the residual.
+ * 
+ * Returns:
+ * A filled in krb5_ccache structure "id".
+ *
+ * Errors:
+ * KRB5_CC_NOMEM - there was insufficient memory to allocate the
+ * 
+ * 		krb5_ccache.  id is undefined.
+ * permission errors
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_resolve (krb5_context context, krb5_ccache *id, const char *residual)
+{
+    krb5_ccache lid;
+    krb5_lcc_data *data;
+    HANDLE LogonHandle;
+    ULONG  PackageId;
+    KERB_EXTERNAL_TICKET *msticket;
+
+    if (!IsKerberosLogon())
+        return KRB5_FCC_NOFILE;
+
+    if(!PackageConnectLookup(&LogonHandle, &PackageId))
+        return KRB5_FCC_NOFILE;
+
+    lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
+    if (lid == NULL) {
+        CloseHandle(LogonHandle);
+        return KRB5_CC_NOMEM;
+    }
+
+    lid->ops = &krb5_lcc_ops;
+
+    lid->data = (krb5_pointer) malloc(sizeof(krb5_lcc_data));
+    if (lid->data == NULL) {
+        krb5_xfree(lid);
+        CloseHandle(LogonHandle);
+        return KRB5_CC_NOMEM;
+    }
+
+    lid->magic = KV5M_CCACHE;
+    data = (krb5_lcc_data *)lid->data;    
+    data->LogonHandle = LogonHandle;
+    data->PackageId = PackageId;
+
+    data->cc_name = (char *)malloc(strlen(residual)+1);
+    if (data->cc_name == NULL) {
+        krb5_xfree(lid->data);
+        krb5_xfree(lid);
+        CloseHandle(LogonHandle);
+        return KRB5_CC_NOMEM;
+    }
+    strcpy(data->cc_name, residual);
+
+    /*
+     * we must obtain a tgt from the cache in order to determine the principal
+     */
+    if (GetMSTGT(data->LogonHandle, data->PackageId, &msticket)) {
+        /* convert the ticket */
+        krb5_creds creds;
+        MSCredToMITCred(msticket, msticket->DomainName, context, &creds);
+        LsaFreeReturnBuffer(msticket);
+
+        krb5_copy_principal(context, creds.client, &data->princ);
+        krb5_free_cred_contents(context,&creds);
+    } else {
+        data->princ = 0;
+    }
+
+    /*
+     * other routines will get errors on open, and callers must expect them,
+     * if cache is non-existent/unusable 
+     */
+    *id = lid;
+    return KRB5_OK;
+}
+
+/*
+ *  not supported
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ)
+{
+    return KRB5_CC_READONLY;
+}
+
+
+/*
+ * Modifies:
+ * id
+ *
+ * Effects:
+ * Closes the microsoft lsa cache, invalidates the id, and frees any resources
+ * associated with the cache.
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_close(krb5_context context, krb5_ccache id)
+{
+    register int closeval = KRB5_OK;
+    register krb5_lcc_data *data = (krb5_lcc_data *) id->data;
+
+    CloseHandle(data->LogonHandle);
+
+    krb5_xfree(data);
+    krb5_xfree(id);
+
+    return closeval;
+}
+
+/*
+ * Effects:
+ * Destroys the contents of id.
+ *
+ * Errors:
+ * system errors
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_destroy(krb5_context context, krb5_ccache id)
+{
+    register krb5_lcc_data *data = (krb5_lcc_data *) id->data;
+
+    return PurgeMSTGT(data->LogonHandle, data->PackageId) ? KRB5_FCC_INTERNAL : KRB5_OK;
+}
+
+/*
+ * Effects:
+ * Prepares for a sequential search of the credentials cache.
+ * Returns a krb5_cc_cursor to be used with krb5_lcc_next_cred and
+ * krb5_lcc_end_seq_get.
+ *
+ * If the cache is modified between the time of this call and the time
+ * of the final krb5_lcc_end_seq_get, the results are undefined.
+ *
+ * Errors:
+ * KRB5_CC_NOMEM
+ * KRB5_FCC_INTERNAL - system errors
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor)
+{
+    krb5_lcc_cursor *lcursor;
+    krb5_lcc_data *data = (krb5_lcc_data *)id->data;
+    KERB_EXTERNAL_TICKET *msticket;
+
+    lcursor = (krb5_lcc_cursor *) malloc(sizeof(krb5_lcc_cursor));
+    if (lcursor == NULL) {
+        *cursor = 0;
+        return KRB5_CC_NOMEM;
+    }
+
+    /*
+     * obtain a tgt to refresh the ccache in case the ticket is expired
+     */
+    if (!GetMSTGT(data->LogonHandle, data->PackageId, &lcursor->mstgt)) {
+        free(lcursor);
+        *cursor = 0;
+        KRB5_FCC_INTERNAL;
+    }
+
+    if ( !GetQueryTktCacheResponse(data->LogonHandle, data->PackageId, &lcursor->response) ) {
+        LsaFreeReturnBuffer(lcursor->mstgt);
+        free(lcursor);
+        *cursor = 0;
+        KRB5_FCC_INTERNAL;
+    }
+    lcursor->index = 0;
+    *cursor = (krb5_cc_cursor) lcursor;
+    return KRB5_OK;
+}
+
+
+/*
+ * Requires:
+ * cursor is a krb5_cc_cursor originally obtained from
+ * krb5_lcc_start_seq_get.
+ *
+ * Modifes:
+ * cursor
+ * 
+ * Effects:
+ * Fills in creds with the TGT obtained from the MS LSA
+ *
+ * The cursor is updated to indicate TGT retrieval
+ *
+ * Errors:
+ * KRB5_CC_END
+ * KRB5_FCC_INTERNAL - system errors
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds)
+{
+    krb5_lcc_cursor *lcursor = (krb5_lcc_cursor *) *cursor;
+    krb5_lcc_data *data = (krb5_lcc_data *)id->data;
+    KERB_EXTERNAL_TICKET *msticket;
+    krb5_error_code  retval = KRB5_OK;
+
+  next_cred:
+    if ( lcursor->index >= lcursor->response->CountOfTickets ) {
+        if (retval == KRB5_OK)
+            return KRB5_CC_END;
+        else {
+            LsaFreeReturnBuffer(lcursor->mstgt);
+            LsaFreeReturnBuffer(lcursor->response);
+            free(*cursor);
+            *cursor = 0;
+            return retval;
+        }
+    }
+
+    if (!GetMSCacheTicketFromCacheInfo(data->LogonHandle, data->PackageId,
+                                        &lcursor->response->Tickets[lcursor->index++],&msticket)) {
+        retval = KRB5_FCC_INTERNAL;
+        goto next_cred;
+    }
+
+    /* Don't return tickets with NULL Session Keys */
+    if ( msticket->SessionKey.KeyType == KERB_ETYPE_NULL) {
+        LsaFreeReturnBuffer(msticket);
+        goto next_cred;
+    }
+
+    /* convert the ticket */
+    MSCredToMITCred(msticket, lcursor->mstgt->DomainName, context, creds);
+    LsaFreeReturnBuffer(msticket);
+    return KRB5_OK;
+}
+
+/*
+ * Requires:
+ * cursor is a krb5_cc_cursor originally obtained from
+ * krb5_lcc_start_seq_get.
+ *
+ * Modifies:
+ * id, cursor
+ *
+ * Effects:
+ * Finishes sequential processing of the file credentials ccache id,
+ * and invalidates the cursor (it must never be used after this call).
+ */
+/* ARGSUSED */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor)
+{
+    krb5_lcc_cursor *lcursor = (krb5_lcc_cursor *) *cursor;
+
+    if ( lcursor ) {
+        LsaFreeReturnBuffer(lcursor->mstgt);
+        LsaFreeReturnBuffer(lcursor->response);
+        free(*cursor);
+    }
+    *cursor = 0;
+
+    return KRB5_OK;
+}
+
+
+/*
+ * Errors:
+ * KRB5_CC_READONLY - not supported
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_generate_new (krb5_context context, krb5_ccache *id)
+{
+    return KRB5_CC_READONLY;
+}
+
+/*
+ * Requires:
+ * id is a ms lsa credential cache
+ * 
+ * Returns:
+ *   The ccname specified during the krb5_lcc_resolve call
+ */
+static const char * KRB5_CALLCONV
+krb5_lcc_get_name (krb5_context context, krb5_ccache id)
+{
+    return (char *) ((krb5_lcc_data *) id->data)->cc_name;
+}
+
+/*
+ * Modifies:
+ * id, princ
+ *
+ * Effects:
+ * Retrieves the primary principal from id, as set with
+ * krb5_lcc_initialize.  The principal is returned is allocated
+ * storage that must be freed by the caller via krb5_free_principal.
+ *
+ * Errors:
+ * system errors
+ * KRB5_CC_NOT_KTYPE
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *princ)
+{
+    krb5_error_code kret = KRB5_OK;
+
+    /* obtain principal */
+    return krb5_copy_principal(context, ((krb5_lcc_data *) id->data)->princ, princ);
+}
+
+     
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields, 
+                  krb5_creds *mcreds, krb5_creds *creds)
+{
+    krb5_error_code kret = KRB5_OK;
+    krb5_lcc_data *data = (krb5_lcc_data *)id->data;
+    KERB_EXTERNAL_TICKET *msticket = 0, *mstgt = 0;
+    krb5_creds * mcreds_noflags;
+    krb5_creds   fetchcreds;
+
+    memset(&fetchcreds, 0, sizeof(krb5_creds));
+
+    /* first try to find out if we have an existing ticket which meets the requirements */
+    kret = krb5_cc_retrieve_cred_default (context, id, whichfields, mcreds, creds);
+    if ( !kret )
+        return KRB5_OK;
+    
+    /* if not, we must try to get a ticket without specifying any flags or etypes */
+    krb5_copy_creds(context, mcreds, &mcreds_noflags);
+    mcreds_noflags->ticket_flags = 0;
+    mcreds_noflags->keyblock.enctype = 0;
+
+    if (!GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, mcreds_noflags, &msticket)) {
+        kret = KRB5_CC_NOTFOUND;
+        goto cleanup;
+    }
+
+    /* try again to find out if we have an existing ticket which meets the requirements */
+    kret = krb5_cc_retrieve_cred_default (context, id, whichfields, mcreds, creds);
+    if ( !kret )
+        goto cleanup;
+
+    /* if not, obtain a ticket using the request flags and enctype even though it will not
+     * be stored in the LSA cache for future use.
+     */
+    if ( msticket ) {
+        LsaFreeReturnBuffer(msticket);
+        msticket = 0;
+    }
+
+    if (!GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, mcreds, &msticket)) {
+        kret = KRB5_CC_NOTFOUND;
+        goto cleanup;
+    }
+
+    /* convert the ticket */
+    GetMSTGT(data->LogonHandle, data->PackageId, &mstgt);
+
+    MSCredToMITCred(msticket, mstgt ? mstgt->DomainName : msticket->DomainName, context, &fetchcreds);
+
+    /* check to see if this ticket matches the request using logic from
+     * krb5_cc_retrieve_cred_default()
+     */
+    if ( krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds) ) {
+        *creds = fetchcreds;
+    } else {
+        krb5_free_cred_contents(context, &fetchcreds);
+        kret = KRB5_CC_NOTFOUND;
+    }
+
+  cleanup:
+    if ( mstgt )
+        LsaFreeReturnBuffer(mstgt);
+    if ( msticket )
+        LsaFreeReturnBuffer(msticket);
+    if ( mcreds_noflags )
+        krb5_free_creds(context, mcreds_noflags);
+    return kret;
+}
+
+
+/*
+ * We can't write to the MS LSA cache.  So we request the cache to obtain a ticket for the same
+ * principal in the hope that next time the application requires a ticket for the service it
+ * is attempt to store, the retrieved ticket will be good enough.
+ *
+ * Errors:
+ * KRB5_CC_READONLY - not supported
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
+{
+    krb5_error_code kret = KRB5_OK;
+    krb5_lcc_data *data = (krb5_lcc_data *)id->data;
+    KERB_EXTERNAL_TICKET *msticket = 0;
+    krb5_creds * creds_noflags;
+
+    /* if not, we must try to get a ticket without specifying any flags or etypes */
+    krb5_copy_creds(context, creds, &creds_noflags);
+    creds_noflags->ticket_flags = 0;
+    creds_noflags->keyblock.enctype = 0;
+
+    if (GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, creds_noflags, &msticket)) {
+        LsaFreeReturnBuffer(msticket);
+        return KRB5_OK;
+    }
+    return KRB5_CC_READONLY;
+}
+
+/* 
+ * The ability to remove a credential from the MS LSA cache cannot be implemented.
+ * 
+ * Errors:
+ *    KRB5_CC_READONLY: 
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
+                     krb5_creds *creds)
+{
+    return KRB5_CC_READONLY;
+}
+
+
+/*
+ * Effects:
+ *   None - ignored
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_lcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags)
+{
+    return KRB5_OK;
+}
+
+const krb5_cc_ops krb5_lcc_ops = {
+     0,
+     "MSLSA",
+     krb5_lcc_get_name,
+     krb5_lcc_resolve,
+     krb5_lcc_generate_new,
+     krb5_lcc_initialize,
+     krb5_lcc_destroy,
+     krb5_lcc_close,
+     krb5_lcc_store,
+     krb5_lcc_retrieve,
+     krb5_lcc_get_principal,
+     krb5_lcc_start_seq_get,
+     krb5_lcc_next_cred,
+     krb5_lcc_end_seq_get,
+     krb5_lcc_remove_cred,
+     krb5_lcc_set_flags
+};
+#endif /* _WIN32 */
\ No newline at end of file
diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c
index ebd6193cd..80d31640c 100644
--- a/src/lib/krb5/ccache/cc_retr.c
+++ b/src/lib/krb5/ccache/cc_retr.c
@@ -157,6 +157,40 @@ pref (krb5_enctype my_ktype, int nktypes, krb5_enctype *ktypes)
  * KRB5_CC_NOT_KTYPE
  */
 
+krb5_boolean
+krb5int_cc_creds_match_request(krb5_context context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds)
+{
+    if (((set(KRB5_TC_MATCH_SRV_NAMEONLY) &&
+		   srvname_match(context, mcreds, creds)) ||
+	       standard_fields_match(context, mcreds, creds))
+	      &&
+	      (! set(KRB5_TC_MATCH_IS_SKEY) ||
+	       mcreds->is_skey == creds->is_skey)
+	      &&
+	      (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
+	       mcreds->ticket_flags == creds->ticket_flags)
+	      &&
+	      (! set(KRB5_TC_MATCH_FLAGS) ||
+	       flags_match(mcreds->ticket_flags, creds->ticket_flags))
+	      &&
+	      (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
+	       times_match_exact(&mcreds->times, &creds->times))
+	      &&
+	      (! set(KRB5_TC_MATCH_TIMES) ||
+	       times_match(&mcreds->times, &creds->times))
+	      &&
+	      ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
+	       authdata_match(mcreds->authdata, creds->authdata))
+	      &&
+	      (! set(KRB5_TC_MATCH_2ND_TKT) ||
+	       data_match (&mcreds->second_ticket, &creds->second_ticket))
+	      &&
+	     ((! set(KRB5_TC_MATCH_KTYPE))||
+		(mcreds->keyblock.enctype == creds->keyblock.enctype)))
+        return TRUE;
+    return FALSE;
+}
+
 static krb5_error_code
 krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds, int nktypes, krb5_enctype *ktypes)
 {
@@ -178,34 +212,8 @@ krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whic
 	  return kret;
 
      while ((kret = krb5_cc_next_cred(context, id, &cursor, &fetchcreds)) == KRB5_OK) {
-	 if (((set(KRB5_TC_MATCH_SRV_NAMEONLY) &&
-		   srvname_match(context, mcreds, &fetchcreds)) ||
-	       standard_fields_match(context, mcreds, &fetchcreds))
-	      &&
-	      (! set(KRB5_TC_MATCH_IS_SKEY) ||
-	       mcreds->is_skey == fetchcreds.is_skey)
-	      &&
-	      (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
-	       mcreds->ticket_flags == fetchcreds.ticket_flags)
-	      &&
-	      (! set(KRB5_TC_MATCH_FLAGS) ||
-	       flags_match(mcreds->ticket_flags, fetchcreds.ticket_flags))
-	      &&
-	      (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
-	       times_match_exact(&mcreds->times, &fetchcreds.times))
-	      &&
-	      (! set(KRB5_TC_MATCH_TIMES) ||
-	       times_match(&mcreds->times, &fetchcreds.times))
-	      &&
-	      ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
-	       authdata_match(mcreds->authdata, fetchcreds.authdata))
-	      &&
-	      (! set(KRB5_TC_MATCH_2ND_TKT) ||
-	       data_match (&mcreds->second_ticket, &fetchcreds.second_ticket))
-	      &&
-	     ((! set(KRB5_TC_MATCH_KTYPE))||
-		(mcreds->keyblock.enctype == fetchcreds.keyblock.enctype)))
-	  {
+      if (krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds))
+      {
 	      if (ktypes) {
 		  fetched.pref = pref (fetchcreds.keyblock.enctype,
 				       nktypes, ktypes);
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index ddd5e80d4..f17870663 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -29,6 +29,8 @@
 
 #include "k5-int.h"
 
+#include "fcc.h"
+
 struct krb5_cc_typelist
  {
   krb5_cc_ops *ops;
@@ -36,9 +38,19 @@ struct krb5_cc_typelist
  };
 extern const krb5_cc_ops krb5_mcc_ops;
 
-static struct krb5_cc_typelist cc_entry = { &krb5_mcc_ops, NULL };
+#ifdef _WIN32
+extern const krb5_cc_ops krb5_lcc_ops;
+static struct krb5_cc_typelist cc_lcc_entry = { &krb5_lcc_ops, NULL };
+static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, &cc_lcc_entry };
+#else
+static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, NULL };
+#endif
+
+static struct krb5_cc_typelist cc_fcc_entry = { &krb5_cc_file_ops,
+						&cc_mcc_entry };
+
+static struct krb5_cc_typelist *cc_typehead = &cc_fcc_entry;
 
-static struct krb5_cc_typelist *cc_typehead = &cc_entry;
 
 /*
  * Register a new credentials cache type
diff --git a/src/lib/krb5/ccache/ccdefault.c b/src/lib/krb5/ccache/ccdefault.c
index 71e6f9c9a..3dfb1a32c 100644
--- a/src/lib/krb5/ccache/ccdefault.c
+++ b/src/lib/krb5/ccache/ccdefault.c
@@ -31,6 +31,11 @@
 
 #ifdef USE_LOGIN_LIBRARY
 #include "KerberosLoginPrivate.h"
+#else
+#ifdef USE_LEASH
+static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal) = NULL;
+static HANDLE hLeashDLL = INVALID_HANDLE_VALUE;
+#endif
 #endif
 
 
@@ -111,6 +116,29 @@ krb5int_cc_default(krb5_context context, krb5_ccache *ccache)
 		if (desiredPrincipal != nil)
 			KLDisposePrincipal (desiredPrincipal);
 	}
+#else
+#ifdef USE_LEASH
+
+    if ( hLeashDLL == INVALID_HANDLE_VALUE ) {
+        hLeashDLL = LoadLibrary("leashw32.dll");
+        if ( hLeashDLL != INVALID_HANDLE_VALUE ) {
+            (FARPROC) pLeash_AcquireInitialTicketsIfNeeded =
+                GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded");
+        }
+    }
+
+    if ( pLeash_AcquireInitialTicketsIfNeeded )
+    {
+              krb5_os_context         os_ctx;
+
+        if (!context || context->magic != KV5M_CONTEXT)
+            return KV5M_CONTEXT;
+
+              os_ctx = context->os_context;
+
+        pLeash_AcquireInitialTicketsIfNeeded(context,os_ctx->default_ccprincipal);
+    }
+#endif
 #endif
 
     return krb5_cc_default (context, ccache);
diff --git a/src/lib/krb5/error_tables/.Sanitize b/src/lib/krb5/error_tables/.Sanitize
index b9521624e..ba18e42bf 100644
--- a/src/lib/krb5/error_tables/.Sanitize
+++ b/src/lib/krb5/error_tables/.Sanitize
@@ -34,6 +34,7 @@ configure.in
 init_ets.c
 kdb5_err.et
 krb5_err.et
+krb524_err.et
 kv5m_err.et
 
 Things-to-lose:
diff --git a/src/lib/krb5/error_tables/ChangeLog b/src/lib/krb5/error_tables/ChangeLog
index 2de7f07d2..c51b6c7a6 100644
--- a/src/lib/krb5/error_tables/ChangeLog
+++ b/src/lib/krb5/error_tables/ChangeLog
@@ -1,3 +1,30 @@
+2004-01-06  Jeffrey Altman <jaltman@mit.edu>
+
+    * krb5_err.et (KRB5_CC_NOSUPP) new ccache error code
+
+2003-12-12  Jeffrey Altman <jaltman@mit.edu>
+
+    * krb5_err.et (KRB5_CC_READONLY) new ccache error code
+
+2003-07-19  Ezra Peisach  <epeisach@mit.edu>
+
+	* init_ets.c (krb5_init_ets): Only initialize error tables once -
+	so that init_conext/free_context loops do not result in memory
+	leaks.
+
+2003-06-03  Ken Raeburn  <raeburn@mit.edu>
+
+	* krb5_err.et (KRB5_ERR_NO_SERVICE): New error code.
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* krb524_err.et: New file, moved from ../../../krb524.  Add new
+	error code KRB524_KRB4_DISABLED.
+	* Makefile.in (STLIBOBJS, HDRS, OBJS, ETSRCS, SRCS, awk-windows):
+	Add it.
+	($(OUTPRE)krb524_err.$(OBJEXT)): List dependence on .c file.
+	* init_ets.c (krb5_init_ets): Call initialize_k524_error_table.
+
 2003-03-04  Ken Raeburn  <raeburn@mit.edu>
 
 	* krb5_err.et (KRB5_ERR_BAD_S2K_PARAMS): New error code.
diff --git a/src/lib/krb5/error_tables/Makefile.in b/src/lib/krb5/error_tables/Makefile.in
index da1f77067..0192f79f0 100644
--- a/src/lib/krb5/error_tables/Makefile.in
+++ b/src/lib/krb5/error_tables/Makefile.in
@@ -12,13 +12,14 @@ THDRDIR=$(BUILDTOP)$(S)include
 EHDRDIR=$(BUILDTOP)$(S)include$(S)krb5
 
 STLIBOBJS= asn1_err.o kdb5_err.o krb5_err.o \
-      kv5m_err.o init_ets.o
+      kv5m_err.o krb524_err.o init_ets.o
 
-HDRS= asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h
+HDRS= asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h krb524_err.h
 OBJS= $(OUTPRE)asn1_err.$(OBJEXT) $(OUTPRE)kdb5_err.$(OBJEXT) $(OUTPRE)krb5_err.$(OBJEXT) \
-      $(OUTPRE)kv5m_err.$(OBJEXT) $(OUTPRE)init_ets.$(OBJEXT)
-ETSRCS= asn1_err.c kdb5_err.c krb5_err.c kv5m_err.c
-SRCS= asn1_err.c kdb5_err.c krb5_err.c kv5m_err.c \
+      $(OUTPRE)kv5m_err.$(OBJEXT) $(OUTPRE)krb524_err.$(OBJEXT) \
+      $(OUTPRE)init_ets.$(OBJEXT)
+ETSRCS= asn1_err.c kdb5_err.c krb5_err.c kv5m_err.c krb524_err.c
+SRCS= asn1_err.c kdb5_err.c krb5_err.c kv5m_err.c krb524_err.c \
 	$(srcdir)/init_ets.c
 
 ##DOS##LIBOBJS = $(OBJS)
@@ -40,14 +41,17 @@ awk-windows:
 	$(AWK) -f $(SRCTOP)/util/et/et_h.awk outfile=kdb5_err.h kdb5_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_h.awk outfile=krb5_err.h krb5_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_h.awk outfile=kv5m_err.h kv5m_err.et
+	$(AWK) -f $(SRCTOP)/util/et/et_h.awk outfile=krb524_err.h krb524_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_c.awk outfile=asn1_err.c asn1_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_c.awk outfile=kdb5_err.c kdb5_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_c.awk outfile=krb5_err.c krb5_err.et
 	$(AWK) -f $(SRCTOP)/util/et/et_c.awk outfile=kv5m_err.c kv5m_err.et
+	$(AWK) -f $(SRCTOP)/util/et/et_c.awk outfile=krb524_err.c krb524_err.et
 	if exist asn1_err.h copy asn1_err.h "$(EHDRDIR)"
 	if exist kdb5_err.h copy kdb5_err.h "$(EHDRDIR)"
 	if exist krb5_err.h copy krb5_err.h "$(EHDRDIR)"
 	if exist kv5m_err.h copy kv5m_err.h "$(EHDRDIR)"
+	if exist krb524_err.h copy krb524_err.h "$(EHDRDIR)"
 
 #
 # dependencies for traditional makes
@@ -56,6 +60,7 @@ $(OUTPRE)asn1_err.$(OBJEXT): asn1_err.c
 $(OUTPRE)kdb5_err.$(OBJEXT): kdb5_err.c
 $(OUTPRE)krb5_err.$(OBJEXT): krb5_err.c
 $(OUTPRE)kv5m_err.$(OBJEXT): kv5m_err.c
+$(OUTPRE)krb524_err.$(OBJEXT): krb524_err.c
 
 clean-unix:: clean-libobjs
 	$(RM) $(HDRS) $(ETSRCS)
@@ -71,9 +76,10 @@ asn1_err.so asn1_err.po $(OUTPRE)asn1_err.$(OBJEXT): asn1_err.c $(COM_ERR_DEPS)
 kdb5_err.so kdb5_err.po $(OUTPRE)kdb5_err.$(OBJEXT): kdb5_err.c $(COM_ERR_DEPS)
 krb5_err.so krb5_err.po $(OUTPRE)krb5_err.$(OBJEXT): krb5_err.c $(COM_ERR_DEPS)
 kv5m_err.so kv5m_err.po $(OUTPRE)kv5m_err.$(OBJEXT): kv5m_err.c $(COM_ERR_DEPS)
+krb524_err.so krb524_err.po $(OUTPRE)krb524_err.$(OBJEXT): krb524_err.c $(COM_ERR_DEPS)
 init_ets.so init_ets.po $(OUTPRE)init_ets.$(OBJEXT): init_ets.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5/error_tables/init_ets.c b/src/lib/krb5/error_tables/init_ets.c
index 0ac810abe..56a750e75 100644
--- a/src/lib/krb5/error_tables/init_ets.c
+++ b/src/lib/krb5/error_tables/init_ets.c
@@ -32,10 +32,16 @@
 void
 krb5_init_ets (krb5_context context)
 {
-    initialize_krb5_error_table();
-    initialize_kv5m_error_table();
-    initialize_kdb5_error_table();
-    initialize_asn1_error_table();
+    static int inited = 0;
+
+    if (inited == 0) {
+	    initialize_krb5_error_table();
+	    initialize_kv5m_error_table();
+	    initialize_kdb5_error_table();
+	    initialize_asn1_error_table();
+	    initialize_k524_error_table();
+	    inited++;
+    }
 }
 
 void
diff --git a/src/krb524/krb524_err.et b/src/lib/krb5/error_tables/krb524_err.et
similarity index 95%
rename from src/krb524/krb524_err.et
rename to src/lib/krb5/error_tables/krb524_err.et
index 471252e56..5a4a004c7 100644
--- a/src/krb524/krb524_err.et
+++ b/src/lib/krb5/error_tables/krb524_err.et
@@ -29,5 +29,6 @@ error_code KRB524_V4ERR, "Kerberos V4 error"
 error_code KRB524_ENCFULL, "Encoding too large"
 error_code KRB524_DECEMPTY, "Decoding out of data"
 error_code KRB524_NOTRESP, "Service not responding"
+error_code KRB524_KRB4_DISABLED,	"Kerberos version 4 support is disabled"
 
 end
diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et
index b401c92bf..b03d3769d 100644
--- a/src/lib/krb5/error_tables/krb5_err.et
+++ b/src/lib/krb5/error_tables/krb5_err.et
@@ -336,4 +336,8 @@ error_code KRB5_ERR_NUMERIC_REALM, "Cannot determine realm for numeric host addr
 
 error_code KRB5_ERR_BAD_S2K_PARAMS, "Invalid key generation parameters from KDC"
 
+error_code KRB5_ERR_NO_SERVICE,	"service not available"
+
+error_code KRB5_CC_READONLY,    "Ccache function not supported: read-only ccache type"
+error_code KRB5_CC_NOSUPP,      "Ccache function not supported: not implemented"
 end
diff --git a/src/lib/krb5/keytab/ChangeLog b/src/lib/krb5/keytab/ChangeLog
index ef0e702f1..a3c4f8c7a 100644
--- a/src/lib/krb5/keytab/ChangeLog
+++ b/src/lib/krb5/keytab/ChangeLog
@@ -1,3 +1,19 @@
+2003-05-22  Tom Yu  <tlyu@mit.edu>
+
+	* kt_file.c (krb5_ktfile_get_entry): Check principal name prior to
+	checking enctype.  Suggested by Wyllys Ingersoll.
+
+2003-05-19  Sam Hartman  <hartmans@mit.edu>
+
+	* ktbase.c: Register writable keytab by default
+
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* kt_file.c (krb5_ktfileint_internal_read_entry): Use
+	krb5_princ_size instead of direct field access.
+	(krb5_ktfileint_write_entry, krb5_ktfileint_size_entry):
+	Likewise.
+
 2003-02-08  Tom Yu  <tlyu@mit.edu>
 
 	* kt_file.c (krb5_ktfile_get_entry): Fix comment; not going to
diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in
index 545cd2784..731c34beb 100644
--- a/src/lib/krb5/keytab/Makefile.in
+++ b/src/lib/krb5/keytab/Makefile.in
@@ -64,47 +64,47 @@ clean-windows::
 #
 ktadd.so ktadd.po $(OUTPRE)ktadd.$(OBJEXT): ktadd.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktbase.so ktbase.po $(OUTPRE)ktbase.$(OBJEXT): ktbase.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktdefault.so ktdefault.po $(OUTPRE)ktdefault.$(OBJEXT): ktdefault.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktfr_entry.so ktfr_entry.po $(OUTPRE)ktfr_entry.$(OBJEXT): ktfr_entry.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktremove.so ktremove.po $(OUTPRE)ktremove.$(OBJEXT): ktremove.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktfns.so ktfns.po $(OUTPRE)ktfns.$(OBJEXT): ktfns.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kt_file.so kt_file.po $(OUTPRE)kt_file.$(OBJEXT): kt_file.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kt_srvtab.so kt_srvtab.po $(OUTPRE)kt_srvtab.$(OBJEXT): kt_srvtab.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 read_servi.so read_servi.po $(OUTPRE)read_servi.$(OBJEXT): read_servi.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 9e4f15aa7..3175de751 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -258,6 +258,14 @@ krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal
 	   and copy new_entry there, or free new_entry.  Otherwise, it
 	   leaks. */
 
+	/* if the principal isn't the one requested, free new_entry
+	   and continue to the next. */
+
+	if (!krb5_principal_compare(context, principal, new_entry.principal)) {
+	    krb5_kt_free_entry(context, &new_entry);
+	    continue;
+	}
+
 	/* if the enctype is not ignored and doesn't match, free new_entry
 	   and continue to the next */
 
@@ -281,14 +289,6 @@ krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal
 
 	}
 
-	/* if the principal isn't the one requested, free new_entry
-	   and continue to the next. */
-
-	if (!krb5_principal_compare(context, principal, new_entry.principal)) {
-	    krb5_kt_free_entry(context, &new_entry);
-	    continue;
-	}
-
 	if (kvno == IGNORE_VNO) {
 	    /* if this is the first match, or if the new vno is
 	       bigger, free the current and keep the new.  Otherwise,
@@ -1324,7 +1324,7 @@ krb5_ktfileint_internal_read_entry(krb5_context context, krb5_keytab id, krb5_ke
     return 0;
 fail:
     
-    for (i = 0; i < ret_entry->principal->length; i++) {
+    for (i = 0; i < krb5_princ_size(context, ret_entry->principal); i++) {
 	    princ = krb5_princ_component(context, ret_entry->principal, i);
 	    if (princ->data)
 		    free(princ->data);
@@ -1375,9 +1375,9 @@ krb5_ktfileint_write_entry(krb5_context context, krb5_keytab id, krb5_keytab_ent
     }
 
     if (KTVERSION(id) == KRB5_KT_VNO_1) {
-	    count = (krb5_int16) entry->principal->length + 1;
+	    count = (krb5_int16) krb5_princ_size(context, entry->principal) + 1;
     } else {
-	    count = htons((u_short) entry->principal->length);
+	    count = htons((u_short) krb5_princ_size(context, entry->principal));
     }
     
     if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) {
@@ -1396,7 +1396,7 @@ krb5_ktfileint_write_entry(krb5_context context, krb5_keytab id, krb5_keytab_ent
 	    goto abend;
     }
 
-    count = (krb5_int16) entry->principal->length;
+    count = (krb5_int16) krb5_princ_size(context, entry->principal);
     for (i = 0; i < count; i++) {
 	princ = krb5_princ_component(context, entry->principal, i);
 	size = princ->length;
@@ -1494,7 +1494,7 @@ krb5_ktfileint_size_entry(krb5_context context, krb5_keytab_entry *entry, krb5_i
     krb5_int32 total_size, i;
     krb5_error_code retval = 0;
 
-    count = (krb5_int16) entry->principal->length;
+    count = (krb5_int16) krb5_princ_size(context, entry->principal);
         
     total_size = sizeof(count);
     total_size += krb5_princ_realm(context, entry->principal)->length + (sizeof(krb5_int16));
diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c
index 41f473d47..684c4e477 100644
--- a/src/lib/krb5/keytab/ktbase.c
+++ b/src/lib/krb5/keytab/ktbase.c
@@ -30,15 +30,20 @@
 #include "k5-int.h"
 
 extern const krb5_kt_ops krb5_ktf_ops;
+extern const krb5_kt_ops krb5_ktf_writable_ops;
 extern const krb5_kt_ops krb5_kts_ops;
 
 struct krb5_kt_typelist {
     const krb5_kt_ops *ops;
     struct krb5_kt_typelist *next;
 };
+static struct krb5_kt_typelist krb5_kt_typelist_wrfile  = {
+    &krb5_ktf_writable_ops,
+    0
+};
 static struct krb5_kt_typelist krb5_kt_typelist_file  = {
     &krb5_ktf_ops,
-    0
+    &krb5_kt_typelist_wrfile
 };
 static struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
     &krb5_kts_ops,
diff --git a/src/lib/krb5/krb/.Sanitize b/src/lib/krb5/krb/.Sanitize
index 7457c8407..a2ab3a0d0 100644
--- a/src/lib/krb5/krb/.Sanitize
+++ b/src/lib/krb5/krb/.Sanitize
@@ -37,6 +37,7 @@ chk_trans.c
 cleanup.h
 configure
 configure.in
+conv_creds.c
 conv_princ.c
 copy_addrs.c
 copy_athctr.c
@@ -60,8 +61,6 @@ gen_seqnum.c
 gen_subkey.c
 get_creds.c
 get_in_tkt.c
-in_tkt_ktb.c
-in_tkt_pwd.c
 in_tkt_sky.c
 init_ctx.c
 int-proto.h
@@ -106,6 +105,7 @@ t_ref_kerb.out
 t_ser.c
 tgtname.c
 unparse.c
+v4lifetime.c
 valid_times.c
 walk_rtree.c
 
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
index c936ca4fd..1272063ee 100644
--- a/src/lib/krb5/krb/ChangeLog
+++ b/src/lib/krb5/krb/ChangeLog
@@ -1,3 +1,315 @@
+2004-02-06  Sam Hartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* init_ctx.c (DEFAULT_ETYPE_LIST): Include aes128-cts
+
+2003-12-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* mk_req_ext.c (krb5int_generate_and_save_subkey): New function,
+	split out from krb5_mk_req_extended.
+	(krb5_mk_req_extended): Call it.
+	* mk_rep.c (krb5_mk_rep): If KRB5_AUTH_CONTEXT_USE_SUBKEY flag is
+	set, call krb5int_generate_and_save_subkey to set up a new subkey
+	to send to the client.
+
+	* serialize.c (krb5_ser_pack_int64, krb5_ser_unpack_int64): New
+	functions.
+
+2003-10-30  Tom Yu  <tlyu@mit.edu>
+
+	* gen_seqnum.c (krb5_generate_seq_number): Fix mask; was short by
+	4 bits.
+
+2003-10-08  Tom Yu  <tlyu@mit.edu>
+
+	* rd_safe.c (krb5_rd_safe_basic): Save the encoded KRB-SAFE-BODY
+	to avoid trouble caused by re-encoding.  Also, handle correctly
+	implemented RFC 1510 KRB-SAFE, i.e., checksummed over
+	KRB-SAFE-BODY only.
+
+2003-09-02  Tom Yu  <tlyu@mit.edu>
+
+	* conv_creds.c (krb524_convert_creds_plain): Apply patch from
+	Cesar Garcia to fix lifetime computation.
+
+2003-08-19  SamHartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* rd_cred.c (decrypt_credencdata): Don't double free credentials.
+
+2003-08-08  Tom Yu  <tlyu@mit.edu>
+
+	* gic_pwd.c (krb5_get_init_creds_password): If DNS SRV support is
+	turned off, the second call to get_init_creds() will fail with
+	KRB5_REALM_UNKNOWN under certain circumstances.  If that happens,
+	return the error from the first call to get_init_creds(), which
+	will be more useful to the user.
+
+2003-07-22  Sam Hartman  <hartmans@avalanche-breakdown.mit.edu>
+
+	* preauth2.c (krb5_do_preauth): Use the etype_info2 decoder for decoding etype_info2
+	(krb5_do_preauth): If an invalid encoding of etype_info or
+	etype_info2 is received, ignore it rather  than failing the request
+
+2003-07-09  Alexandra Ellwood  <lxs@mit.edu>
+
+        * init_ctx.c: Export krb5_get_permitted_enctypes for Samba.
+
+2003-06-27  Tom Yu  <tlyu@mit.edu>
+
+	* gic_keytab.c (krb5_get_in_tkt_with_keytab): Pass (void*)keytab,
+	not &keytab, to get_init_creds.  Thanks to Herb Lewis.
+
+2003-06-16  Sam Hartman  <hartmans@mit.edu>
+
+	* fwd_tgt.c (krb5_fwd_tgt_creds): Set use_conf_ktypes to true while getting the TGT key
+
+2003-06-13  Tom Yu  <tlyu@mit.edu>
+
+	* rd_rep.c (krb5_rd_rep): Free subkeys before replacing them, if
+	needed.  This avoids a memory leak.
+
+2003-06-11  Tom Yu  <tlyu@mit.edu>
+
+	* srv_rcache.c (krb5_get_server_rcache): Octal escapes begin with
+	hyphen now, since backslash is a pathname separator on DOS.
+
+2003-06-06  Sam Hartman  <hartmans@mit.edu>
+
+	* get_in_tkt.c (krb5_get_init_creds): Mask out renewable_ok if the
+	request is for a renewable ticket with rtime greater than till 
+
+2003-06-06  Ezra Peisach  <epeisach@mit.edu>
+
+	* mk_req_ext.c (krb5_generate_authenticator): Sequence numbers are
+	unsigned now.
+
+2003-05-30  Ken Raeburn  <raeburn@mit.edu>
+
+	* get_in_tkt.c (krb5_get_init_creds): Change hardcoded default
+	ticket lifetime from 10 hours to 24 hours.
+
+	* init_ctx.c (DEFAULT_KDC_TIMESYNC): Define as 1 always.
+	(DEFAULT_CCACHE_TYPE): Define as 4 always.
+
+2003-05-30  Alexandra Ellwood <lxs@mit.edu>
+
+	* get_in_tkt.c: (verify_as_reply) Only check the renewable lifetime
+	of tickets whose request options included KDC_OPT_RENEWABLE_OK
+	if those options did not also include KDC_OPT_RENEWABLE.   Otherwise 
+	verify_as_reply() will fail for all renewable tickets.
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* conv_creds.c: Enable support on Windows always.
+	(krb5_524_convert_creds): Renamed from krb524_convert_creds_kdc.
+	(krb524_convert_creds_kdc, krb524_init_ets) [!_WIN32]: Backwards
+	compatibility functions.
+
+2003-05-27  Sam Hartman  <hartmans@mit.edu>
+
+	* gic_keytab.c (krb5_get_in_tkt_with_keytab): as below
+
+	* gic_pwd.c (krb5_get_in_tkt_with_password): Store client and
+	server principals to avoid memory leak  
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* conv_creds.c: New file, moved from krb524/conv_creds.c and
+	krb524/encode.c.  Rename exported encode routine, make other
+	encode and decode routines static.  If KRB5_KRB4_COMPAT is not
+	defined, return an error.
+	* v4lifetime.c: New file, moved from lib/krb4/lifetime.c.  Renamed
+	functions, changed interface to use krb5 types.
+	* Makefile.in (STLIBOBJS, OBJS, SRCS): Add them.
+
+2003-05-23  Sam Hartman  <hartmans@mit.edu>
+
+	* get_in_tkt.c (krb5_get_init_creds): Initialize options based on
+	context.kdc_default_options 
+
+2003-05-22  Tom Yu  <tlyu@mit.edu>
+
+	* gen_seqnum.c (krb5_generate_seq_number): Fix think-o on sequence
+	number mask.
+
+	* auth_con.c (krb5int_auth_con_chkseqnum): New function; implement
+	heuristic for broken Heimdal sequence number encoding.
+	(chk_heimdal_seqnum): Auxiliary function for above.
+
+	* auth_con.h: Add flags for sequence number heuristic.
+
+	* rd_priv.c: Use krb5int_auth_con_chkseqnum.
+
+	* rd_safe.c: Use krb5int_auth_con_chkseqnum.
+
+2003-05-22  Sam Hartman  <hartmans@mit.edu>
+
+	* gic_pwd.c (krb5int_populate_gic_opt): returns void
+
+2003-05-21  Tom Yu  <tlyu@mit.edu>
+
+	* gic_pwd.c (krb5_get_in_tkt_with_password): Set pw0.length
+	correctly if a password is passed in.
+
+2003-05-20  Sam Hartman  <hartmans@mit.edu>
+
+	* Makefile.in (SRCS): Remove in_ktb.c
+
+	* gic_keytab.c (krb5_get_in_tkt_with_keytab): Move from
+	in_tkt_keytab.c and rewrite to use krb5_get_init_creds 
+
+	* gic_pwd.c (krb5_get_in_tkt_with_password): Moved here from
+	in_tkt_pwd.c so it can share code with
+	krb5_get_init_creds_password.  Rewritten to call
+	krb5_get_in_tkt_password 
+
+	* Makefile.in (SRCS): Delete in_tkt_pwd.c
+
+2003-05-18  Tom Yu  <tlyu@mit.edu>
+
+	* auth_con.h: Sequence numbers are now unsigned.
+
+	* gen_seqnum.c (krb5_generate_seq_number): Constrain initial
+	sequence number space to facilitate backwards compatibility.
+
+2003-05-16  Ken Raeburn  <raeburn@mit.edu>
+
+	* chpw.c (krb5int_rd_chpw_rep): Allow new kpasswd error codes up
+	through _INITIAL_FLAG_NEEDED.
+
+2003-05-13  Sam Hartman  <hartmans@mit.edu>
+
+	* fwd_tgt.c (krb5_fwd_tgt_creds): Try with no specified enctype if
+	forwarding a specific enctype fails. l
+
+	* get_in_tkt.c (krb5_get_init_creds): Free s2kparams
+
+	* preauth2.c (krb5_do_preauth): Fix memory management
+	(pa_salt): Use copy_data_contents
+
+	* copy_data.c (krb5int_copy_data_contents): New function
+
+2003-05-09  Sam Hartman  <hartmans@mit.edu>
+
+	* preauth2.c: Patch from Sun to reorganize code   for handling
+	etype_info requests.  More efficient  and easier to implement etype_info2
+	(krb5_do_preauth): Support enctype_info2
+
+2003-05-08  Sam Hartman  <hartmans@mit.edu>
+
+	* preauth2.c: Add s2kparams to the declaration of a preauth
+	function, to every instance of a preauth function and to every
+	call to gak_fct 
+
+	* get_in_tkt.c (krb5_get_init_creds): Add s2kparams support
+
+	* gic_keytab.c (krb5_get_as_key_keytab): Add s2kparams
+
+	* gic_pwd.c (krb5_get_as_key_password): Add s2kparams support
+
+2003-05-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* init_ctx.c (init_common): Copy tgs_ktypes array to
+	conf_tgs_ktypes.  Clear use_conf_ktypes.
+	(krb5_free_context): Free conf_tgs_ktypes.
+	(krb5_get_tgs_ktypes): Use use_conf_ktypes to choose between
+	tgs_ktypes and conf_tgs_ktypes.
+
+	* gc_frm_kdc.c (krb5_get_cred_from_kdc_opt): Set use_conf_ktypes
+	in context to 1 for all operations except the acquisition of the
+	desired service ticket.
+
+2003-05-09  Tom Yu  <tlyu@mit.edu>
+
+	* auth_con.c (krb5_auth_con_setsendsubkey) 
+	(krb5_auth_con_setrecvsubkey, krb5_auth_con_getsendsubkey) 
+	(krb5_auth_con_getrecvsubkey): New functions.  Set or retrieve
+	subkeys from an auth_context.
+	(krb5_auth_con_getlocalsubkey, krb5_auth_con_getremotesubkey):
+	Reimplement in terms of the above.
+
+	* auth_con.h, ser_actx.c: Rename {local,remote}_subkey ->
+	{send,recv}_subkey.
+
+	* chpw.c (krb5int_rd_chpw_rep): Save send_subkey prior to rd_rep;
+	use saved send_subkey to smash recv_subkey obtained from rd_rep.
+
+	* mk_req_ext.c (krb5_mk_req_extended): Rename
+	{local,remote}_subkey -> {send,recv}_subkey.  Set both subkeys if
+	subkey generation is requested.
+
+	* mk_cred.c, mk_priv.c, mk_safe.c: Rename {local,remote}_subkey ->
+	{send,recv}_subkey.  Use either send_subkey or keyblock, in that
+	order.
+
+	* rd_cred.c, rd_priv.c, rd_safe.c: Rename {local,remote}_subkey ->
+	{send,recv}_subkey.  Use either recv_subkey or keyblock, in that
+	order.
+
+	* rd_rep.c (krb5_rd_rep): Rename {local,remote}_subkey ->
+	{send,recv}_subkey.  Set both subkeys if a subkey is present in
+	the AP-REP message.
+
+	* rd_req_dec.c (krb5_rd_req_decoded_opt): Rename
+	{local,remote}_subkey -> {send,recv}_subkey.  Set both subkeys if
+	a subkey is present in the AP-REQ message.
+
+2003-05-06  Sam Hartman  <hartmans@mit.edu>
+
+	* kfree.c (krb5_free_etype_info): Free s2kparams
+
+2003-04-27  Sam Hartman  <hartmans@mit.edu>
+
+	* chpw.c (krb5int_setpw_result_code_string): Make internal 
+
+2003-04-25  Sam Hartman  <hartmans@mit.edu>
+
+	* chpw.c (krb5int_rd_setpw_rep): Fix error handling; allow
+	krberrors to be read correctly; fix memory alloctaion so that
+	allocated structures are freed. 
+
+2003-04-24  Ezra Peisach  <epeisach@mit.edu>
+
+	* kfree.c (krb5_free_pwd_sequences): Correction to previous
+	fix. Free contents of krb5_data - not just the pointer.
+
+2003-04-23  Ezra Peisach  <epeisach@mit.edu>
+
+	* kfree.c (krb5_free_pwd_sequences): Actually free the entire
+	sequence of passwd_phase_elements and not just the first one.
+
+2003-04-16  Sam Hartman  <hartmans@mit.edu>
+
+	* chpw.c (krb5int_mk_setpw_req): Use encode_krb5_setpw_req.  Fix
+	memory handling to free data that is allocated  
+
+2003-04-15  Sam Hartman  <hartmans@mit.edu>
+
+	* chpw.c (krb5int_mk_setpw_req krb5int_rd_setpw_rep): New function
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* init_ctx.c (DEFAULT_ETYPE_LIST): Add AES with 256 bits at the
+	front of the list.  No 128-bit support by defaut.
+
+2003-04-01  Nalin Dahyabhai  <nalin@redhat.com>
+
+	* gc_frm_kdc.c (krb5_get_cred_from_kdc_opt): Check principal name
+	length before examining components.
+
+	* parse.c (krb5_parse_name): Double-check principal name length
+	before filling in components.
+
+	* srv_rcache.c (krb5_get_server_rcache): Check for null pointer
+	supplied in place of name.
+
+	* unparse.c (krb5_unparse_name_ext): Don't move buffer pointer
+	backwards if nothing has been put into the buffer yet.
+
+2003-04-01  Sam Hartman  <hartmans@mit.edu>
+
+	* rd_req.c (krb5_rd_req): If AUTH_CONTEXT_DO_TIME is cleared,
+	don't set up a replay cache. 
+
 2003-03-08  Ezra Peisach  <epeisach@mit.edu>
 
 	* t_kerb.c: Only include krb.h if krb4 support compiled in,
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 18627b12a..b703e56aa 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -23,6 +23,7 @@ STLIBOBJS= \
 	bld_princ.o	\
 	chk_trans.o	\
 	chpw.o		\
+	conv_creds.o	\
 	conv_princ.o	\
 	copy_addrs.o	\
 	copy_auth.o	\
@@ -51,8 +52,6 @@ STLIBOBJS= \
 	gic_keytab.o	\
 	gic_opt.o	\
 	gic_pwd.o	\
-	in_tkt_ktb.o	\
-	in_tkt_pwd.o	\
 	in_tkt_sky.o	\
 	init_ctx.o	\
 	init_keyblock.o \
@@ -95,6 +94,7 @@ STLIBOBJS= \
 	str_conv.o	\
 	tgtname.o	\
 	unparse.o	\
+	v4lifetime.o	\
 	valid_times.o	\
 	vfy_increds.o	\
 	vic_opt.o	\
@@ -109,6 +109,7 @@ OBJS=	$(OUTPRE)addr_comp.$(OBJEXT)	\
 	$(OUTPRE)bld_princ.$(OBJEXT)	\
 	$(OUTPRE)chk_trans.$(OBJEXT)	\
 	$(OUTPRE)chpw.$(OBJEXT)		\
+	$(OUTPRE)conv_creds.$(OBJEXT)	\
 	$(OUTPRE)conv_princ.$(OBJEXT)	\
 	$(OUTPRE)copy_addrs.$(OBJEXT)	\
 	$(OUTPRE)copy_auth.$(OBJEXT)	\
@@ -137,8 +138,6 @@ OBJS=	$(OUTPRE)addr_comp.$(OBJEXT)	\
 	$(OUTPRE)gic_keytab.$(OBJEXT)	\
 	$(OUTPRE)gic_opt.$(OBJEXT)	\
 	$(OUTPRE)gic_pwd.$(OBJEXT)	\
-	$(OUTPRE)in_tkt_ktb.$(OBJEXT)	\
-	$(OUTPRE)in_tkt_pwd.$(OBJEXT)	\
 	$(OUTPRE)in_tkt_sky.$(OBJEXT)	\
 	$(OUTPRE)init_ctx.$(OBJEXT)	\
 	$(OUTPRE)init_keyblock.$(OBJEXT) \
@@ -181,6 +180,7 @@ OBJS=	$(OUTPRE)addr_comp.$(OBJEXT)	\
 	$(OUTPRE)str_conv.$(OBJEXT)	\
 	$(OUTPRE)tgtname.$(OBJEXT)	\
 	$(OUTPRE)unparse.$(OBJEXT)	\
+	$(OUTPRE)v4lifetime.$(OBJEXT)	\
 	$(OUTPRE)valid_times.$(OBJEXT)	\
 	$(OUTPRE)vfy_increds.$(OBJEXT)	\
 	$(OUTPRE)vic_opt.$(OBJEXT)	\
@@ -196,6 +196,7 @@ SRCS=	$(srcdir)/addr_comp.c	\
 	$(srcdir)/brand.c	\
 	$(srcdir)/chk_trans.c	\
 	$(srcdir)/chpw.c	\
+	$(srcdir)/conv_creds.c	\
 	$(srcdir)/conv_princ.c	\
 	$(srcdir)/copy_addrs.c	\
 	$(srcdir)/copy_auth.c	\
@@ -224,8 +225,6 @@ SRCS=	$(srcdir)/addr_comp.c	\
 	$(srcdir)/gic_keytab.c	\
 	$(srcdir)/gic_opt.c	\
 	$(srcdir)/gic_pwd.c	\
-	$(srcdir)/in_tkt_ktb.c	\
-	$(srcdir)/in_tkt_pwd.c	\
 	$(srcdir)/in_tkt_sky.c	\
 	$(srcdir)/init_ctx.c	\
 	$(srcdir)/init_keyblock.c \
@@ -268,6 +267,7 @@ SRCS=	$(srcdir)/addr_comp.c	\
 	$(srcdir)/str_conv.c	\
 	$(srcdir)/tgtname.c	\
 	$(srcdir)/unparse.c	\
+	$(srcdir)/v4lifetime.c	\
 	$(srcdir)/valid_times.c	\
 	$(srcdir)/vfy_increds.c \
 	$(srcdir)/vic_opt.c	\
@@ -367,449 +367,482 @@ clean::
 #
 addr_comp.so addr_comp.po $(OUTPRE)addr_comp.$(OBJEXT): addr_comp.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 addr_order.so addr_order.po $(OUTPRE)addr_order.$(OBJEXT): addr_order.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 addr_srch.so addr_srch.po $(OUTPRE)addr_srch.$(OBJEXT): addr_srch.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 appdefault.so appdefault.po $(OUTPRE)appdefault.$(OBJEXT): appdefault.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 auth_con.so auth_con.po $(OUTPRE)auth_con.$(OBJEXT): auth_con.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 bld_pr_ext.so bld_pr_ext.po $(OUTPRE)bld_pr_ext.$(OBJEXT): bld_pr_ext.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 bld_princ.so bld_princ.po $(OUTPRE)bld_princ.$(OBJEXT): bld_princ.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 brand.so brand.po $(OUTPRE)brand.$(OBJEXT): brand.c
 chk_trans.so chk_trans.po $(OUTPRE)chk_trans.$(OBJEXT): chk_trans.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 chpw.so chpw.po $(OUTPRE)chpw.$(OBJEXT): chpw.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/krb5_err.h \
-  auth_con.h
-conv_princ.so conv_princ.po $(OUTPRE)conv_princ.$(OBJEXT): conv_princ.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5_err.h auth_con.h
+conv_creds.so conv_creds.po $(OUTPRE)conv_creds.$(OBJEXT): conv_creds.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(KRB_ERR_H_DEP)
+conv_princ.so conv_princ.po $(OUTPRE)conv_princ.$(OBJEXT): conv_princ.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_addrs.so copy_addrs.po $(OUTPRE)copy_addrs.$(OBJEXT): copy_addrs.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_auth.so copy_auth.po $(OUTPRE)copy_auth.$(OBJEXT): copy_auth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_athctr.so copy_athctr.po $(OUTPRE)copy_athctr.$(OBJEXT): copy_athctr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_cksum.so copy_cksum.po $(OUTPRE)copy_cksum.$(OBJEXT): copy_cksum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_creds.so copy_creds.po $(OUTPRE)copy_creds.$(OBJEXT): copy_creds.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_data.so copy_data.po $(OUTPRE)copy_data.$(OBJEXT): copy_data.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_key.so copy_key.po $(OUTPRE)copy_key.$(OBJEXT): copy_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_princ.so copy_princ.po $(OUTPRE)copy_princ.$(OBJEXT): copy_princ.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 copy_tick.so copy_tick.po $(OUTPRE)copy_tick.$(OBJEXT): copy_tick.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 cp_key_cnt.so cp_key_cnt.po $(OUTPRE)cp_key_cnt.$(OBJEXT): cp_key_cnt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 decode_kdc.so decode_kdc.po $(OUTPRE)decode_kdc.$(OBJEXT): decode_kdc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 decrypt_tk.so decrypt_tk.po $(OUTPRE)decrypt_tk.$(OBJEXT): decrypt_tk.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 deltat.so deltat.po $(OUTPRE)deltat.$(OBJEXT): deltat.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 enc_helper.so enc_helper.po $(OUTPRE)enc_helper.$(OBJEXT): enc_helper.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 encode_kdc.so encode_kdc.po $(OUTPRE)encode_kdc.$(OBJEXT): encode_kdc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 encrypt_tk.so encrypt_tk.po $(OUTPRE)encrypt_tk.$(OBJEXT): encrypt_tk.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 free_rtree.so free_rtree.po $(OUTPRE)free_rtree.$(OBJEXT): free_rtree.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 fwd_tgt.so fwd_tgt.po $(OUTPRE)fwd_tgt.$(OBJEXT): fwd_tgt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 gc_frm_kdc.so gc_frm_kdc.po $(OUTPRE)gc_frm_kdc.$(OBJEXT): gc_frm_kdc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 gc_via_tkt.so gc_via_tkt.po $(OUTPRE)gc_via_tkt.$(OBJEXT): gc_via_tkt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 gen_seqnum.so gen_seqnum.po $(OUTPRE)gen_seqnum.$(OBJEXT): gen_seqnum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 gen_subkey.so gen_subkey.po $(OUTPRE)gen_subkey.$(OBJEXT): gen_subkey.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 get_creds.so get_creds.po $(OUTPRE)get_creds.$(OBJEXT): get_creds.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 get_in_tkt.so get_in_tkt.po $(OUTPRE)get_in_tkt.$(OBJEXT): get_in_tkt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h $(srcdir)/../os/os-proto.h
+  int-proto.h $(srcdir)/../os/os-proto.h
 gic_keytab.so gic_keytab.po $(OUTPRE)gic_keytab.$(OBJEXT): gic_keytab.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 gic_opt.so gic_opt.po $(OUTPRE)gic_opt.$(OBJEXT): gic_opt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 gic_pwd.so gic_pwd.po $(OUTPRE)gic_pwd.$(OBJEXT): gic_pwd.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
-in_tkt_ktb.so in_tkt_ktb.po $(OUTPRE)in_tkt_ktb.$(OBJEXT): in_tkt_ktb.c $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
-in_tkt_pwd.so in_tkt_pwd.po $(OUTPRE)in_tkt_pwd.$(OBJEXT): in_tkt_pwd.c $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 in_tkt_sky.so in_tkt_sky.po $(OUTPRE)in_tkt_sky.$(OBJEXT): in_tkt_sky.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 init_ctx.so init_ctx.po $(OUTPRE)init_ctx.$(OBJEXT): init_ctx.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h brand.c $(srcdir)/../krb5_libinit.h
+  brand.c $(srcdir)/../krb5_libinit.h
 init_keyblock.so init_keyblock.po $(OUTPRE)init_keyblock.$(OBJEXT): init_keyblock.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kdc_rep_dc.so kdc_rep_dc.po $(OUTPRE)kdc_rep_dc.$(OBJEXT): kdc_rep_dc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kfree.so kfree.po $(OUTPRE)kfree.$(OBJEXT): kfree.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 mk_cred.so mk_cred.po $(OUTPRE)mk_cred.$(OBJEXT): mk_cred.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 mk_error.so mk_error.po $(OUTPRE)mk_error.$(OBJEXT): mk_error.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 mk_priv.so mk_priv.po $(OUTPRE)mk_priv.$(OBJEXT): mk_priv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 mk_rep.so mk_rep.po $(OUTPRE)mk_rep.$(OBJEXT): mk_rep.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 mk_req.so mk_req.po $(OUTPRE)mk_req.$(OBJEXT): mk_req.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 mk_req_ext.so mk_req_ext.po $(OUTPRE)mk_req_ext.$(OBJEXT): mk_req_ext.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 mk_safe.so mk_safe.po $(OUTPRE)mk_safe.$(OBJEXT): mk_safe.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 parse.so parse.po $(OUTPRE)parse.$(OBJEXT): parse.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 pr_to_salt.so pr_to_salt.po $(OUTPRE)pr_to_salt.$(OBJEXT): pr_to_salt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 preauth.so preauth.po $(OUTPRE)preauth.$(OBJEXT): preauth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 preauth2.so preauth2.po $(OUTPRE)preauth2.$(OBJEXT): preauth2.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 princ_comp.so princ_comp.po $(OUTPRE)princ_comp.$(OBJEXT): princ_comp.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 rd_cred.so rd_cred.po $(OUTPRE)rd_cred.$(OBJEXT): rd_cred.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 rd_error.so rd_error.po $(OUTPRE)rd_error.$(OBJEXT): rd_error.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 rd_priv.so rd_priv.po $(OUTPRE)rd_priv.$(OBJEXT): rd_priv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 rd_rep.so rd_rep.po $(OUTPRE)rd_rep.$(OBJEXT): rd_rep.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 rd_req.so rd_req.po $(OUTPRE)rd_req.$(OBJEXT): rd_req.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 rd_req_dec.so rd_req_dec.po $(OUTPRE)rd_req_dec.$(OBJEXT): rd_req_dec.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 rd_safe.so rd_safe.po $(OUTPRE)rd_safe.$(OBJEXT): rd_safe.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h cleanup.h auth_con.h
+  cleanup.h auth_con.h
 recvauth.so recvauth.po $(OUTPRE)recvauth.$(OBJEXT): recvauth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 sendauth.so sendauth.po $(OUTPRE)sendauth.$(OBJEXT): sendauth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 send_tgs.so send_tgs.po $(OUTPRE)send_tgs.$(OBJEXT): send_tgs.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ser_actx.so ser_actx.po $(OUTPRE)ser_actx.$(OBJEXT): ser_actx.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h auth_con.h
+  int-proto.h auth_con.h
 ser_adata.so ser_adata.po $(OUTPRE)ser_adata.$(OBJEXT): ser_adata.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 ser_addr.so ser_addr.po $(OUTPRE)ser_addr.$(OBJEXT): ser_addr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 ser_auth.so ser_auth.po $(OUTPRE)ser_auth.$(OBJEXT): ser_auth.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 ser_cksum.so ser_cksum.po $(OUTPRE)ser_cksum.$(OBJEXT): ser_cksum.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 ser_ctx.so ser_ctx.po $(OUTPRE)ser_ctx.$(OBJEXT): ser_ctx.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ser_eblk.so ser_eblk.po $(OUTPRE)ser_eblk.$(OBJEXT): ser_eblk.c
 ser_key.so ser_key.po $(OUTPRE)ser_key.$(OBJEXT): ser_key.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 ser_princ.so ser_princ.po $(OUTPRE)ser_princ.$(OBJEXT): ser_princ.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 serialize.so serialize.po $(OUTPRE)serialize.$(OBJEXT): serialize.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 set_realm.so set_realm.po $(OUTPRE)set_realm.$(OBJEXT): set_realm.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 srv_rcache.so srv_rcache.po $(OUTPRE)srv_rcache.$(OBJEXT): srv_rcache.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): str_conv.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 tgtname.so tgtname.po $(OUTPRE)tgtname.$(OBJEXT): tgtname.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 unparse.so unparse.po $(OUTPRE)unparse.$(OBJEXT): unparse.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
+v4lifetime.so v4lifetime.po $(OUTPRE)v4lifetime.$(OBJEXT): v4lifetime.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 valid_times.so valid_times.po $(OUTPRE)valid_times.$(OBJEXT): valid_times.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 vfy_increds.so vfy_increds.po $(OUTPRE)vfy_increds.$(OBJEXT): vfy_increds.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 vic_opt.so vic_opt.po $(OUTPRE)vic_opt.$(OBJEXT): vic_opt.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 walk_rtree.so walk_rtree.po $(OUTPRE)walk_rtree.$(OBJEXT): walk_rtree.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h int-proto.h
+  int-proto.h
 t_walk_rtree.so t_walk_rtree.po $(OUTPRE)t_walk_rtree.$(OBJEXT): t_walk_rtree.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_kerb.so t_kerb.po $(OUTPRE)t_kerb.$(OBJEXT): t_kerb.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
   $(SRCTOP)/include/kerberosIV/des.h $(KRB_ERR_H_DEP) \
   $(BUILDTOP)/include/profile.h
 t_ser.so t_ser.po $(OUTPRE)t_ser.$(OBJEXT): t_ser.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h auth_con.h
+  auth_con.h
 t_deltat.so t_deltat.po $(OUTPRE)t_deltat.$(OBJEXT): t_deltat.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 t_expand.so t_expand.po $(OUTPRE)t_expand.$(OBJEXT): t_expand.c chk_trans.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
index 09ccf9808..cd3acf176 100644
--- a/src/lib/krb5/krb/auth_con.c
+++ b/src/lib/krb5/krb/auth_con.c
@@ -1,6 +1,8 @@
 #include "k5-int.h"
 #include "auth_con.h"
 
+static krb5_boolean chk_heimdal_seqnum(krb5_ui_4, krb5_ui_4);
+
 static krb5_error_code
 actx_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **outad)
 {
@@ -59,10 +61,10 @@ krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
 	krb5_free_authenticator(context, auth_context->authentp);
     if (auth_context->keyblock) 
 	krb5_free_keyblock(context, auth_context->keyblock);
-    if (auth_context->local_subkey) 
-	krb5_free_keyblock(context, auth_context->local_subkey);
-    if (auth_context->remote_subkey) 
-	krb5_free_keyblock(context, auth_context->remote_subkey);
+    if (auth_context->send_subkey) 
+	krb5_free_keyblock(context, auth_context->send_subkey);
+    if (auth_context->recv_subkey) 
+	krb5_free_keyblock(context, auth_context->recv_subkey);
     if (auth_context->rcache)
 	krb5_rc_close(context, auth_context->rcache);
     if (auth_context->permitted_etypes)
@@ -176,17 +178,53 @@ krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_
 krb5_error_code KRB5_CALLCONV
 krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
 {
-    if (auth_context->local_subkey)
-    	return krb5_copy_keyblock(context,auth_context->local_subkey,keyblock);
+    return krb5_auth_con_getsendsubkey(context, auth_context, keyblock);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
+{
+    return krb5_auth_con_getrecvsubkey(context, auth_context, keyblock);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
+{
+    if (ac->send_subkey != NULL)
+	krb5_free_keyblock(ctx, ac->send_subkey);
+    ac->send_subkey = NULL;
+    if (keyblock !=NULL)
+	return krb5_copy_keyblock(ctx, keyblock, &ac->send_subkey);
+    else
+	return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
+{
+    if (ac->recv_subkey != NULL)
+	krb5_free_keyblock(ctx, ac->recv_subkey);
+    ac->recv_subkey = NULL;
+    if (keyblock != NULL)
+	return krb5_copy_keyblock(ctx, keyblock, &ac->recv_subkey);
+    else
+	return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
+{
+    if (ac->send_subkey != NULL)
+	return krb5_copy_keyblock(ctx, ac->send_subkey, keyblock);
     *keyblock = NULL;
     return 0;
 }
 
 krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
+krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
 {
-    if (auth_context->remote_subkey)
-    	return krb5_copy_keyblock(context,auth_context->remote_subkey,keyblock);
+    if (ac->recv_subkey != NULL)
+	return krb5_copy_keyblock(ctx, ac->recv_subkey, keyblock);
     *keyblock = NULL;
     return 0;
 }
@@ -359,3 +397,167 @@ krb5_auth_con_get_checksum_func( krb5_context context,
   *data = auth_context->checksum_func_data;
   return 0;
 }
+
+/*
+ * krb5int_auth_con_chkseqnum
+ *
+ * We use a somewhat complex heuristic for validating received
+ * sequence numbers.  We must accommodate both our older
+ * implementation, which sends negative sequence numbers, and the
+ * broken Heimdal implementation (at least as of 0.5.2), which
+ * violates X.690 BER for integer encodings.  The requirement of
+ * handling negative sequence numbers removes one of easier means of
+ * detecting a Heimdal implementation, so we resort to this mess
+ * here.
+ *
+ * X.690 BER (and consequently DER, which are the required encoding
+ * rules in RFC1510) encode all integer types as signed integers.
+ * This means that the MSB being set on the first octet of the
+ * contents of the encoding indicates a negative value.  Heimdal does
+ * not prepend the required zero octet to unsigned integer encodings
+ * which would otherwise have the MSB of the first octet of their
+ * encodings set.
+ *
+ * Our ASN.1 library implements a special decoder for sequence
+ * numbers, accepting both negative and positive 32-bit numbers but
+ * mapping them both into the space of positive unsigned 32-bit
+ * numbers in the obvious bit-pattern-preserving way.  This maintains
+ * compatibility with our older implementations.  This also means that
+ * encodings emitted by Heimdal are ambiguous.
+ *
+ * Heimdal counter value	received uint32 value
+ *
+ * 0x00000080			0xFFFFFF80
+ * 0x000000FF			0xFFFFFFFF
+ * 0x00008000			0xFFFF8000
+ * 0x0000FFFF			0xFFFFFFFF
+ * 0x00800000			0xFF800000
+ * 0x00FFFFFF			0xFFFFFFFF
+ * 0xFF800000			0xFF800000
+ * 0xFFFFFFFF			0xFFFFFFFF
+ *
+ * We use two auth_context flags, SANE_SEQ and HEIMDAL_SEQ, which are
+ * only set after we can unambiguously determine the sanity of the
+ * sending implementation.  Once one of these flags is set, we accept
+ * only the sequence numbers appropriate to the remote implementation
+ * type.  We can make the determination in two different ways.  The
+ * first is to note the receipt of a "negative" sequence number when a
+ * "positive" one was expected.  The second is to note the receipt of
+ * a sequence number that wraps through "zero" in a weird way.  The
+ * latter corresponds to the receipt of an initial sequence number in
+ * the ambiguous range.
+ *
+ * There are 2^7 + 2^15 + 2^23 + 2^23 = 16810112 total ambiguous
+ * initial Heimdal counter values, but we receive them as one of 2^23
+ * possible values.  There is a ~1/256 chance of a Heimdal
+ * implementation sending an intial sequence number in the ambiguous
+ * range.
+ *
+ * We have to do special treatment when receiving sequence numbers
+ * between 0xFF800000..0xFFFFFFFF, or when wrapping through zero
+ * weirdly (due to ambiguous initial sequence number).  If we are
+ * expecting a value corresponding to an ambiguous Heimdal counter
+ * value, and we receive an exact match, we can mark the remote end as
+ * sane.
+ */
+krb5_boolean
+krb5int_auth_con_chkseqnum(
+    krb5_context ctx,
+    krb5_auth_context ac,
+    krb5_ui_4 in_seq)
+{
+    krb5_ui_4 exp_seq;
+
+    exp_seq = ac->remote_seq_number;
+
+    /*
+     * If sender is known to be sane, accept _only_ exact matches.
+     */
+    if (ac->auth_context_flags & KRB5_AUTH_CONN_SANE_SEQ)
+	return in_seq == exp_seq;
+
+    /*
+     * If sender is not known to be sane, first check the ambiguous
+     * range of received values, 0xFF800000..0xFFFFFFFF.
+     */
+    if ((in_seq & 0xFF800000) == 0xFF800000) {
+	/*
+	 * If expected sequence number is in the range
+	 * 0xFF800000..0xFFFFFFFF, then we can't make any
+	 * determinations about the sanity of the sending
+	 * implementation.
+	 */
+	if ((exp_seq & 0xFF800000) == 0xFF800000 && in_seq == exp_seq)
+	    return 1;
+	/*
+	 * If sender is not known for certain to be a broken Heimdal
+	 * implementation, check for exact match.
+	 */
+	if (!(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)
+	    && in_seq == exp_seq)
+	    return 1;
+	/*
+	 * Now apply hairy algorithm for matching sequence numbers
+	 * sent by broken Heimdal implementations.  If it matches, we
+	 * know for certain it's a broken Heimdal sender.
+	 */
+	if (chk_heimdal_seqnum(exp_seq, in_seq)) {
+	    ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+	    return 1;
+	}
+	return 0;
+    }
+
+    /*
+     * Received value not in the ambiguous range?  If the _expected_
+     * value is in the range of ambiguous Hemidal counter values, and
+     * it matches the received value, sender is known to be sane.
+     */
+    if (in_seq == exp_seq) {
+	if ((   exp_seq & 0xFFFFFF80) == 0x00000080
+	    || (exp_seq & 0xFFFF8000) == 0x00008000
+	    || (exp_seq & 0xFF800000) == 0x00800000)
+	    ac->auth_context_flags |= KRB5_AUTH_CONN_SANE_SEQ;
+	return 1;
+    }
+
+    /*
+     * Magic wraparound for the case where the intial sequence number
+     * is in the ambiguous range.  This means that the sender's
+     * counter is at a different count than ours, so we correct ours,
+     * and mark the sender as being a broken Heimdal implementation.
+     */
+    if (exp_seq == 0
+	&& !(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)) {
+	switch (in_seq) {
+	case 0x100:
+	case 0x10000:
+	case 0x1000000:
+	    ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+	    exp_seq = in_seq;
+	    return 1;
+	default:
+	    return 0;
+	}
+    }
+    return 0;
+}
+
+static krb5_boolean
+chk_heimdal_seqnum(krb5_ui_4 exp_seq, krb5_ui_4 in_seq)
+{
+    if (( exp_seq & 0xFF800000) == 0x00800000
+	&& (in_seq & 0xFF800000) == 0xFF800000
+	&& (in_seq & 0x00FFFFFF) == exp_seq)
+	return 1;
+    else if ((  exp_seq & 0xFFFF8000) == 0x00008000
+	     && (in_seq & 0xFFFF8000) == 0xFFFF8000
+	     && (in_seq & 0x0000FFFF) == exp_seq)
+	return 1;
+    else if ((  exp_seq & 0xFFFFFF80) == 0x00000080
+	     && (in_seq & 0xFFFFFF80) == 0xFFFFFF80
+	     && (in_seq & 0x000000FF) == exp_seq)
+	return 1;
+    else
+	return 0;
+}
diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h
index d83d6b86e..9543de355 100644
--- a/src/lib/krb5/krb/auth_con.h
+++ b/src/lib/krb5/krb/auth_con.h
@@ -9,12 +9,12 @@ struct _krb5_auth_context {
     krb5_address      *	local_addr;
     krb5_address      *	local_port;
     krb5_keyblock     * keyblock;
-    krb5_keyblock     * local_subkey;
-    krb5_keyblock     * remote_subkey;
+    krb5_keyblock     * send_subkey;
+    krb5_keyblock     * recv_subkey;
 
     krb5_int32		auth_context_flags;
-    krb5_int32		remote_seq_number;
-    krb5_int32		local_seq_number;
+    krb5_ui_4		remote_seq_number;
+    krb5_ui_4		local_seq_number;
     krb5_authenticator *authentp;		/* mk_req, rd_req, mk_rep, ...*/
     krb5_cksumtype	req_cksumtype;		/* mk_safe, ... */
     krb5_cksumtype	safe_cksumtype;		/* mk_safe, ... */
@@ -30,5 +30,7 @@ struct _krb5_auth_context {
 #define KRB5_AUTH_CONN_INITIALIZED	0x00010000
 #define KRB5_AUTH_CONN_USED_W_MK_REQ	0x00020000
 #define KRB5_AUTH_CONN_USED_W_RD_REQ	0x00040000
+#define KRB5_AUTH_CONN_SANE_SEQ		0x00080000
+#define KRB5_AUTH_CONN_HEIMDAL_SEQ	0x00100000
 
 #endif
diff --git a/src/lib/krb5/krb/chpw.c b/src/lib/krb5/krb/chpw.c
index bb2cfe9c7..a455cc40b 100644
--- a/src/lib/krb5/krb/chpw.c
+++ b/src/lib/krb5/krb/chpw.c
@@ -1,11 +1,15 @@
+/*
+** set password functions added by Paul W. Nelson, Thursby Software Systems, Inc.
+*/
 #include <string.h>
 
 #include "k5-int.h"
 #include "krb5_err.h"
 #include "auth_con.h"
 
-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)
+
+krb5_error_code 
+krb5int_mk_chpw_req(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, char *passwd, krb5_data *packet)
 {
     krb5_error_code ret = 0;
     krb5_data clearpw;
@@ -66,8 +70,8 @@ cleanup:
     return(ret);
 }
 
-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)
+krb5_error_code 
+krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *packet, int *result_code, krb5_data *result_data)
 {
     char *ptr;
     int plen, vno;
@@ -116,8 +120,18 @@ krb5_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data
 	ap_rep.data = ptr;
 	ptr += ap_rep.length;
 
-	if ((ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc)))
+	/*
+	 * Save send_subkey to later smash recv_subkey.
+	 */
+	ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmp);
+	if (ret)
+	    return ret;
+
+	ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
+	if (ret) {
+	    krb5_free_keyblock(context, tmp);
 	    return(ret);
+	}
 
 	krb5_free_ap_rep_enc_part(context, ap_rep_enc);
 
@@ -126,18 +140,17 @@ krb5_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data
 	cipherresult.data = ptr;
 	cipherresult.length = (packet->data + packet->length) - ptr;
 
-	/* XXX there's no api to do this right. The problem is that
-	   if there's a remote subkey, it will be used.  This is
-	   not what the spec requires */
-
-	tmp = auth_context->remote_subkey;
-	auth_context->remote_subkey = NULL;
+	/*
+	 * Smash recv_subkey to be send_subkey, per spec.
+	 */
+	ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmp);
+	krb5_free_keyblock(context, tmp);
+	if (ret)
+	    return ret;
 
 	ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
 			   &replay);
 
-	auth_context->remote_subkey = tmp;
-
 	if (ret)
 	    return(ret);
     } else {
@@ -161,7 +174,7 @@ krb5_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data
     *result_code = (*result_code<<8) | (*ptr++ & 0xff);
 
     if ((*result_code < KRB5_KPASSWD_SUCCESS) ||
-	(*result_code > KRB5_KPASSWD_SOFTERROR)) {
+	(*result_code > KRB5_KPASSWD_INITIAL_FLAG_NEEDED)) {
 	ret = KRB5KRB_AP_ERR_MODIFIED;
 	goto cleanup;
     }
@@ -221,3 +234,284 @@ krb5_chpw_result_code_string(krb5_context context, int result_code, char **code_
 
    return(0);
 }
+
+krb5_error_code 
+krb5int_mk_setpw_req(
+     krb5_context context,
+     krb5_auth_context auth_context,
+     krb5_data *ap_req,
+     krb5_principal targprinc,
+     char *passwd,
+     krb5_data *packet )
+{
+    krb5_error_code ret;
+    krb5_data	cipherpw;
+    krb5_data	*encoded_setpw;
+
+    char *ptr;
+     int count = 2;
+
+     cipherpw.data = NULL;
+     cipherpw.length = 0;
+     
+    if (ret = krb5_auth_con_setflags(context, auth_context,
+				     KRB5_AUTH_CONTEXT_DO_SEQUENCE))
+		return(ret);
+
+    ret = encode_krb5_setpw_req(targprinc, passwd, &encoded_setpw);
+    if (ret) {
+	return ret;
+    }
+
+    if ( (ret = krb5_mk_priv(context, auth_context, encoded_setpw, &cipherpw, NULL)) != 0) {
+	krb5_free_data( context, encoded_setpw);
+	return(ret);
+    }
+    krb5_free_data( context, encoded_setpw);
+    
+
+    packet->length = 6 + ap_req->length + cipherpw.length;
+    packet->data = (char *) malloc(packet->length);
+    if (packet->data  == NULL) {
+	ret = ENOMEM;
+	goto cleanup;
+    }
+    ptr = packet->data;
+/*
+** build the packet -
+*/
+/* put in the length */
+    *ptr++ = (packet->length>>8) & 0xff;
+    *ptr++ = packet->length & 0xff;
+/* put in the version */
+    *ptr++ = (char)0xff;
+    *ptr++ = (char)0x80;
+/* the ap_req length is big endian */
+    *ptr++ = (ap_req->length>>8) & 0xff;
+    *ptr++ = ap_req->length & 0xff;
+/* put in the request data */
+    memcpy(ptr, ap_req->data, ap_req->length);
+    ptr += ap_req->length;
+/*
+** put in the "private" password data -
+*/
+    memcpy(ptr, cipherpw.data, cipherpw.length);
+    ret = 0;
+ cleanup:
+    if (cipherpw.data)
+	krb5_free_data_contents(context, &cipherpw);
+    if ((ret != 0) && packet->data) {
+	free( packet->data);
+	packet->data = NULL;
+    }
+    return ret;
+}
+
+krb5_error_code 
+krb5int_rd_setpw_rep( krb5_context context, krb5_auth_context auth_context, krb5_data *packet,
+     int *result_code, krb5_data *result_data )
+{
+    char *ptr;
+    unsigned int message_length, version_number;
+    krb5_data ap_rep;
+    krb5_ap_rep_enc_part *ap_rep_enc;
+    krb5_error_code ret;
+    krb5_data cipherresult;
+    krb5_data clearresult;
+    krb5_replay_data replay;
+    krb5_keyblock *tmpkey;
+/*
+** validate the packet length -
+*/
+    if (packet->length < 4)
+	return(KRB5KRB_AP_ERR_MODIFIED);
+
+    ptr = packet->data;
+
+/*
+** see if it is an error
+*/
+    if (krb5_is_krb_error(packet)) {
+	krb5_error *krberror;
+	if (ret = krb5_rd_error(context, packet, &krberror))
+	    return(ret);
+	if (krberror->e_data.data  == NULL) {
+	    ret = ERROR_TABLE_BASE_krb5 + krberror->error;
+	    krb5_free_error(context, krberror);
+	    return (ret);
+	}
+	clearresult = krberror->e_data;
+	krberror->e_data.data  = NULL; /*So we can free it later*/
+	krberror->e_data.length = 0;
+	krb5_free_error(context, krberror);
+		
+    } else { /* Not an error*/
+
+/*
+** validate the message length -
+** length is big endian 
+*/
+	message_length = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
+	ptr += 2;
+/*
+** make sure the message length and packet length agree -
+*/
+	if (message_length != packet->length)
+	    return(KRB5KRB_AP_ERR_MODIFIED);
+/*
+** get the version number -
+*/
+	version_number = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
+	ptr += 2;
+/*
+** make sure we support the version returned -
+*/
+/*
+** set password version is 0xff80, change password version is 1
+*/
+	if (version_number != 0xff80 && version_number != 1)
+	    return(KRB5KDC_ERR_BAD_PVNO);
+/*
+** now fill in ap_rep with the reply -
+*/
+/*
+** get the reply length -
+*/
+	ap_rep.length = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
+	ptr += 2;
+/*
+** validate ap_rep length agrees with the packet length -
+*/
+	if (ptr + ap_rep.length >= packet->data + packet->length)
+	    return(KRB5KRB_AP_ERR_MODIFIED);
+/*
+** if data was returned, set the ap_rep ptr -
+*/
+	if( ap_rep.length ) {
+	    ap_rep.data = ptr;
+	    ptr += ap_rep.length;
+
+	    /*
+	     * Save send_subkey to later smash recv_subkey.
+	     */
+	    ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmpkey);
+	    if (ret)
+		return ret;
+
+	    ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
+	    if (ret) {
+		krb5_free_keyblock(context, tmpkey);
+		return(ret);
+	    }
+
+	    krb5_free_ap_rep_enc_part(context, ap_rep_enc);
+/*
+** now decrypt the result -
+*/
+	    cipherresult.data = ptr;
+	    cipherresult.length = (packet->data + packet->length) - ptr;
+
+	    /*
+	     * Smash recv_subkey to be send_subkey, per spec.
+	     */
+	    ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmpkey);
+	    krb5_free_keyblock(context, tmpkey);
+	    if (ret)
+		return ret;
+
+	    ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
+			       NULL);
+	    if (ret)
+		return(ret);
+	} /*We got an ap_rep*/
+	else
+	    return (KRB5KRB_AP_ERR_MODIFIED);
+    } /*Response instead of error*/
+
+/*
+** validate the cleartext length 
+*/
+    if (clearresult.length < 2) {
+	ret = KRB5KRB_AP_ERR_MODIFIED;
+	goto cleanup;
+    }
+/*
+** now decode the result -
+*/
+    ptr = clearresult.data;
+
+    *result_code = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
+    ptr += 2;
+
+/*
+** result code 5 is access denied
+*/
+    if ((*result_code < KRB5_KPASSWD_SUCCESS) || (*result_code > 5))
+    {
+	ret = KRB5KRB_AP_ERR_MODIFIED;
+	goto cleanup;
+    }
+/*
+** all success replies should be authenticated/encrypted
+*/
+    if( (ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS) )
+    {
+	ret = KRB5KRB_AP_ERR_MODIFIED;
+	goto cleanup;
+    }
+
+    if (result_data) {
+	result_data->length = (clearresult.data + clearresult.length) - ptr;
+
+	if (result_data->length)
+	{
+	    result_data->data = (char *) malloc(result_data->length);
+	    if (result_data->data)
+		memcpy(result_data->data, ptr, result_data->length);
+	}
+	else
+	    result_data->data = NULL;
+    }
+    ret = 0;
+
+ cleanup:
+    krb5_free_data_contents(context, &clearresult);
+    return(ret);
+}
+
+krb5_error_code 
+krb5int_setpw_result_code_string( krb5_context context, int result_code, const char **code_string )
+{
+   switch (result_code)
+   {
+   case KRB5_KPASSWD_MALFORMED:
+      *code_string = "Malformed request error";
+      break;
+   case KRB5_KPASSWD_HARDERROR:
+      *code_string = "Server error";
+      break;
+   case KRB5_KPASSWD_AUTHERROR:
+      *code_string = "Authentication error";
+      break;
+   case KRB5_KPASSWD_SOFTERROR:
+      *code_string = "Password change rejected";
+      break;
+   case 5: /* access denied */
+      *code_string = "Access denied";
+      break;
+   case 6:	/* bad version */
+      *code_string = "Wrong protocol version";
+      break;
+   case 7: /* initial flag is needed */
+      *code_string = "Initial password required";
+      break;
+   case 0:
+	  *code_string = "Success";
+   default:
+      *code_string = "Password change failed";
+      break;
+   }
+
+   return(0);
+}
+
diff --git a/src/lib/krb5/krb/conv_creds.c b/src/lib/krb5/krb/conv_creds.c
new file mode 100644
index 000000000..3a4e66dc5
--- /dev/null
+++ b/src/lib/krb5/krb/conv_creds.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright 1994 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "k5-int.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "port-sockets.h"
+#include "socket-utils.h"
+
+#if defined(KRB5_KRB4_COMPAT) || defined(_WIN32) /* yuck */
+#include "kerberosIV/krb.h"
+
+#ifdef USE_CCAPI
+#include <CredentialsCache.h>
+#endif
+
+#define krb524_debug krb5int_krb524_debug
+int krb524_debug = 0;
+
+static krb5_error_code krb524_convert_creds_plain
+(krb5_context context, krb5_creds *v5creds, 
+		   CREDENTIALS *v4creds);
+
+static int decode_v4tkt
+	(struct ktext *v4tkt, char *buf, unsigned int *encoded_len);
+
+krb5_error_code KRB5_CALLCONV
+krb5_524_convert_creds(krb5_context context, krb5_creds *v5creds,
+		       CREDENTIALS *v4creds)
+{
+     krb5_error_code ret;
+     krb5_data reply;
+     char *p;
+     struct sockaddr_storage ss;
+     socklen_t slen = sizeof(ss);
+
+     ret = krb524_convert_creds_plain(context, v5creds, v4creds);
+     if (ret)
+	 return ret;
+
+     reply.data = NULL;
+     ret = krb5int_524_sendto_kdc(context, &v5creds->ticket,
+				  &v5creds->server->realm, &reply,
+				  ss2sa(&ss), &slen);
+     if (ret)
+	 return ret;
+
+#if TARGET_OS_MAC
+#ifdef USE_CCAPI
+     v4creds->stk_type = cc_v4_stk_des;
+#endif
+     if (slen == sizeof(struct sockaddr_in)
+	 && ss2sa(&ss)->sa_family == AF_INET) {
+	 v4creds->address = ss2sin(&ss)->sin_addr.s_addr;
+     }
+     /* Otherwise, leave it set to all-zero.  */
+#endif
+
+     p = reply.data;
+     ret = ntohl(*((krb5_error_code *) p));
+     p += sizeof(krb5_int32);
+     reply.length -= sizeof(krb5_int32);
+     if (ret)
+	 goto fail;
+
+     v4creds->kvno = ntohl(*((krb5_error_code *) p));
+     p += sizeof(krb5_int32);
+     reply.length -= sizeof(krb5_int32);
+     ret = decode_v4tkt(&v4creds->ticket_st, p, &reply.length);
+
+fail:
+     if (reply.data) 
+	 free(reply.data);
+     reply.data = NULL;
+     return ret;
+}
+
+static krb5_error_code
+krb524_convert_creds_plain(context, v5creds, v4creds)
+     krb5_context context;
+     krb5_creds *v5creds;
+     CREDENTIALS *v4creds;
+{
+     int ret;
+     krb5_timestamp endtime;
+     char dummy[REALM_SZ];
+     memset((char *) v4creds, 0, sizeof(CREDENTIALS));
+
+     if ((ret = krb5_524_conv_principal(context, v5creds->client,
+					v4creds->pname, v4creds->pinst,
+					dummy)))
+	 return ret;
+     if ((ret = krb5_524_conv_principal(context, v5creds->server,
+					v4creds->service, v4creds->instance,
+					v4creds->realm)))
+	 return ret;
+
+     /* Check enctype too */
+     if (v5creds->keyblock.length != sizeof(C_Block)) {
+	  if (krb524_debug)
+	       fprintf(stderr, "v5 session keyblock length %d != C_Block size %d\n",
+		       v5creds->keyblock.length,
+		       (int) sizeof(C_Block));
+	  return KRB524_BADKEY;
+     } else
+	  memcpy(v4creds->session, (char *) v5creds->keyblock.contents,
+		 sizeof(C_Block));
+
+     /* V4 has no concept of authtime or renew_till, so ignore them */
+     v4creds->issue_date = v5creds->times.starttime;
+     v4creds->lifetime = krb5int_krb_time_to_life(v5creds->times.starttime,
+						  v5creds->times.endtime);
+     endtime = krb5int_krb_life_to_time(v4creds->issue_date,
+					v4creds->lifetime);
+     /*
+      * Adjust start time backwards to deal with rounding up in
+      * krb_time_to_life(), to match code on server side.
+      */
+     if (endtime > v5creds->times.endtime)
+	 v4creds->issue_date -= endtime - v5creds->times.endtime;
+
+     return 0;
+}
+
+/* this used to be krb524/encode.c, under same copyright as above */
+/*
+ * I'm sure that this is reinventing the wheel, but I don't know where
+ * the wheel is hidden.
+ */
+
+int  encode_v4tkt (KTEXT_ST *, char *, unsigned int *);
+static int encode_bytes (char **, int *, char *, unsigned int),
+    encode_int32 (char **, int *, krb5_int32 *);
+
+static int decode_bytes (char **, int *, char *, unsigned int),
+    decode_int32 (char **, int *, krb5_int32 *);
+
+static int encode_bytes(out, outlen, in, len)
+     char **out;
+     int *outlen;
+     char *in;
+     unsigned int len;
+{
+     if (len > *outlen)
+	  return KRB524_ENCFULL;
+     memcpy(*out, in, len);
+     *out += len;
+     *outlen -= len;
+     return 0;
+}
+
+static int encode_int32(out, outlen, v)
+     char **out;
+     int *outlen;
+     krb5_int32 *v;
+{
+     krb5_int32 nv; /* Must be 4 bytes */
+
+     nv = htonl(*v);
+     return encode_bytes(out, outlen, (char *) &nv, sizeof(nv));
+}
+
+int krb5int_encode_v4tkt(v4tkt, buf, encoded_len)
+     KTEXT_ST *v4tkt;
+     char *buf;
+     unsigned int *encoded_len;
+{
+     int buflen, ret;
+
+     buflen = *encoded_len;
+
+     if ((ret = encode_int32(&buf, &buflen, &v4tkt->length)))
+	  return ret;
+     if ((ret = encode_bytes(&buf, &buflen, (char *)v4tkt->dat, MAX_KTXT_LEN)))
+	  return ret;
+     if ((ret = encode_int32(&buf, &buflen, (krb5_int32 *) &v4tkt->mbz)))
+	  return ret;
+
+     *encoded_len -= buflen;
+     return 0;
+}
+
+/* decode functions */
+
+static int decode_bytes(out, outlen, in, len)
+     char **out;
+     int *outlen;
+     char *in; 
+     unsigned int len;
+{
+     if (len > *outlen)
+	  return KRB524_DECEMPTY;
+     memcpy(in, *out, len);
+     *out += len;
+     *outlen -= len;
+     return 0;
+}
+
+static int decode_int32(out, outlen, v)
+     char **out;
+     int *outlen;
+     krb5_int32 *v;
+{
+     int ret;
+     krb5_int32 nv; /* Must be four bytes */
+
+     if ((ret = decode_bytes(out, outlen, (char *) &nv, sizeof(nv))))
+	  return ret;
+     *v = ntohl(nv);
+     return 0;
+}
+
+static int decode_v4tkt(v4tkt, buf, encoded_len)
+     KTEXT_ST *v4tkt;
+     char *buf;
+     unsigned int *encoded_len;
+{
+     int buflen, ret;
+
+     buflen = *encoded_len;
+     if ((ret = decode_int32(&buf, &buflen, &v4tkt->length)))
+	  return ret;
+     if ((ret = decode_bytes(&buf, &buflen, (char *)v4tkt->dat, MAX_KTXT_LEN)))
+	  return ret;
+     if ((ret = decode_int32(&buf, &buflen, (krb5_int32 *) &v4tkt->mbz)))
+	  return ret;
+     *encoded_len -= buflen;
+     return 0;
+}
+
+#else /* no krb4 compat */
+
+krb5_error_code KRB5_CALLCONV
+krb5_524_convert_creds(krb5_context context, krb5_creds *v5creds,
+		       struct credentials *v4creds)
+{
+    return KRB524_KRB4_DISABLED;
+}
+
+#endif
+
+/* These may be needed for object-level backwards compatibility on Mac
+   OS and UNIX, but Windows should be okay.  */
+#ifndef _WIN32
+#undef krb524_convert_creds_kdc
+krb5_error_code KRB5_CALLCONV
+krb524_convert_creds_kdc(krb5_context context, krb5_creds *v5creds,
+			 struct credentials *v4creds)
+{
+    return krb5_524_convert_creds(context, v5creds, v4creds);
+}
+
+#undef krb524_init_ets
+void KRB5_CALLCONV krb524_init_ets ()
+{
+}
+#endif
diff --git a/src/lib/krb5/krb/copy_data.c b/src/lib/krb5/krb/copy_data.c
index 2899c5a88..1be2a2da5 100644
--- a/src/lib/krb5/krb/copy_data.c
+++ b/src/lib/krb5/krb/copy_data.c
@@ -58,3 +58,25 @@ krb5_copy_data(krb5_context context, const krb5_data *indata, krb5_data **outdat
     *outdata = tempdata;
     return 0;
 }
+
+krb5_error_code 
+krb5int_copy_data_contents(krb5_context context, const krb5_data *indata, krb5_data *outdata)
+{
+    if (!indata) {
+	return EINVAL;
+    }
+    
+
+    outdata->length = indata->length;
+    if (outdata->length) {
+	if (!(outdata->data = malloc(outdata->length))) {
+	    krb5_xfree(outdata);
+	    return ENOMEM;
+	}
+	memcpy((char *)outdata->data, (char *)indata->data, outdata->length);
+    } else
+	outdata->data = 0;
+    outdata->magic = KV5M_DATA;
+
+    return 0;
+}
diff --git a/src/lib/krb5/krb/fwd_tgt.c b/src/lib/krb5/krb/fwd_tgt.c
index aa42f8cc1..4e2c8f04b 100644
--- a/src/lib/krb5/krb/fwd_tgt.c
+++ b/src/lib/krb5/krb/fwd_tgt.c
@@ -56,6 +56,7 @@ krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, char *r
     int free_rhost = 0;
     krb5_enctype enctype = 0;
     krb5_keyblock *session_key;
+    krb5_boolean old_use_conf_ktypes = context->use_conf_ktypes;
 
     memset((char *)&creds, 0, sizeof(creds));
     memset((char *)&tgt, 0, sizeof(creds));
@@ -109,8 +110,10 @@ krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, char *r
 	goto errout;
 	
     /* fetch tgt directly from cache */
+    context->use_conf_ktypes = 1;
     retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_SUPPORTED_KTYPES,
 				    &creds, &tgt);
+    context->use_conf_ktypes = old_use_conf_ktypes;
     if (retval)
 	goto errout;
 
@@ -161,9 +164,15 @@ retval = KRB5_FWD_BAD_PRINCIPAL;
       kdcoptions &= ~(KDC_OPT_FORWARDABLE);
 
     if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
-					addrs, &creds, &pcreds)))
-        goto errout;
-
+					addrs, &creds, &pcreds))) {
+	if (enctype) {
+	    creds.keyblock.enctype = 0;
+	    if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
+						addrs, &creds, &pcreds))) 
+		goto errout;
+	}
+	else goto errout;
+    }
     retval = krb5_mk_1cred(context, auth_context, pcreds,
                            &scratch, &replaydata);
     krb5_free_creds(context, pcreds);
diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c
index fdf00e6b1..8ca62cce6 100644
--- a/src/lib/krb5/krb/gc_frm_kdc.c
+++ b/src/lib/krb5/krb/gc_frm_kdc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994 by the Massachusetts Institute of Technology.
+ * Copyright (c) 1994,2003 by the Massachusetts Institute of Technology.
  * Copyright (c) 1994 CyberSAFE Corporation
  * Copyright (c) 1993 Open Computing Security Group
  * Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
@@ -76,6 +76,7 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
   krb5_principal  *top_server = NULL;
   krb5_principal  *next_server = NULL;
   unsigned int    nservers = 0;
+  krb5_boolean	  old_use_conf_ktypes = context->use_conf_ktypes;
 
   /* in case we never get a TGT, zero the return */
 
@@ -114,6 +115,7 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
       goto cleanup;
   }
 
+    context->use_conf_ktypes = 1;
   if ((retval = krb5_cc_retrieve_cred(context, ccache,
 				      KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES,
 				      &tgtq, &tgt))) {
@@ -231,21 +233,17 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
     
 	krb5_free_cred_contents(context, &tgtq);
 	memset(&tgtq, 0, sizeof(tgtq));
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
 	tgtq.times        = tgt.times;
-#else
-	memcpy(&tgtq.times, &tgt.times, sizeof(krb5_ticket_times));
-#endif
-
 	if ((retval = krb5_copy_principal(context, tgt.client, &tgtq.client)))
 	    goto cleanup;
 	if ((retval = krb5_copy_principal(context, int_server, &tgtq.server)))
 	    goto cleanup;
 	tgtq.is_skey      = FALSE;
 	tgtq.ticket_flags = tgt.ticket_flags;
-	if ((retval = krb5_get_cred_via_tkt(context, &tgt,
-					    FLAGS2OPTS(tgtq.ticket_flags),
-					    tgt.addresses, &tgtq, &tgtr))) {
+	retval = krb5_get_cred_via_tkt(context, &tgt,
+				       FLAGS2OPTS(tgtq.ticket_flags),
+				       tgt.addresses, &tgtq, &tgtr);
+	if (retval) {
 	      
        /*
 	* couldn't get one so now loop backwards through the realms
@@ -301,12 +299,12 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
 		  goto cleanup;
 	      tgtq.is_skey      = FALSE;
 	      tgtq.ticket_flags = tgt.ticket_flags;
-	      if ((retval = krb5_get_cred_via_tkt(context, &tgt,
-						  FLAGS2OPTS(tgtq.ticket_flags),
-						  tgt.addresses,
-						  &tgtq, &tgtr))) {
+	      retval = krb5_get_cred_via_tkt(context, &tgt,
+					     FLAGS2OPTS(tgtq.ticket_flags),
+					     tgt.addresses,
+					     &tgtq, &tgtr);
+	      if (retval)
 		  continue;
-	      }
 	      
 	      /* save tgt in return array */
 	      if ((retval = krb5_copy_creds(context, tgtr,
@@ -341,7 +339,9 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
 	for (next_server = top_server; *next_server; next_server++) {
             krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1);
             krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1);
-            if (realm_1->length == realm_2->length &&
+	    if (realm_1 != NULL &&
+		realm_2 != NULL &&
+                realm_1->length == realm_2->length &&
                 !memcmp(realm_1->data, realm_2->data, realm_1->length)) {
 		break;
             }
@@ -374,10 +374,12 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_creds
     goto cleanup;
   }
 
-  retval = krb5_get_cred_via_tkt(context, &tgt, FLAGS2OPTS(tgt.ticket_flags) |
-				 kdcopt | 
-  				 	(in_cred->second_ticket.length ? 
-				  	 KDC_OPT_ENC_TKT_IN_SKEY : 0),
+  context->use_conf_ktypes = old_use_conf_ktypes;
+  retval = krb5_get_cred_via_tkt(context, &tgt,
+				 FLAGS2OPTS(tgt.ticket_flags) |
+				 kdcopt |
+				 (in_cred->second_ticket.length ?
+				  KDC_OPT_ENC_TKT_IN_SKEY : 0),
 				 tgt.addresses, in_cred, out_cred);
 
   /* cleanup and return */
@@ -393,6 +395,7 @@ cleanup:
       if (ret_tgts)  free(ret_tgts);
       krb5_free_cred_contents(context, &tgt);
   }
+  context->use_conf_ktypes = old_use_conf_ktypes;
   return(retval);
 }
 
diff --git a/src/lib/krb5/krb/gen_seqnum.c b/src/lib/krb5/krb/gen_seqnum.c
index 196a43744..373764097 100644
--- a/src/lib/krb5/krb/gen_seqnum.c
+++ b/src/lib/krb5/krb/gen_seqnum.c
@@ -36,7 +36,7 @@
 #endif
 
 krb5_error_code
-krb5_generate_seq_number(krb5_context context, const krb5_keyblock *key, krb5_int32 *seqno)
+krb5_generate_seq_number(krb5_context context, const krb5_keyblock *key, krb5_ui_4 *seqno)
 {
     krb5_data seed;
     krb5_error_code retval;
@@ -48,5 +48,20 @@ krb5_generate_seq_number(krb5_context context, const krb5_keyblock *key, krb5_in
 
     seed.length = sizeof(*seqno);
     seed.data = (char *) seqno;
-    return(krb5_c_random_make_octets(context, &seed));
+    retval = krb5_c_random_make_octets(context, &seed);
+    if (retval)
+	return retval;
+    /*
+     * Work around implementation incompatibilities by not generating
+     * initial sequence numbers greater than 2^30.  Previous MIT
+     * implementations use signed sequence numbers, so initial
+     * sequence numbers 2^31 to 2^32-1 inclusive will be rejected.
+     * Letting the maximum initial sequence number be 2^30-1 allows
+     * for about 2^30 messages to be sent before wrapping into
+     * "negative" numbers.
+     */
+    *seqno &= 0x3fffffff;
+    if (*seqno == 0)
+	*seqno = 1;
+    return 0;
 }
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index dc06c5353..df5ebaf71 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/krb/get_in_tkt.c
  *
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991, 2003 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -262,6 +262,7 @@ verify_as_reply(krb5_context 		context,
 	    (request->rtime != 0) &&
 	    (as_reply->enc_part2->times.renew_till > request->rtime))
 	|| ((request->kdc_options & KDC_OPT_RENEWABLE_OK) &&
+	    !(request->kdc_options & KDC_OPT_RENEWABLE) &&
 	    (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) &&
 	    (request->till != 0) &&
 	    (as_reply->enc_part2->times.renew_till > request->till))
@@ -409,6 +410,15 @@ make_preauth_list(krb5_context	context,
 }
 
 #define MAX_IN_TKT_LOOPS 16
+static krb5_enctype get_in_tkt_enctypes[] = {
+    ENCTYPE_DES3_CBC_SHA1,
+    ENCTYPE_ARCFOUR_HMAC,
+    ENCTYPE_DES_CBC_MD5,
+    ENCTYPE_DES_CBC_MD4,
+    ENCTYPE_DES_CBC_CRC,
+    0
+};
+
 
 krb5_error_code KRB5_CALLCONV
 krb5_get_in_tkt(krb5_context context,
@@ -460,8 +470,13 @@ krb5_get_in_tkt(krb5_context context,
     request.from = creds->times.starttime;
     request.till = creds->times.endtime;
     request.rtime = creds->times.renew_till;
-    if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype)))
+
+    request.ktype = malloc (sizeof(get_in_tkt_enctypes));
+    if (request.ktype == NULL) {
+	retval = ENOMEM;
 	goto cleanup;
+    }
+    memcpy(request.ktype, get_in_tkt_enctypes, sizeof(get_in_tkt_enctypes));
     for (request.nktypes = 0;request.ktype[request.nktypes];request.nktypes++);
     if (ktypes) {
 	int i, req, next = 0;
@@ -734,6 +749,7 @@ krb5_get_init_creds(krb5_context context,
     krb5_deltat renew_life;
     int loopcount;
     krb5_data salt;
+    krb5_data s2kparams;
     krb5_keyblock as_key;
     krb5_error *err_reply;
     krb5_kdc_rep *local_as_reply;
@@ -742,6 +758,8 @@ krb5_get_init_creds(krb5_context context,
 
     /* initialize everything which will be freed at cleanup */
 
+    s2kparams.data = NULL;
+    s2kparams.length = 0;
     request.server = NULL;
     request.ktype = NULL;
     request.addresses = NULL;
@@ -761,7 +779,7 @@ krb5_get_init_creds(krb5_context context,
 
     /* request.padata is filled in later */
 
-    request.kdc_options = 0;
+    request.kdc_options = context->kdc_default_options;
 
     /* forwardable */
 
@@ -854,11 +872,13 @@ krb5_get_init_creds(krb5_context context,
     if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE))
 	request.till += options->tkt_life;
     else
-	request.till += 10*60*60; /* this used to be hardcoded in kinit.c */
+	request.till += 24*60*60; /* this used to be hardcoded in kinit.c */
 
     if (renew_life > 0) {
 	request.rtime = request.from;
 	request.rtime += renew_life;
+	if (request.rtime >= request.till)
+	    request.kdc_options &= ~(KDC_OPT_RENEWABLE_OK);
     } else {
 	request.rtime = 0;
     }
@@ -927,7 +947,7 @@ krb5_get_init_creds(krb5_context context,
 
 	if ((ret = krb5_do_preauth(context, &request,
 				  padata, &request.padata,
-				  &salt, &etype, &as_key, prompter,
+				  &salt, &s2kparams, &etype, &as_key, prompter,
 				   prompter_data, gak_fct, gak_data)))
 	    goto cleanup;
 
@@ -973,7 +993,7 @@ krb5_get_init_creds(krb5_context context,
 
     if ((ret = krb5_do_preauth(context, &request,
 			       local_as_reply->padata, &padata,
-			       &salt, &etype, &as_key, prompter,
+			       &salt, &s2kparams, &etype, &as_key, prompter,
 			       prompter_data, gak_fct, gak_data)))
 	goto cleanup;
 
@@ -1005,7 +1025,7 @@ krb5_get_init_creds(krb5_context context,
 
 	if ((ret = ((*gak_fct)(context, request.client,
 			       local_as_reply->enc_part.enctype,
-			       prompter, prompter_data, &salt,
+			       prompter, prompter_data, &salt, &s2kparams,
 			       &as_key, gak_data))))
 	    goto cleanup;
 
@@ -1050,6 +1070,7 @@ cleanup:
     if (salt.data &&
 	(!(options && (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT))))
 	krb5_xfree(salt.data);
+    krb5_free_data_contents(context, &s2kparams);
     if (as_reply)
 	*as_reply = local_as_reply;
     else if (local_as_reply)
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
index a7cb773a0..38a88ee14 100644
--- a/src/lib/krb5/krb/gic_keytab.c
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -1,3 +1,29 @@
+/*
+ * lib/krb5/krb/gic_keytab.c
+ *
+ * Copyright (C) 2002, 2003 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
 #include "k5-int.h"
 
 static krb5_error_code
@@ -8,6 +34,7 @@ krb5_get_as_key_keytab(
     krb5_prompter_fct prompter,
     void *prompter_data,
     krb5_data *salt,
+    krb5_data *params,
     krb5_keyblock *as_key,
     void *gak_data)
 {
@@ -115,3 +142,57 @@ cleanup:
 
    return(ret);
 }
+krb5_error_code KRB5_CALLCONV
+krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
+			      krb5_address *const *addrs, krb5_enctype *ktypes,
+			      krb5_preauthtype *pre_auth_types,
+			      krb5_keytab arg_keytab, krb5_ccache ccache,
+			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
+{
+    krb5_error_code retval;
+    krb5_get_init_creds_opt opt;
+    char * server = NULL;
+    krb5_keytab keytab;
+    krb5_principal client_princ, server_princ;
+    
+    krb5int_populate_gic_opt(context, &opt,
+			     options, addrs, ktypes,
+			     pre_auth_types);
+    if (arg_keytab == NULL) {
+	retval = krb5_kt_default(context, &keytab);
+	if (retval)
+	    return retval;
+    }
+    else keytab = arg_keytab;
+    
+    retval = krb5_unparse_name( context, creds->server, &server);
+    if (retval)
+	goto cleanup;
+    server_princ = creds->server;
+    client_princ = creds->client;
+    retval = krb5_get_init_creds (context,
+				  creds, creds->client,  
+				  krb5_prompter_posix,  NULL,
+				  0, server, &opt,
+				  krb5_get_as_key_keytab, (void *)keytab,
+				  0, ret_as_reply);
+    krb5_free_unparsed_name( context, server);
+    if (retval) {
+	goto cleanup;
+    }
+	if (creds->server)
+	    krb5_free_principal( context, creds->server);
+	if (creds->client)
+	    krb5_free_principal( context, creds->client);
+	creds->client = client_princ;
+	creds->server = server_princ;
+	
+    /* store it in the ccache! */
+    if (ccache)
+	if ((retval = krb5_cc_store_cred(context, ccache, creds)))
+	    goto cleanup;
+ cleanup:    if (arg_keytab == NULL)
+     krb5_kt_close(context, keytab);
+    return retval;
+}
+
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 7b5e0bab3..fdd7c514a 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -9,6 +9,7 @@ krb5_get_as_key_password(
     krb5_prompter_fct prompter,
     void *prompter_data,
     krb5_data *salt,
+    krb5_data *params,
     krb5_keyblock *as_key,
     void *gak_data)
 {
@@ -42,7 +43,7 @@ krb5_get_as_key_password(
 	    return(EIO);
 
 	if ((ret = krb5_unparse_name(context, client, &clientstr)))
-	    return(ret);
+	  return(ret);
 
 	strcpy(promptstr, "Password for ");
 	strncat(promptstr, clientstr, sizeof(promptstr)-strlen(promptstr)-1);
@@ -74,7 +75,8 @@ krb5_get_as_key_password(
 	defsalt.length = 0;
     }
 
-    ret = krb5_c_string_to_key(context, etype, password, salt, as_key);
+    ret = krb5_c_string_to_key_with_params(context, etype, password, salt,
+					   params->data?params:NULL, as_key);
 
     if (defsalt.length)
 	krb5_xfree(defsalt.data);
@@ -158,7 +160,8 @@ krb5_get_init_creds_password(krb5_context context, krb5_creds *creds, krb5_princ
 	 slave we were able to contact */
 
       if ((ret2 == KRB5_KDC_UNREACH) ||
-		  (ret2 == KRB5_REALM_CANT_RESOLVE))
+	  (ret2 == KRB5_REALM_CANT_RESOLVE) ||
+	  (ret2 == KRB5_REALM_UNKNOWN))
 	 goto cleanup;
 
       ret = ret2;
@@ -366,3 +369,109 @@ cleanup:
 
    return(ret);
 }
+void krb5int_populate_gic_opt (
+    krb5_context context, krb5_get_init_creds_opt *opt,
+    krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
+    krb5_preauthtype *pre_auth_types)
+{
+  int i;
+    krb5_get_init_creds_opt_init(opt);
+    if (addrs)
+      krb5_get_init_creds_opt_set_address_list(opt, (krb5_address **) addrs);
+    if (ktypes) {
+	for (i=0; ktypes[i]; i++);
+	if (i)
+	    krb5_get_init_creds_opt_set_etype_list(opt, ktypes, i);
+    }
+    if (pre_auth_types) {
+	for (i=0; pre_auth_types[i]; i++);
+	if (i)
+	    krb5_get_init_creds_opt_set_preauth_list(opt, pre_auth_types, i);
+    }
+    if (options&KDC_OPT_FORWARDABLE)
+	krb5_get_init_creds_opt_set_forwardable(opt, 1);
+    else krb5_get_init_creds_opt_set_forwardable(opt, 0);
+    if (options&KDC_OPT_PROXIABLE)
+	krb5_get_init_creds_opt_set_proxiable(opt, 1);
+    else krb5_get_init_creds_opt_set_proxiable(opt, 0);
+    
+
+}
+
+/*
+  Rewrites get_in_tkt in terms of newer get_init_creds API.
+ Attempts to get an initial ticket for creds->client to use server
+ creds->server, (realm is taken from creds->client), with options
+ options, and using creds->times.starttime, creds->times.endtime,
+ creds->times.renew_till as from, till, and rtime.  
+ creds->times.renew_till is ignored unless the RENEWABLE option is requested.
+
+ If addrs is non-NULL, it is used for the addresses requested.  If it is
+ null, the system standard addresses are used.
+
+ If password is non-NULL, it is converted using the cryptosystem entry
+ point for a string conversion routine, seeded with the client's name.
+ If password is passed as NULL, the password is read from the terminal,
+ and then converted into a key.
+
+ A succesful call will place the ticket in the credentials cache ccache.
+
+ returns system errors, encryption errors
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
+			      krb5_address *const *addrs, krb5_enctype *ktypes,
+			      krb5_preauthtype *pre_auth_types,
+			      const char *password, krb5_ccache ccache,
+			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
+{
+    krb5_error_code retval;
+    krb5_data pw0;
+    char pw0array[1024];
+    krb5_get_init_creds_opt opt;
+    char * server;
+    krb5_principal server_princ, client_princ;
+
+    pw0array[0] = '\0';
+    pw0.data = pw0array;
+    if (password) {
+	pw0.length = strlen(password);
+	if (pw0.length > sizeof(pw0array))
+	    return EINVAL;
+	strncpy(pw0.data, password, sizeof(pw0array));
+	if (pw0.length == 0)
+	    pw0.length = sizeof(pw0array);
+    } else {
+	pw0.length = sizeof(pw0array);
+    }
+    krb5int_populate_gic_opt(context, &opt,
+			     options, addrs, ktypes,
+			     pre_auth_types);
+    retval = krb5_unparse_name( context, creds->server, &server);
+    if (retval)
+      return (retval);
+    server_princ = creds->server;
+    client_princ = creds->client;
+        retval = krb5_get_init_creds (context,
+					   creds, creds->client,  
+					   krb5_prompter_posix,  NULL,
+					   0, server, &opt,
+				      krb5_get_as_key_password, &pw0,
+				      0, ret_as_reply);
+	  krb5_free_unparsed_name( context, server);
+	if (retval) {
+	  return (retval);
+	}
+	if (creds->server)
+	    krb5_free_principal( context, creds->server);
+	if (creds->client)
+	    krb5_free_principal( context, creds->client);
+	creds->client = client_princ;
+	creds->server = server_princ;
+	/* store it in the ccache! */
+	if (ccache)
+	  if ((retval = krb5_cc_store_cred(context, ccache, creds)))
+	    return (retval);
+	return retval;
+  }
+
diff --git a/src/lib/krb5/krb/in_tkt_ktb.c b/src/lib/krb5/krb/in_tkt_ktb.c
deleted file mode 100644
index db4f3b411..000000000
--- a/src/lib/krb5/krb/in_tkt_ktb.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * lib/krb5/krb/in_tkt_ktb.c
- *
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- *   require a specific license from the United States Government.
- *   It is the responsibility of any person or organization contemplating
- *   export to obtain such a license before exporting.
- * 
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- * 
- *
- * krb5_get_in_tkt_with_keytab()
- *	
- */
-
-#include "k5-int.h"
-
-struct keytab_keyproc_arg {
-    krb5_keytab	keytab;
-    krb5_principal client;
-};
-
-/*
- * Key-generator for in_tkt_keytab, below.
- * "keyseed" is actually a krb5_keytab, or NULL if we should fetch
- * from system area.
- */
-static krb5_error_code keytab_keyproc
-    (krb5_context,
-               const krb5_enctype,
-               krb5_data *,
-               krb5_const_pointer,
-               krb5_keyblock **);
-
-static krb5_error_code
-keytab_keyproc(krb5_context context, krb5_enctype type, krb5_data *salt,
-	       krb5_const_pointer keyseed, krb5_keyblock **key)
-{
-    const struct keytab_keyproc_arg * arg = 
-	(const struct keytab_keyproc_arg *)keyseed;
-    krb5_keyblock *realkey;
-    krb5_error_code retval = 0;
-    krb5_keytab kt_id;
-    krb5_keytab_entry kt_ent;
-
-    kt_id = arg->keytab;
-
-    if (!krb5_c_valid_enctype(type))
-	return KRB5_PROG_ETYPE_NOSUPP;
-
-    if (kt_id == NULL)
-	/* Fetch from default keytab location */
-	if ((retval = krb5_kt_default(context, &kt_id)))
-	    return retval;
-
-
-    if ((retval = krb5_kt_get_entry(context, kt_id, arg->client,
-				    0, /* don't have vno available */
-				    type, &kt_ent)))
-	    goto cleanup;
-
-    if ((retval = krb5_copy_keyblock(context, &kt_ent.key, &realkey))) {
-	(void) krb5_kt_free_entry(context, &kt_ent);
-	goto cleanup;
-    }
-
-    (void) krb5_kt_free_entry(context, &kt_ent);
-    *key = realkey;
-    
-cleanup:
-    if (! arg->keytab) 
-	krb5_kt_close(context, kt_id);
-    return retval;
-}
-
-/*
- Similar to krb5_get_in_tkt_with_skey.
-
- Attempts to get an initial ticket for creds->client to use server
- creds->server, (realm is taken from creds->client), with options
- options, and using creds->times.starttime, creds->times.endtime, 
- creds->times.renew_till as from, till, and rtime. 
- creds->times.renew_till is ignored unless the RENEWABLE option is requested.
-
- If addrs is non-NULL, it is used for the addresses requested.  If it is
- null, the system standard addresses are used.
-
- A succesful call will place the ticket in the credentials cache ccache.
-
- returns system errors, encryption errors
-
- */
-krb5_error_code KRB5_CALLCONV
-krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
-			    krb5_address *const *addrs, krb5_enctype *ktypes,
-			    krb5_preauthtype *pre_auth_types,
-			    krb5_keytab keytab, krb5_ccache ccache,
-			    krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
-{
-    struct keytab_keyproc_arg arg;
-
-    arg.keytab = keytab;
-    arg.client = creds->client;
-
-    return(krb5_get_in_tkt(context, options, addrs, ktypes,
-			   pre_auth_types,
-			   keytab_keyproc, (krb5_pointer)&arg,
-			   krb5_kdc_rep_decrypt_proc, 0, creds,
-			   ccache, ret_as_reply));
-}
diff --git a/src/lib/krb5/krb/in_tkt_pwd.c b/src/lib/krb5/krb/in_tkt_pwd.c
deleted file mode 100644
index 1d9ad2ef4..000000000
--- a/src/lib/krb5/krb/in_tkt_pwd.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * lib/krb5/krb/in_tkt_pwd.c
- *
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- *   require a specific license from the United States Government.
- *   It is the responsibility of any person or organization contemplating
- *   export to obtain such a license before exporting.
- * 
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- * 
- *
- * krb5_get_in_tkt_with_password()
- */
-
-#include "k5-int.h"
-
-extern char *krb5_default_pwd_prompt1;
-
-/* 
- * key-producing procedure for use by krb5_get_in_tkt_with_password.
- */
-static krb5_error_code pwd_keyproc
-    (krb5_context,
-               const krb5_enctype,
-               krb5_data *,
-               krb5_const_pointer,
-               krb5_keyblock **);
-
-static krb5_error_code
-pwd_keyproc(krb5_context context, krb5_enctype type, krb5_data *salt,
-	    krb5_const_pointer keyseed, krb5_keyblock **key)
-{
-    krb5_error_code retval;
-    krb5_data * password;
-    unsigned int pwsize;
-
-    password = (krb5_data *)keyseed;
-
-    if (!password->length) {
-	pwsize = BUFSIZ;
-	if ((password->data = malloc(pwsize)) == NULL)
-	    return ENOMEM;
-	
-	if ((retval = krb5_read_password(context, krb5_default_pwd_prompt1, 0,
-					 password->data, &pwsize))) {
-	    return retval;
-	}
-	password->length = pwsize;
-    }
-
-    if (!(*key = (krb5_keyblock *)malloc(sizeof(**key))))
-	return ENOMEM;
-
-    if ((retval = krb5_c_string_to_key(context, type, password, salt, *key)))
-	krb5_xfree(*key);
-
-    return(retval);
-}
-
-/*
- Attempts to get an initial ticket for creds->client to use server
- creds->server, (realm is taken from creds->client), with options
- options, and using creds->times.starttime, creds->times.endtime,
- creds->times.renew_till as from, till, and rtime.  
- creds->times.renew_till is ignored unless the RENEWABLE option is requested.
-
- If addrs is non-NULL, it is used for the addresses requested.  If it is
- null, the system standard addresses are used.
-
- If password is non-NULL, it is converted using the cryptosystem entry
- point for a string conversion routine, seeded with the client's name.
- If password is passed as NULL, the password is read from the terminal,
- and then converted into a key.
-
- A succesful call will place the ticket in the credentials cache ccache.
-
- returns system errors, encryption errors
- */
-krb5_error_code KRB5_CALLCONV
-krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
-			      krb5_address *const *addrs, krb5_enctype *ktypes,
-			      krb5_preauthtype *pre_auth_types,
-			      const char *password, krb5_ccache ccache,
-			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
-{
-    krb5_error_code retval;
-    krb5_data data;
-
-
-    if ((data.data = (char *)password)) {
-	data.length = strlen(password);
-    } else {
-	data.length = 0;
-    }
-
-    retval = krb5_get_in_tkt(context, options, addrs, ktypes, pre_auth_types, 
-			     pwd_keyproc, (krb5_pointer) &data,
-			     krb5_kdc_rep_decrypt_proc, 0,
-			     creds, ccache, ret_as_reply);
-
-    if ((password == NULL) && (data.data)) {
-	memset(data.data, 0, strlen(data.data));
-	free(data.data);
-    }
-
-    return retval;
-}
-
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 59b6123e6..2740d8361 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/krb/init_ctx.c
  *
- * Copyright 1994,1999,2000, 2002  by the Massachusetts Institute of Technology.
+ * Copyright 1994,1999,2000, 2002, 2003  by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -65,9 +65,15 @@
    them.  This'll be fixed, but for better compatibility, let's prefer
    des-crc for now.  */
 #define DEFAULT_ETYPE_LIST	\
+	"aes256-cts-hmac-sha1-96 " \
+	"aes128-cts-hmac-sha1-96 " \
 	"des3-cbc-sha1 arcfour-hmac-md5 " \
 	"des-cbc-crc des-cbc-md5 des-cbc-md4 "
 
+/* Not included:
+	"aes128-cts-hmac-sha1-96 " \
+ */
+
 #if (defined(_WIN32))
 extern krb5_error_code krb5_vercheck();
 extern void krb5_win_ccdll_load(krb5_context context);
@@ -142,6 +148,13 @@ init_common (krb5_context *context, krb5_boolean secure)
 	if ((retval = krb5_set_default_tgs_ktypes(ctx, NULL)))
 		goto cleanup;
 
+	ctx->conf_tgs_ktypes = calloc(ctx->tgs_ktype_count, sizeof(krb5_enctype));
+	if (ctx->conf_tgs_ktypes == NULL && ctx->tgs_ktype_count != 0)
+	    goto cleanup;
+	memcpy(ctx->conf_tgs_ktypes, ctx->tgs_ktypes,
+	       sizeof(krb5_enctype) * ctx->tgs_ktype_count);
+	ctx->conf_tgs_ktypes_count = ctx->tgs_ktype_count;
+
 	if ((retval = krb5_os_init_context(ctx)))
 		goto cleanup;
 
@@ -189,11 +202,7 @@ init_common (krb5_context *context, krb5_boolean secure)
 			    "kdc_default_options", 0,
 			    KDC_OPT_RENEWABLE_OK, &tmp);
 	ctx->kdc_default_options = tmp;
-#if TARGET_OS_MAC
 #define DEFAULT_KDC_TIMESYNC 1
-#else
-#define DEFAULT_KDC_TIMESYNC 0
-#endif
 	profile_get_integer(ctx->profile, "libdefaults",
 			    "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC,
 			    &tmp);
@@ -207,16 +216,13 @@ init_common (krb5_context *context, krb5_boolean secure)
 	 * Note: DCE 1.0.3a only supports a cache type of 1
 	 * 	DCE 1.1 supports a cache type of 2.
 	 */
-#if TARGET_OS_MAC
 #define DEFAULT_CCACHE_TYPE 4
-#else
-#define DEFAULT_CCACHE_TYPE 3
-#endif
 	profile_get_integer(ctx->profile, "libdefaults", "ccache_type",
 			    0, DEFAULT_CCACHE_TYPE, &tmp);
 	ctx->fcc_default_format = tmp + 0x0500;
 	ctx->scc_default_format = tmp + 0x0500;
 	ctx->prompt_types = 0;
+	ctx->use_conf_ktypes = 0;
 
 	ctx->udp_pref_limit = -1;
 	*context = ctx;
@@ -243,6 +249,11 @@ krb5_free_context(krb5_context ctx)
 	  ctx->tgs_ktypes = 0;
      }
 
+     if (ctx->conf_tgs_ktypes) {
+	 free(ctx->conf_tgs_ktypes);
+	 ctx->conf_tgs_ktypes = 0;
+     }
+
      if (ctx->default_realm) {
 	  free(ctx->default_realm);
 	  ctx->default_realm = 0;
@@ -291,7 +302,8 @@ krb5_set_default_in_tkt_ktypes(krb5_context context, const krb5_enctype *ktypes)
 }
 
 static krb5_error_code
-get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr, int ctx_count, krb5_enctype *ctx_list)
+get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
+		       int ctx_count, krb5_enctype *ctx_list)
 {
     krb5_enctype *old_ktypes;
 
@@ -426,12 +438,19 @@ krb5_error_code
 KRB5_CALLCONV
 krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_enctype **ktypes)
 {
-    return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
-				  context->tgs_ktype_count,
-				  context->tgs_ktypes));
+    if (context->use_conf_ktypes)
+	/* This one is set *only* by reading the config file; it's not
+	   set by the application.  */
+	return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
+				      context->conf_tgs_ktypes_count,
+				      context->conf_tgs_ktypes));
+    else
+	return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
+				      context->tgs_ktype_count,
+				      context->tgs_ktypes));
 }
 
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
 krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)
 {
     return(get_profile_etype_list(context, ktypes, "permitted_enctypes",
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index 46d485d32..470043971 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -246,6 +246,7 @@ void krb5_free_etype_info(krb5_context context, krb5_etype_info info)
   for(i=0; info[i] != NULL; i++) {
       if (info[i]->salt)
 	  free(info[i]->salt);
+      krb5_free_data_contents( context, &info[i]->s2kparams);
       free(info[i]);
   }
   free(info);
@@ -429,14 +430,20 @@ krb5_free_pwd_data(krb5_context context, krb5_pwd_data *val)
 void KRB5_CALLCONV
 krb5_free_pwd_sequences(krb5_context context, passwd_phrase_element **val)
 {
-    if ((*val)->passwd) {
-	krb5_xfree((*val)->passwd);
-	(*val)->passwd = 0;
-    }
-    if ((*val)->phrase) {
-	krb5_xfree((*val)->phrase);
-	(*val)->phrase = 0;
+    register passwd_phrase_element **temp;
+
+    for (temp = val; *temp; temp++) {
+	if ((*temp)->passwd) {
+	   krb5_free_data(context, (*temp)->passwd);
+	   (*temp)->passwd = 0;
+	}
+	if ((*temp)->phrase) {
+	   krb5_free_data(context, (*temp)->phrase);
+	   (*temp)->phrase = 0;
+	}
+	krb5_xfree(*temp);
     }
+    krb5_xfree(val);
 }
 
 
diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c
index 638929861..04248c08d 100644
--- a/src/lib/krb5/krb/mk_cred.c
+++ b/src/lib/krb5/krb/mk_cred.c
@@ -182,9 +182,8 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
     memset(pcred->tickets, 0, sizeof(krb5_ticket *) * (ncred +1));
 
     /* Get keyblock */
-    if ((keyblock = auth_context->local_subkey) == NULL) 
-	if ((keyblock = auth_context->remote_subkey) == NULL) 
-	    keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->send_subkey) == NULL) 
+	keyblock = auth_context->keyblock;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 196b6eea0..efe254ac0 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -119,9 +119,8 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context,
     memset((char *) &replaydata, 0, sizeof(krb5_replay_data));
 
     /* Get keyblock */
-    if ((keyblock = auth_context->local_subkey) == NULL)
-        if ((keyblock = auth_context->remote_subkey) == NULL)
-            keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->send_subkey) == NULL)
+	keyblock = auth_context->keyblock;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c
index 31f3fe500..393f634bb 100644
--- a/src/lib/krb5/krb/mk_rep.c
+++ b/src/lib/krb5/krb/mk_rep.c
@@ -59,7 +59,14 @@ krb5_mk_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *out
 
     repl.ctime = auth_context->authentp->ctime;    
     repl.cusec = auth_context->authentp->cusec;    
-    repl.subkey = auth_context->authentp->subkey;    
+    if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_USE_SUBKEY) {
+	retval = krb5int_generate_and_save_subkey (context, auth_context,
+						   auth_context->keyblock);
+	if (retval)
+	    return retval;
+	repl.subkey = auth_context->send_subkey;
+    } else
+	repl.subkey = auth_context->authentp->subkey;
     repl.seq_number = auth_context->local_seq_number;
 
     /* encode it before encrypting */
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index 1ed14a922..cdb8f6950 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -68,7 +68,39 @@ static krb5_error_code
 krb5_generate_authenticator (krb5_context,
 				       krb5_authenticator *, krb5_principal,
 				       krb5_checksum *, krb5_keyblock *,
-				       krb5_int32, krb5_authdata ** );
+				       krb5_ui_4, krb5_authdata ** );
+
+krb5_error_code
+krb5int_generate_and_save_subkey (krb5_context context,
+				  krb5_auth_context auth_context,
+				  krb5_keyblock *keyblock)
+{
+    /* Provide some more fodder for random number code.
+       This isn't strong cryptographically; the point here is not
+       to guarantee randomness, but to make it less likely that multiple
+       sessions could pick the same subkey.  */
+    struct {
+	krb5_int32 sec, usec;
+    } rnd_data;
+    krb5_data d;
+    krb5_error_code retval;
+
+    krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
+    d.length = sizeof (rnd_data);
+    d.data = (char *) &rnd_data;
+    (void) krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_TIMING, &d);
+
+    if ((retval = krb5_generate_subkey(context, keyblock, &auth_context->send_subkey)))
+	return retval;
+    retval = krb5_copy_keyblock(context, auth_context->send_subkey,
+				&auth_context->recv_subkey);
+    if (retval) {
+	krb5_free_keyblock(context, auth_context->send_subkey);
+	auth_context->send_subkey = NULL;
+	return retval;
+    }
+    return 0;
+}
 
 krb5_error_code KRB5_CALLCONV
 krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
@@ -130,22 +162,10 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
 	    goto cleanup;
     }
 
-    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) {
-	/* Provide some more fodder for random number code.
-	   This isn't strong cryptographically; the point here is not
-	   to guarantee randomness, but to make it less likely that multiple
-	   sessions could pick the same subkey.  */
-	struct {
-	    krb5_int32 sec, usec;
-	} rnd_data;
-	krb5_data d;
-	krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
-	d.length = sizeof (rnd_data);
-	d.data = (char *) &rnd_data;
-	(void) krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_TIMING, &d);
-
-	if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock, 
-					   &(*auth_context)->local_subkey)))
+    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->send_subkey)) {
+	retval = krb5int_generate_and_save_subkey (context, *auth_context,
+						   &in_creds->keyblock);
+	if (retval)
 	    goto cleanup;
     }
 
@@ -178,7 +198,7 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
     if ((retval = krb5_generate_authenticator(context,
 					      (*auth_context)->authentp,
 					      (in_creds)->client, checksump,
-					      (*auth_context)->local_subkey,
+					      (*auth_context)->send_subkey,
 					      (*auth_context)->local_seq_number,
 					      (in_creds)->authdata)))
 	goto cleanup_cksum;
@@ -232,7 +252,7 @@ cleanup:
 }
 
 static krb5_error_code
-krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, krb5_principal client, krb5_checksum *cksum, krb5_keyblock *key, krb5_int32 seq_number, krb5_authdata **authorization)
+krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, krb5_principal client, krb5_checksum *cksum, krb5_keyblock *key, krb5_ui_4 seq_number, krb5_authdata **authorization)
 {
     krb5_error_code retval;
     
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index 992a456a9..eefcab7cd 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -120,9 +120,8 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
     memset((char *) &replaydata, 0, sizeof(krb5_replay_data));
 
     /* Get keyblock */
-    if ((keyblock = auth_context->local_subkey) == NULL)
-        if ((keyblock = auth_context->remote_subkey) == NULL)
-            keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->send_subkey) == NULL)
+	keyblock = auth_context->keyblock;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
diff --git a/src/lib/krb5/krb/parse.c b/src/lib/krb5/krb/parse.c
index abbcfbe2d..3debb6acf 100644
--- a/src/lib/krb5/krb/parse.c
+++ b/src/lib/krb5/krb/parse.c
@@ -170,11 +170,13 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
 				cp++;
 				size++;
 			} else if (c == COMPONENT_SEP) {
-				krb5_princ_component(context, principal, i)->length = size;
+				if (krb5_princ_size(context, principal) > i)
+					krb5_princ_component(context, principal, i)->length = size;
 				size = 0;
 				i++;
 			} else if (c == REALM_SEP) {
-				krb5_princ_component(context, principal, i)->length = size;
+				if (krb5_princ_size(context, principal) > i)
+					krb5_princ_component(context, principal, i)->length = size;
 				size = 0;
 				parsed_realm = cp+1;
 			} else
@@ -183,7 +185,8 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
 		if (parsed_realm)
 			krb5_princ_realm(context, principal)->length = size;
 		else
-			krb5_princ_component(context, principal, i)->length = size;
+			if (krb5_princ_size(context, principal) > i)
+				krb5_princ_component(context, principal, i)->length = size;
 		if (i + 1 != components) {
 #if !defined(_WIN32) && !defined(macintosh)
 			fprintf(stderr,
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index e50440e2b..6238a8276 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -35,7 +35,7 @@ typedef krb5_error_code (*pa_function)(krb5_context,
 				       krb5_kdc_req *request,
 				       krb5_pa_data *in_padata,
 				       krb5_pa_data **out_padata,
-				       krb5_data *salt,
+				       krb5_data *salt, krb5_data *s2kparams,
 				       krb5_enctype *etype,
 				       krb5_keyblock *as_key,
 				       krb5_prompter_fct prompter_fct,
@@ -57,7 +57,7 @@ krb5_error_code pa_salt(krb5_context context,
 			krb5_kdc_req *request,
 			krb5_pa_data *in_padata,
 			krb5_pa_data **out_padata,
-			krb5_data *salt,
+			krb5_data *salt, krb5_data *s2kparams,
 			krb5_enctype *etype,
 			krb5_keyblock *as_key,
 			krb5_prompter_fct prompter, void *prompter_data,
@@ -65,22 +65,11 @@ krb5_error_code pa_salt(krb5_context context,
 {
     krb5_data tmp;
 
-    /* screw the abstraction.  If there was a *reasonable* copy_data,
-       I'd use it.  But I'm inside the library, which is the twilight
-       zone of source code, so I can do anything. */
-
+    tmp.data = in_padata->contents;
     tmp.length = in_padata->length;
-    if (tmp.length) {
-	if ((tmp.data = malloc(tmp.length)) == NULL)
-	    return ENOMEM;
-	memcpy(tmp.data, in_padata->contents, tmp.length);
-    } else {
-	tmp.data = NULL;
-    }
-
-    *salt = tmp;
-
-    /* assume that no other salt was allocated */
+    krb5_free_data_contents(context, salt);
+    krb5int_copy_data_contents(context, &tmp, salt);
+    
 
     if (in_padata->pa_type == KRB5_PADATA_AFS3_SALT)
 	salt->length = SALT_TYPE_AFS_LENGTH;
@@ -94,6 +83,7 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
 				 krb5_pa_data *in_padata,
 				 krb5_pa_data **out_padata,
 				 krb5_data *salt,
+				 krb5_data *s2kparams,
 				 krb5_enctype *etype,
 				 krb5_keyblock *as_key,
 				 krb5_prompter_fct prompter,
@@ -119,7 +109,7 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
        if ((ret = ((*gak_fct)(context, request->client,
 			      *etype ? *etype : request->ktype[0],
 			      prompter, prompter_data,
-			      salt, as_key, gak_data))))
+			      salt, s2kparams, as_key, gak_data))))
            return(ret);
     }
 
@@ -233,6 +223,7 @@ krb5_error_code pa_sam(krb5_context context,
 		       krb5_pa_data *in_padata,
 		       krb5_pa_data **out_padata,
 		       krb5_data *salt,
+		       krb5_data *s2kparams,
 		       krb5_enctype *etype,
 		       krb5_keyblock *as_key,
 		       krb5_prompter_fct prompter,
@@ -283,7 +274,7 @@ krb5_error_code pa_sam(krb5_context context,
 	   *etype = ENCTYPE_DES_CBC_CRC;
 
 	if ((ret = (gak_fct)(context, request->client, *etype, prompter,
-			prompter_data, salt, as_key, gak_data)))
+			prompter_data, salt, s2kparams, as_key, gak_data)))
 	   return(ret);
     }
     sprintf(name, "%.*s",
@@ -472,6 +463,7 @@ krb5_error_code pa_sam_2(krb5_context context,
 				krb5_pa_data *in_padata,
 				krb5_pa_data **out_padata,
 				krb5_data *salt,
+			 krb5_data *s2kparams,
 				krb5_enctype *etype,
 				krb5_keyblock *as_key,
 				krb5_prompter_fct prompter,
@@ -542,7 +534,7 @@ krb5_error_code pa_sam_2(krb5_context context,
 
 	retval = (gak_fct)(context, request->client,
 			sc2b->sam_etype, prompter,
-			prompter_data, salt, as_key, gak_data);
+			prompter_data, salt, s2kparams, as_key, gak_data);
 	if (retval) {
 	   krb5_free_sam_challenge_2(context, sc2);
 	   krb5_free_sam_challenge_2_body(context, sc2b);
@@ -827,87 +819,19 @@ static const pa_types_t pa_types[] = {
     },
 };
 
-static void
-sort_etype_info(krb5_context  context, krb5_kdc_req *request,
-                krb5_etype_info_entry **etype_info)
-{
-/* Originally adapted from a proposed solution in ticket 1006.  This
- * solution  is  not efficient, but implementing an efficient sort
- * with a comparison function based on order in the kdc request would
- * be difficult.*/
-    krb5_etype_info_entry *tmp;
-    int i, j, e;
-    krb5_boolean similar;
-
-    if (etype_info == NULL)
-	return;
-
-    /* First, move up etype_info_entries whose enctype exactly matches a
-     * requested enctype.
-     */
-    e = 0;
-    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
-    {
-	if (request->ktype[i] == etype_info[e]->etype)
-	{
-	    e++;
-	    continue;
-	}
-	for ( j = e+1 ; etype_info[j] ; j++ )
-	    if (request->ktype[i] == etype_info[j]->etype)
-		break;
-	if (etype_info[j] == NULL)
-	    continue;
-
-	tmp = etype_info[j];
-	etype_info[j] = etype_info[e];
-	etype_info[e] = tmp;
-	e++;
-    }
-
-    /* Then move up etype_info_entries whose enctype is similar to a
-     * requested enctype.
-     */
-    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
-    {
-	if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[e]->etype, &similar) != 0)
-	    continue;
-
-	if (similar)
-	{
-	    e++;
-	    continue;
-	}
-	for ( j = e+1 ; etype_info[j] ; j++ )
-	{
-	    if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[j]->etype, &similar) != 0)
-		continue;
-
-	    if (similar)
-		break;
-	}
-	if (etype_info[j] == NULL)
-	    continue;
-
-	tmp = etype_info[j];
-	etype_info[j] = etype_info[e];
-	etype_info[e] = tmp;
-	e++;
-    }
-}
-
-
 krb5_error_code
 krb5_do_preauth(krb5_context context,
 		krb5_kdc_req *request,
 		krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
-		krb5_data *salt, krb5_enctype *etype,
+		krb5_data *salt, krb5_data *s2kparams,
+		krb5_enctype *etype,
 		krb5_keyblock *as_key,
 		krb5_prompter_fct prompter, void *prompter_data,
 		krb5_gic_get_as_key_fct gak_fct, void *gak_data)
 {
     int h, i, j, out_pa_list_size;
-    krb5_pa_data *out_pa, **out_pa_list;
+    int seen_etype_info2 = 0;
+    krb5_pa_data *out_pa = NULL, **out_pa_list = NULL;
     krb5_data scratch;
     krb5_etype_info etype_info = NULL;
     krb5_error_code ret;
@@ -938,6 +862,7 @@ krb5_do_preauth(krb5_context context,
     for (h=0; h<(sizeof(paorder)/sizeof(paorder[0])); h++) {
 	realdone = 0;
 	for (i=0; in_padata[i] && !realdone; i++) {
+	    int k, l, etype_found, valid_etype_found;
 	    /*
 	     * This is really gross, but is necessary to prevent
 	     * lossge when talking to a 1.0.x KDC, which returns an
@@ -946,27 +871,81 @@ krb5_do_preauth(krb5_context context,
 	     */
 	    switch (in_padata[i]->pa_type) {
 	    case KRB5_PADATA_ETYPE_INFO:
-		if (etype_info)
-		    continue;
+	    case KRB5_PADATA_ETYPE_INFO2:
+	    {
+		krb5_preauthtype pa_type = in_padata[i]->pa_type;
+		if (etype_info) {
+		    if (seen_etype_info2 || pa_type != KRB5_PADATA_ETYPE_INFO2)
+			continue;
+		    if (pa_type == KRB5_PADATA_ETYPE_INFO2) {
+			krb5_free_etype_info( context, etype_info);
+			etype_info = NULL;
+		    }
+		}
+
 		scratch.length = in_padata[i]->length;
 		scratch.data = (char *) in_padata[i]->contents;
-		ret = decode_krb5_etype_info(&scratch, &etype_info);
+		if (pa_type == KRB5_PADATA_ETYPE_INFO2) {
+		    seen_etype_info2++;
+		    ret = decode_krb5_etype_info2(&scratch, &etype_info);
+		}
+		else ret = decode_krb5_etype_info(&scratch, &etype_info);
 		if (ret) {
-		    if (out_pa_list) {
-			out_pa_list[out_pa_list_size++] = NULL;
-			krb5_free_pa_data(context, out_pa_list);
-		    }
-		    return ret;
+		    ret = 0; /*Ignore error and etype_info element*/
+		    krb5_free_etype_info( context, etype_info);
+		    etype_info = NULL;
+		    continue;
 		}
 		if (etype_info[0] == NULL) {
 		    krb5_free_etype_info(context, etype_info);
 		    etype_info = NULL;
 		    break;
 		}
-                sort_etype_info(context, request, etype_info);
-		salt->data = (char *) etype_info[0]->salt;
-		salt->length = etype_info[0]->length;
-		*etype = etype_info[0]->etype;
+		/*
+		 * Select first etype in our request which is also in
+		 * etype-info (preferring client request ktype order).
+		 */
+		for (etype_found = 0, valid_etype_found = 0, k = 0;
+		     !etype_found && k < request->nktypes; k++) {
+		    for (l = 0; etype_info[l]; l++) {
+			if (etype_info[l]->etype == request->ktype[k]) {
+			    etype_found++;
+			    break;
+			}
+			/* check if program has support for this etype for more
+			 * precise error reporting.
+			 */
+			if (valid_enctype(etype_info[l]->etype))
+			    valid_etype_found++;
+		    }
+		}
+		if (!etype_found) {
+		  if (valid_etype_found) {
+			/* supported enctype but not requested */
+		    ret =  KRB5_CONFIG_ETYPE_NOSUPP;
+		    goto cleanup;
+		  }
+		  else {
+		    /* unsupported enctype */
+		    ret =  KRB5_PROG_ETYPE_NOSUPP;
+		    goto cleanup;
+		  }
+
+		}
+		scratch.data = (char *) etype_info[l]->salt;
+		scratch.length = etype_info[l]->length;
+		krb5_free_data_contents(context, salt);
+		if (scratch.length == KRB5_ETYPE_NO_SALT) 
+		  salt->data = NULL;
+		else
+		    if ((ret = krb5int_copy_data_contents( context, &scratch, salt)) != 0)
+		  goto cleanup;
+		*etype = etype_info[l]->etype;
+		krb5_free_data_contents(context, s2kparams);
+		if ((ret = krb5int_copy_data_contents(context,
+						      &etype_info[l]->s2kparams,
+						      s2kparams)) != 0)
+		  goto cleanup;
 #ifdef DEBUG
 		for (j = 0; etype_info[j]; j++) {
 		    krb5_etype_info_entry *e = etype_info[j];
@@ -978,6 +957,7 @@ krb5_do_preauth(krb5_context context,
 		}
 #endif
 		break;
+	    }
 	    case KRB5_PADATA_PW_SALT:
 	    case KRB5_PADATA_AFS3_SALT:
 		if (etype_info)
@@ -993,16 +973,10 @@ krb5_do_preauth(krb5_context context,
 
 		    if ((ret = ((*pa_types[j].fct)(context, request,
 						   in_padata[i], &out_pa,
-						   salt, etype, as_key,
+						   salt, s2kparams, etype, as_key,
 						   prompter, prompter_data,
 						   gak_fct, gak_data)))) {
-			if (out_pa_list) {
-			    out_pa_list[out_pa_list_size++] = NULL;
-			    krb5_free_pa_data(context, out_pa_list);
-			}
-			if (etype_info)
-			    krb5_free_etype_info(context, etype_info);
-			return(ret);
+		      goto cleanup;
 		    }
 
 		    if (out_pa) {
@@ -1010,18 +984,22 @@ krb5_do_preauth(krb5_context context,
 			    if ((out_pa_list =
 				 (krb5_pa_data **)
 				 malloc(2*sizeof(krb5_pa_data *)))
-				== NULL)
-				return(ENOMEM);
+				== NULL) {
+			      ret = ENOMEM;
+			      goto cleanup;
+			    }
 			} else {
 			    if ((out_pa_list =
 				 (krb5_pa_data **)
 				 realloc(out_pa_list,
 					 (out_pa_list_size+2)*
 					 sizeof(krb5_pa_data *)))
-				== NULL)
-				/* XXX this will leak the pointers which
+				== NULL) {
+			      /* XXX this will leak the pointers which
 				   have already been allocated.  oh well. */
-				return(ENOMEM);
+			      ret = ENOMEM;
+			      goto cleanup;
+			    }
 			}
 			
 			out_pa_list[out_pa_list_size++] = out_pa;
@@ -1037,6 +1015,16 @@ krb5_do_preauth(krb5_context context,
 	out_pa_list[out_pa_list_size++] = NULL;
 
     *out_padata = out_pa_list;
-
+    if (etype_info)
+      krb5_free_etype_info(context, etype_info);
+    
     return(0);
+ cleanup:
+    if (out_pa_list) {
+      out_pa_list[out_pa_list_size++] = NULL;
+      krb5_free_pa_data(context, out_pa_list);
+    }
+    if (etype_info)
+      krb5_free_etype_info(context, etype_info);
+    return (ret);
 }
diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c
index 228219f76..11be47f05 100644
--- a/src/lib/krb5/krb/rd_cred.c
+++ b/src/lib/krb5/krb/rd_cred.c
@@ -33,15 +33,11 @@ decrypt_credencdata(krb5_context context, krb5_cred *pcred, krb5_keyblock *pkeyb
 
     /*  now decode the decrypted stuff */
     if ((retval = decode_krb5_enc_cred_part(&scratch, &ppart)))
-    	goto cleanup_encpart;
+    	goto cleanup;
 
     *pcredenc = *ppart;
     retval = 0;
 
-cleanup_encpart:
-    memset(ppart, 0, sizeof(*ppart));
-    krb5_xfree(ppart);
-
 cleanup:
     memset(scratch.data, 0, scratch.length);
     krb5_xfree(scratch.data);
@@ -169,9 +165,8 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data *pc
     krb5_replay_data      replaydata;
 
     /* Get keyblock */
-    if ((keyblock = auth_context->remote_subkey) == NULL)
-	if ((keyblock = auth_context->local_subkey) == NULL)
-            keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->recv_subkey) == NULL)
+	keyblock = auth_context->keyblock;
 
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index 813205662..cf7480779 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -156,9 +156,8 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_da
     krb5_replay_data	  replaydata;
 
     /* Get keyblock */
-    if ((keyblock = auth_context->remote_subkey) == NULL)
-	if ((keyblock = auth_context->local_subkey) == NULL)
-            keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->recv_subkey) == NULL)
+	keyblock = auth_context->keyblock;
 
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
@@ -247,7 +246,8 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_da
     }
 
     if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
-	if (auth_context->remote_seq_number != replaydata.seq) {
+	if (!krb5int_auth_con_chkseqnum(context, auth_context,
+					replaydata.seq)) {
 	    retval =  KRB5KRB_AP_ERR_BADORDER;
 	    goto error;
 	}
diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c
index e35e43f5d..80192294e 100644
--- a/src/lib/krb5/krb/rd_rep.c
+++ b/src/lib/krb5/krb/rd_rep.c
@@ -81,8 +81,24 @@ krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_dat
 
     /* Set auth subkey */
     if ((*repl)->subkey) {
+	if (auth_context->recv_subkey) {
+	    krb5_free_keyblock(context, auth_context->recv_subkey);
+	    auth_context->recv_subkey = NULL;
+	}
 	retval = krb5_copy_keyblock(context, (*repl)->subkey,
-				    &auth_context->remote_subkey);
+				    &auth_context->recv_subkey);
+	if (retval)
+	    goto clean_scratch;
+	if (auth_context->send_subkey) {
+	    krb5_free_keyblock(context, auth_context->send_subkey);
+	    auth_context->send_subkey = NULL;
+	}
+	retval = krb5_copy_keyblock(context, (*repl)->subkey,
+				    &auth_context->send_subkey);
+	if (retval) {
+	    krb5_free_keyblock(context, auth_context->send_subkey);
+	    auth_context->send_subkey = NULL;
+	}
     }
 
     /* Get remote sequence number */
diff --git a/src/lib/krb5/krb/rd_req.c b/src/lib/krb5/krb/rd_req.c
index f844e3cd6..9a2f4589d 100644
--- a/src/lib/krb5/krb/rd_req.c
+++ b/src/lib/krb5/krb/rd_req.c
@@ -83,7 +83,9 @@ krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_da
 	server = request->ticket->server;
     }
     /* Get an rcache if necessary. */
-    if (((*auth_context)->rcache == NULL) && server) {
+    if (((*auth_context)->rcache == NULL)
+	&& ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME)
+&& server) {
 	if ((retval = krb5_get_server_rcache(context,
      krb5_princ_component(context,server,0), &(*auth_context)->rcache)))
 	    goto cleanup_auth_context;
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index fa126b4ab..3c398aed1 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -290,10 +290,18 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, c
     if ((*auth_context)->authentp->subkey) {
 	if ((retval = krb5_copy_keyblock(context,
 					 (*auth_context)->authentp->subkey,
-					 &((*auth_context)->remote_subkey))))
+					 &((*auth_context)->recv_subkey))))
 	    goto cleanup;
+	retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey,
+				    &((*auth_context)->send_subkey));
+	if (retval) {
+	    krb5_free_keyblock(context, (*auth_context)->recv_subkey);
+	    (*auth_context)->recv_subkey = NULL;
+	    goto cleanup;
+	}
     } else {
-	(*auth_context)->remote_subkey = 0;
+	(*auth_context)->recv_subkey = 0;
+	(*auth_context)->send_subkey = 0;
     }
 
     if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session,
diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c
index 0f6cec27f..15dc6dccc 100644
--- a/src/lib/krb5/krb/rd_safe.c
+++ b/src/lib/krb5/krb/rd_safe.c
@@ -51,6 +51,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
 {
     krb5_error_code 	  retval;
     krb5_safe 		* message;
+    krb5_data safe_body;
     krb5_checksum our_cksum, *his_cksum;
     krb5_octet zero_octet = 0;
     krb5_data *scratch;
@@ -59,7 +60,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
     if (!krb5_is_krb_safe(inbuf))
 	return KRB5KRB_AP_ERR_MSG_TYPE;
 
-    if ((retval = decode_krb5_safe(inbuf, &message)))
+    if ((retval = decode_krb5_safe_with_body(inbuf, &message, &safe_body)))
 	return retval;
 
     if (!krb5_c_valid_cksumtype(message->checksum->checksum_type)) {
@@ -113,7 +114,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
 
     message->checksum = &our_cksum;
 
-    if ((retval = encode_krb5_safe(message, &scratch)))
+    if ((retval = encode_krb5_safe_with_body(message, &safe_body, &scratch)))
 	goto cleanup;
 
     message->checksum = his_cksum;
@@ -126,8 +127,17 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
     krb5_free_data(context, scratch);
     
     if (!valid) {
-	retval = KRB5KRB_AP_ERR_MODIFIED;
-	goto cleanup;
+	/*
+	 * Checksum over only the KRB-SAFE-BODY, like RFC 1510 says, in
+	 * case someone actually implements it correctly.
+	 */
+	retval = krb5_c_verify_checksum(context, keyblock,
+					KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
+					&safe_body, his_cksum, &valid);
+	if (!valid) {
+	    retval = KRB5KRB_AP_ERR_MODIFIED;
+	    goto cleanup;
+	}
     }
 
     replaydata->timestamp = message->timestamp;
@@ -161,9 +171,8 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
 	return KRB5_RC_REQUIRED;
 
     /* Get keyblock */
-    if ((keyblock = auth_context->remote_subkey) == NULL)
-	if ((keyblock = auth_context->local_subkey) == NULL)
-            keyblock = auth_context->keyblock;
+    if ((keyblock = auth_context->recv_subkey) == NULL)
+	keyblock = auth_context->keyblock;
 
 {
     krb5_address * premote_fulladdr = NULL;
@@ -240,7 +249,8 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
     }
 
     if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
-	if (auth_context->remote_seq_number != replaydata.seq) {
+	if (!krb5int_auth_con_chkseqnum(context, auth_context,
+					replaydata.seq)) {
 	    retval =  KRB5KRB_AP_ERR_BADORDER;
 	    goto error;
 	}
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index a8ec90ee6..32519e19f 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -151,21 +151,21 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
 		required += sizeof(krb5_int32);
 	}
 
-	/* Calculate size required by local_subkey, if appropriate */
-	if (!kret && auth_context->local_subkey) {
+	/* Calculate size required by send_subkey, if appropriate */
+	if (!kret && auth_context->send_subkey) {
 	    kret = krb5_size_opaque(kcontext,
 				    KV5M_KEYBLOCK,
-				    (krb5_pointer) auth_context->local_subkey,
+				    (krb5_pointer) auth_context->send_subkey,
 				    &required);
 	    if (!kret)
 		required += sizeof(krb5_int32);
 	}
 
-	/* Calculate size required by remote_subkey, if appropriate */
-	if (!kret && auth_context->remote_subkey) {
+	/* Calculate size required by recv_subkey, if appropriate */
+	if (!kret && auth_context->recv_subkey) {
 	    kret = krb5_size_opaque(kcontext,
 				    KV5M_KEYBLOCK,
-				    (krb5_pointer) auth_context->remote_subkey,
+				    (krb5_pointer) auth_context->recv_subkey,
 				    &required);
 	    if (!kret)
 		required += sizeof(krb5_int32);
@@ -300,23 +300,23 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
 	    }
 
 	    /* Now handle subkey, if appropriate */
-	    if (!kret && auth_context->local_subkey) {
+	    if (!kret && auth_context->send_subkey) {
 		(void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain);
 		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_KEYBLOCK,
 					       (krb5_pointer)
-					       auth_context->local_subkey,
+					       auth_context->send_subkey,
 					       &bp,
 					       &remain);
 	    }
 
 	    /* Now handle subkey, if appropriate */
-	    if (!kret && auth_context->remote_subkey) {
+	    if (!kret && auth_context->recv_subkey) {
 		(void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain);
 		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_KEYBLOCK,
 					       (krb5_pointer)
-					       auth_context->remote_subkey,
+					       auth_context->recv_subkey,
 					       &bp,
 					       &remain);
 	    }
@@ -474,26 +474,26 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc
 		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
 	    }
 
-	    /* This is the local_subkey */
+	    /* This is the send_subkey */
 	    if (!kret && (tag == TOKEN_LSKBLOCK)) {
 		if (!(kret = krb5_internalize_opaque(kcontext,
 						     KV5M_KEYBLOCK,
 						     (krb5_pointer *)
 						     &auth_context->
-						     local_subkey,
+						     send_subkey,
 						     &bp,
 						     &remain)))
 		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
 	    }
 
-	    /* This is the remote_subkey */
+	    /* This is the recv_subkey */
 	    if (!kret) {
 		if (tag == TOKEN_RSKBLOCK) {
 		    kret = krb5_internalize_opaque(kcontext,
 						   KV5M_KEYBLOCK,
 						   (krb5_pointer *)
 						   &auth_context->
-						   remote_subkey,
+						   recv_subkey,
 						   &bp,
 						   &remain);
 		}
diff --git a/src/lib/krb5/krb/serialize.c b/src/lib/krb5/krb/serialize.c
index 7c5f17a4c..9cbcef78d 100644
--- a/src/lib/krb5/krb/serialize.c
+++ b/src/lib/krb5/krb/serialize.c
@@ -174,7 +174,7 @@ krb5_internalize_opaque(krb5_context kcontext, krb5_magic odtype, krb5_pointer *
 }
 
 /*
- * krb5_ser_pack_int32()	- Pack a 4-byte integer if space is availble.
+ * krb5_ser_pack_int32()	- Pack a 4-byte integer if space is available.
  *				  Update buffer pointer and remaining space.
  */
 krb5_error_code KRB5_CALLCONV
@@ -193,6 +193,23 @@ krb5_ser_pack_int32(krb5_int32 iarg, krb5_octet **bufp, size_t *remainp)
 	return(ENOMEM);
 }
 
+/*
+ * krb5_ser_pack_int64()	- Pack an 8-byte integer if space is available.
+ *				  Update buffer pointer and remaining space.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_ser_pack_int64(krb5_int64 iarg, krb5_octet **bufp, size_t *remainp)
+{
+    if (*remainp >= sizeof(krb5_int64)) {
+	store_64_be(iarg, (unsigned char *)*bufp);
+	*bufp += sizeof(krb5_int64);
+	*remainp -= sizeof(krb5_int64);
+	return(0);
+    }
+    else
+	return(ENOMEM);
+}
+
 /*
  * krb5_ser_pack_bytes()	- Pack a string of bytes.
  */
@@ -228,6 +245,22 @@ krb5_ser_unpack_int32(krb5_int32 *intp, krb5_octet **bufp, size_t *remainp)
 	return(ENOMEM);
 }
 
+/*
+ * krb5_ser_unpack_int64()	- Unpack an 8-byte integer if it's there.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_ser_unpack_int64(krb5_int64 *intp, krb5_octet **bufp, size_t *remainp)
+{
+    if (*remainp >= sizeof(krb5_int64)) {
+	*intp = load_64_be((unsigned char *)*bufp);
+	*bufp += sizeof(krb5_int64);
+	*remainp -= sizeof(krb5_int64);
+	return(0);
+    }
+    else
+	return(ENOMEM);
+}
+
 /*
  * krb5_ser_unpack_bytes()	- Unpack a byte string if it's there.
  */
diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c
index aa41bc52b..e66d2d366 100644
--- a/src/lib/krb5/krb/srv_rcache.c
+++ b/src/lib/krb5/krb/srv_rcache.c
@@ -48,6 +48,9 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache
     unsigned long uid = geteuid();
 #endif
     
+    if (piece == NULL)
+	return ENOMEM;
+    
     rcache = (krb5_rcache) malloc(sizeof(*rcache));
     if (!rcache)
 	return ENOMEM;
@@ -58,7 +61,7 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache
 
     len = piece->length + 3 + 1;
     for (i = 0; i < piece->length; i++) {
-	if (piece->data[i] == '\\')
+	if (piece->data[i] == '-')
 	    len++;
 	else if (!isvalidrcname((int) piece->data[i]))
 	    len += 3;
@@ -78,14 +81,14 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache
     strcpy(cachename, "rc_");
     p = 3;
     for (i = 0; i < piece->length; i++) {
-	if (piece->data[i] == '\\') {
-	    cachename[p++] = '\\';
-	    cachename[p++] = '\\';
+	if (piece->data[i] == '-') {
+	    cachename[p++] = '-';
+	    cachename[p++] = '-';
 	    continue;
 	}
 	if (!isvalidrcname((int) piece->data[i])) {
 	    sprintf(tmp, "%03o", piece->data[i]);
-	    cachename[p++] = '\\';
+	    cachename[p++] = '-';
 	    cachename[p++] = tmp[0];
 	    cachename[p++] = tmp[1];
 	    cachename[p++] = tmp[2];
diff --git a/src/lib/krb5/krb/unparse.c b/src/lib/krb5/krb/unparse.c
index f0e52dcee..6f1a3c9e8 100644
--- a/src/lib/krb5/krb/unparse.c
+++ b/src/lib/krb5/krb/unparse.c
@@ -149,7 +149,8 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, regi
 		*q++ = COMPONENT_SEP;
 	}
 
-	q--;			/* Back up last component separator */
+	if (i > 0)
+	    q--;		/* Back up last component separator */
 	*q++ = REALM_SEP;
 	
 	cp = krb5_princ_realm(context, principal)->data;
diff --git a/src/lib/krb5/krb/v4lifetime.c b/src/lib/krb5/krb/v4lifetime.c
new file mode 100644
index 000000000..94bf5f6ab
--- /dev/null
+++ b/src/lib/krb5/krb/v4lifetime.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000, 2001, 2003 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include "k5-int.h"
+
+/*
+ * Only lifetime bytes values less than 128 are on a linear scale.
+ * The following table contains an exponential scale that covers the
+ * lifetime values 128 to 191 inclusive (a total of 64 values).
+ * Values greater than 191 get interpreted the same as 191, but they
+ * will never be generated by the functions in this file.
+ *
+ * The ratio is approximately 1.069144898 (actually exactly
+ * exp(log(67.5)/63), where 67.5 = 2592000/38400, and 259200 = 30
+ * days, and 38400 = 128*5 minutes.  This allows a lifetime byte of
+ * 191 to correspond to a ticket life of exactly 30 days and a
+ * lifetime byte of 128 to correspond to exactly 128*5 minutes, with
+ * the other values spread on an exponential curve fit in between
+ * them.  This table should correspond exactly to the set of extended
+ * ticket lifetime values used by AFS and CMU.
+ *
+ * The following awk script is sufficient to reproduce the table:
+ * BEGIN {
+ *     r = exp(log(2592000/38400)/63);
+ *     x = 38400;
+ *     for (i=0;i<64;i++) {
+ *         printf("%d\n",x+0.5);
+ *         x *= r;
+ *     }
+ * }
+ */
+#ifndef SHORT_LIFETIME
+#define NLIFETIMES 64
+static const krb5_int32 lifetimes[NLIFETIMES] = {
+    38400, 41055,		/* 00:10:40:00, 00:11:24:15 */
+    43894, 46929,		/* 00:12:11:34, 00:13:02:09 */
+    50174, 53643,		/* 00:13:56:14, 00:14:54:03 */
+    57352, 61318,		/* 00:15:55:52, 00:17:01:58 */
+    65558, 70091,		/* 00:18:12:38, 00:19:28:11 */
+    74937, 80119,		/* 00:20:48:57, 00:22:15:19 */
+    85658, 91581,		/* 00:23:47:38, 01:01:26:21 */
+    97914, 104684,		/* 01:03:11:54, 01:05:04:44 */
+    111922, 119661,		/* 01:07:05:22, 01:09:14:21 */
+    127935, 136781,		/* 01:11:32:15, 01:13:59:41 */
+    146239, 156350,		/* 01:16:37:19, 01:19:25:50 */
+    167161, 178720,		/* 01:22:26:01, 02:01:38:40 */
+    191077, 204289,		/* 02:05:04:37, 02:08:44:49 */
+    218415, 233517,		/* 02:12:40:15, 02:16:51:57 */
+    249664, 266926,		/* 02:21:21:04, 03:02:08:46 */
+    285383, 305116,		/* 03:07:16:23, 03:12:45:16 */
+    326213, 348769,		/* 03:18:36:53, 04:00:52:49 */
+    372885, 398668,		/* 04:07:34:45, 04:14:44:28 */
+    426234, 455705,		/* 04:22:23:54, 05:06:35:05 */
+    487215, 520904,		/* 05:15:20:15, 06:00:41:44 */
+    556921, 595430,		/* 06:10:42:01, 06:21:23:50 */
+    636601, 680618,		/* 07:08:50:01, 07:21:03:38 */
+    727680, 777995,		/* 08:10:08:00, 09:00:06:35 */
+    831789, 889303,		/* 09:15:03:09, 10:07:01:43 */
+    950794, 1016537,		/* 11:00:06:34, 11:18:22:17 */
+    1086825, 1161973,		/* 12:13:53:45, 13:10:46:13 */
+    1242318, 1328218,		/* 14:09:05:18, 15:08:56:58 */
+    1420057, 1518247,		/* 16:10:27:37, 17:13:44:07 */
+    1623226, 1735464,		/* 18:18:53:46, 20:02:04:24 */
+    1855462, 1983758,		/* 21:11:24:22, 22:23:02:38 */
+    2120925, 2267576,		/* 24:13:08:45, 26:05:52:56 */
+    2424367, 2592000		/* 28:01:26:07, 30:00:00:00 */
+};
+#define MINFIXED 0x80
+#define MAXFIXED (MINFIXED + NLIFETIMES - 1)
+#endif /* !SHORT_LIFETIME */
+
+/*
+ * krb_life_to_time
+ *
+ * Given a start date and a lifetime byte, compute the expiration
+ * date.
+ */
+krb5_int32
+krb5int_krb_life_to_time(krb5_int32 start, int life)
+{
+    if (life < 0 || life > 255)	/* possibly sign botch in caller */
+	return start;
+#ifndef SHORT_LIFETIME
+    if (life < MINFIXED)
+	return start + life * 5 * 60;
+    if (life > MAXFIXED)
+	return start + lifetimes[NLIFETIMES - 1];
+    return start + lifetimes[life - MINFIXED];
+#else  /* SHORT_LIFETIME */
+    return start + life * 5 * 60;
+#endif /* SHORT_LIFETIME */
+}
+
+/*
+ * krb_time_to_life
+ *
+ * Given the start date and the end date, compute the lifetime byte.
+ * Round up, since we can adjust the start date backwards if we are
+ * issuing the ticket to cause it to expire at the correct time.
+ */
+int
+krb5int_krb_time_to_life(krb5_int32 start, krb5_int32 end)
+{
+    krb5_int32 dt;
+#ifndef SHORT_LIFETIME
+    int i;
+#endif
+
+    dt = end - start;
+    if (dt <= 0)
+	return 0;
+#ifndef SHORT_LIFETIME
+    if (dt < lifetimes[0])
+	return (dt + 5 * 60 - 1) / (5 * 60);
+    /* This depends on the array being ordered. */
+    for (i = 0; i < NLIFETIMES; i++) {
+	if (lifetimes[i] >= dt)
+	    return i + MINFIXED;
+    }
+    return MAXFIXED;
+#else  /* SHORT_LIFETIME */
+    if (dt > 5 * 60 * 255)
+	return 255;
+    else
+	return (dt + 5 * 60 - 1) / (5 * 60);
+#endif /* SHORT_LIFETIME */
+}
diff --git a/src/lib/krb5/os/.Sanitize b/src/lib/krb5/os/.Sanitize
index cf13ff1d4..e17c876b9 100644
--- a/src/lib/krb5/os/.Sanitize
+++ b/src/lib/krb5/os/.Sanitize
@@ -61,6 +61,7 @@ read_msg.c
 read_pwd.c
 realm_dom.c
 ref_std_conf.out
+send524.c
 sendto_kdc.c
 sn2princ.c
 timeofday.c
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index 51638d9e4..20fbdf160 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,3 +1,127 @@
+2004-02-09  Sam Hartman  <hartmans@mit.edu>
+
+	* changepw.c (krb5_locate_kpasswd): Run htons on the default port
+
+2003-12-22  Jeffrey Altman <jaltman@mit.edu>
+
+    * dnssrv.c:  wrap within #ifdef KRB5_DNS_LOOKUP to prevent references
+      to resolver functions when DNS support is not being compiled 
+
+2003-12-18  Jeffrey Altman <jaltman@mit.edu>
+
+    * accessor.c: Add new functions for use by gssapi
+
+2003-10-27  Jeffrey Altman <jaltman@mit.edu>
+
+    * sendto_kdc.c: sockets must be closed with closesocket() and 
+      and not close() in order to ensure portability among different
+      operating systems.
+
+2003-08-21  Ken Raeburn  <raeburn@mit.edu>
+
+	* dnssrv.c: New file; split out DNS SRV RR query support...
+	* locate_kdc.c: ...from here.  Always compile in the calls.
+	* Makefile.in (STLIBOBJS, OBJS, SRCS): Add it.
+
+2003-07-25  Ken Raeburn  <raeburn@mit.edu>
+
+	* locate_kdc.c (krb5_locate_kdc): Always pass 0 to locate_server
+	as the get_masters argument.  Instead, if get_masters is set,
+	look up "master_kdc" in the config file instead of "kdc".
+
+2003-07-09  Alexandra Ellwood  <lxs@mit.edu>
+
+        * toffset.c: Export and krb5_set_real_time for Samba.
+
+2003-06-06  Ken Raeburn  <raeburn@mit.edu>
+
+	* locate_kdc.c (struct srv_dns_entry): Moved to k5-int.h.
+	(krb5int_make_srv_query_realm): Renamed from make_srv_query_realm.
+	(krb5int_free_srv_dns_data): New function.
+	(krb5_locate_srv_dns_1): Use it.
+
+	* accessor.c (krb5int_accessor): Fill in make_srv_query_realm and
+	free_srv_dns_data fields.
+
+2003-06-05  Ken Raeburn  <raeburn@mit.edu>
+
+	* locate_kdc.c (make_srv_query_realm): Punt if strdup fails.
+	Always return what data we can, even if memory allocation or other
+	problems prevent us from returning more.
+	(krb5_locate_srv_dns_1): Always return what data we can.  Fix
+	memory leak.  Free up temporary storage as quickly as possible,
+	while building up address list to return.
+
+2003-06-03  Ken Raeburn  <raeburn@mit.edu>
+
+	* accessor.c (krb5int_accessor): Initialize restored locate_server
+	field.
+
+	* locate_kdc.c (struct srv_dns_entry): Move to top level.
+	(make_srv_query_realm): Separate from krb5_locate_srv_dns_1; just
+	do query and return results.
+	(krb5_locate_srv_dns_1): Call it, and build addlist entries.
+	Check for one RR with a target of ".", and return an error.
+	(krb5_locate_srv_dns): Deleted.
+
+	* t_locate_kdc.c (main): Call krb5_locate_srv_dns_1.
+
+	* changepw.c (krb5_locate_kpasswd): Check specifically for certain
+	errors before using fallback heuristics.
+
+2003-06-03  Alexandra Ellwood  <lxs@mit.edu>
+
+        * init_os_ctx.c: Included header to get __KLAllowHomeDirectoryAccess().
+
+2003-05-27  Ken Raeburn  <raeburn@mit.edu>
+
+	* send524.c (krb5int_524_sendto_kdc): Enable support on Windows
+	always.
+
+2003-05-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* send524.c: New file, moved from krb524/sendmsg.c.  Rename
+	function to have krb5int_ prefix.  If KRB5_KRB4_COMPAT not
+	defined, return an error.
+	* accessor.c (krb5int_accessor): Update for deleted and added
+	fields.  If KRB5_KRB4_COMPAT is not defined, just use null
+	pointers for the new fields.
+
+2003-05-06  Alexandra Ellwood  <lxs@mit.edu>
+
+        * init_os_ctx.c: Added support for KLL's __KLAllowHomeDirectoryAccess()
+        function so that krb4, krb5 and gssapi will not access the user's homedir
+        if the application forbids it.
+
+2003-04-28  Sam Hartman  <hartmans@mit.edu>
+
+	* changepw.c (krb5_change_set_password): Locate server in realm of
+	creds.server, not in realm of target principal because target
+	principal is null in the  changepw case.
+
+2003-04-27  Sam Hartman  <hartmans@mit.edu>
+
+	* changepw.c (krb5_change_set_password): Call
+	krb5_setpw_result_code_string not krb5_setpw_result_code_string  
+
+2003-04-24  Sam Hartman  <hartmans@mit.edu>
+
+	* changepw.c (krb5_change_set_password): return error from
+	auth_con_setaddrs not last socket errno if auth_con_setaddrs fails 
+
+2003-04-15  Sam Hartman  <hartmans@mit.edu>
+
+	* changepw.c (krb5_change_set_password): Patches from Paul Nelson
+	to implement Microsoft set password protocol  
+	(krb5_set_password_using_ccache): Use kadmin/changepw in target realm, not local realm and use a two-component principal
+	(krb5_change_set_password): Find the kpasswd server for the realm
+	of the target principal not the client 
+
+2003-04-13  Ken Raeburn  <raeburn@mit.edu>
+
+	* read_pwd.c (krb5_read_password): Always free temporary storage
+	used for verification version of password.
+
 2003-03-06  Alexandra Ellwood <lxs@mit.edu>
 
     * c_ustime.c: Removed Mac OS 9 code.
diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in
index acd37b22c..27431a0f1 100644
--- a/src/lib/krb5/os/Makefile.in
+++ b/src/lib/krb5/os/Makefile.in
@@ -18,6 +18,7 @@ STLIBOBJS= \
 	def_realm.o	\
 	ccdefname.o	\
 	changepw.o	\
+	dnssrv.o	\
 	free_krbhs.o	\
 	free_hstrl.o	\
 	full_ipadr.o	\
@@ -46,6 +47,7 @@ STLIBOBJS= \
 	read_pwd.o	\
 	realm_dom.o	\
 	realm_iter.o	\
+	send524.o	\
 	sendto_kdc.o	\
 	sn2princ.o	\
 	timeofday.o	\
@@ -61,6 +63,7 @@ OBJS= \
 	$(OUTPRE)def_realm.$(OBJEXT)	\
 	$(OUTPRE)ccdefname.$(OBJEXT)	\
 	$(OUTPRE)changepw.$(OBJEXT)	\
+	$(OUTPRE)dnssrv.$(OBJEXT)	\
 	$(OUTPRE)free_krbhs.$(OBJEXT)	\
 	$(OUTPRE)free_hstrl.$(OBJEXT)	\
 	$(OUTPRE)full_ipadr.$(OBJEXT)	\
@@ -89,6 +92,7 @@ OBJS= \
 	$(OUTPRE)read_pwd.$(OBJEXT)	\
 	$(OUTPRE)realm_dom.$(OBJEXT)	\
 	$(OUTPRE)realm_iter.$(OBJEXT)	\
+	$(OUTPRE)send524.$(OBJEXT)	\
 	$(OUTPRE)sendto_kdc.$(OBJEXT)	\
 	$(OUTPRE)sn2princ.$(OBJEXT)	\
 	$(OUTPRE)timeofday.$(OBJEXT)	\
@@ -104,6 +108,7 @@ SRCS= \
 	$(srcdir)/def_realm.c	\
 	$(srcdir)/ccdefname.c	\
 	$(srcdir)/changepw.c	\
+	$(srcdir)/dnssrv.c	\
 	$(srcdir)/free_krbhs.c	\
 	$(srcdir)/free_hstrl.c	\
 	$(srcdir)/full_ipadr.c	\
@@ -132,6 +137,7 @@ SRCS= \
 	$(srcdir)/realm_dom.c	\
 	$(srcdir)/realm_iter.c	\
 	$(srcdir)/port2ip.c	\
+	$(srcdir)/send524.c	\
 	$(srcdir)/sendto_kdc.c	\
 	$(srcdir)/sn2princ.c	\
 	$(srcdir)/timeofday.c	\
@@ -235,210 +241,235 @@ clean::
 #
 accessor.so accessor.po $(OUTPRE)accessor.$(OBJEXT): accessor.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 an_to_ln.so an_to_ln.po $(OUTPRE)an_to_ln.$(OBJEXT): an_to_ln.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 c_ustime.so c_ustime.po $(OUTPRE)c_ustime.$(OBJEXT): c_ustime.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 def_realm.so def_realm.po $(OUTPRE)def_realm.$(OBJEXT): def_realm.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 ccdefname.so ccdefname.po $(OUTPRE)ccdefname.$(OBJEXT): ccdefname.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): changepw.c $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/krb5/kdb.h os-proto.h
+dnssrv.so dnssrv.po $(OUTPRE)dnssrv.$(OBJEXT): dnssrv.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
   os-proto.h
 free_krbhs.so free_krbhs.po $(OUTPRE)free_krbhs.$(OBJEXT): free_krbhs.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 free_hstrl.so free_hstrl.po $(OUTPRE)free_hstrl.$(OBJEXT): free_hstrl.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 full_ipadr.so full_ipadr.po $(OUTPRE)full_ipadr.$(OBJEXT): full_ipadr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 get_krbhst.so get_krbhst.po $(OUTPRE)get_krbhst.$(OBJEXT): get_krbhst.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 gen_port.so gen_port.po $(OUTPRE)gen_port.$(OBJEXT): gen_port.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 genaddrs.so genaddrs.po $(OUTPRE)genaddrs.$(OBJEXT): genaddrs.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 gen_rname.so gen_rname.po $(OUTPRE)gen_rname.$(OBJEXT): gen_rname.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 gmt_mktime.so gmt_mktime.po $(OUTPRE)gmt_mktime.$(OBJEXT): gmt_mktime.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 hostaddr.so hostaddr.po $(OUTPRE)hostaddr.$(OBJEXT): hostaddr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/fake-addrinfo.h
+  $(SRCTOP)/include/fake-addrinfo.h
 hst_realm.so hst_realm.po $(OUTPRE)hst_realm.$(OBJEXT): hst_realm.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h $(SRCTOP)/include/fake-addrinfo.h
+  os-proto.h $(SRCTOP)/include/fake-addrinfo.h
 init_os_ctx.so init_os_ctx.po $(OUTPRE)init_os_ctx.$(OBJEXT): init_os_ctx.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 krbfileio.so krbfileio.po $(OUTPRE)krbfileio.$(OBJEXT): krbfileio.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ktdefname.so ktdefname.po $(OUTPRE)ktdefname.$(OBJEXT): ktdefname.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 kuserok.so kuserok.po $(OUTPRE)kuserok.$(OBJEXT): kuserok.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 mk_faddr.so mk_faddr.po $(OUTPRE)mk_faddr.$(OBJEXT): mk_faddr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
 localaddr.so localaddr.po $(OUTPRE)localaddr.$(OBJEXT): localaddr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/foreachaddr.c
+  $(SRCTOP)/include/foreachaddr.c
 locate_kdc.so locate_kdc.po $(OUTPRE)locate_kdc.$(OBJEXT): locate_kdc.c $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  os-proto.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/krb5/kdb.h os-proto.h
 lock_file.so lock_file.po $(OUTPRE)lock_file.$(OBJEXT): lock_file.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 net_read.so net_read.po $(OUTPRE)net_read.$(OBJEXT): net_read.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 net_write.so net_write.po $(OUTPRE)net_write.$(OBJEXT): net_write.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 osconfig.so osconfig.po $(OUTPRE)osconfig.$(OBJEXT): osconfig.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 prompter.so prompter.po $(OUTPRE)prompter.$(OBJEXT): prompter.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 promptusr.so promptusr.po $(OUTPRE)promptusr.$(OBJEXT): promptusr.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 read_msg.so read_msg.po $(OUTPRE)read_msg.$(OBJEXT): read_msg.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 read_pwd.so read_pwd.po $(OUTPRE)read_pwd.$(OBJEXT): read_pwd.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 realm_dom.so realm_dom.po $(OUTPRE)realm_dom.$(OBJEXT): realm_dom.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 realm_iter.so realm_iter.po $(OUTPRE)realm_iter.$(OBJEXT): realm_iter.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 port2ip.so port2ip.po $(OUTPRE)port2ip.$(OBJEXT): port2ip.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h os-proto.h
+  os-proto.h
+send524.so send524.po $(OUTPRE)send524.$(OBJEXT): send524.c $(SRCTOP)/include/fake-addrinfo.h \
+  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/krb5/kdb.h os-proto.h
 sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): sendto_kdc.c $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-int.h \
-  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  os-proto.h $(SRCTOP)/include/cm.h
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/k5-platform.h \
+  $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/krb5/kdb.h os-proto.h $(SRCTOP)/include/cm.h
 sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): sn2princ.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/fake-addrinfo.h
+  $(SRCTOP)/include/fake-addrinfo.h
 timeofday.so timeofday.po $(OUTPRE)timeofday.$(OBJEXT): timeofday.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 toffset.so toffset.po $(OUTPRE)toffset.$(OBJEXT): toffset.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 unlck_file.so unlck_file.po $(OUTPRE)unlck_file.$(OBJEXT): unlck_file.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ustime.so ustime.po $(OUTPRE)ustime.$(OBJEXT): ustime.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 write_msg.so write_msg.po $(OUTPRE)write_msg.$(OBJEXT): write_msg.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c
index 509d317fa..4e907b1c4 100644
--- a/src/lib/krb5/os/accessor.c
+++ b/src/lib/krb5/os/accessor.c
@@ -35,18 +35,32 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
   if (version == KRB5INT_ACCESS_VERSION)
   {
     krb5int_access internals_temp;
-    internals_temp.krb5_locate_server = krb5int_locate_server;
-    internals_temp.krb5_locate_kdc = krb5_locate_kdc;
     internals_temp.free_addrlist = krb5int_free_addrlist;
-    internals_temp.krb5_max_skdc_timeout = krb5_max_skdc_timeout;
-    internals_temp.krb5_skdc_timeout_shift = krb5_skdc_timeout_shift;
-    internals_temp.krb5_skdc_timeout_1 = krb5_skdc_timeout_1;
-    internals_temp.krb5_max_dgram_size = krb5_max_dgram_size;
     internals_temp.krb5_hmac = krb5_hmac;
     internals_temp.md5_hash_provider = &krb5int_hash_md5;
     internals_temp.arcfour_enc_provider = &krb5int_enc_arcfour;
+    internals_temp.locate_server = &krb5int_locate_server;
     internals_temp.sendto_udp = &krb5int_sendto;
     internals_temp.add_host_to_list = krb5int_add_host_to_list;
+#ifdef KRB5_DNS_LOOKUP
+    internals_temp.make_srv_query_realm = krb5int_make_srv_query_realm;
+    internals_temp.free_srv_dns_data = krb5int_free_srv_dns_data;
+#else
+    internals_temp.make_srv_query_realm = 0;
+    internals_temp.free_srv_dns_data = 0;
+#endif
+#ifdef KRB5_KRB4_COMPAT
+    internals_temp.krb_life_to_time = krb5int_krb_life_to_time;
+    internals_temp.krb_time_to_life = krb5int_krb_time_to_life;
+    internals_temp.krb524_encode_v4tkt = krb5int_encode_v4tkt;
+#else
+    internals_temp.krb_life_to_time = 0;
+    internals_temp.krb_time_to_life = 0;
+    internals_temp.krb524_encode_v4tkt = 0;
+#endif
+    internals_temp.krb5int_c_mandatory_cksumtype = krb5int_c_mandatory_cksumtype;
+    internals_temp.krb5_ser_pack_int64 = krb5_ser_pack_int64;
+    internals_temp.krb5_ser_unpack_int64 = krb5_ser_unpack_int64;
     *internals = internals_temp;
     return 0;
   }
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index 60cb3a915..df558b6f2 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -24,6 +24,10 @@
  * or implied warranty.
  *
  */
+/*
+ * krb5_set_password - Implements set password per RFC 3244
+ * Added by Paul W. Nelson, Thursby Software Systems, Inc.
+ */
 
 #define NEED_SOCKETS
 #include "fake-addrinfo.h"
@@ -49,8 +53,8 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
 
     code = krb5int_locate_server (context, realm, addrlist, 0,
 				  "kpasswd_server", "_kpasswd", 0,
-				  DEFAULT_KPASSWD_PORT, 0, 0);
-    if (code) {
+				  htons(DEFAULT_KPASSWD_PORT), 0, 0);
+    if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) {
 	code = krb5int_locate_server (context, realm, addrlist, 0,
 				      "admin_server", "_kerberos-adm", 1,
 				      DEFAULT_KPASSWD_PORT, 0, 0);
@@ -69,8 +73,16 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
 }
 
 
+/*
+** The logic for setting and changing a password is mostly the same
+** krb5_change_set_password handles both cases 
+**	if set_password_for is NULL, then a password change is performed,
+**  otherwise, the password is set for the principal indicated in set_password_for
+*/
 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)
+krb5_change_set_password(
+	krb5_context context, krb5_creds *creds, char *newpw, krb5_principal set_password_for,
+	int *result_code, krb5_data *result_code_string, krb5_data *result_string)
 {
     krb5_auth_context auth_context;
     krb5_data ap_req, chpw_req, chpw_rep;
@@ -104,7 +116,7 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
 	  goto cleanup;
 
     if ((code = krb5_locate_kpasswd(context,
-                                    krb5_princ_realm(context, creds->client),
+                                    krb5_princ_realm(context, creds->server),
 				    &al)))
         goto cleanup;
 
@@ -218,14 +230,15 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
 
 	if ((code = krb5_auth_con_setaddrs(context, auth_context,
 					   &local_kaddr, NULL))) {
-	    code = SOCKET_ERRNO;
-	    goto cleanup;
+	  goto cleanup;
 	}
 
-	if ((code = krb5_mk_chpw_req(context, auth_context, &ap_req,
-				     newpw, &chpw_req)))
+	if( set_password_for )
+		code = krb5int_mk_setpw_req(context, auth_context, &ap_req, set_password_for, newpw, &chpw_req);
+	else
+		code = krb5int_mk_chpw_req(context, auth_context, &ap_req, newpw, &chpw_req);
+	if (code)
 	{
-	    code = SOCKET_ERRNO;
 	    goto cleanup;
 	}
 
@@ -289,19 +302,23 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
 					   NULL, &remote_kaddr)))
 	    goto cleanup;
 
-	if ((code = krb5_rd_chpw_rep(context, auth_context, &chpw_rep,
-				     &local_result_code,
-				     result_string)))
-	    goto cleanup;
+	if( set_password_for )
+		code = krb5int_rd_setpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
+	else
+		code = krb5int_rd_chpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
+	if (code)
+		goto cleanup;
 
 	if (result_code)
 	    *result_code = local_result_code;
 
 	if (result_code_string) {
-	    if ((code = krb5_chpw_result_code_string(context,
-						     local_result_code,
-						     &code_string)))
-		goto cleanup;
+		if( set_password_for )
+	    	code = krb5int_setpw_result_code_string(context, local_result_code, (const char **)&code_string);
+		else
+	    	code = krb5_chpw_result_code_string(context, local_result_code, &code_string);
+		if(code)
+			goto cleanup;
 
 	    result_code_string->length = strlen(code_string);
 	    result_code_string->data = malloc(result_code_string->length);
@@ -343,3 +360,71 @@ cleanup:
 
     return(code);
 }
+
+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)
+{
+	return krb5_change_set_password(
+		context, creds, newpw, NULL, result_code, result_code_string, result_string );
+}
+
+/*
+ * krb5_set_password - Implements set password per RFC 3244
+ *
+ */
+
+krb5_error_code KRB5_CALLCONV
+krb5_set_password(
+	krb5_context context,
+	krb5_creds *creds,
+	char *newpw,
+	krb5_principal change_password_for,
+	int *result_code, krb5_data *result_code_string, krb5_data *result_string
+	)
+{
+	return krb5_change_set_password(
+		context, creds, newpw, change_password_for, result_code, result_code_string, result_string );
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_set_password_using_ccache(
+	krb5_context context,
+	krb5_ccache ccache,
+	char *newpw,
+	krb5_principal change_password_for,
+	int *result_code, krb5_data *result_code_string, krb5_data *result_string
+	)
+{
+	krb5_creds		creds;
+	krb5_creds		*credsp;
+	krb5_error_code	code;
+
+/*
+** get the proper creds for use with krb5_set_password -
+*/
+	memset( &creds, 0, sizeof(creds) );
+/*
+** first get the principal for the password service -
+*/
+	code = krb5_cc_get_principal( context, ccache, &creds.client );
+	if( !code )
+	{
+		code = krb5_build_principal( context, &creds.server, 
+				krb5_princ_realm(context, change_password_for)->length,
+				krb5_princ_realm(context, change_password_for)->data,
+				"kadmin", "changepw", NULL );
+		if(!code)
+		{
+			code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
+			if( ! code )
+			{
+				code = krb5_set_password(context, credsp, newpw, change_password_for,
+					result_code, result_code_string,
+					result_string);
+				krb5_free_creds(context, credsp);
+			}
+		}
+		krb5_free_cred_contents(context, &creds);
+	}
+	return code;
+}
diff --git a/src/lib/krb5/os/dnssrv.c b/src/lib/krb5/os/dnssrv.c
new file mode 100644
index 000000000..90279fdd3
--- /dev/null
+++ b/src/lib/krb5/os/dnssrv.c
@@ -0,0 +1,273 @@
+/*
+ * lib/krb5/os/dnssrv.c
+ *
+ * Copyright 1990,2000,2001,2002,2003 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * do DNS SRV RR queries
+ */
+
+#ifdef KRB5_DNS_LOOKUP
+#define NEED_SOCKETS
+#include "k5-int.h"
+#include "os-proto.h"
+#include <stdio.h>
+#ifdef WSHELPER
+#include <wshelper.h>
+#else /* WSHELPER */
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+#endif /* WSHELPER */
+#ifndef T_SRV
+#define T_SRV 33
+#endif /* T_SRV */
+
+/* for old Unixes and friends ... */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
+
+/*
+ * Lookup a KDC via DNS SRV records
+ */
+
+void krb5int_free_srv_dns_data (struct srv_dns_entry *p)
+{
+    struct srv_dns_entry *next;
+    while (p) {
+	next = p->next;
+	free(p->host);
+	free(p);
+	p = next;
+    }
+}
+
+/* Do DNS SRV query, return results in *answers.
+
+   Make best effort to return all the data we can.  On memory or
+   decoding errors, just return what we've got.  Always return 0,
+   currently.  */
+
+krb5_error_code
+krb5int_make_srv_query_realm(const krb5_data *realm,
+			     const char *service,
+			     const char *protocol,
+			     struct srv_dns_entry **answers)
+{
+    union {
+        unsigned char bytes[2048];
+        HEADER hdr;
+    } answer;
+    unsigned char *p=NULL;
+    char host[MAX_DNS_NAMELEN], *h;
+    int type, rrclass;
+    int priority, weight, size, len, numanswers, numqueries, rdlen;
+    unsigned short port;
+    const int hdrsize = sizeof(HEADER);
+
+    struct srv_dns_entry *head = NULL;
+    struct srv_dns_entry *srv = NULL, *entry = NULL;
+
+    /*
+     * First off, build a query of the form:
+     *
+     * service.protocol.realm
+     *
+     * which will most likely be something like:
+     *
+     * _kerberos._udp.REALM
+     *
+     */
+
+    if (memchr(realm->data, 0, realm->length))
+	return 0;
+    if ( strlen(service) + strlen(protocol) + realm->length + 6 
+         > MAX_DNS_NAMELEN )
+	return 0;
+    sprintf(host, "%s.%s.%.*s", service, protocol, (int) realm->length,
+	    realm->data);
+
+    /* Realm names don't (normally) end with ".", but if the query
+       doesn't end with "." and doesn't get an answer as is, the
+       resolv code will try appending the local domain.  Since the
+       realm names are absolutes, let's stop that.  
+
+       But only if a name has been specified.  If we are performing
+       a search on the prefix alone then the intention is to allow
+       the local domain or domain search lists to be expanded.  */
+
+    h = host + strlen (host);
+    if ((h[-1] != '.') && ((h - host + 1) < sizeof(host)))
+        strcpy (h, ".");
+
+#ifdef TEST
+    fprintf (stderr, "sending DNS SRV query for %s\n", host);
+#endif
+
+    size = res_search(host, C_IN, T_SRV, answer.bytes, sizeof(answer.bytes));
+
+    if ((size < hdrsize) || (size > sizeof(answer.bytes)))
+	goto out;
+
+    /*
+     * We got an answer!  First off, parse the header and figure out how
+     * many answers we got back.
+     */
+
+    p = answer.bytes;
+
+    numqueries = ntohs(answer.hdr.qdcount);
+    numanswers = ntohs(answer.hdr.ancount);
+
+    p += sizeof(HEADER);
+
+    /*
+     * We need to skip over all of the questions, so we have to iterate
+     * over every query record.  dn_expand() is able to tell us the size
+     * of compress DNS names, so we use it.
+     */
+
+#define INCR_CHECK(x,y) x += y; if (x > size + answer.bytes) goto out
+#define CHECK(x,y) if (x + y > size + answer.bytes) goto out
+#define NTOHSP(x,y) x[0] << 8 | x[1]; x += y
+
+    while (numqueries--) {
+	len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
+	if (len < 0)
+	    goto out;
+	INCR_CHECK(p, len + 4);
+    }
+
+    /*
+     * We're now pointing at the answer records.  Only process them if
+     * they're actually T_SRV records (they might be CNAME records,
+     * for instance).
+     *
+     * But in a DNS reply, if you get a CNAME you always get the associated
+     * "real" RR for that CNAME.  RFC 1034, 3.6.2:
+     *
+     * CNAME RRs cause special action in DNS software.  When a name server
+     * fails to find a desired RR in the resource set associated with the
+     * domain name, it checks to see if the resource set consists of a CNAME
+     * record with a matching class.  If so, the name server includes the CNAME
+     * record in the response and restarts the query at the domain name
+     * specified in the data field of the CNAME record.  The one exception to
+     * this rule is that queries which match the CNAME type are not restarted.
+     *
+     * In other words, CNAMEs do not need to be expanded by the client.
+     */
+
+    while (numanswers--) {
+
+	/* First is the name; use dn_expand to get the compressed size */
+	len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
+	if (len < 0)
+	    goto out;
+	INCR_CHECK(p, len);
+
+	/* Next is the query type */
+        CHECK(p, 2);
+	type = NTOHSP(p,2);
+
+	/* Next is the query class; also skip over 4 byte TTL */
+        CHECK(p, 6);
+	rrclass = NTOHSP(p,6);
+
+	/* Record data length */
+
+        CHECK(p,2);
+	rdlen = NTOHSP(p,2);
+
+	/*
+	 * If this is an SRV record, process it.  Record format is:
+	 *
+	 * Priority
+	 * Weight
+	 * Port
+	 * Server name
+	 */
+
+	if (rrclass == C_IN && type == T_SRV) {
+            CHECK(p,2);
+	    priority = NTOHSP(p,2);
+	    CHECK(p, 2);
+	    weight = NTOHSP(p,2);
+	    CHECK(p, 2);
+	    port = NTOHSP(p,2);
+	    len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
+	    if (len < 0)
+		goto out;
+	    INCR_CHECK(p, len);
+
+	    /*
+	     * We got everything!  Insert it into our list, but make sure
+	     * it's in the right order.  Right now we don't do anything
+	     * with the weight field
+	     */
+
+	    srv = (struct srv_dns_entry *) malloc(sizeof(struct srv_dns_entry));
+	    if (srv == NULL)
+		goto out;
+	
+	    srv->priority = priority;
+	    srv->weight = weight;
+	    srv->port = port;
+	    srv->host = strdup(host);
+	    if (srv->host == NULL) {
+		free(srv);
+		goto out;
+	    }
+
+	    if (head == NULL || head->priority > srv->priority) {
+		srv->next = head;
+		head = srv;
+	    } else
+		/*
+		 * This is confusing.  Only insert an entry into this
+		 * spot if:
+		 * The next person has a higher priority (lower priorities
+		 * are preferred).
+		 * Or
+		 * There is no next entry (we're at the end)
+		 */
+		for (entry = head; entry != NULL; entry = entry->next)
+		    if ((entry->next &&
+			 entry->next->priority > srv->priority) ||
+			entry->next == NULL) {
+			srv->next = entry->next;
+			entry->next = srv;
+			break;
+		    }
+	} else
+	    INCR_CHECK(p, rdlen);
+    }
+	
+  out:
+    *answers = head;
+    return 0;
+}
+#endif
\ No newline at end of file
diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c
index eb2321d42..c43771d76 100644
--- a/src/lib/krb5/os/init_os_ctx.c
+++ b/src/lib/krb5/os/init_os_ctx.c
@@ -31,6 +31,10 @@
 #include "k5-int.h"
 #include "os-proto.h"
 
+#ifdef USE_LOGIN_LIBRARY
+#include "KerberosLoginPrivate.h"
+#endif
+
 #if defined(_WIN32)
 
 static krb5_error_code
@@ -234,8 +238,14 @@ os_get_default_config_files(profile_filespec_t **pfiles, krb5_boolean secure)
     unsigned int ent_len;
     const char *s, *t;
 
+#ifdef USE_LOGIN_LIBRARY
+    /* If __KLAllowHomeDirectoryAccess() == FALSE, we are probably
+        trying to authenticate to a fileserver for the user's homedir. */
+    if (secure || !__KLAllowHomeDirectoryAccess ()) {
+#else
     if (secure) {
-        filepath = DEFAULT_SECURE_PROFILE_PATH;
+#endif
+            filepath = DEFAULT_SECURE_PROFILE_PATH;
     } else { 
         filepath = getenv("KRB5_CONFIG");
         if (!filepath) filepath = DEFAULT_PROFILE_PATH;
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index 9c9fed4d1..ce90127af 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -502,12 +502,6 @@ krb5_locate_srv_conf(krb5_context context, const krb5_data *realm,
 }
 #endif
 
-#ifdef KRB5_DNS_LOOKUP
-
-/*
- * Lookup a KDC via DNS SRV records
- */
-
 static krb5_error_code
 krb5_locate_srv_dns_1 (const krb5_data *realm,
 		       const char *service,
@@ -515,196 +509,14 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
 		       struct addrlist *addrlist,
 		       int family)
 {
-    union {
-        unsigned char bytes[2048];
-        HEADER hdr;
-    } answer;
-    unsigned char *p=NULL;
-    char host[MAX_DNS_NAMELEN], *h;
-    int type, rrclass;
-    int priority, weight, size, len, numanswers, numqueries, rdlen;
-    unsigned short port;
-    const int hdrsize = sizeof(HEADER);
-    struct srv_dns_entry {
-	struct srv_dns_entry *next;
-	int priority;
-	int weight;
-	unsigned short port;
-	char *host;
-    };
-
     struct srv_dns_entry *head = NULL;
-    struct srv_dns_entry *srv = NULL, *entry = NULL;
+    struct srv_dns_entry *entry = NULL, *next;
     krb5_error_code code = 0;
 
-    /*
-     * First off, build a query of the form:
-     *
-     * service.protocol.realm
-     *
-     * which will most likely be something like:
-     *
-     * _kerberos._udp.REALM
-     *
-     */
-
-    if ( strlen(service) + strlen(protocol) + realm->length + 6 
-         > MAX_DNS_NAMELEN )
-        goto out;
-    sprintf(host, "%s.%s.%.*s", service, protocol, (int) realm->length,
-	    realm->data);
-
-    /* Realm names don't (normally) end with ".", but if the query
-       doesn't end with "." and doesn't get an answer as is, the
-       resolv code will try appending the local domain.  Since the
-       realm names are absolutes, let's stop that.  
-
-       But only if a name has been specified.  If we are performing
-       a search on the prefix alone then the intention is to allow
-       the local domain or domain search lists to be expanded.  */
-
-    h = host + strlen (host);
-    if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host)))
-        strcpy (h, ".");
-
-#ifdef TEST
-    fprintf (stderr, "sending DNS SRV query for %s\n", host);
-#endif
-
-    size = res_search(host, C_IN, T_SRV, answer.bytes, sizeof(answer.bytes));
-
-    if ((size < hdrsize) || (size > sizeof(answer.bytes)))
-	goto out;
-
-    /*
-     * We got an answer!  First off, parse the header and figure out how
-     * many answers we got back.
-     */
-
-    p = answer.bytes;
-
-    numqueries = ntohs(answer.hdr.qdcount);
-    numanswers = ntohs(answer.hdr.ancount);
-
-    p += sizeof(HEADER);
-
-    /*
-     * We need to skip over all of the questions, so we have to iterate
-     * over every query record.  dn_expand() is able to tell us the size
-     * of compress DNS names, so we use it.
-     */
-
-#define INCR_CHECK(x,y) x += y; if (x > size + answer.bytes) goto out
-#define CHECK(x,y) if (x + y > size + answer.bytes) goto out
-#define NTOHSP(x,y) x[0] << 8 | x[1]; x += y
-
-    while (numqueries--) {
-	len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
-	if (len < 0)
-	    goto out;
-	INCR_CHECK(p, len + 4);
-    }
-
-    /*
-     * We're now pointing at the answer records.  Only process them if
-     * they're actually T_SRV records (they might be CNAME records,
-     * for instance).
-     *
-     * But in a DNS reply, if you get a CNAME you always get the associated
-     * "real" RR for that CNAME.  RFC 1034, 3.6.2:
-     *
-     * CNAME RRs cause special action in DNS software.  When a name server
-     * fails to find a desired RR in the resource set associated with the
-     * domain name, it checks to see if the resource set consists of a CNAME
-     * record with a matching class.  If so, the name server includes the CNAME
-     * record in the response and restarts the query at the domain name
-     * specified in the data field of the CNAME record.  The one exception to
-     * this rule is that queries which match the CNAME type are not restarted.
-     *
-     * In other words, CNAMEs do not need to be expanded by the client.
-     */
-
-    while (numanswers--) {
-
-	/* First is the name; use dn_expand to get the compressed size */
-	len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
-	if (len < 0)
-	    goto out;
-	INCR_CHECK(p, len);
-
-	/* Next is the query type */
-        CHECK(p, 2);
-	type = NTOHSP(p,2);
-
-	/* Next is the query class; also skip over 4 byte TTL */
-        CHECK(p, 6);
-	rrclass = NTOHSP(p,6);
-
-	/* Record data length */
-
-        CHECK(p,2);
-	rdlen = NTOHSP(p,2);
-
-	/*
-	 * If this is an SRV record, process it.  Record format is:
-	 *
-	 * Priority
-	 * Weight
-	 * Port
-	 * Server name
-	 */
+    code = krb5int_make_srv_query_realm(realm, service, protocol, &head);
+    if (code)
+	return 0;
 
-	if (rrclass == C_IN && type == T_SRV) {
-            CHECK(p,2);
-	    priority = NTOHSP(p,2);
-	    CHECK(p, 2);
-	    weight = NTOHSP(p,2);
-	    CHECK(p, 2);
-	    port = NTOHSP(p,2);
-	    len = dn_expand(answer.bytes, answer.bytes + size, p, host, sizeof(host));
-	    if (len < 0)
-		goto out;
-	    INCR_CHECK(p, len);
-
-	    /*
-	     * We got everything!  Insert it into our list, but make sure
-	     * it's in the right order.  Right now we don't do anything
-	     * with the weight field
-	     */
-
-	    srv = (struct srv_dns_entry *) malloc(sizeof(struct srv_dns_entry));
-	    if (srv == NULL)
-		goto out;
-	
-	    srv->priority = priority;
-	    srv->weight = weight;
-	    srv->port = port;
-	    srv->host = strdup(host);
-
-	    if (head == NULL || head->priority > srv->priority) {
-		srv->next = head;
-		head = srv;
-	    } else
-		/*
-		 * This is confusing.  Only insert an entry into this
-		 * spot if:
-		 * The next person has a higher priority (lower priorities
-		 * are preferred).
-		 * Or
-		 * There is no next entry (we're at the end)
-		 */
-		for (entry = head; entry != NULL; entry = entry->next)
-		    if ((entry->next &&
-			 entry->next->priority > srv->priority) ||
-			entry->next == NULL) {
-			srv->next = entry->next;
-			entry->next = srv;
-			break;
-		    }
-	} else
-	    INCR_CHECK(p, rdlen);
-    }
-	
     /*
      * Okay!  Now we've got a linked list of entries sorted by
      * priority.  Start looking up A records and returning
@@ -712,53 +524,44 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
      */
 
     if (head == NULL)
-	goto out;
+	return 0;
+
+    /* Check for the "." case indicating no support.  */
+    if (head->next == 0 && head->host[0] == 0) {
+	free(head->host);
+	free(head);
+	return KRB5_ERR_NO_SERVICE;
+    }
 
 #ifdef TEST
     fprintf (stderr, "walking answer list:\n");
 #endif
-    for (entry = head; entry != NULL; entry = entry->next) {
+    for (entry = head; entry != NULL; entry = next) {
 #ifdef TEST
 	fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host);
 #endif
+	next = entry->next;
 	code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0,
 				 (strcmp("_tcp", protocol)
 				  ? SOCK_DGRAM
 				  : SOCK_STREAM), family);
 	if (code)
 	    break;
+	if (entry == head) {
+	    free(entry->host);
+	    free(entry);
+	    head = next;
+	    entry = 0;
+	}
     }
 #ifdef TEST
     fprintf (stderr, "[end]\n");
 #endif
 
-    for (entry = head; entry != NULL; ) {
-	free(entry->host);
-        entry->host = NULL;
-	srv = entry;
-	entry = entry->next;
-	free(srv);
-        srv = NULL;
-    }
-
-  out:
-    if (srv)
-        free(srv);
-
+    krb5int_free_srv_dns_data(head);
     return code;
 }
 
-#ifdef TEST
-static krb5_error_code
-krb5_locate_srv_dns(const krb5_data *realm,
-		    const char *service, const char *protocol,
-		    struct addrlist *al)
-{
-    return krb5_locate_srv_dns_1 (realm, service, protocol, al, 0);
-}
-#endif
-#endif /* KRB5_DNS_LOOKUP */
-
 /*
  * Wrapper function for the two backends
  */
@@ -852,7 +655,8 @@ krb5_locate_kdc(krb5_context context, const krb5_data *realm,
 	    sec_udpport = 0;
     }
 
-    return krb5int_locate_server(context, realm, addrlist, get_masters, "kdc",
+    return krb5int_locate_server(context, realm, addrlist, 0,
+				 get_masters ? "master_kdc" : "kdc",
 				 (get_masters
 				  ? "_kerberos-master"
 				  : "_kerberos"),
diff --git a/src/lib/krb5/os/read_pwd.c b/src/lib/krb5/os/read_pwd.c
index 9023b8e98..1bb631c6a 100644
--- a/src/lib/krb5/os/read_pwd.c
+++ b/src/lib/krb5/os/read_pwd.c
@@ -64,15 +64,12 @@ krb5_read_password(krb5_context context, const char *prompt, const char *prompt2
 	    return ENOMEM;
 	retval = krb5_prompter_posix(NULL,
 				     NULL,NULL, NULL, 1, &k5prompt);
-	if (retval) {
-	    free(verify_data.data);
-	} else {
+	if (retval == 0) {
 	    /* compare */
-	    if (strncmp(return_pwd, (char *)verify_data.data, *size_return)) {
+	    if (strncmp(return_pwd, (char *)verify_data.data, *size_return))
 		retval = KRB5_LIBOS_BADPWDMATCH;
-		free(verify_data.data);
-	    }
 	}
+	free(verify_data.data);
     }
     if (!retval)
 	*size_return = k5prompt.reply->length;
diff --git a/src/krb524/sendmsg.c b/src/lib/krb5/os/send524.c
similarity index 83%
rename from src/krb524/sendmsg.c
rename to src/lib/krb5/os/send524.c
index 5cbd324ac..0ca8e93c3 100644
--- a/src/krb524/sendmsg.c
+++ b/src/lib/krb5/os/send524.c
@@ -39,8 +39,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <krb.h>
-#include "krb524.h"
+#include "os-proto.h"
 
 /*
  * krb524_sendto_kdc:
@@ -58,7 +57,7 @@
  */
 
 krb5_error_code
-krb524_sendto_kdc (context, message, realm, reply, addr, addrlen)
+krb5int_524_sendto_kdc (context, message, realm, reply, addr, addrlen)
     krb5_context context;
     const krb5_data * message;
     const krb5_data * realm;
@@ -66,16 +65,13 @@ krb524_sendto_kdc (context, message, realm, reply, addr, addrlen)
     struct sockaddr *addr;
     socklen_t *addrlen;
 {
+#if defined(KRB5_KRB4_COMPAT) || defined(_WIN32) /* yuck! */
     int i;
     struct addrlist al = ADDRLIST_INIT;
     struct servent *serv;
     krb5_error_code retval;
-    krb5int_access internals;
     int port;
 
-    retval = krb5int_accessor(&internals, KRB5INT_ACCESS_VERSION);
-    if (retval)
-	return retval;
     /*
      * find KDC location(s) for realm
      */
@@ -83,15 +79,14 @@ krb524_sendto_kdc (context, message, realm, reply, addr, addrlen)
     serv = getservbyname(KRB524_SERVICE, "udp");
     port = serv ? serv->s_port : htons (KRB524_PORT);
 
-    retval = internals.krb5_locate_server(context, realm, &al, 0,
-					  "krb524_server", "_krb524",
-					  SOCK_DGRAM, port,
-					  0, PF_INET);
+    retval = krb5int_locate_server(context, realm, &al, 0,
+				   "krb524_server", "_krb524",
+				   SOCK_DGRAM, port,
+				   0, PF_INET);
     if (retval == KRB5_REALM_CANT_RESOLVE || retval == KRB5_REALM_UNKNOWN) {
 	/* Fallback heuristic: Assume krb524 port on every KDC might
 	   work.  */
-	retval = internals.krb5_locate_kdc(context, realm, &al, 0,
-					   SOCK_DGRAM, PF_INET);
+	retval = krb5_locate_kdc(context, realm, &al, 0, SOCK_DGRAM, PF_INET);
 	/*
 	 * Bash the ports numbers.
 	 */
@@ -107,8 +102,10 @@ krb524_sendto_kdc (context, message, realm, reply, addr, addrlen)
     if (al.naddrs == 0)
 	return KRB5_REALM_UNKNOWN;
 
-    retval = internals.sendto_udp (context, message, &al, reply, addr,
-				   addrlen);
-    internals.free_addrlist (&al);
+    retval = krb5int_sendto (context, message, &al, reply, addr, addrlen);
+    krb5int_free_addrlist (&al);
     return retval;
+#else
+    return KRB524_KRB4_DISABLED;
+#endif
 }
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 0f5b9f275..8e0f719a4 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -1073,7 +1073,7 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
 egress:
     for (i = 0; i < n_conns; i++) {
 	if (conns[i].fd != INVALID_SOCKET)
-	    close(conns[i].fd);
+	    closesocket(conns[i].fd);
 	if (conns[i].state == READING
 	    && conns[i].x.in.buf != 0
 	    && conns[i].x.in.buf != udpbuf)
diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c
index a3d682860..03dac07ef 100644
--- a/src/lib/krb5/os/t_locate_kdc.c
+++ b/src/lib/krb5/os/t_locate_kdc.c
@@ -117,7 +117,7 @@ int main (int argc, char *argv[])
 	break;
 
     case LOOKUP_DNS:
-	err = krb5_locate_srv_dns (&realm, "_kerberos", "_udp", &al);
+	err = krb5_locate_srv_dns_1 (&realm, "_kerberos", "_udp", &al, 0);
 	break;
 
     case LOOKUP_WHATEVER:
diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c
index aad995a18..4578f822a 100644
--- a/src/lib/krb5/os/toffset.c
+++ b/src/lib/krb5/os/toffset.c
@@ -35,7 +35,7 @@
  * between the system time and the "real time" as passed to this
  * routine
  */
-krb5_error_code 
+krb5_error_code KRB5_CALLCONV
 krb5_set_real_time(krb5_context context, krb5_int32 seconds, krb5_int32 microseconds)
 {
     krb5_os_context os_ctx = context->os_context;
diff --git a/src/lib/krb5/rcache/Makefile.in b/src/lib/krb5/rcache/Makefile.in
index 79b6a282e..d67b044fa 100644
--- a/src/lib/krb5/rcache/Makefile.in
+++ b/src/lib/krb5/rcache/Makefile.in
@@ -49,38 +49,40 @@ clean-unix:: clean-libobjs
 #
 rc_base.so rc_base.po $(OUTPRE)rc_base.$(OBJEXT): rc_base.c rc_base.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 rc_dfl.so rc_dfl.po $(OUTPRE)rc_dfl.$(OBJEXT): rc_dfl.c rc_base.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h rc_dfl.h rc_io.h
+  rc_dfl.h rc_io.h
 rc_io.so rc_io.po $(OUTPRE)rc_io.$(OBJEXT): rc_io.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) rc_base.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  rc_dfl.h rc_io.h
+  $(SRCTOP)/include/krb5/kdb.h rc_dfl.h rc_io.h
 rcdef.so rcdef.po $(OUTPRE)rcdef.$(OBJEXT): rcdef.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h rc_dfl.h
+  rc_dfl.h
 rc_conv.so rc_conv.po $(OUTPRE)rc_conv.$(OBJEXT): rc_conv.c rc_base.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 ser_rc.so ser_rc.po $(OUTPRE)ser_rc.$(OBJEXT): ser_rc.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 rcfns.so rcfns.po $(OUTPRE)rcfns.$(OBJEXT): rcfns.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index 53172a85c..58b4390df 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -36,8 +36,10 @@ EXPORTS
 	krb5_auth_con_getlocalseqnumber
 	krb5_auth_con_getlocalsubkey
 	krb5_auth_con_getrcache			; KRB5_CALLCONV_WRONG
+	krb5_auth_con_getrecvsubkey
 	krb5_auth_con_getremoteseqnumber
 	krb5_auth_con_getremotesubkey
+	krb5_auth_con_getsendsubkey
 	krb5_auth_con_init
 	krb5_auth_con_initivector		; DEPRECATED
 	krb5_auth_con_setaddrs			; KRB5_CALLCONV_WRONG
@@ -45,6 +47,8 @@ EXPORTS
 	krb5_auth_con_setflags
 	krb5_auth_con_setports
 	krb5_auth_con_setrcache
+	krb5_auth_con_setrecvsubkey
+	krb5_auth_con_setsendsubkey
 	krb5_auth_con_setuseruserkey
 	krb5_build_principal
 	krb5_build_principal_ext
@@ -63,6 +67,7 @@ EXPORTS
 	krb5_c_random_make_octets
 	krb5_c_random_seed
 	krb5_c_string_to_key
+krb5_c_string_to_key_with_params
 	krb5_c_valid_cksumtype
 	krb5_c_valid_enctype
 	krb5_c_verify_checksum
@@ -153,6 +158,7 @@ EXPORTS
 	krb5_get_init_creds_opt_set_salt
 	krb5_get_init_creds_opt_set_tkt_life
 	krb5_get_init_creds_password
+	krb5_get_permitted_enctypes
 	krb5_get_prompt_types
 	krb5_get_renewed_creds
 	krb5_get_server_rcache
@@ -187,6 +193,7 @@ EXPORTS
 	krb5_os_localaddr
 	krb5_parse_name
 	krb5_principal_compare
+	krb5_principal2salt
 	krb5_process_key
 	krb5_prompter_posix
 	krb5_random_key
@@ -204,7 +211,10 @@ EXPORTS
 	krb5_sendauth
 	krb5_set_default_realm
 	krb5_set_default_tgs_enctypes
+krb5_set_password
+krb5_set_password_using_ccache
 	krb5_set_principal_realm
+	krb5_set_real_time
 	krb5_sname_to_principal
 	krb5_string_to_cksumtype
 	krb5_string_to_deltat
@@ -224,6 +234,10 @@ EXPORTS
 	krb5_verify_init_creds_opt_init
 	krb5_verify_init_creds_opt_set_ap_req_nofail
 
+	krb5_524_convert_creds
+; Don't add krb524_convert_creds_kdc or krb524_init_ets here;
+; they've never been exported by this library, and are deprecated. -KR
+
 	krb5int_accessor	; INTERNAL (to end all internals)
 
 ; To Add (exported on Mac OS X):
@@ -265,3 +279,4 @@ EXPORTS
 	krb5_rc_close				; PRIVATE GSSAPI krb5.hin
 	krb5_free_enc_tkt_part			; PRIVATE GSSAPI krb5.hin
 	krb5_decrypt_tkt_part			; PRIVATE GSSAPI krb5.hin
+    
\ No newline at end of file
diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog
index 653424054..279ec8adb 100644
--- a/src/lib/rpc/ChangeLog
+++ b/src/lib/rpc/ChangeLog
@@ -1,3 +1,16 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* bindresvport.c: Include errno.h.
+	(gssrpc_bindresvport): Don't declare errno.
+	* clnt_tcp.c: Don't declare errno.
+	* svc.c: Don't declare errno.  Include errno.h.
+
+2003-03-24  Tom Yu  <tlyu@mit.edu>
+
+	* xdr_mem.c (xdrmem_create): Perform some additional size checks.
+	(xdrmem_getlong, xdrmem_putlong, xdrmem_getbytes): Check x_handy
+	prior to decrementing it.
+
 2003-01-12  Ezra Peisach  <epeisach@bu.edu>
 
 	* svc_auth_gssapi.c (_svcauth_gssapi_unset_names): If invoked more
diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c
index 36b3ed533..28017d6cf 100644
--- a/src/lib/rpc/bindresvport.c
+++ b/src/lib/rpc/bindresvport.c
@@ -41,6 +41,7 @@ static  char sccsid[] = "@(#)bindresvport.c	2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <gssrpc/rpc.h>
+#include <errno.h>
 
 /*
  * Bind a socket to a privileged IP port
@@ -53,7 +54,6 @@ gssrpc_bindresvport(sd, sockin)
 	int res;
 	static short port;
 	struct sockaddr_in myaddr;
-	extern int errno;
 	int i;
 
 #define STARTPORT 600
diff --git a/src/lib/rpc/clnt_tcp.c b/src/lib/rpc/clnt_tcp.c
index abadf339c..9906bca0e 100644
--- a/src/lib/rpc/clnt_tcp.c
+++ b/src/lib/rpc/clnt_tcp.c
@@ -60,8 +60,6 @@ static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
 
 #define MCALL_MSG_SIZE 24
 
-extern int errno;
-
 static enum clnt_stat	clnttcp_call(CLIENT *, rpc_u_int32, xdrproc_t, void *,
 				     xdrproc_t, void *, struct timeval);
 static void		clnttcp_abort(CLIENT *);
diff --git a/src/lib/rpc/svc.c b/src/lib/rpc/svc.c
index 7429acda1..902681541 100644
--- a/src/lib/rpc/svc.c
+++ b/src/lib/rpc/svc.c
@@ -46,8 +46,7 @@ static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro";
 #include <gssrpc/pmap_clnt.h>
 #include <stdio.h>
 #include <string.h>
-
-extern int errno;
+#include <errno.h>
 
 #ifdef FD_SETSIZE
 static SVCXPRT **xports;
diff --git a/src/lib/rpc/xdr_mem.c b/src/lib/rpc/xdr_mem.c
index 18265da81..58e2d82a3 100644
--- a/src/lib/rpc/xdr_mem.c
+++ b/src/lib/rpc/xdr_mem.c
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
 #include <netinet/in.h>
 #include <stdio.h>
 #include <string.h>
+#include <limits.h>
 
 static bool_t	xdrmem_getlong(XDR *, long *);
 static bool_t	xdrmem_putlong(XDR *, long *);
@@ -84,7 +85,7 @@ xdrmem_create(xdrs, addr, size, op)
 	xdrs->x_op = op;
 	xdrs->x_ops = &xdrmem_ops;
 	xdrs->x_private = xdrs->x_base = addr;
-	xdrs->x_handy = size;
+	xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */
 }
 
 static void
@@ -99,8 +100,10 @@ xdrmem_getlong(xdrs, lp)
 	long *lp;
 {
 
-	if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+	if (xdrs->x_handy < sizeof(rpc_int32))
 		return (FALSE);
+	else
+		xdrs->x_handy -= sizeof(rpc_int32);
 	*lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private)));
 	xdrs->x_private = (char *)xdrs->x_private + sizeof(rpc_int32);
 	return (TRUE);
@@ -112,8 +115,10 @@ xdrmem_putlong(xdrs, lp)
 	long *lp;
 {
 
-	if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+	if (xdrs->x_handy < sizeof(rpc_int32))
 		return (FALSE);
+	else
+		xdrs->x_handy -= sizeof(rpc_int32);
 	*(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp));
 	xdrs->x_private = (char *)xdrs->x_private + sizeof(rpc_int32);
 	return (TRUE);
@@ -126,8 +131,10 @@ xdrmem_getbytes(xdrs, addr, len)
 	register unsigned int len;
 {
 
-	if ((xdrs->x_handy -= len) < 0)
+	if (xdrs->x_handy < len)
 		return (FALSE);
+	else
+		xdrs->x_handy -= len;
 	memmove(addr, xdrs->x_private, len);
 	xdrs->x_private = (char *)xdrs->x_private + len;
 	return (TRUE);
@@ -140,8 +147,10 @@ xdrmem_putbytes(xdrs, addr, len)
 	register unsigned int len;
 {
 
-	if ((xdrs->x_handy -= len) < 0)
+	if (xdrs->x_handy < len)
 		return (FALSE);
+	else
+		xdrs->x_handy -= len;
 	memmove(xdrs->x_private, addr, len);
 	xdrs->x_private = (char *)xdrs->x_private + len;
 	return (TRUE);
@@ -180,7 +189,7 @@ xdrmem_inline(xdrs, len)
 {
 	rpc_int32 *buf = 0;
 
-	if (xdrs->x_handy >= len) {
+	if (len >= 0 && xdrs->x_handy >= len) {
 		xdrs->x_handy -= len;
 		buf = (rpc_int32 *) xdrs->x_private;
 		xdrs->x_private = (char *)xdrs->x_private + len;
diff --git a/src/mac/MacOSX/Headers/Kerberos5Prefix.h b/src/mac/MacOSX/Headers/Kerberos5Prefix.h
index 24acb4845..acd5ebb4f 100644
--- a/src/mac/MacOSX/Headers/Kerberos5Prefix.h
+++ b/src/mac/MacOSX/Headers/Kerberos5Prefix.h
@@ -146,8 +146,8 @@
 #define KRB4_USE_KEYTAB              1
 #define KRB5                         1
 #define KRB524_PRIVATE               1
-#define KRB5_DNS_LOOKUP              0
-#define KRB5_DNS_LOOKUP_KDC          0
+#define KRB5_DNS_LOOKUP              1
+#define KRB5_DNS_LOOKUP_KDC          1
 #define KRB5_KRB4_COMPAT             1
 #define KRB5_PRIVATE                 1
 #define krb5_sigtype                 void
diff --git a/src/mac/MacOSX/Projects/Kerberos5.pbexp b/src/mac/MacOSX/Projects/Kerberos5.pbexp
index a3dfbe985..6cae45313 100644
--- a/src/mac/MacOSX/Projects/Kerberos5.pbexp
+++ b/src/mac/MacOSX/Projects/Kerberos5.pbexp
@@ -24,13 +24,14 @@
 	_krb5_c_random_make_octets
 	_krb5_c_random_seed
 #
-# Will be added for 1.3
-#	_krb5_c_random_os_entropy
-#	_krb5_c_random_add_entropy
-#	_krb5_c_init_state
-#	_krb5_c_free_state
+# Added for 1.3
+	_krb5_c_random_os_entropy
+	_krb5_c_random_add_entropy
+	_krb5_c_init_state
+	_krb5_c_free_state
 #
 	_krb5_c_string_to_key
+	_krb5_c_string_to_key_with_params
 	_krb5_c_enctype_compare
 	_krb5_c_make_checksum
 	_krb5_c_verify_checksum
@@ -57,6 +58,10 @@
 	_krb5_auth_con_getremotesubkey
 	_krb5_auth_con_getlocalseqnumber
 	_krb5_auth_con_getremoteseqnumber
+	_krb5_auth_con_getrecvsubkey
+	_krb5_auth_con_getsendsubkey
+	_krb5_auth_con_setrecvsubkey
+	_krb5_auth_con_setsendsubkey
 	_krb5_auth_con_setrcache
 	_krb5_auth_con_getrcache
 	_krb5_auth_con_getauthenticator
@@ -121,6 +126,7 @@
 	_krb5_verify_init_creds_opt_set_ap_req_nofail
 #
 	_krb5_set_default_tgs_enctypes
+	_krb5_get_permitted_enctypes
 #
 	_krb5_free_tgt_creds
 #
@@ -218,8 +224,11 @@
 	_krb5_free_default_realm
 #
 	_krb5_sname_to_principal
-    _krb5_principal2salt
+	_krb5_principal2salt
 	_krb5_change_password
+#
+	_krb5_set_password
+	_krb5_set_password_using_ccache
 #
 	_krb5_get_profile
 #
@@ -230,6 +239,7 @@
 	_krb5_kuserok
 #
 	_krb5_get_time_offsets
+	_krb5_set_real_time
 #
 	_krb5_string_to_cksumtype
 	_krb5_cksumtype_to_string
@@ -256,6 +266,7 @@
 	_krb5_appdefault_boolean
 #
 	_krb524_convert_creds_kdc
+	_krb5_524_convert_creds
 #
 #
 # DEPRECATED:
diff --git a/src/mac/MacOSX/Projects/Kerberos5.pbproj/project.pbxproj b/src/mac/MacOSX/Projects/Kerberos5.pbproj/project.pbxproj
index c674f4b5b..17dfd9513 100644
--- a/src/mac/MacOSX/Projects/Kerberos5.pbproj/project.pbxproj
+++ b/src/mac/MacOSX/Projects/Kerberos5.pbproj/project.pbxproj
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 38;
+	objectVersion = 39;
 	objects = {
 		A12536AA040BC4FB003D8244 = {
 			fileRef = F517343503F1B65A01120114;
@@ -78,12 +78,15 @@
 			isa = PBXGroup;
 			path = kadmin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536B5040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536B6040BEC05003D8244 = {
 			children = (
@@ -107,12 +110,15 @@
 			isa = PBXGroup;
 			path = cli;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536B7040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536B8040BEC05003D8244 = {
 			children = (
@@ -120,95 +126,126 @@
 			isa = PBXGroup;
 			path = attic;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536B9040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BA040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.yacc;
 			path = getdate.y;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BB040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = k5srvutil.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BC040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = k5srvutil.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BD040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadmin.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BE040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kadmin.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536BF040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kadmin.local.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C0040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kadmin.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C1040BEC05003D8244 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kadmin_ct.ct;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C2040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = keytab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C3040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C4040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = memmove.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C5040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ss_wrapper.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536C6040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strftime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536CA040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536CD040BEC05003D8244 = {
 			children = (
@@ -238,138 +275,183 @@
 			isa = PBXGroup;
 			path = dbutil;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536CE040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536CF040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D0040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = dump.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D1040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = dumpv4.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D2040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = import_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D3040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm5_create.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D4040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kdb5_create.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D5040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kdb5_destroy.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D6040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kdb5_edit.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D7040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kdb5_stash.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D8040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kdb5_util.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536D9040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kdb5_util.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DA040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kdb5_util.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DB040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = loadv4.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DC040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DD040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = nstrtok.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DE040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ovload.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536DF040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string_table.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536E0040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = string_table.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536E1040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strtok.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536E2040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tcl_wrapper.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536E3040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536EC040BEC05003D8244 = {
 			children = (
@@ -380,24 +462,31 @@
 			isa = PBXGroup;
 			path = kdbkeys;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536ED040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536EE040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = "do-test.pl";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536EF040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536F5040BEC05003D8244 = {
 			children = (
@@ -414,65 +503,86 @@
 			isa = PBXGroup;
 			path = ktutil;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536F6040BEC05003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536F7040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536F8040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536F9040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktutil.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FA040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = ktutil.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FB040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = ktutil.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FC040BEC06003D8244 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ktutil_ct.ct;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FD040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktutil_funcs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FE040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12536FF040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253700040BEC06003D8244 = {
 			children = (
@@ -490,54 +600,71 @@
 			isa = PBXGroup;
 			path = passwd;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253701040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253702040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253703040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kpasswd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253704040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kpasswd.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253705040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kpasswd.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253706040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kpasswd_strings.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253707040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253708040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tty_kpasswd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253709040BEC06003D8244 = {
 			children = (
@@ -550,12 +677,15 @@
 			isa = PBXGroup;
 			path = "unit-test";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370B040BEC06003D8244 = {
 			children = (
@@ -564,12 +694,15 @@
 			isa = PBXGroup;
 			path = config;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370C040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = unix.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370D040BEC06003D8244 = {
 			children = (
@@ -581,30 +714,39 @@
 			isa = PBXGroup;
 			path = kpasswd.0;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370E040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = changing.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125370F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = connecting.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253710040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = principal.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253711040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = usage.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253712040BEC06003D8244 = {
 			children = (
@@ -613,24 +755,31 @@
 			isa = PBXGroup;
 			path = lib;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253713040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = helpers.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253714040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253715040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = xm_kpasswd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253716040BEC06003D8244 = {
 			children = (
@@ -639,12 +788,15 @@
 			isa = PBXGroup;
 			path = scripts;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253717040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "inst-hdrs.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253718040BEC06003D8244 = {
 			children = (
@@ -664,78 +816,103 @@
 			isa = PBXGroup;
 			path = server;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253719040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.lex;
 			path = acls.l;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371C040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_rpc_svc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371D040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = kadmind.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371E040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125371F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = misc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253720040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = misc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253721040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ovsec_kadmd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253722040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = schpw.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253723040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = server_glue_v1.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253724040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = server_stubs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253725040BEC06003D8244 = {
 			children = (
@@ -751,18 +928,23 @@
 			isa = PBXGroup;
 			path = testing;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253726040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253727040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253728040BEC06003D8244 = {
 			children = (
@@ -770,12 +952,15 @@
 			isa = PBXGroup;
 			path = lib;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253729040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372A040BEC06003D8244 = {
 			children = (
@@ -787,29 +972,38 @@
 			isa = PBXGroup;
 			path = proto;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372C040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kdc.conf.proto;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372D040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = krb5.conf.proto;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372E040BEC06003D8244 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ovsec_adm.dict;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125372F040BEC06003D8244 = {
 			children = (
@@ -834,108 +1028,143 @@
 			isa = PBXGroup;
 			path = scripts;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253730040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253731040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253732040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = compare_dump.plin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253733040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "env-setup.shin";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253734040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "find-make.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253735040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = "fixup-conf-files.plin";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253736040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = init_db;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253737040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = "make-host-keytab.plin";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253738040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253739040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = qualname.plin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = save_files.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = simple_dump.plin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373C040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = start_servers;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373D040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = start_servers_local;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373E040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = stop_servers;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125373F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = stop_servers_local;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253740040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = verify_xrunner_report.plin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253741040BEC06003D8244 = {
 			children = (
@@ -944,12 +1173,15 @@
 			isa = PBXGroup;
 			path = tcl;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253742040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = util.t;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253743040BEC06003D8244 = {
 			children = (
@@ -967,66 +1199,87 @@
 			isa = PBXGroup;
 			path = util;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253744040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253745040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = bsddb_dump.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253746040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253747040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253748040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tcl_kadm5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253749040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = tcl_kadm5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tcl_krb5_hash.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tcl_ovsec_kadm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374C040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = tcl_ovsec_kadm_syntax;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374D040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = test.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374E040BEC06003D8244 = {
 			children = (
@@ -1048,29 +1301,38 @@
 			isa = PBXGroup;
 			path = v4server;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125374F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253750040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = acl_files.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253751040BEC06003D8244 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = acl_files.doc;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253752040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = admin_server.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253753040BEC06003D8244 = {
 			children = (
@@ -1078,54 +1340,71 @@
 			isa = PBXGroup;
 			path = attic;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253754040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = build_pwfile.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253755040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253756040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_funcs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253757040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_ser_wrap.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253758040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_server.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253759040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kadm_server.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_supp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375C040BEC06003D8244 = {
 			children = (
@@ -1141,12 +1420,15 @@
 			isa = PBXGroup;
 			path = "unit-test";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375D040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375E040BEC06003D8244 = {
 			children = (
@@ -1156,24 +1438,31 @@
 			isa = PBXGroup;
 			path = config;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125375F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253760040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = unix.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253761040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = getpid.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253762040BEC06003D8244 = {
 			children = (
@@ -1182,24 +1471,31 @@
 			isa = PBXGroup;
 			path = lib;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253763040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = helpers.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253764040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253765040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = remove_changepw_perms.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253766040BEC06003D8244 = {
 			children = (
@@ -1208,12 +1504,15 @@
 			isa = PBXGroup;
 			path = v4server.0;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253767040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = "setup-srvtab.exp";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253768040BEC06003D8244 = {
 			children = (
@@ -1224,24 +1523,31 @@
 			isa = PBXGroup;
 			path = v4server.1;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253769040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = access.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125376A040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = "change-password.exp";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125376B040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = usage.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125376D040BEC06003D8244 = {
 			children = (
@@ -1260,102 +1566,134 @@
 			isa = PBXGroup;
 			path = v5passwdd;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125376E040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125376F040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = adm_conn.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253770040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = adm_rw.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253771040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253772040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kadm5_defs.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253773040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kpasswd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253774040BEC06003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = main.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253775040BEC07003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253776040BEC07003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = proto_serv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253777040BEC07003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = srv_net.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253778040BEC07003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.objcpp;
 			path = v5passwd.M;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253780040BF748003D8244 = {
 			isa = PBXTargetDependency;
 			target = F5E59BD503FD803201120114;
+			targetProxy = A181DA4705CEFC0400E4C246;
 		};
 		A1253781040BF780003D8244 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5E6022D8A9901120112;
+			targetProxy = A181DA4605CEFC0400E4C246;
 		};
 		A1253782040BF7B4003D8244 = {
 			isa = PBXTargetDependency;
 			target = F5CFD629022D922C01120112;
+			targetProxy = A181DA4205CEFC0400E4C246;
 		};
 		A1253783040BF7E6003D8244 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = KerberosDES.pbexp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253784040BF80F003D8244 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Kerberos4.pbexp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A125378D040BFA0E003D8244 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = KerberosProfile.pbexp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537EA040C0795003D8244 = {
 			children = (
@@ -1363,37 +1701,28 @@
 				A12537FE040C080B003D8244,
 				A1253803040C0D3E003D8244,
 				A12537EB040C0795003D8244,
-				A12537EC040C0795003D8244,
-				A12537ED040C0795003D8244,
 				A12537EE040C0795003D8244,
 			);
 			isa = PBXGroup;
 			path = include;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537EB040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb5.h;
 			refType = 4;
-		};
-		A12537EC040C0795003D8244 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524.h;
-			refType = 4;
-		};
-		A12537ED040C0795003D8244 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524_err.h;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537EE040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = profile.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537EF040C0795003D8244 = {
 			children = (
@@ -1403,74 +1732,77 @@
 				A12537F3040C0795003D8244,
 				A12537F4040C0795003D8244,
 				A12537F5040C0795003D8244,
-				A12537F6040C0795003D8244,
-				A12537F7040C0795003D8244,
 				A12537F8040C0795003D8244,
 				A12537F9040C0795003D8244,
 			);
 			isa = PBXGroup;
 			path = Kerberos;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F0040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = des.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F1040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F2040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_generic.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F3040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_krb5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F4040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F5040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb5.h;
 			refType = 4;
-		};
-		A12537F6040C0795003D8244 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524.h;
-			refType = 4;
-		};
-		A12537F7040C0795003D8244 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524_err.h;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F8040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537F9040C0795003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = profile.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FA040C080B003D8244 = {
 			children = (
@@ -1481,24 +1813,31 @@
 			isa = PBXGroup;
 			path = gssapi;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FB040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FC040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_generic.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FD040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_krb5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FE040C080B003D8244 = {
 			children = (
@@ -1509,24 +1848,31 @@
 			isa = PBXGroup;
 			path = kerberosIV;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A12537FF040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = des.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253800040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253801040C080B003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253803040C0D3E003D8244 = {
 			children = (
@@ -1536,24 +1882,73 @@
 			isa = PBXGroup;
 			path = krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253804040C0D3E003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = autoconf.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1253805040C0D3E003D8244 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = osconf.h;
 			refType = 4;
+			sourceTree = "<group>";
+		};
+		A125397605CF124D003BD89B = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = k5sealv3.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A125397705CF124E003BD89B = {
+			fileRef = A125397605CF124D003BD89B;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		A125399205CF12A2003BD89B = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = mandatory_sumtype.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A125399305CF12A2003BD89B = {
+			fileRef = A125399205CF12A2003BD89B;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		A12539AD05CF12D5003BD89B = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = dnssrv.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A12539AE05CF12D5003BD89B = {
+			fileRef = A12539AD05CF12D5003BD89B;
+			isa = PBXBuildFile;
+			settings = {
+			};
 		};
 		A166BCC3040D36F8004AA618 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mac_des_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A166BCC4040D36F8004AA618 = {
 			fileRef = A166BCC3040D36F8004AA618;
@@ -1561,6 +1956,161 @@
 			settings = {
 			};
 		};
+		A16DA36604854EF700120112 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = conv_creds.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A16DA36704854EF700120112 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = v4lifetime.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A16DA36804854EF700120112 = {
+			fileRef = A16DA36604854EF700120112;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		A16DA36904854EF700120112 = {
+			fileRef = A16DA36704854EF700120112;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		A16DA36A0485503F00120112 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = text;
+			path = krb524_err.et;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A16DB01304868A7E00120112 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
+			path = send524.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A16DB01404868A7E00120112 = {
+			fileRef = A16DB01304868A7E00120112;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		A181DA3F05CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5E6022D8A9901120112;
+			remoteInfo = "Error Table Generation";
+		};
+		A181DA4005CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD629022D922C01120112;
+			remoteInfo = "Header Generation";
+		};
+		A181DA4105CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5E6022D8A9901120112;
+			remoteInfo = "Error Table Generation";
+		};
+		A181DA4205CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD629022D922C01120112;
+			remoteInfo = "Header Generation";
+		};
+		A181DA4305CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD629022D922C01120112;
+			remoteInfo = "Header Generation";
+		};
+		A181DA4405CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5CD022D86AD01120112;
+			remoteInfo = KerberosProfile;
+		};
+		A181DA4505CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5E2686C03F8336601120114;
+			remoteInfo = KerberosDES;
+		};
+		A181DA4605CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5E6022D8A9901120112;
+			remoteInfo = "Error Table Generation";
+		};
+		A181DA4705CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5E59BD503FD803201120114;
+			remoteInfo = ServerBuild;
+		};
+		A181DA4805CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5E6022D8A9901120112;
+			remoteInfo = "Error Table Generation";
+		};
+		A181DA4905CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5E2686C03F8336601120114;
+			remoteInfo = KerberosDES;
+		};
+		A181DA4A05CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD629022D922C01120112;
+			remoteInfo = "Header Generation";
+		};
+		A181DA4B05CEFC0400E4C246 = {
+			containerPortal = F5CFD36E022D854401120112;
+			isa = PBXContainerItemProxy;
+			proxyType = 1;
+			remoteGlobalIDString = F5CFD5E6022D8A9901120112;
+			remoteInfo = "Error Table Generation";
+		};
+		A181DA5405CF0BD800E4C246 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			path = "k5-platform.h";
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		A181DA5505CF0BD800E4C246 = {
+			fileRef = A181DA5405CF0BD800E4C246;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		A198BBE10406D04A00120114 = {
 			children = (
 				A198BBE60406D04A00120114,
@@ -1572,12 +2122,15 @@
 			isa = PBXGroup;
 			path = mac;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BBE60406D04A00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC050406D04A00120114 = {
 			children = (
@@ -1586,12 +2139,15 @@
 			isa = PBXGroup;
 			path = libraries;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC0A0406D04A00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC180406D04A00120114 = {
 			children = (
@@ -1603,6 +2159,7 @@
 			isa = PBXGroup;
 			path = MacOSX;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC190406D04A00120114 = {
 			children = (
@@ -1611,6 +2168,7 @@
 			isa = PBXGroup;
 			path = Headers;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC1A0406D04A00120114 = {
 			children = (
@@ -1619,6 +2177,7 @@
 			isa = PBXGroup;
 			path = Projects;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC1B0406D04A00120114 = {
 			children = (
@@ -1626,6 +2185,7 @@
 			isa = PBXGroup;
 			path = Kerberos5.pbproj;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC1C0406D04A00120114 = {
 			children = (
@@ -1633,6 +2193,7 @@
 			isa = PBXGroup;
 			path = Scripts;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC1D0406D04A00120114 = {
 			children = (
@@ -1640,18 +2201,23 @@
 			isa = PBXGroup;
 			path = Sources;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC200406D04A00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ReadMe;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC210406D04A00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "Release notes";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC270406D66000120114 = {
 			fileRef = F517343303F1B65A01120114;
@@ -1662,8 +2228,10 @@
 		A198BC2A0406DA8F00120114 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_FSp_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A198BC2B0406DA8F00120114 = {
 			fileRef = A198BC2A0406DA8F00120114;
@@ -1674,14 +2242,18 @@
 		A1B21F170417D6BC00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aes_s2k.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1B21F180417D6BC00120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = aes_s2k.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1B21F190417D6BC00120114 = {
 			fileRef = A1B21F170417D6BC00120114;
@@ -1695,6 +2267,14 @@
 			settings = {
 			};
 		};
+		A1BBFF1604226DBD00120114 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = text;
+			path = configure.in;
+			refType = 4;
+			sourceTree = "<group>";
+		};
 		A1CA6042040F24850013F915 = {
 			fileRef = F517325103F1B65901120114;
 			isa = PBXBuildFile;
@@ -2292,8 +2872,10 @@
 		A1CA623604168DFE0013F915 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = Kerberos5Prefix.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		A1CA623704168DFE0013F915 = {
 			fileRef = A1CA623604168DFE0013F915;
@@ -2319,7 +2901,6 @@
 				F5E59C0F03FD95CF01120114,
 				F51730DE03F1B65801120114,
 				A12536B3040BEC05003D8244,
-				F517320A03F1B65901120114,
 				F517322103F1B65901120114,
 				A198BBE10406D04A00120114,
 				F51736C803F1B65B01120114,
@@ -2328,20 +2909,25 @@
 			name = Sources;
 			path = ../Sources;
 			refType = 2;
+			sourceTree = SOURCE_ROOT;
 		};
 		F517307F03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730DE03F1B65801120114 = {
 			children = (
 				F51730E203F1B65801120114,
 				F51730E303F1B65801120114,
+				A1BBFF1604226DBD00120114,
 				F51730E503F1B65801120114,
 				F51730E603F1B65801120114,
 				F51730E703F1B65801120114,
+				A181DA5405CF0BD800E4C246,
 				F51730E803F1B65801120114,
 				F51730E903F1B65801120114,
 				F51730FB03F1B65801120114,
@@ -2357,42 +2943,55 @@
 			isa = PBXGroup;
 			path = include;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E203F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E303F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = cm.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E503F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "fake-addrinfo.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E603F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = foreachaddr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E703F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "k5-int.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E803F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "k5-util.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730E903F1B65801120114 = {
 			children = (
@@ -2417,120 +3016,153 @@
 			isa = PBXGroup;
 			path = kerberosIV;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730EA03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730EB03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730EC03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = addr_comp.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730ED03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = admin_server.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730EE03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730EF03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = des.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F003F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kadm.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F103F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kdc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F203F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = klog.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F303F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kparse.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F403F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krb.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F503F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krb_db.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F603F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krbports.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F703F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = lsb_addr_cmp.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F803F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730F903F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "mit-copyright.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730FA03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = prot.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730FB03F1B65801120114 = {
 			children = (
 				F51730FF03F1B65801120114,
 				F517310003F1B65801120114,
 				F517310103F1B65801120114,
-				F517310203F1B65801120114,
 				F517310303F1B65801120114,
 				F517310403F1B65801120114,
 				F517310503F1B65801120114,
 				F517310603F1B65801120114,
-				F517310703F1B65801120114,
 				F517310803F1B65801120114,
 				F517310903F1B65801120114,
 				F517310A03F1B65801120114,
@@ -2538,73 +3170,79 @@
 			isa = PBXGroup;
 			path = krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51730FF03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = adm.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310003F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = adm_defs.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310103F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = adm_proto.h;
 			refType = 4;
-		};
-		F517310203F1B65801120114 = {
-			children = (
-			);
-			isa = PBXGroup;
-			path = asn.1;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310303F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310403F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = copyright.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310503F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kdb.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310603F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kdb_dbc.h;
 			refType = 4;
-		};
-		F517310703F1B65801120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = kdb_dbm.h;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310803F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = kdb_kt.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310903F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310A03F1B65801120114 = {
 			children = (
@@ -2615,219 +3253,95 @@
 			isa = PBXGroup;
 			path = stock;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310B03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310C03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310D03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = osconf.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310E03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = krb5.hin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517310F03F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krb54proto.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311003F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311103F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "port-sockets.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311203F1B65801120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "socket-utils.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "spnego-asn1.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = syslog.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517311603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "win-mac.h";
 			refType = 4;
-		};
-		F517320A03F1B65901120114 = {
-			children = (
-				F517320D03F1B65901120114,
-				F517320E03F1B65901120114,
-				F517320F03F1B65901120114,
-				F517321003F1B65901120114,
-				F517321103F1B65901120114,
-				F517321203F1B65901120114,
-				F517321303F1B65901120114,
-				F517321403F1B65901120114,
-				F517321503F1B65901120114,
-				F517321603F1B65901120114,
-				F517321703F1B65901120114,
-				F517321803F1B65901120114,
-				F517321903F1B65901120114,
-				F517321A03F1B65901120114,
-				F517321B03F1B65901120114,
-				F517321C03F1B65901120114,
-				F517321D03F1B65901120114,
-				F517321E03F1B65901120114,
-				F517321F03F1B65901120114,
-				F517322003F1B65901120114,
-			);
-			isa = PBXGroup;
-			path = krb524;
-			refType = 4;
-		};
-		F517320D03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = ChangeLog;
-			refType = 4;
-		};
-		F517320E03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = cnv_tkt_skey.c;
-			refType = 4;
-		};
-		F517320F03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = configure.in;
-			refType = 4;
-		};
-		F517321003F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = conv_creds.c;
-			refType = 4;
-		};
-		F517321103F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = conv_princ.c;
-			refType = 4;
-		};
-		F517321203F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = encode.c;
-			refType = 4;
-		};
-		F517321303F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = getcred.c;
-			refType = 4;
-		};
-		F517321403F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = globals.c;
-			refType = 4;
-		};
-		F517321503F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = k524init.c;
-			refType = 4;
-		};
-		F517321603F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524.def;
-			refType = 4;
-		};
-		F517321703F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524.h;
-			refType = 4;
-		};
-		F517321803F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524_err.et;
-			refType = 4;
-		};
-		F517321903F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524_prot;
-			refType = 4;
-		};
-		F517321A03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = krb524d.c;
-			refType = 4;
-		};
-		F517321B03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = libinit.c;
-			refType = 4;
-		};
-		F517321C03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = Makefile.in;
-			refType = 4;
-		};
-		F517321D03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = misc.c;
-			refType = 4;
-		};
-		F517321E03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = README;
-			refType = 4;
-		};
-		F517321F03F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = sendmsg.c;
-			refType = 4;
-		};
-		F517322003F1B65901120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = test.c;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322103F1B65901120114 = {
 			children = (
@@ -2848,12 +3362,15 @@
 			isa = PBXGroup;
 			path = lib;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322603F1B65901120114 = {
 			children = (
@@ -2893,6 +3410,7 @@
 				F51732B003F1B65901120114,
 				F51732B103F1B65901120114,
 				F51732B203F1B65901120114,
+				A125399205CF12A2003BD89B,
 				F51732B303F1B65901120114,
 				F51732BB03F1B65901120114,
 				F51732C503F1B65901120114,
@@ -2927,18 +3445,23 @@
 			isa = PBXGroup;
 			path = crypto;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322903F1B65901120114 = {
 			children = (
@@ -2969,107 +3492,142 @@
 			isa = PBXGroup;
 			path = aes;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = "aes-gen.c";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = "aes-test.c";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = aes.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = aes.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = aescpp.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517322F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aescrypp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.asm;
 			path = aescrypt.asm;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aescrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aeskey.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aeskeypp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = aesopt.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323503F1B65901120114 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = aessrc.url;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aestab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "expect-vk.txt";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "expect-vt.txt";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323B03F1B65901120114 = {
 			children = (
@@ -3088,88 +3646,117 @@
 			isa = PBXGroup;
 			path = test;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = cbc_d_m.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = cbc_e_m.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_d_m.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517323F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_e_m.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_iv.readme;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_iv.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_tbl.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_vk.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ecb_vt.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324503F1B65901120114 = {
 			isa = PBXFileReference;
+			lastKnownFileType = image.pdf;
 			path = katmct.pdf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Readme.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = uitypes.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = vb.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324903F1B65901120114 = {
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = vbaxam.doc;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324A03F1B65901120114 = {
 			children = (
@@ -3183,96 +3770,127 @@
 			isa = PBXGroup;
 			path = arcfour;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "arcfour-int.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = arcfour.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = arcfour.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517324F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string_to_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = block_size.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = checksum_length.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cksumtype_to_string.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cksumtypes.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = cksumtypes.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = coll_proof_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = combine_keys.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325A03F1B65901120114 = {
 			children = (
@@ -3290,90 +3908,119 @@
 			isa = PBXGroup;
 			path = crc32;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "crc-32.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517325F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = crc.pl;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = CRC.pm;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = crc32.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = Poly.pm;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_crc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = crypto_libinit.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = crypto_libinit.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = decrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = default_state.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326903F1B65901120114 = {
 			children = (
@@ -3404,54 +4051,71 @@
 			isa = PBXGroup;
 			path = des;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = afsstring2key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = d3_cbc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517326F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = d3_kysched.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = des_int.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = destest.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327203F1B65901120114 = {
 			children = (
@@ -3461,101 +4125,134 @@
 			isa = PBXGroup;
 			path = doc;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327403F1B65901120114 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = libdes.doc;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = f_cbc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = f_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = f_parity.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = f_sched.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = f_tables.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = f_tables.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = key_sched.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = keytest.data;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517327F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string2key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_afss2k.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_verify.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = weak_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328303F1B65901120114 = {
 			children = (
@@ -3571,54 +4268,71 @@
 			isa = PBXGroup;
 			path = dk;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = checksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = derive.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = dk.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = dk_decrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = dk_encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = stringtokey.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328C03F1B65901120114 = {
 			children = (
@@ -3633,84 +4347,111 @@
 			isa = PBXGroup;
 			path = enc_provider;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = aes.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = arcfour.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517328F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = des.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = des3.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = enc_provider.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = encrypt_length.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = enctype_compare.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = enctype_to_string.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = etypes.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = etypes.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329A03F1B65901120114 = {
 			children = (
@@ -3725,72 +4466,95 @@
 			isa = PBXGroup;
 			path = hash_provider;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hash_crc32.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hash_md4.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hash_md5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517329F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = hash_provider.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hash_sha1.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hmac.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = keyed_checksum_types.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = keyed_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A603F1B65901120114 = {
 			children = (
@@ -3807,78 +4571,103 @@
 			isa = PBXGroup;
 			path = keyhash_provider;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732A903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = descbc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hmac_md5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AB03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = k5_md4des.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = k5_md5des.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AD03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = keyhash_provider.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AE03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732AF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = make_checksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = make_random_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B303F1B65901120114 = {
 			children = (
@@ -3893,48 +4682,63 @@
 			isa = PBXGroup;
 			path = md4;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732B903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = md4.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "rsa-md4.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BB03F1B65901120114 = {
 			children = (
@@ -3951,66 +4755,87 @@
 			isa = PBXGroup;
 			path = md5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BD03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BE03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732BF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = md5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "rsa-md5.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_mddriver.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = nfold.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C603F1B65901120114 = {
 			children = (
@@ -4024,60 +4849,79 @@
 			isa = PBXGroup;
 			path = old;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = des_stringtokey.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732C903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732CA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = old.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732CB03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = old_decrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732CC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = old_encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732CD03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = old_api_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732CF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = pbkdf2.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prng.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D103F1B65901120114 = {
 			children = (
@@ -4090,36 +4934,47 @@
 			isa = PBXGroup;
 			path = raw;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = raw.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = raw_decrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = raw_encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D803F1B65901120114 = {
 			children = (
@@ -4135,174 +4990,231 @@
 			isa = PBXGroup;
 			path = sha1;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732D903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .cvsignore;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DB03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DD03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = shs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DE03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = shs.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732DF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_shs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_shs3.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = state.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string_to_cksumtype.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string_to_enctype.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string_to_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_cts.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_hmac.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_nfold.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732E903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_pkcs5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732EA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_prng.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732EB03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_prng.comments;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732EC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_prng.expected;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732ED03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_prng.reseedtest;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732EE03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "t_prng.reseedtest-comments";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732EF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "t_prng.reseedtest-expected";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_prng.seed;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = valid_cksumtype.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = valid_enctype.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vectors.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = verify_checksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F503F1B65901120114 = {
 			children = (
@@ -4328,114 +5240,151 @@
 			isa = PBXGroup;
 			path = yarrow;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ASSUMPTIONS;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = LICENSE;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732F903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FA03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = README;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FB03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = TODO;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FC03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = yarrow.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FD03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = yarrow.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FE03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = yarrow.man;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51732FF03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = yarrow.pod;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ycipher.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = ycipher.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = yexcep.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = yhash.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = ylock.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = ystate.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ytest.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = ytypes.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330803F1B65901120114 = {
 			children = (
@@ -4466,168 +5415,223 @@
 			isa = PBXGroup;
 			path = des425;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = des.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517330F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = enc_dec.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = key_parity.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = key_sched.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = new_rnd_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = pcbc_encrypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = quad_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = random_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = read_passwd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = str_to_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = string2key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_pcbc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_quad.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unix_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517331F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = verify.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = weak_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = exports.crypto;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = exports.des425;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = exports.kdb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = exports.krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = glue4.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332603F1B65901120114 = {
 			children = (
@@ -4643,12 +5647,15 @@
 			isa = PBXGroup;
 			path = gssapi;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332A03F1B65901120114 = {
 			children = (
@@ -4677,144 +5684,191 @@
 			isa = PBXGroup;
 			path = generic;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = disp_com_err_status.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517332F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = disp_major_status.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = gssapi.hin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = gssapi_err_generic.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gssapi_generic.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = gssapi_generic.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = gssapiP_generic.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = oid_ops.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rel_buffer.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rel_oid_set.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_buffer.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_canonhost.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_localhost.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_oid.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_ordering.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_set.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517333F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_token.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_validate.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = utl_nohash_validate.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gss_libinit.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = gss_libinit.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334403F1B65901120114 = {
 			children = (
@@ -4846,6 +5900,7 @@
 				F517336003F1B65901120114,
 				F517336103F1B65901120114,
 				F517336203F1B65901120114,
+				A125397605CF124D003BD89B,
 				F517336303F1B65901120114,
 				F517336403F1B65901120114,
 				F517336503F1B65901120114,
@@ -4869,294 +5924,391 @@
 			isa = PBXGroup;
 			path = krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = 3des.txt;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = accept_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = acquire_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = add_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = canon_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = compare_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = context_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517334F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_ccache.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = delete_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = disp_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = disp_status.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = duplicate_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = export_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = export_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = get_tkt_flags.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = gssapi_err_krb5.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gssapi_krb5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = gssapi_krb5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = gssapiP_krb5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = import_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = import_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = indicate_mechs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517335F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = inq_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = inq_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = inq_names.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = k5seal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = k5unseal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = krb5_gss_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = process_context_token.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336703F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rel_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336803F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rel_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336903F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rel_oid.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336A03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = seal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336B03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_sctx.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336C03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = set_ccache.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336D03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sign.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336E03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unseal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517336F03F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337003F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_crypt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337103F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_seed.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337203F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = util_seqnum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337303F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = val_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337403F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = verify.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337503F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = wrap_size_limit.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337603F1B65901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337703F1B65A01120114 = {
 			children = (
@@ -5201,234 +6353,311 @@
 			isa = PBXGroup;
 			path = mechglue;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = .Sanitize;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_accept_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_acquire_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_compare_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_context_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_delete_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517337F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_dsp_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_dsp_status.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_exp_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_imp_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_imp_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_indicate_mechs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_init_sec_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_initialize.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_inq_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_inq_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_inq_names.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_mechname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_oid_ops.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_process_context.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_rel_buffer.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517338F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_rel_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_rel_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_rel_oid_set.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_seal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_sign.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_unseal.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_verify.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gen_oids.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gssd_pname_to_uid.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = mech.conf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = mechglue.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = mglueP.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = oid_ops.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517339D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = README_SAMPLE_APP;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342003F1B65A01120114 = {
 			children = (
@@ -5541,635 +6770,846 @@
 			isa = PBXGroup;
 			path = krb4;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ad_print.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = "CCache-glue.c";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = change_password.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cr_auth_repl.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cr_ciph.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cr_death_pkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cr_err_repl.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cr_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = debug.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = decomp_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517342F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = dest_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = err_txt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = fakeenv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = fgetst.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = "FSp-glue.c";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_ad_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_cnffile.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_in_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_phost.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_pw_in_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_pw_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_svc_in_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_tf_fname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_tf_realm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = g_tkt_svc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517343F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gethostname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = getst.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = in_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kadm_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_net.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kadm_stream.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = klog.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kname_parse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kntoln.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kparse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krb4int.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = krb_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kuserok.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = lifetime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = log.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mac_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517344F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mac_store.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = mac_store.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mac_stubs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mac_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = macsock.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = memcache.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = memcache.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_auth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_preauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_priv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_req.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_safe.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = month_sname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = netread.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517345F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = netwrite.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = Password.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = password_to_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = pkt_cipher.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = pkt_clen.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prot_client.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prot_common.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prot_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = put_svc_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_preauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_priv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_req.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_safe.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_svc_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = "RealmsConfig-glue.c";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517346F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = recvauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "ren-cyg.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "ren-pc.bat";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "ren-pc.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "ren-pl10.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ren.msg;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = ren2dos.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = ren2long.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = save_creds.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "sed-cyg.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "sed-pc.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "sed-pl10.sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = send_to_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sendauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = setenv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = stime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517347F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strcasecmp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strnlen.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = swab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tf_shm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tf_util.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tkt_string.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unix_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unix_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348703F1B65A01120114 = {
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = vmslink.com;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vmsswab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = win_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = win_store.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = win_time.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517348E03F1B65A01120114 = {
 			children = (
@@ -6190,6 +7630,7 @@
 			isa = PBXGroup;
 			path = krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349003F1B65A01120114 = {
 			children = (
@@ -6220,144 +7661,191 @@
 			isa = PBXGroup;
 			path = asn.1;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_decode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_decode.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_encode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_encode.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_get.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_get.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_k_decode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_k_decode.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_k_encode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_k_encode.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_make.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517349F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_make.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1_misc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1_misc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = asn1buf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1buf.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = asn1glue.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.python;
 			path = "KRB5-asn.py";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = krb5_decode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = krb5_encode.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734A903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krbasn1.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734AA03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734AB03F1B65A01120114 = {
 			children = (
@@ -6386,24 +7874,31 @@
 			isa = PBXGroup;
 			path = ccache;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734AE03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cc_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734AF03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cc_memory.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cc_retr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B103F1B65A01120114 = {
 			children = (
@@ -6419,96 +7914,127 @@
 			isa = PBXGroup;
 			path = ccapi;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = stdcc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = stdcc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = stdcc_util.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = stdcc_util.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = winccld.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734B903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = winccld.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BA03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ccbase.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BB03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cccopy.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BC03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ccdefault.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BD03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ccdefops.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BE03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ccfns.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734BF03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = fcc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C103F1B65A01120114 = {
 			children = (
@@ -6516,12 +8042,15 @@
 			isa = PBXGroup;
 			path = file;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C303F1B65A01120114 = {
 			children = (
@@ -6529,18 +8058,23 @@
 			isa = PBXGroup;
 			path = memory;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = scc.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_cc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C603F1B65A01120114 = {
 			children = (
@@ -6548,42 +8082,55 @@
 			isa = PBXGroup;
 			path = stdio;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_cc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734C903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_memory.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734CA03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_stdio.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734CB03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734CC03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734CD03F1B65A01120114 = {
 			children = (
@@ -6591,6 +8138,7 @@
 				F51734D203F1B65A01120114,
 				F51734D303F1B65A01120114,
 				F51734D403F1B65A01120114,
+				A16DA36A0485503F00120112,
 				F51734D503F1B65A01120114,
 				F51734D603F1B65A01120114,
 				F51734D703F1B65A01120114,
@@ -6598,48 +8146,63 @@
 			isa = PBXGroup;
 			path = error_tables;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = asn1_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_ets.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kdb5_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = krb5_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = kv5m_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734D903F1B65A01120114 = {
 			children = (
@@ -6658,72 +8221,95 @@
 			isa = PBXGroup;
 			path = keytab;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734DB03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734DE03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kt_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734DF03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kt_srvtab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktadd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktbase.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktdefault.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktfns.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktfr_entry.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktremove.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = read_servi.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734E903F1B65A01120114 = {
 			children = (
@@ -6740,6 +8326,7 @@
 				F51734F603F1B65A01120114,
 				F51734F703F1B65A01120114,
 				F51734F803F1B65A01120114,
+				A16DA36604854EF700120112,
 				F51734F903F1B65A01120114,
 				F51734FA03F1B65A01120114,
 				F51734FB03F1B65A01120114,
@@ -6768,8 +8355,6 @@
 				F517351203F1B65A01120114,
 				F517351303F1B65A01120114,
 				F517351403F1B65A01120114,
-				F517351503F1B65A01120114,
-				F517351603F1B65A01120114,
 				F517351703F1B65A01120114,
 				F517351803F1B65A01120114,
 				F517351903F1B65A01120114,
@@ -6824,6 +8409,7 @@
 				F517354A03F1B65A01120114,
 				F517354B03F1B65A01120114,
 				F517354C03F1B65A01120114,
+				A16DA36704854EF700120112,
 				F517354D03F1B65A01120114,
 				F517354E03F1B65A01120114,
 				F517354F03F1B65A01120114,
@@ -6833,636 +8419,831 @@
 			isa = PBXGroup;
 			path = krb;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734EC03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = addr_comp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734ED03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = addr_order.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734EE03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = addr_srch.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734EF03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = appdefault.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = auth_con.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = auth_con.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = bld_pr_ext.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = bld_princ.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = brand.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = chk_trans.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = chpw.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = cleanup.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734F903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = conv_princ.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FA03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_addrs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FB03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_athctr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FC03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_auth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FD03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FE03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_creds.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51734FF03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_data.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_princ.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = copy_tick.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = cp_key_cnt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = decode_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = decrypt_tk.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = deltat.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = enc_helper.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = encode_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = encrypt_tk.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = free_rtree.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = fwd_tgt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gc_frm_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gc_via_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gen_seqnum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517350F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gen_subkey.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = get_creds.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = get_in_tkt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gic_keytab.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gic_opt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gic_pwd.c;
 			refType = 4;
-		};
-		F517351503F1B65A01120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = in_tkt_ktb.c;
-			refType = 4;
-		};
-		F517351603F1B65A01120114 = {
-			fileEncoding = 30;
-			isa = PBXFileReference;
-			path = in_tkt_pwd.c;
-			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = in_tkt_sky.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_ctx.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_keyblock.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "int-proto.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kdc_rep_dc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kfree.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517351F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_error.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_priv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_rep.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_req.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_req_ext.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_safe.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = parse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = pr_to_salt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = preauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = preauth2.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = princ_comp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_cred.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_error.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_priv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_rep.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_req.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517352F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_req_dec.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rd_safe.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = recvauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = send_tgs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sendauth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_actx.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_adata.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_addr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_auth.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_cksum.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_ctx.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_eblk.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_key.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_princ.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = serialize.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = set_realm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517353F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = srv_rcache.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = str_conv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strftime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strptime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_deltat.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_expand.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_kerb.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_krb5.conf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = t_ref_kerb.out;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_ser.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_walk_rtree.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = tgtname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "transit-tests";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unparse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = valid_times.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vfy_increds.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517354F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vic_opt.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = walk_rtree.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.yacc;
 			path = "x-deltat.y";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = krb5_libinit.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = krb5_libinit.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355503F1B65A01120114 = {
 			children = (
@@ -7473,6 +9254,7 @@
 				F517355C03F1B65A01120114,
 				F517355D03F1B65A01120114,
 				F517355E03F1B65A01120114,
+				A12539AD05CF12D5003BD89B,
 				F517355F03F1B65A01120114,
 				F517356003F1B65A01120114,
 				F517356103F1B65A01120114,
@@ -7505,6 +9287,7 @@
 				F517357C03F1B65A01120114,
 				F517357D03F1B65A01120114,
 				F517357E03F1B65A01120114,
+				A16DB01304868A7E00120112,
 				F517357F03F1B65A01120114,
 				F517358003F1B65A01120114,
 				F517358103F1B65A01120114,
@@ -7521,312 +9304,415 @@
 			isa = PBXGroup;
 			path = os;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = accessor.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = an_to_ln.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = c_ustime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ccdefname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = changepw.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = def_realm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517355F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = free_hstrl.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = free_krbhs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = full_ipadr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gen_port.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gen_rname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = genaddrs.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = get_krbhst.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = gmt_mktime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hostaddr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = hst_realm.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_os_ctx.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = krbfileio.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ktdefname.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = kuserok.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = localaddr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = locate_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517356F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = lock_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = mk_faddr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = net_read.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = net_write.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "os-proto.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = osconfig.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = port2ip.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prompter.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = promptusr.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = read_msg.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = read_pwd.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357B03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = realm_dom.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357C03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = realm_iter.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ref_std_conf.out;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sendto_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517357F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sn2princ.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_an_to_ln.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_gifconf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_locate_kdc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_realm_iter.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_std_conf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = td_krb5.conf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = timeofday.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = toffset.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = unlck_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ustime.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = write_msg.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358B03F1B65A01120114 = {
 			children = (
@@ -7848,90 +9734,119 @@
 			isa = PBXGroup;
 			path = posix;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358D03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = daemon.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517358F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = getuid.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = memmove.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "pos-obsolete.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = setenv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = sscanf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strcasecmp.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strdup.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = strerror.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = syslog.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vfprintf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359A03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vsprintf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359B03F1B65A01120114 = {
 			children = (
@@ -7953,102 +9868,135 @@
 			isa = PBXGroup;
 			path = rcache;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359E03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517359F03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A003F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rc_base.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = rc_base.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A203F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rc_conv.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A303F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rc_dfl.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A403F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = rc_dfl.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A503F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rc_io.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A603F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = rc_io.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A703F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rcdef.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A803F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = rcfns.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735A903F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = README;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735AA03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = RELEASE;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735AB03F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = ser_rc.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51735B103F1B65A01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517360C03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = win_glue.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51736C803F1B65B01120114 = {
 			children = (
@@ -8059,12 +10007,15 @@
 			isa = PBXGroup;
 			path = util;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51736DD03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737AF03F1B65B01120114 = {
 			children = (
@@ -8096,144 +10047,191 @@
 			isa = PBXGroup;
 			path = profile;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B203F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = argv_parse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B303F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = argv_parse.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B403F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B603F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = dosshell.ini;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B703F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = krb5.conf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B803F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737B903F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = prof_err.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BA03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_file.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BB03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_get.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BC03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_init.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BD03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = prof_int.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BE03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_parse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737BF03F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_set.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C003F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = prof_tree.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C103F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = profile.5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C203F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = profile.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C303F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = profile.hin;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C403F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = profile.pbexp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C503F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = prtest.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C603F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = prtest.script;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C703F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = test.ini;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C803F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = test_parse.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F51737C903F1B65B01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = test_profile.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F517388E03F1B8BD01120114 = {
 			fileRef = F517355203F1B65A01120114;
@@ -8721,12 +10719,6 @@
 			settings = {
 			};
 		};
-		F51738E403F1BA7F01120114 = {
-			fileRef = F517310D03F1B65801120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 		F51738E503F1BAF701120114 = {
 			fileRef = F51734DE03F1B65A01120114;
 			isa = PBXBuildFile;
@@ -9015,18 +11007,6 @@
 			settings = {
 			};
 		};
-		F517391603F1BB2901120114 = {
-			fileRef = F517351503F1B65A01120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F517391703F1BB2A01120114 = {
-			fileRef = F517351603F1B65A01120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 		F517391803F1BB2B01120114 = {
 			fileRef = F517351703F1B65A01120114;
 			isa = PBXBuildFile;
@@ -9759,18 +11739,6 @@
 			settings = {
 			};
 		};
-		F58183510253A2F201120112 = {
-			fileRef = F5C2DF200240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F58183520253A2F301120112 = {
-			fileRef = F5C2DF210240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 		F5C2DF100240F9F601650119 = {
 			children = (
 				F5C2DF140240F9F601650119,
@@ -9807,239 +11775,207 @@
 			isa = PBXGroup;
 			path = ErrorTables;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF140240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = asn1_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF150240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = asn1_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF160240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = asn1_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF170240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_generic.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF180240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_generic.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF190240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_generic.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1A0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_krb5.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1B0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_krb5.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1C0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = gssapi_err_krb5.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1D0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kdb5_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1E0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kdb5_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF1F0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kdb5_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF200240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb524_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF210240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb524_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF220240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb524_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF230240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb5_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF240240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb5_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF250240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb5_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF260240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kv5m_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF270240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kv5m_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF280240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kv5m_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF290240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = prof_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF2A0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = prof_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5C2DF2B0240F9F601650119 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = prof_err.strings;
 			refType = 4;
-		};
-		F5C2DF2E0240F9F601650119 = {
-			fileRef = F5C2DF140240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF2F0240F9F601650119 = {
-			fileRef = F5C2DF150240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF340240F9F601650119 = {
-			fileRef = F5C2DF1D0240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF350240F9F601650119 = {
-			fileRef = F5C2DF1E0240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF380240F9F601650119 = {
-			fileRef = F5C2DF230240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF390240F9F601650119 = {
-			fileRef = F5C2DF240240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF3A0240F9F601650119 = {
-			fileRef = F5C2DF260240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF3B0240F9F601650119 = {
-			fileRef = F5C2DF270240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF3E0240F9FC01650119 = {
-			fileRef = F5C2DF290240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF3F0240F9FD01650119 = {
-			fileRef = F5C2DF2A0240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF420240FA1301650119 = {
-			fileRef = F5C2DF1B0240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF430240FA1401650119 = {
-			fileRef = F5C2DF1A0240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF440240FA1501650119 = {
-			fileRef = F5C2DF180240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5C2DF450240FA1601650119 = {
-			fileRef = F5C2DF170240F9F601650119;
-			isa = PBXBuildFile;
-			settings = {
-			};
+			sourceTree = "<group>";
 		};
 		F5C44E900231BD6801120112 = {
+			explicitFileType = "compiled.mach-o.dylib";
+			fallbackIsa = PBXFileReference;
 			isa = PBXLibraryReference;
 			path = libGSS.a;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5C44E910231BD6801120112 = {
 			buildPhases = (
@@ -10072,8 +12008,6 @@
 		F5C44E920231BD6801120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF420240FA1301650119,
-				F5C2DF440240FA1501650119,
 				F517395503F1BC9701120114,
 				F517395A03F1BCAB01120114,
 				F517397703F1BCCF01120114,
@@ -10086,8 +12020,6 @@
 		F5C44E9C0231BD6801120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF430240FA1401650119,
-				F5C2DF450240FA1601650119,
 				F517395403F1BC9601120114,
 				F517395603F1BCA801120114,
 				F517395703F1BCA801120114,
@@ -10142,6 +12074,7 @@
 				F517399003F1BCE701120114,
 				F517399103F1BCE801120114,
 				F517399203F1BCE801120114,
+				A125397705CF124E003BD89B,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -10163,12 +12096,16 @@
 		F5C44EE80231CEA101120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD629022D922C01120112;
+			targetProxy = A181DA4005CEFC0400E4C246;
 		};
 		F5C44EE90231CEA101120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5E6022D8A9901120112;
+			targetProxy = A181DA4105CEFC0400E4C246;
 		};
 		F5CFD36E022D854401120112 = {
+			buildSettings = {
+			};
 			buildStyles = (
 				F5CFD370022D854401120112,
 				F5CFD371022D854401120112,
@@ -10203,12 +12140,18 @@
 			);
 			isa = PBXGroup;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5CFD370022D854401120112 = {
 			buildRules = (
 			);
 			buildSettings = {
 				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				ZERO_LINK = YES;
 			};
 			isa = PBXBuildStyle;
 			name = Development;
@@ -10218,6 +12161,8 @@
 			);
 			buildSettings = {
 				COPY_PHASE_STRIP = YES;
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				ZERO_LINK = NO;
 			};
 			isa = PBXBuildStyle;
 			name = Deployment;
@@ -10233,11 +12178,15 @@
 			isa = PBXGroup;
 			name = Products;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5CFD5CC022D86AD01120112 = {
+			explicitFileType = "compiled.mach-o.dylib";
+			fallbackIsa = PBXFileReference;
 			isa = PBXLibraryReference;
 			path = libKerberosProfile.a;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5CFD5CD022D86AD01120112 = {
 			buildPhases = (
@@ -10270,7 +12219,6 @@
 		F5CFD5CE022D86AD01120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF3F0240F9FD01650119,
 				F517399703F1BD1301120114,
 				F5E266F803F4443301120114,
 				F5E266F903F4443301120114,
@@ -10281,7 +12229,6 @@
 		F5CFD5CF022D86AD01120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF3E0240F9FC01650119,
 				F517399403F1BD1201120114,
 				F517399503F1BD1201120114,
 				F517399603F1BD1301120114,
@@ -10317,12 +12264,15 @@
 			name = Scripts;
 			path = ../Scripts;
 			refType = 2;
+			sourceTree = SOURCE_ROOT;
 		};
 		F5CFD5E5022D891701120112 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.jam;
 			path = Kerberos5Errors.jam;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5CFD5E6022D8A9901120112 = {
 			buildArgumentsString = "-d3 \"-sJAMFILE=$(SRCROOT)/../Scripts/Kerberos5Errors.jam\" $(ACTION)";
@@ -10339,25 +12289,27 @@
 			name = "Error Table Generation";
 			passBuildSettingsInEnvironment = 1;
 			productName = "Error Table Generation";
-			settingsToExpand = 6;
-			settingsToPassInEnvironment = 287;
-			settingsToPassOnCommandLine = 280;
 		};
 		F5CFD5E7022D8A9901120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5E6022D8A9901120112;
+			targetProxy = A181DA4B05CEFC0400E4C246;
 		};
 		F5CFD5EC022D8B6001120112 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = GSS.pbexp;
 			refType = 2;
+			sourceTree = SOURCE_ROOT;
 		};
 		F5CFD5ED022D8B6001120112 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Kerberos5.pbexp;
 			refType = 2;
+			sourceTree = SOURCE_ROOT;
 		};
 		F5CFD5EE022D8B6001120112 = {
 			children = (
@@ -10370,13 +12322,16 @@
 			isa = PBXGroup;
 			path = Kerberos5.intermediates;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5CFD60D022D8BD601120112 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.jam;
 			lineEnding = 0;
 			path = Kerberos5Headers.jam;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5CFD629022D922C01120112 = {
 			buildArgumentsString = "-d3 \"-sJAMFILE=$(SRCROOT)/../Scripts/Kerberos5Headers.jam\" $(ACTION)";
@@ -10395,22 +12350,24 @@
 			name = "Header Generation";
 			passBuildSettingsInEnvironment = 1;
 			productName = "Header Generation";
-			settingsToExpand = 6;
-			settingsToPassInEnvironment = 287;
-			settingsToPassOnCommandLine = 280;
 		};
 		F5CFD62A022D922C01120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5E6022D8A9901120112;
+			targetProxy = A181DA3F05CEFC0400E4C246;
 		};
 		F5CFD62B022D922C01120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD629022D922C01120112;
+			targetProxy = A181DA4A05CEFC0400E4C246;
 		};
 		F5CFD638022DD45401120112 = {
+			explicitFileType = "compiled.mach-o.dylib";
+			fallbackIsa = PBXFileReference;
 			isa = PBXLibraryReference;
 			path = libKerberos5.a;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5CFD639022DD45401120112 = {
 			buildPhases = (
@@ -10444,11 +12401,6 @@
 		F5CFD63A022DD45401120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF2F0240F9F601650119,
-				F5C2DF350240F9F601650119,
-				F5C2DF390240F9F601650119,
-				F5C2DF3B0240F9F601650119,
-				F58183520253A2F301120112,
 				F517388F03F1B8BE01120114,
 				F51738AA03F1B96401120114,
 				F51738BE03F1B9B001120114,
@@ -10466,7 +12418,6 @@
 				F51738DE03F1BA2701120114,
 				F51738DF03F1BA2701120114,
 				F51738E303F1BA7501120114,
-				F51738E403F1BA7F01120114,
 				F51738F303F1BB1701120114,
 				F51738F903F1BB1A01120114,
 				F517391B03F1BB2D01120114,
@@ -10500,6 +12451,7 @@
 				A1CA60A4040F25DD0013F915,
 				A1CA60A5040F25DE0013F915,
 				A1B21F1A0417D6BC00120114,
+				A181DA5505CF0BD800E4C246,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -10507,11 +12459,6 @@
 		F5CFD63B022DD45401120112 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5C2DF2E0240F9F601650119,
-				F5C2DF340240F9F601650119,
-				F5C2DF380240F9F601650119,
-				F5C2DF3A0240F9F601650119,
-				F58183510253A2F201120112,
 				F517388E03F1B8BD01120114,
 				F517389003F1B90D01120114,
 				F517389103F1B90E01120114,
@@ -10622,8 +12569,6 @@
 				F517391303F1BB2801120114,
 				F517391403F1BB2801120114,
 				F517391503F1BB2901120114,
-				F517391603F1BB2901120114,
-				F517391703F1BB2A01120114,
 				F517391803F1BB2B01120114,
 				F517391903F1BB2B01120114,
 				F517391A03F1BB2C01120114,
@@ -10678,14 +12623,6 @@
 				F517395103F1BC4E01120114,
 				F517395203F1BC4E01120114,
 				F517395303F1BC5101120114,
-				F5E2670B03F4730501120114,
-				F5E2670C03F4730701120114,
-				F5E2670D03F4730901120114,
-				F5E2670E03F4730B01120114,
-				F5E2670F03F4731401120114,
-				F5E2671003F4731B01120114,
-				F5E2671103F4732801120114,
-				F5E2671203F4732A01120114,
 				A1CA6042040F24850013F915,
 				A1CA6043040F24870013F915,
 				A1CA6044040F24880013F915,
@@ -10761,6 +12698,11 @@
 				A1CA609D040F25D40013F915,
 				A1CA609F040F25D70013F915,
 				A1B21F190417D6BC00120114,
+				A16DA36804854EF700120112,
+				A16DA36904854EF700120112,
+				A16DB01404868A7E00120112,
+				A125399305CF12A2003BD89B,
+				A12539AE05CF12D5003BD89B,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -10782,10 +12724,12 @@
 		F5CFD7D8022DE82501120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5E6022D8A9901120112;
+			targetProxy = A181DA4805CEFC0400E4C246;
 		};
 		F5CFD7D9022DE82501120112 = {
 			isa = PBXTargetDependency;
 			target = F5CFD629022D922C01120112;
+			targetProxy = A181DA4305CEFC0400E4C246;
 		};
 		F5E265DF03F443E901120114 = {
 			children = (
@@ -10794,6 +12738,7 @@
 			isa = PBXGroup;
 			path = build;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2662703F443E901120114 = {
 			children = (
@@ -10802,6 +12747,7 @@
 			isa = PBXGroup;
 			path = include;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2662C03F443E901120114 = {
 			children = (
@@ -10811,24 +12757,31 @@
 			isa = PBXGroup;
 			path = krb5;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2662D03F443E901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = autoconf.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2662F03F443E901120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = osconf.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E266F503F443EA01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = configure.stamp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E266F603F4442A01120114 = {
 			fileRef = F5E2662D03F443E901120114;
@@ -10866,89 +12819,53 @@
 			settings = {
 			};
 		};
-		F5E2670B03F4730501120114 = {
-			fileRef = F517321003F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2670C03F4730701120114 = {
-			fileRef = F517321103F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2670D03F4730901120114 = {
-			fileRef = F517320E03F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2670E03F4730B01120114 = {
-			fileRef = F517321203F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2670F03F4731401120114 = {
-			fileRef = F517321403F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2671003F4731B01120114 = {
-			fileRef = F517321B03F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2671103F4732801120114 = {
-			fileRef = F517321F03F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2671203F4732A01120114 = {
-			fileRef = F517321D03F1B65901120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 		F5E2671F03F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kadm_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2672003F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kadm_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2672103F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = kadm_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2672203F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2672303F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2672403F8200601120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = file;
 			path = krb_err.strings;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E2686803F8336601120114 = {
 			buildActionMask = 2147483647;
@@ -11021,9 +12938,12 @@
 			productReference = F5E2686D03F8336601120114;
 		};
 		F5E2686D03F8336601120114 = {
+			explicitFileType = "compiled.mach-o.dylib";
+			fallbackIsa = PBXFileReference;
 			isa = PBXLibraryReference;
 			path = libKerberosDES.a;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5E2686E03F833E001120114 = {
 			fileRef = F517332003F1B65901120114;
@@ -11106,7 +13026,6 @@
 		F5E2688003F83E7D01120114 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5E2689C03F8423F01120114,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -11114,7 +13033,6 @@
 		F5E2688103F83E7D01120114 = {
 			buildActionMask = 2147483647;
 			files = (
-				F5E2689B03F8423E01120114,
 				F5E268A503F8428101120114,
 				F5E268A603F8428301120114,
 				F5E268A703F8428401120114,
@@ -11217,33 +13135,27 @@
 			productReference = F5E2688503F83E7D01120114;
 		};
 		F5E2688503F83E7D01120114 = {
+			explicitFileType = "compiled.mach-o.dylib";
+			fallbackIsa = PBXFileReference;
 			isa = PBXLibraryReference;
 			path = libKerberos4.a;
 			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 		F5E2688703F8404801120114 = {
 			isa = PBXTargetDependency;
 			target = F5CFD5CD022D86AD01120112;
+			targetProxy = A181DA4405CEFC0400E4C246;
 		};
 		F5E2688803F8404F01120114 = {
 			isa = PBXTargetDependency;
 			target = F5E2686C03F8336601120114;
+			targetProxy = A181DA4505CEFC0400E4C246;
 		};
 		F5E2688903F8405301120114 = {
 			isa = PBXTargetDependency;
 			target = F5E2686C03F8336601120114;
-		};
-		F5E2689B03F8423E01120114 = {
-			fileRef = F5E2671F03F8200601120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F5E2689C03F8423F01120114 = {
-			fileRef = F5E2672003F8200601120114;
-			isa = PBXBuildFile;
-			settings = {
-			};
+			targetProxy = A181DA4905CEFC0400E4C246;
 		};
 		F5E268A503F8428101120114 = {
 			fileRef = F517345A03F1B65A01120114;
@@ -11506,8 +13418,10 @@
 		F5E59BD403FD7D5301120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.jam;
 			path = Kerberos5ServerBuild.jam;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BD503FD803201120114 = {
 			buildArgumentsString = "-d3 \"-sJAMFILE=$(SRCROOT)/../Scripts/Kerberos5ServerBuild.jam\" $(ACTION)";
@@ -11524,9 +13438,6 @@
 			name = ServerBuild;
 			passBuildSettingsInEnvironment = 1;
 			productName = ServerBuild;
-			settingsToExpand = 6;
-			settingsToPassInEnvironment = 287;
-			settingsToPassOnCommandLine = 280;
 		};
 		F5E59BD603FD832C01120114 = {
 			children = (
@@ -11570,234 +13481,312 @@
 			isa = PBXGroup;
 			path = et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BD903FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDA03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = com_err.3;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDB03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = com_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDC03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = com_err.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDD03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = com_err.texinfo;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDE03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.man;
 			path = compile_et.1;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BDF03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = compile_et.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE003FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = compile_et.sh;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE103FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = compiler.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE203FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = config_script;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE303FD832C01120114 = {
+			fallbackIsa = PBXFileReference;
 			fileEncoding = 30;
 			isa = PBXExecutableFileReference;
+			lastKnownFileType = text.script.sh;
 			path = configure;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE403FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE503FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = error_message.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE603FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = error_table.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE703FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.yacc;
 			path = error_table.y;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE803FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.exports;
 			path = et.exp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BE903FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = et.pbexp;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BEA03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = et1.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BEB03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = et2.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BEC03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = et_c.awk;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BED03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = et_c.pl;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BEE03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = et_h.awk;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BEF03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.perl;
 			path = et_h.pl;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF003FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.lex;
 			path = et_lex.lex.l;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF103FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = et_name.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF203FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = init_et.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF303FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = internal.h;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF403FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ISSUES;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF503FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = Makefile.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF603FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
 			path = "mit-sipb-copyright.h";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF703FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = t_com_err.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF803FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = test1.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BF903FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = test2.et;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BFA03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = test_et.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BFB03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = texinfo.tex;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59BFC03FD832C01120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.c;
 			path = vfprintf.c;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C0D03FD95A101120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = aclocal.m4;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C0E03FD95A101120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = configure.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C0F03FD95CF01120114 = {
 			children = (
@@ -11827,138 +13816,183 @@
 			isa = PBXGroup;
 			path = config;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1103FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ChangeLog;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1203FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = config.guess;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1303FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = config.sub;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1503FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "install-sh";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1603FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = lib.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1703FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = libobj.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1803FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "mac-config.cache";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1903FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "mac-config.README";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1A03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "mac-mf.sed";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1B03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "mac-post.in";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1C03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "mac-pre.in";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1D03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = mkinstalldirs;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1E03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = "move-if-changed";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C1F03FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = post.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2003FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = pre.in;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2103FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text.script.sh;
 			path = ren2long;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2203FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = ren2long.awk;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2303FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = rm.bat;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2403FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = shlib.conf;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2503FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "win-post.in";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2603FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = "win-pre.in";
 			refType = 4;
+			sourceTree = "<group>";
 		};
 		F5E59C2703FD95D001120114 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
+			lastKnownFileType = text;
 			path = winexclude.sed;
 			refType = 4;
+			sourceTree = "<group>";
 		};
 	};
 	rootObject = F5CFD36E022D854401120112;
diff --git a/src/mac/MacOSX/Scripts/Kerberos5Errors.jam b/src/mac/MacOSX/Scripts/Kerberos5Errors.jam
index 9f7ce57dd..dfa3e8acb 100644
--- a/src/mac/MacOSX/Scripts/Kerberos5Errors.jam
+++ b/src/mac/MacOSX/Scripts/Kerberos5Errors.jam
@@ -3,55 +3,55 @@ include "$(SRCROOT)/../../KerberosErrors/Scripts/compile_et.jam" ;
 Intermediates = "$(BUILT_PRODUCTS_DIR)/Kerberos5.intermediates" ;
 IntermediateErrorTables = "$(Intermediates)/ErrorTables" ;
 
-compile_et 	"$(IntermediateErrorTables)/prof_err.h"
+compile_et  "$(IntermediateErrorTables)/prof_err.h"
             "$(IntermediateErrorTables)/prof_err.c"
             "$(IntermediateErrorTables)/prof_err.strings" : 
-            "$(SRCROOT)/../Sources/util/profile/prof_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/util/profile/prof_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/krb_err.h"
+compile_et  "$(IntermediateErrorTables)/krb_err.h"
             "$(IntermediateErrorTables)/krb_err.c"
             "$(IntermediateErrorTables)/krb_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb4/krb_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb4/krb_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/kadm_err.h"
+compile_et  "$(IntermediateErrorTables)/kadm_err.h"
             "$(IntermediateErrorTables)/kadm_err.c"
             "$(IntermediateErrorTables)/kadm_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb4/kadm_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb4/kadm_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/krb524_err.h"
+compile_et  "$(IntermediateErrorTables)/krb524_err.h"
             "$(IntermediateErrorTables)/krb524_err.c"
             "$(IntermediateErrorTables)/krb524_err.strings" : 
-            "$(SRCROOT)/../Sources/krb524/krb524_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb5/error_tables/krb524_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/asn1_err.h"
+compile_et  "$(IntermediateErrorTables)/asn1_err.h"
             "$(IntermediateErrorTables)/asn1_err.c"
             "$(IntermediateErrorTables)/asn1_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb5/error_tables/asn1_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb5/error_tables/asn1_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/kdb5_err.h"
+compile_et  "$(IntermediateErrorTables)/kdb5_err.h"
             "$(IntermediateErrorTables)/kdb5_err.c"
             "$(IntermediateErrorTables)/kdb5_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb5/error_tables/kdb5_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb5/error_tables/kdb5_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/krb5_err.h"
+compile_et  "$(IntermediateErrorTables)/krb5_err.h"
             "$(IntermediateErrorTables)/krb5_err.c"
             "$(IntermediateErrorTables)/krb5_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb5/error_tables/krb5_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb5/error_tables/krb5_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/kv5m_err.h"
+compile_et  "$(IntermediateErrorTables)/kv5m_err.h"
             "$(IntermediateErrorTables)/kv5m_err.c"
             "$(IntermediateErrorTables)/kv5m_err.strings" : 
-            "$(SRCROOT)/../Sources/lib/krb5/error_tables/kv5m_err.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/krb5/error_tables/kv5m_err.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/gssapi_err_generic.h"
+compile_et  "$(IntermediateErrorTables)/gssapi_err_generic.h"
             "$(IntermediateErrorTables)/gssapi_err_generic.c"
             "$(IntermediateErrorTables)/gssapi_err_generic.strings" : 
-            "$(SRCROOT)/../Sources/lib/gssapi/generic/gssapi_err_generic.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/gssapi/generic/gssapi_err_generic.et" ;
 
-compile_et 	"$(IntermediateErrorTables)/gssapi_err_krb5.h"
+compile_et  "$(IntermediateErrorTables)/gssapi_err_krb5.h"
             "$(IntermediateErrorTables)/gssapi_err_krb5.c"
             "$(IntermediateErrorTables)/gssapi_err_krb5.strings" : 
-            "$(SRCROOT)/../Sources/lib/gssapi/krb5/gssapi_err_krb5.et" ;
+            "$(SRCROOT)/../../Kerberos5/Sources/lib/gssapi/krb5/gssapi_err_krb5.et" ;
                         
 DEPENDS all :	"$(IntermediateErrorTables)/prof_err.h"
                 "$(IntermediateErrorTables)/prof_err.c"
diff --git a/src/mac/MacOSX/Scripts/Kerberos5Headers.jam b/src/mac/MacOSX/Scripts/Kerberos5Headers.jam
index 02bc57a06..de62e18c6 100644
--- a/src/mac/MacOSX/Scripts/Kerberos5Headers.jam
+++ b/src/mac/MacOSX/Scripts/Kerberos5Headers.jam
@@ -59,8 +59,6 @@ actions MakeFrameworkHeader
            -e 's:<kerberosIV/krb_err.h>:<Kerberos/krb_err.h>:' \
            -e 's:<profile.h>:<Kerberos/profile.h>:' \
            -e 's:<krb5.h>:<Kerberos/krb5.h>:' \
-           -e 's:<krb524.h>:<Kerberos/krb524.h>:' \
-           -e 's:<krb524_err.h>:<Kerberos/krb524_err.h>:' \
            -e 's:<gssapi/gssapi.h>:<Kerberos/gssapi.h>:' \
            -e 's:<gssapi/gssapi_krb5.h>:<Kerberos/gssapi_krb5.h>:' \
            -e 's:<gssapi/gssapi_generic.h>:<Kerberos/gssapi_generic.h>:' \
@@ -82,37 +80,34 @@ actions CopyHeader
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/com_err.h" : "$(SRCROOT)/../../KerberosErrors/Headers/Kerberos/com_err.h" ;
 CopyHeader          "$(IntermediateIncludes)/com_err.h"         : "$(SRCROOT)/../../KerberosErrors/Headers/Kerberos/com_err.h" ;
 
-CopyHeader          "$(IntermediateV4Includes)/des.h"       : "$(SRCROOT)/../Sources/include/kerberosIV/des.h" ;
+CopyHeader          "$(IntermediateV4Includes)/des.h"       : "$(SRCROOT)/../../Kerberos5/Sources/include/kerberosIV/des.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/des.h" : "$(IntermediateV4Includes)/des.h" ;
 
-CopyHeader          "$(IntermediateV4Includes)/krb.h"           : "$(SRCROOT)/../Sources/include/kerberosIV/krb.h" ;
+CopyHeader          "$(IntermediateV4Includes)/krb.h"           : "$(SRCROOT)/../../Kerberos5/Sources/include/kerberosIV/krb.h" ;
 CopyHeader          "$(IntermediateV4Includes)/krb_err.h"       : "$(IntermediateErrorTables)/krb_err.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/krb.h"     : "$(IntermediateV4Includes)/krb.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/krb_err.h" : "$(IntermediateV4Includes)/krb_err.h" ;
 
 CatHeader           "$(IntermediateIncludes)/profile.h"         : "__KERBEROSPROFILE__"
-                                                                  "$(SRCROOT)/../Sources/util/profile/profile.hin"
+                                                                  "$(SRCROOT)/../../Kerberos5/Sources/util/profile/profile.hin"
                                                                   "$(IntermediateErrorTables)/prof_err.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/profile.h" : "$(IntermediateIncludes)/profile.h" ;
 
 CatHeader           "$(IntermediateIncludes)/krb5.h"               : "__KERBEROS5__"
-                                                                     "$(SRCROOT)/../Sources/include/krb5.hin"
+                                                                     "$(SRCROOT)/../../Kerberos5/Sources/include/krb5.hin"
                                                                      "$(IntermediateErrorTables)/asn1_err.h"
                                                                      "$(IntermediateErrorTables)/kdb5_err.h"
                                                                      "$(IntermediateErrorTables)/krb5_err.h"
+                                                                     "$(IntermediateErrorTables)/krb524_err.h"
                                                                      "$(IntermediateErrorTables)/kv5m_err.h" ;
-CopyHeader          "$(IntermediateIncludes)/krb524.h"             : "$(SRCROOT)/../Sources/krb524/krb524.h" ;
-CopyHeader          "$(IntermediateIncludes)/krb524_err.h"         : "$(IntermediateErrorTables)/krb524_err.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/krb5.h"       : "$(IntermediateIncludes)/krb5.h" ;
-MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/krb524.h"     : "$(IntermediateIncludes)/krb524.h" ;
-MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/krb524_err.h" : "$(IntermediateIncludes)/krb524_err.h" ;
 
 CatHeader           "$(IntermediateGSSIncludes)/gssapi.h"              : "__GSSAPI__"
-                                                                         "$(SRCROOT)/../Sources/lib/gssapi/generic/gssapi.hin"
+                                                                         "$(SRCROOT)/../../Kerberos5/Sources/lib/gssapi/generic/gssapi.hin"
                                                                          "$(IntermediateErrorTables)/gssapi_err_generic.h"
                                                                          "$(IntermediateErrorTables)/gssapi_err_krb5.h" ;
-CopyHeader          "$(IntermediateGSSIncludes)/gssapi_generic.h"      : "$(SRCROOT)/../Sources/lib/gssapi/generic/gssapi_generic.h" ;
-CopyHeader          "$(IntermediateGSSIncludes)/gssapi_krb5.h"         : "$(SRCROOT)/../Sources/lib/gssapi/krb5/gssapi_krb5.h" ;
+CopyHeader          "$(IntermediateGSSIncludes)/gssapi_generic.h"      : "$(SRCROOT)/../../Kerberos5/Sources/lib/gssapi/generic/gssapi_generic.h" ;
+CopyHeader          "$(IntermediateGSSIncludes)/gssapi_krb5.h"         : "$(SRCROOT)/../../Kerberos5/Sources/lib/gssapi/krb5/gssapi_krb5.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/gssapi.h"         : "$(IntermediateGSSIncludes)/gssapi.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/gssapi_generic.h" : "$(IntermediateGSSIncludes)/gssapi_generic.h" ;
 MakeFrameworkHeader "$(IntermediateFrameworkHeaders)/gssapi_krb5.h"    : "$(IntermediateGSSIncludes)/gssapi_krb5.h" ;
@@ -135,11 +130,7 @@ DEPENDS all :	"$(IntermediateIncludes)/com_err.h"
                 "$(IntermediateFrameworkHeaders)/profile.h"
                 
                 "$(IntermediateIncludes)/krb5.h"
-                "$(IntermediateIncludes)/krb524.h"
-                "$(IntermediateIncludes)/krb524_err.h"
                 "$(IntermediateFrameworkHeaders)/krb5.h"
-                "$(IntermediateFrameworkHeaders)/krb524.h"
-                "$(IntermediateFrameworkHeaders)/krb524_err.h"
                 
                 "$(IntermediateGSSIncludes)/gssapi.h"
                 "$(IntermediateGSSIncludes)/gssapi_generic.h"
diff --git a/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam b/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam
index 9969720be..d4a969843 100644
--- a/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam
+++ b/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam
@@ -1,10 +1,23 @@
 Intermediates = "$(BUILT_PRODUCTS_DIR)/Kerberos5.intermediates" ;
 IntermediateBuild = "$(Intermediates)/build" ;
-Sources = "$(SRCROOT)/../Sources" ;
+Sources = "$(SRCROOT)/../../Kerberos5/Sources" ;
 
 Reconf = "$(Sources)/util/reconf" ;
 Configure = "$(Sources)/configure" ;
 Makefile = "$(IntermediateBuild)/Makefile" ;
+MakeStamp = "$(IntermediateBuild)/make.stamp" ;
+
+if $(KerberosCFLAGS) != "" { 
+    KerberosCFLAGS = "CFLAGS=$(CFLAGS) -fno-common -include /usr/include/TargetConditionals.h -DUSE_PASSWORD_SERVER" ; 
+} else {
+    KerberosCFLAGS = "CFLAGS=-fno-common -include /usr/include/TargetConditionals.h -DUSE_PASSWORD_SERVER" ;
+}
+
+if $(KerberosLDFLAGS) != "" { 
+    KerberosLDFLAGS = "LDFLAGS=$(LDFLAGS) -Wl,-search_paths_first" ; 
+} else {
+    KerberosLDFLAGS = "LDFLAGS=-Wl,-search_paths_first" ;
+}
 
 #
 # Note: in this jam script we have separated the dependency tree from the 
@@ -32,10 +45,10 @@ rule Configure
 actions Configure
 {
     mkdir -p "$(1:D)"
-    cd "$(1:D)" && /bin/sh "$(2)" --prefix=/usr CFLAGS="-fno-common" || rm -f "$(1)"
+    cd "$(1:D)" && /bin/sh "$(2)" --prefix=/usr --localstatedir=/var/db "$(KerberosCFLAGS)" "$(KerberosLDFLAGS)" || rm -f "$(1)"
 }
 
-# Make <stamp file> <build dir> : <makefile>
+# Make <stamp file> : <makefile>
 rule Make
 {
     DEPENDS "$(1)" : "$(2)" ;
@@ -48,8 +61,80 @@ actions Make
     cd "$(1:D)" && make && touch "$(1)" && echo "### HAPPINESS ###"
 }
 
-Make "$(IntermediateBuild)/make.stamp" : "$(Makefile)" ;
+# InstallProgram <destination executable> : <source executable>
+rule InstallProgram
+{
+    DEPENDS "$(1)" : "$(2)" ;
+    DEPENDS "$(2)" : "$(MakeStamp)" ;
+    Clean.Remove clean "$(1)" ;
+}
+actions InstallProgram
+{
+    mkdir -p "$(1:D)"
+    /usr/bin/install -c -s "$(2)" "$(1)" 
+}
+
+# InstallFile <destination file> : <source file>
+rule InstallFile
+{
+    DEPENDS "$(1)" : "$(2)" ;
+    DEPENDS "$(2)" : "$(MakeStamp)" ;
+    Clean.Remove clean "$(1)" ;
+}
+actions InstallFile
+{
+    mkdir -p "$(1:D)"
+    /usr/bin/install -c -m 644 "$(2)" "$(1)" 
+}
+
+Make "$(MakeStamp)" : "$(Makefile)" ;
+
+InstallProgram "$(DSTROOT)/usr/sbin/kadmin"          : "$(IntermediateBuild)/kadmin/cli/kadmin" ;
+InstallProgram "$(DSTROOT)/usr/sbin/kadmin.local"    : "$(IntermediateBuild)/kadmin/cli/kadmin.local" ;
+InstallProgram "$(DSTROOT)/usr/sbin/kadmind"         : "$(IntermediateBuild)/kadmin/server/kadmind" ;
+InstallProgram "$(DSTROOT)/usr/sbin/ktutil"          : "$(IntermediateBuild)/kadmin/ktutil/ktutil" ;
+InstallProgram "$(DSTROOT)/usr/sbin/kdb5_util"       : "$(IntermediateBuild)/kadmin/dbutil/kdb5_util" ;
+InstallProgram "$(DSTROOT)/usr/sbin/kprop"           : "$(IntermediateBuild)/slave/kprop" ;
+InstallProgram "$(DSTROOT)/usr/sbin/kpropd"          : "$(IntermediateBuild)/slave/kpropd" ;
+InstallProgram "$(DSTROOT)/usr/sbin/krb524d"         : "$(IntermediateBuild)/krb524/krb524d" ;
+InstallProgram "$(DSTROOT)/usr/sbin/krb5kdc"         : "$(IntermediateBuild)/kdc/krb5kdc" ;
+                  
+InstallFile "$(DSTROOT)/usr/share/man/man1/kerberos.1"     : "$(SRCROOT)/../../Kerberos5/Sources/gen-manpages/kerberos.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man5/kdc.conf.5"     : "$(SRCROOT)/../../Kerberos5/Sources/config-files/kdc.conf.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man5/krb5.conf.5"    : "$(SRCROOT)/../../Kerberos5/Sources/config-files/krb5.conf.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kadmin.8"       : "$(SRCROOT)/../../Kerberos5/Sources/kadmin/cli/kadmin.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kadmin.local.8" : "$(SRCROOT)/../../Kerberos5/Sources/kadmin/cli/kadmin.local.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kadmind.8"      : "$(SRCROOT)/../../Kerberos5/Sources/kadmin/server/kadmind.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/ktutil.8"       : "$(SRCROOT)/../../Kerberos5/Sources/kadmin/ktutil/ktutil.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kdb5_util.8"    : "$(SRCROOT)/../../Kerberos5/Sources/kadmin/dbutil/kdb5_util.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kprop.8"        : "$(SRCROOT)/../../Kerberos5/Sources/slave/kprop.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/kpropd.8"       : "$(SRCROOT)/../../Kerberos5/Sources/slave/kpropd.M" ;
+InstallFile "$(DSTROOT)/usr/share/man/man8/krb5kdc.8"      : "$(SRCROOT)/../../Kerberos5/Sources/kdc/krb5kdc.M" ;
+
+
+DEPENDS all     : "$(MakeStamp)" ;
 
-DEPENDS all : "$(IntermediateBuild)/make.stamp" ;
-DEPENDS install : all ;
+DEPENDS install : all 
+                  "$(DSTROOT)/usr/sbin/kadmin"
+                  "$(DSTROOT)/usr/sbin/kadmin.local"
+                  "$(DSTROOT)/usr/sbin/kadmind"
+                  "$(DSTROOT)/usr/sbin/kdb5_util"
+                  "$(DSTROOT)/usr/sbin/kprop"
+                  "$(DSTROOT)/usr/sbin/kpropd"
+                  "$(DSTROOT)/usr/sbin/krb524d"
+                  "$(DSTROOT)/usr/sbin/krb5kdc"
+                  "$(DSTROOT)/usr/sbin/ktutil"
+                  
+                  "$(DSTROOT)/usr/share/man/man1/kerberos.1"
+                  "$(DSTROOT)/usr/share/man/man5/kdc.conf.5"
+                  "$(DSTROOT)/usr/share/man/man5/krb5.conf.5"
+                  "$(DSTROOT)/usr/share/man/man8/kadmin.8"
+                  "$(DSTROOT)/usr/share/man/man8/kadmin.local.8"
+                  "$(DSTROOT)/usr/share/man/man8/kadmind.8"
+                  "$(DSTROOT)/usr/share/man/man8/kdb5_util.8"
+                  "$(DSTROOT)/usr/share/man/man8/kprop.8"
+                  "$(DSTROOT)/usr/share/man/man8/kpropd.8"
+                  "$(DSTROOT)/usr/share/man/man8/krb5kdc.8"
+                  "$(DSTROOT)/usr/share/man/man8/ktutil.8" ;
+                  
 DEPENDS installhdrs : all ;
diff --git a/src/slave/Makefile.in b/src/slave/Makefile.in
index af75ff3d7..19c98f113 100644
--- a/src/slave/Makefile.in
+++ b/src/slave/Makefile.in
@@ -43,13 +43,14 @@ clean::
 #
 $(OUTPRE)kprop.$(OBJEXT): kprop.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h kprop.h
+  kprop.h
 $(OUTPRE)kpropd.$(OBJEXT): kpropd.c $(SRCTOP)/include/syslog.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  kprop.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h kprop.h
 
diff --git a/src/tests/ChangeLog b/src/tests/ChangeLog
index 7ed1b8ae1..a4bf487a3 100644
--- a/src/tests/ChangeLog
+++ b/src/tests/ChangeLog
@@ -1,3 +1,9 @@
+2003-06-04  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in (kdb_check): Remove uses of "dump -old", etc., since
+	it doesn't work anymore given the new default for triple-DES
+	master keys.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
 	* configure.in: Use V5_AC_OUTPUT_MAKEFILE instead of
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index b126a9f98..e0fab313f 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -35,7 +35,6 @@ kdb_check: kdc.conf
 	$(RUN_SETUP) ../tests/verify/kdb5_verify $(KTEST_OPTS) 
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -ov $(TEST_DB).ovdump
-	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -old $(TEST_DB).odump
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load $(TEST_DB).dump 
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load -update -ov $(TEST_DB).ovdump 
@@ -49,14 +48,6 @@ kdb_check: kdc.conf
 	cmp $(TEST_DB).sort $(TEST_DB).sort2
 	cmp $(TEST_DB).ovsort $(TEST_DB).ovsort2
 	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f
-	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -s
-	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load -old $(TEST_DB).odump 
-	$(RUN_SETUP) ../tests/verify/kdb5_verify $(KTEST_OPTS) 
-	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -old $(TEST_DB).odump2
-	sort $(TEST_DB).odump > $(TEST_DB).osort
-	sort $(TEST_DB).odump2 > $(TEST_DB).osort2
-	cmp $(TEST_DB).osort $(TEST_DB).osort2
-	$(RUN_SETUP) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f
 	$(RM) $(TEST_DB)* stash_file
 
 clean::
diff --git a/src/tests/asn.1/ChangeLog b/src/tests/asn.1/ChangeLog
index d4c543025..6bed2ccf6 100644
--- a/src/tests/asn.1/ChangeLog
+++ b/src/tests/asn.1/ChangeLog
@@ -1,3 +1,34 @@
+2003-05-18  Tom Yu  <tlyu@mit.edu>
+
+	* krb5_decode_test.c (main): Add new test cases for sequence
+	number compatibility.
+
+	* utility.c (krb5_data_hex_parse): Rewrite to be more lenient
+	about whitespace.
+
+2003-05-12  Ezra Peisach  <epeisach@mit.edu>
+
+	* krb5_decode_test.c: Modify decode_run macro to take a cleanup
+	handler to free allocated memory. Add static handlers to free
+	krb5_alt_method, passwd_phrase_element and krb5_enc_data as the
+	krb5 library does not handle at this time.
+
+	* krb5_encode_test.c: Free krb5_context at end. Utilize the many
+	ktest_empty and detroy functions to cleanup memory.
+
+	* ktest.h, ktest.c: Add many ktest free and empty functions to
+	cleanup allocated structures in tests.
+
+	* utility.c (krb5_data_hex_parse): Free temporary data.
+	
+
+2003-05-06  Sam Hartman  <hartmans@mit.edu>
+
+	* krb5_encode_test.c (main): Add etype_info2 support
+
+	* ktest.c (ktest_make_sample_etype_info): Initialize s2kparams to be null.
+	(ktest_make_sample_etype_info2): New function
+
 2002-11-07  Ezra Peisach  <epeisach@bu.edu>
 
 	* krb5_decode_test.c: Test for sam_challenege without empty
diff --git a/src/tests/asn.1/Makefile.in b/src/tests/asn.1/Makefile.in
index 920f3d84f..514f768c2 100644
--- a/src/tests/asn.1/Makefile.in
+++ b/src/tests/asn.1/Makefile.in
@@ -66,27 +66,29 @@ ktest_equal.o: ktest_equal.h
 #
 $(OUTPRE)krb5_encode_test.$(OBJEXT): krb5_encode_test.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
-  utility.h $(SRCTOP)/lib/krb5/asn.1/krbasn1.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h \
-  ktest.h debug.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h utility.h $(SRCTOP)/lib/krb5/asn.1/krbasn1.h \
+  $(SRCTOP)/lib/krb5/asn.1/asn1buf.h ktest.h debug.h
 $(OUTPRE)ktest.$(OBJEXT): ktest.c ktest.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h utility.h $(SRCTOP)/lib/krb5/asn.1/krbasn1.h \
-  $(SRCTOP)/lib/krb5/asn.1/asn1buf.h
+  utility.h $(SRCTOP)/lib/krb5/asn.1/krbasn1.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h
 $(OUTPRE)ktest_equal.$(OBJEXT): ktest_equal.c ktest_equal.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h
 $(OUTPRE)utility.$(OBJEXT): utility.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) utility.h $(SRCTOP)/lib/krb5/asn.1/krbasn1.h \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h
+  $(SRCTOP)/lib/krb5/asn.1/asn1buf.h
 $(OUTPRE)trval.$(OBJEXT): trval.c
 
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index ea679cc0c..c205232d9 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -10,6 +10,11 @@
 krb5_context test_context;
 int error_count = 0;
 
+void krb5_ktest_free_alt_method(krb5_context context, krb5_alt_method *val);
+void krb5_ktest_free_pwd_sequence(krb5_context context, 
+				  passwd_phrase_element *val);
+void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val);
+
 int main(argc, argv)
 	int argc;
 	char **argv;
@@ -23,6 +28,7 @@ int main(argc, argv)
 	  exit(1);
   }
   
+
 #define setup(type,typestring,constructor)\
   type ref, *var;\
   retval = constructor(&ref);\
@@ -30,8 +36,8 @@ int main(argc, argv)
     com_err("krb5_decode_test", retval, "while making sample %s", typestring);\
     exit(1);\
   }
-    
-#define decode_run(typestring,description,encoding,decoder,comparator)\
+
+#define decode_run(typestring,description,encoding,decoder,comparator,cleanup)\
     retval = krb5_data_hex_parse(&code,encoding);\
     if(retval){\
       com_err("krb5_decode_test", retval, "while parsing %s", typestring);\
@@ -43,32 +49,204 @@ int main(argc, argv)
       error_count++;\
     }\
     assert(comparator(&ref,var),typestring);\
-    printf("%s\n",description)
+    printf("%s\n",description);\
+    krb5_free_data_contents(test_context, &code);\
+    cleanup(test_context, var);
 
   /****************************************************************/
   /* decode_krb5_authenticator */
   {
     setup(krb5_authenticator,"krb5_authenticator",ktest_make_sample_authenticator);
 
-    decode_run("authenticator","","62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_authenticator,ktest_equal_authenticator);
+    decode_run("authenticator","","62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0xffffff80;
+    decode_run("authenticator","(80 -> seq-number 0xffffff80)",
+	       "62 81 A1 30 81 9E"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 03 02 01 80"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0xffffffff;
+    decode_run("authenticator","(FF -> seq-number 0xffffffff)",
+	       "62 81 A1 30 81 9E"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 03 02 01 FF"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0xff;
+    decode_run("authenticator","(00FF -> seq-number 0xff)",
+	       "62 81 A2 30 81 9F"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 04 02 02 00 FF"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0xffffffff;
+    decode_run("authenticator","(00FFFFFFFF -> seq-number 0xffffffff)",
+	       "62 81 A5 30 81 A2"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 07 02 05 00 FF FF FF FF"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0x7fffffff;
+    decode_run("authenticator","(7FFFFFFF -> seq-number 0x7fffffff)",
+	       "62 81 A4 30 81 A1"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 06 02 04 7F FF FF FF"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ref.seq_number = 0xffffffff;
+    decode_run("authenticator","(FFFFFFFF -> seq-number 0xffffffff)",
+	       "62 81 A4 30 81 A1"
+	       "   A0 03 02 01 05"
+	       "   A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55"
+	       "   A2 1A 30 18"
+	       "      A0 03 02 01 01"
+	       "      A1 11 30 0F"
+	       "         1B 06 68 66 74 73 61 69"
+	       "         1B 05 65 78 74 72 61"
+	       "   A3 0F 30 0D"
+	       "      A0 03 02 01 01"
+	       "      A1 06 04 04 31 32 33 34"
+	       "   A4 05 02 03 01 E2 40"
+	       "   A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A"
+	       "   A6 13 30 11"
+	       "      A0 03 02 01 01"
+	       "      A1 0A 04 08 31 32 33 34 35 36 37 38"
+	       "   A7 06 02 04 FF FF FF FF"
+	       "   A8 24 30 22"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       "      30 0F"
+	       "         A0 03 02 01 01"
+	       "         A1 08 04 06 66 6F 6F 62 61 72"
+	       ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
 
     ktest_destroy_checksum(&(ref.checksum));
     ktest_destroy_keyblock(&(ref.subkey));
     ref.seq_number = 0;
     ktest_empty_authorization_data(ref.authorization_data);
-    decode_run("authenticator","(optionals empty)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator);
+    decode_run("authenticator","(optionals empty)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
 
-   ktest_destroy_authorization_data(&(ref.authorization_data));
+    ktest_destroy_authorization_data(&(ref.authorization_data));
     
-    decode_run("authenticator","(optionals NULL)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator);
+    decode_run("authenticator","(optionals NULL)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator);
+
+    ktest_empty_authenticator(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_ticket */
   {
     setup(krb5_ticket,"krb5_ticket",ktest_make_sample_ticket);
-    decode_run("ticket","","61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ticket,ktest_equal_ticket);
-    decode_run("ticket","(+ trailing [4] INTEGER","61 61 30 5F A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 03 02 01 01",decode_krb5_ticket,ktest_equal_ticket);
+    decode_run("ticket","","61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
+    decode_run("ticket","(+ trailing [4] INTEGER","61 61 30 5F A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 03 02 01 01",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
 
 /*
   "61 80 30 80 "
@@ -89,7 +267,7 @@ int main(argc, argv)
   "  00 00 00 00"
   "00 00 00 00"
 */
-    decode_run("ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket,ktest_equal_ticket);
+    decode_run("ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
 /*
   "61 80 30 80 "
   "  A0 03 02 01 05 "
@@ -110,37 +288,44 @@ int main(argc, argv)
   "  A4 03 02 01 01 "
   "00 00 00 00"
 */
-    decode_run("ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket,ktest_equal_ticket);
+    decode_run("ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
+
+    ktest_empty_ticket(&ref);
+
   }
 
   /****************************************************************/
   /* decode_krb5_encryption_key */
   {
     setup(krb5_keyblock,"krb5_keyblock",ktest_make_sample_keyblock);
-    decode_run("encryption_key","","30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(+ trailing [2] INTEGER)","30 16 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(+ trailing [2] SEQUENCE {[0] INTEGER})","30 1A A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 07 30 05 A0 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key);
-    decode_run("encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key);
+
+    decode_run("encryption_key","","30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+
+    decode_run("encryption_key","(+ trailing [2] INTEGER)","30 16 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+    decode_run("encryption_key","(+ trailing [2] SEQUENCE {[0] INTEGER})","30 1A A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 07 30 05 A0 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+    decode_run("encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+    decode_run("encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+    decode_run("encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+    decode_run("encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
     ref.enctype = -1;
-    decode_run("encryption_key","(enctype = -1)","30 11 A0 03 02 01 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
+    decode_run("encryption_key","(enctype = -1)","30 11 A0 03 02 01 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
     ref.enctype = -255;
-    decode_run("encryption_key","(enctype = -255)","30 12 A0 04 02 02 FF 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
+    decode_run("encryption_key","(enctype = -255)","30 12 A0 04 02 02 FF 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
     ref.enctype = 255;
-    decode_run("encryption_key","(enctype = 255)","30 12 A0 04 02 02 00 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
+    decode_run("encryption_key","(enctype = 255)","30 12 A0 04 02 02 00 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
     ref.enctype = -2147483648;
-    decode_run("encryption_key","(enctype = -2147483648)","30 14 A0 06 02 04 80 00 00 00 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
+    decode_run("encryption_key","(enctype = -2147483648)","30 14 A0 06 02 04 80 00 00 00 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
     ref.enctype = 2147483647;
-    decode_run("encryption_key","(enctype = 2147483647)","30 14 A0 06 02 04 7F FF FF FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key);
+    decode_run("encryption_key","(enctype = 2147483647)","30 14 A0 06 02 04 7F FF FF FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+
+    ktest_empty_keyblock(&ref);
   }  
   
   /****************************************************************/
   /* decode_krb5_enc_tkt_part */
   {
     setup(krb5_enc_tkt_part,"krb5_enc_tkt_part",ktest_make_sample_enc_tkt_part);
-    decode_run("enc_tkt_part","","63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
+    decode_run("enc_tkt_part","","63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part);
   
     /* ref.times.starttime = 0; */
     ref.times.starttime = ref.times.authtime;
@@ -153,18 +338,19 @@ int main(argc, argv)
     ktest_destroy_addresses(&(ref.caddrs));
     ktest_destroy_authorization_data(&(ref.authorization_data));
   
-    decode_run("enc_tkt_part","(optionals NULL)","63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
+    decode_run("enc_tkt_part","(optionals NULL)","63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part, krb5_free_enc_tkt_part);
 
-    decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 38 bits)","63 81 A6 30 81 A3 A0 08 03 06 02 FE DC BA 98 DC A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
+    decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 38 bits)","63 81 A6 30 81 A3 A0 08 03 06 02 FE DC BA 98 DC A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part);
 
-    decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 40 bits)","63 81 A6 30 81 A3 A0 08 03 06 00 FE DC BA 98 DE A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
+    decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 40 bits)","63 81 A6 30 81 A3 A0 08 03 06 00 FE DC BA 98 DE A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part);
 
-    decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 29 bits)","63 81 A5 30 81 A2 A0 07 03 05 03 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
+    decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 29 bits)","63 81 A5 30 81 A2 A0 07 03 05 03 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part);
 
     ref.flags &= 0xFFFFFF00;
 
-    decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 24 bits)","63 81 A4 30 81 A1 A0 06 03 04 00 FE DC BA A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part);
-    
+    decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 24 bits)","63 81 A4 30 81 A1 A0 06 03 04 00 FE DC BA A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part);
+
+    ktest_empty_enc_tkt_part(&ref);
   }  
   
   /****************************************************************/
@@ -173,10 +359,10 @@ int main(argc, argv)
     setup(krb5_enc_kdc_rep_part,"krb5_enc_kdc_rep_part",ktest_make_sample_enc_kdc_rep_part);
   
 #ifdef KRB5_GENEROUS_LR_TYPE
-    decode_run("enc_kdc_rep_part","(compat_lr_type)","7A 82 01 10 30 82 01 0C A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part);
+    decode_run("enc_kdc_rep_part","(compat_lr_type)","7A 82 01 10 30 82 01 0C A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
 #endif
   
-    decode_run("enc_kdc_rep_part","","7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part);
+    decode_run("enc_kdc_rep_part","","7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
   
     ref.key_exp = 0;
     /* ref.times.starttime = 0;*/
@@ -186,10 +372,12 @@ int main(argc, argv)
     ktest_destroy_addresses(&(ref.caddrs));
   
 #ifdef KRB5_GENEROUS_LR_TYPE
-    decode_run("enc_kdc_rep_part","(optionals NULL)(compat lr_type)","7A 81 B4 30 81 B1 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part);
+    decode_run("enc_kdc_rep_part","(optionals NULL)(compat lr_type)","7A 81 B4 30 81 B1 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
 #endif
 
-    decode_run("enc_kdc_rep_part","(optionals NULL)","7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part);
+    decode_run("enc_kdc_rep_part","(optionals NULL)","7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
+
+    ktest_empty_enc_kdc_rep_part(&ref);
   }  
 
   /****************************************************************/
@@ -198,7 +386,7 @@ int main(argc, argv)
     setup(krb5_kdc_rep,"krb5_kdc_rep",ktest_make_sample_kdc_rep);
     ref.msg_type = KRB5_AS_REP;
 
-    decode_run("as_rep","","6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep);
+    decode_run("as_rep","","6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep);
 
 /*
   6B 80 30 80
@@ -249,9 +437,11 @@ int main(argc, argv)
     00 00 00 00
   00 00 00 00
 */
-    decode_run("as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep,ktest_equal_as_rep);
+    decode_run("as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep);
     ktest_destroy_pa_data_array(&(ref.padata));
-    decode_run("as_rep","(optionals NULL)","6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep);
+    decode_run("as_rep","(optionals NULL)","6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep);
+
+  ktest_empty_kdc_rep(&ref);
   }  
   
   /****************************************************************/
@@ -260,24 +450,29 @@ int main(argc, argv)
     setup(krb5_kdc_rep,"krb5_kdc_rep",ktest_make_sample_kdc_rep);
     ref.msg_type = KRB5_TGS_REP;
 
-    decode_run("tgs_rep","","6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep);
+    decode_run("tgs_rep","","6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep);
 
     ktest_destroy_pa_data_array(&(ref.padata));
-    decode_run("tgs_rep","(optionals NULL)","6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep);
+    decode_run("tgs_rep","(optionals NULL)","6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep);
+
+  ktest_empty_kdc_rep(&ref);
   }  
   
   /****************************************************************/
   /* decode_krb5_ap_req */
   {
     setup(krb5_ap_req,"krb5_ap_req",ktest_make_sample_ap_req);
-    decode_run("ap_req","","6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_req,ktest_equal_ap_req);
+    decode_run("ap_req","","6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_req,ktest_equal_ap_req,krb5_free_ap_req);
+    ktest_empty_ap_req(&ref);
+
   }  
 
   /****************************************************************/
   /* decode_krb5_ap_rep */
   {
     setup(krb5_ap_rep,"krb5_ap_rep",ktest_make_sample_ap_rep);
-    decode_run("ap_rep","","6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_rep,ktest_equal_ap_rep);
+    decode_run("ap_rep","","6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_rep,ktest_equal_ap_rep,krb5_free_ap_rep);
+    ktest_empty_ap_rep(&ref);
   }  
 
   /****************************************************************/
@@ -285,11 +480,12 @@ int main(argc, argv)
   {
     setup(krb5_ap_rep_enc_part,"krb5_ap_rep_enc_part",ktest_make_sample_ap_rep_enc_part);
 
-    decode_run("ap_rep_enc_part","","7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part);
+    decode_run("ap_rep_enc_part","","7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part);
   
     ktest_destroy_keyblock(&(ref.subkey));
     ref.seq_number = 0;
-    decode_run("ap_rep_enc_part","(optionals NULL)","7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part);
+    decode_run("ap_rep_enc_part","(optionals NULL)","7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part);
+    ktest_empty_ap_rep_enc_part(&ref);
   }
   
   /****************************************************************/
@@ -299,7 +495,7 @@ int main(argc, argv)
     ref.msg_type = KRB5_AS_REQ;
 
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("as_req","","6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req);
+    decode_run("as_req","","6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req);
 
     ktest_destroy_pa_data_array(&(ref.padata));
     ktest_destroy_principal(&(ref.client));
@@ -311,14 +507,18 @@ int main(argc, argv)
     ref.rtime = 0;
     ktest_destroy_addresses(&(ref.addresses));
     ktest_destroy_enc_data(&(ref.authorization_data));
-    decode_run("as_req","(optionals NULL except second_ticket)","6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req);
+    decode_run("as_req","(optionals NULL except second_ticket)","6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req);
     ktest_destroy_sequence_of_ticket(&(ref.second_ticket));
 #ifndef ISODE_SUCKS
     ktest_make_sample_principal(&(ref.server));
 #endif
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("as_req","(optionals NULL except server)","6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_as_req,ktest_equal_as_req);
+    decode_run("as_req","(optionals NULL except server)","6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req);
+
+  ktest_empty_kdc_req(&ref);
+
   }
+
   
   /****************************************************************/
   /* decode_krb5_tgs_req */
@@ -327,7 +527,7 @@ int main(argc, argv)
     ref.msg_type = KRB5_TGS_REQ;
 
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("tgs_req","","6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req);
+    decode_run("tgs_req","","6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req);
 
     ktest_destroy_pa_data_array(&(ref.padata));
     ktest_destroy_principal(&(ref.client));
@@ -339,27 +539,30 @@ int main(argc, argv)
     ref.rtime = 0;
     ktest_destroy_addresses(&(ref.addresses));
     ktest_destroy_enc_data(&(ref.authorization_data));
-    decode_run("tgs_req","(optionals NULL except second_ticket)","6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req);
+    decode_run("tgs_req","(optionals NULL except second_ticket)","6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req);
 
     ktest_destroy_sequence_of_ticket(&(ref.second_ticket));
 #ifndef ISODE_SUCKS
     ktest_make_sample_principal(&(ref.server));
 #endif
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("tgs_req","(optionals NULL except server)","6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_tgs_req,ktest_equal_tgs_req);
+    decode_run("tgs_req","(optionals NULL except server)","6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req);
+
+    ktest_empty_kdc_req(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_kdc_req_body */
   {
     krb5_kdc_req ref, *var;
+    memset(&ref, 0, sizeof(krb5_kdc_req));
     retval = ktest_make_sample_kdc_req_body(&ref);
     if(retval){
       com_err("making sample kdc_req_body",retval,"");
       exit(1);
     }
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("kdc_req_body","","30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body);
+    decode_run("kdc_req_body","","30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req);
 
     ktest_destroy_principal(&(ref.client));
 #ifndef ISODE_SUCKS
@@ -370,66 +573,75 @@ int main(argc, argv)
     ref.rtime = 0;
     ktest_destroy_addresses(&(ref.addresses));
     ktest_destroy_enc_data(&(ref.authorization_data));
-    decode_run("kdc_req_body","(optionals NULL except second_ticket)","30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body);
+    decode_run("kdc_req_body","(optionals NULL except second_ticket)","30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req);
 
     ktest_destroy_sequence_of_ticket(&(ref.second_ticket));
 #ifndef ISODE_SUCKS
     ktest_make_sample_principal(&(ref.server));
 #endif
     ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
-    decode_run("kdc_req_body","(optionals NULL except server)","30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body);
+    decode_run("kdc_req_body","(optionals NULL except server)","30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req);
     ref.nktypes = 0;
     free(ref.ktype);
     ref.ktype = NULL;
-    decode_run("kdc_req_body","(optionals NULL except server; zero-length etypes)","30 53 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 02 30 00",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body);
+    decode_run("kdc_req_body","(optionals NULL except server; zero-length etypes)","30 53 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 02 30 00",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req);
+
+    ktest_empty_kdc_req(&ref);
   }
+
   
   /****************************************************************/
   /* decode_krb5_safe */
   {
     setup(krb5_safe,"krb5_safe",ktest_make_sample_safe);
-    decode_run("safe","","74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe);
+    decode_run("safe","","74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe);
 
     ref.timestamp = 0;
     ref.usec = 0;
     ref.seq_number = 0;
     ktest_destroy_address(&(ref.r_address));
-    decode_run("safe","(optionals NULL)","74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe);
+    decode_run("safe","(optionals NULL)","74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe);
+
+    ktest_empty_safe(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_priv */
   {
     setup(krb5_priv,"krb5_priv",ktest_make_sample_priv);
-    decode_run("priv","","75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_priv,ktest_equal_priv);
+    decode_run("priv","","75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_priv,ktest_equal_priv,krb5_free_priv);
+    ktest_empty_priv(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_enc_priv_part */
   {
     setup(krb5_priv_enc_part,"krb5_priv_enc_part",ktest_make_sample_priv_enc_part);
-    decode_run("enc_priv_part","","7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part);
+    decode_run("enc_priv_part","","7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part);
 
     ref.timestamp = 0;
     ref.usec = 0;
     ref.seq_number = 0;
     ktest_destroy_address(&(ref.r_address));
-    decode_run("enc_priv_part","(optionals NULL)","7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part);
+    decode_run("enc_priv_part","(optionals NULL)","7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part);
+    ktest_empty_priv_enc_part(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_cred */
   {
     setup(krb5_cred,"krb5_cred",ktest_make_sample_cred);
-    decode_run("cred","","76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_cred,ktest_equal_cred);
+    decode_run("cred","","76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_cred,ktest_equal_cred,krb5_free_cred);
+    ktest_empty_cred(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_enc_cred_part */
   {
     setup(krb5_cred_enc_part,"krb5_cred_enc_part",ktest_make_sample_cred_enc_part);
-    decode_run("enc_cred_part","","7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part);
-
+    decode_run("enc_cred_part","","7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part);
+    /* free_cred_enc_part does not free the pointer */
+    krb5_xfree(var);
     ktest_destroy_principal(&(ref.ticket_info[0]->client));
     ktest_destroy_principal(&(ref.ticket_info[0]->server));
     ref.ticket_info[0]->flags = 0;
@@ -443,20 +655,26 @@ int main(argc, argv)
     ref.usec = 0;
     ktest_destroy_address(&(ref.s_address));
     ktest_destroy_address(&(ref.r_address));
-    decode_run("enc_cred_part","(optionals NULL)","7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part);
+    decode_run("enc_cred_part","(optionals NULL)","7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part);
+    /* free_cred_enc_part does not free the pointer */
+    krb5_xfree(var);
+
+    ktest_empty_cred_enc_part(&ref);
   }
   
   /****************************************************************/
   /* decode_krb5_error */
   {
     setup(krb5_error,"krb5_error",ktest_make_sample_error);
-    decode_run("error","","7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_error,ktest_equal_error);
+    decode_run("error","","7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_error,ktest_equal_error,krb5_free_error);
 
     ref.ctime = 0;
     ktest_destroy_principal(&(ref.client));
     ktest_empty_data(&(ref.text));
     ktest_empty_data(&(ref.e_data));
-    decode_run("error","(optionals NULL)","7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_error,ktest_equal_error);
+    decode_run("error","(optionals NULL)","7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_error,ktest_equal_error,krb5_free_error);
+
+    ktest_empty_error(&ref);
   }
   
   /****************************************************************/
@@ -476,20 +694,25 @@ int main(argc, argv)
     retval = decode_krb5_authdata(&code,&var);
     if(retval) com_err("decoding authorization_data",retval,"");
     assert(ktest_equal_authorization_data(ref,var),"authorization_data\n")
+    krb5_free_data_contents(test_context, &code);
+    krb5_free_authdata(test_context, var);
+    ktest_destroy_authorization_data(&ref);
   }
   
   /****************************************************************/
   /* decode_pwd_sequence */
   {
     setup(passwd_phrase_element,"passwd_phrase_element",ktest_make_sample_passwd_phrase_element);
-    decode_run("PasswdSequence","","30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_pwd_sequence,ktest_equal_passwd_phrase_element);
+    decode_run("PasswdSequence","","30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_pwd_sequence,ktest_equal_passwd_phrase_element,krb5_ktest_free_pwd_sequence);
+    ktest_empty_passwd_phrase_element(&ref);
   }
 
   /****************************************************************/
   /* decode_passwd_data */
   {
     setup(krb5_pwd_data,"krb5_pwd_data",ktest_make_sample_krb5_pwd_data);
-    decode_run("PasswdData","","30 3D A0 03 02 01 02 A1 36 30 34 30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_pwd_data,ktest_equal_krb5_pwd_data);
+    decode_run("PasswdData","","30 3D A0 03 02 01 02 A1 36 30 34 30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 30 18 A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_pwd_data,ktest_equal_krb5_pwd_data,krb5_free_pwd_data);
+    ktest_empty_pwd_data(&ref);
   }
 
   /****************************************************************/
@@ -508,7 +731,10 @@ int main(argc, argv)
     }
     retval = decode_krb5_padata_sequence(&code,&var);
     if(retval) com_err("decoding padata_sequence",retval,"");
-    assert(ktest_equal_sequence_of_pa_data(ref,var),"pa_data\n")
+    assert(ktest_equal_sequence_of_pa_data(ref,var),"pa_data\n");
+    krb5_free_pa_data(test_context, var);
+    krb5_free_data_contents(test_context, &code);
+    ktest_destroy_pa_data_array(&ref);
   }
   
   /****************************************************************/
@@ -527,17 +753,20 @@ int main(argc, argv)
     }
     retval = decode_krb5_padata_sequence(&code,&var);
     if(retval) com_err("decoding padata_sequence (empty)",retval,"");
-    assert(ktest_equal_sequence_of_pa_data(ref,var),"pa_data (empty)\n")
+    assert(ktest_equal_sequence_of_pa_data(ref,var),"pa_data (empty)\n");
+    krb5_free_pa_data(test_context, var);
+    krb5_free_data_contents(test_context, &code);
+    ktest_destroy_pa_data_array(&ref);
   }
   
   /****************************************************************/
   /* decode_pwd_sequence */
   {
     setup(krb5_alt_method,"krb5_alt_method",ktest_make_sample_alt_method);
-    decode_run("alt_method","","30 0F A0 03 02 01 2A A1 08 04 06 73 65 63 72 65 74",decode_krb5_alt_method,ktest_equal_krb5_alt_method);
+    decode_run("alt_method","","30 0F A0 03 02 01 2A A1 08 04 06 73 65 63 72 65 74",decode_krb5_alt_method,ktest_equal_krb5_alt_method,krb5_ktest_free_alt_method);
     ref.length = 0;
-    decode_run("alt_method (no data)","","30 05 A0 03 02 01 2A",decode_krb5_alt_method,ktest_equal_krb5_alt_method);
-    
+    decode_run("alt_method (no data)","","30 05 A0 03 02 01 2A",decode_krb5_alt_method,ktest_equal_krb5_alt_method,krb5_ktest_free_alt_method);
+    ktest_empty_alt_method(&ref);
   }
 
   /****************************************************************/
@@ -565,6 +794,7 @@ int main(argc, argv)
       ktest_destroy_etype_info(var);
       ktest_destroy_etype_info_entry(ref[2]);      ref[2] = 0;
       ktest_destroy_etype_info_entry(ref[1]);      ref[1] = 0;
+      krb5_free_data_contents(test_context, &code);
       
       retval = krb5_data_hex_parse(&code,"30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30");
       if(retval){
@@ -581,6 +811,7 @@ int main(argc, argv)
       
       ktest_destroy_etype_info(var);
       ktest_destroy_etype_info_entry(ref[0]);      ref[0] = 0;
+      krb5_free_data_contents(test_context, &code);
       
       retval = krb5_data_hex_parse(&code,"30 00");
       if(retval){
@@ -595,6 +826,7 @@ int main(argc, argv)
       }
       assert(ktest_equal_etype_info(ref,var),"etype_info (no info)\n");
 
+      krb5_free_data_contents(test_context, &code);
       ktest_destroy_etype_info(var);
       ktest_destroy_etype_info(ref);
   }
@@ -603,41 +835,70 @@ int main(argc, argv)
   /* decode_pa_enc_ts */
   {
     setup(krb5_pa_enc_ts,"krb5_pa_enc_ts",ktest_make_sample_pa_enc_ts);
-    decode_run("pa_enc_ts","","30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts);
+    decode_run("pa_enc_ts","","30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts);
     ref.pausec = 0;
-    decode_run("pa_enc_ts (no usec)","","30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts);
+    decode_run("pa_enc_ts (no usec)","","30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts);
   }
   
   /****************************************************************/
   /* decode_enc_data */
   {
     setup(krb5_enc_data,"krb5_enc_data",ktest_make_sample_enc_data);
-    decode_run("enc_data","","30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data);
+    decode_run("enc_data","","30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data);
+    ktest_destroy_enc_data(&ref);
   }
   
   /****************************************************************/
   /* decode_sam_challenge */
   {
     setup(krb5_sam_challenge,"krb5_sam_challenge",ktest_make_sample_sam_challenge);
-    decode_run("sam_challenge","","30 78 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A3 02 04 00 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A7 02 04 00 A8 05 02 03 54 32 10 A9 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge,ktest_equal_sam_challenge);
+    decode_run("sam_challenge","","30 78 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A3 02 04 00 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A7 02 04 00 A8 05 02 03 54 32 10 A9 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge,ktest_equal_sam_challenge,krb5_free_sam_challenge);
+    ktest_empty_sam_challenge(&ref);
+
   }
   
   /****************************************************************/
   /* decode_sam_challenge */
   {
     setup(krb5_sam_challenge,"krb5_sam_challenge - no optionals",ktest_make_sample_sam_challenge);
-    decode_run("sam_challenge","","30 70 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge,ktest_equal_sam_challenge);
+    decode_run("sam_challenge","","30 70 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge,ktest_equal_sam_challenge,krb5_free_sam_challenge);
+    ktest_empty_sam_challenge(&ref);
   }
   
   /****************************************************************/
   /* decode_sam_response */
   {
     setup(krb5_sam_response,"krb5_sam_response",ktest_make_sample_sam_response);
-    decode_run("sam_response","","30 6A A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0C 04 0A 74 72 61 63 6B 20 64 61 74 61 A3 14 30 12 A0 03 02 01 01 A1 04 02 02 07 96 A2 05 04 03 6B 65 79 A4 1C 30 1A A0 03 02 01 01 A1 04 02 02 0D 36 A2 0D 04 0B 6E 6F 6E 63 65 20 6F 72 20 74 73 A5 05 02 03 54 32 10 A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_sam_response,ktest_equal_sam_response);
+    decode_run("sam_response","","30 6A A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0C 04 0A 74 72 61 63 6B 20 64 61 74 61 A3 14 30 12 A0 03 02 01 01 A1 04 02 02 07 96 A2 05 04 03 6B 65 79 A4 1C 30 1A A0 03 02 01 01 A1 04 02 02 0D 36 A2 0D 04 0B 6E 6F 6E 63 65 20 6F 72 20 74 73 A5 05 02 03 54 32 10 A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_sam_response,ktest_equal_sam_response,krb5_free_sam_response);
+
+    ktest_empty_sam_response(&ref);
   }
   
+  krb5_free_context(test_context);
   exit(error_count);
   return(error_count);
 }
 
 
+void krb5_ktest_free_alt_method(krb5_context context, krb5_alt_method *val)
+{
+  if (val->data)
+    krb5_xfree(val->data);
+  krb5_xfree(val);
+}
+
+void krb5_ktest_free_pwd_sequence(krb5_context context, 
+				  passwd_phrase_element *val)
+{
+  krb5_free_data(context, val->passwd);
+  krb5_free_data(context, val->phrase);
+  krb5_xfree(val);
+}
+
+void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val)
+{
+  if(val) {
+       krb5_free_data_contents(context, &(val->ciphertext));
+       free(val);
+  }
+}
diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c
index 012be90b4..284d31b77 100644
--- a/src/tests/asn.1/krb5_encode_test.c
+++ b/src/tests/asn.1/krb5_encode_test.c
@@ -133,6 +133,7 @@ main(argc, argv)
 
     ktest_destroy_authorization_data(&(authent.authorization_data));
     encode_run(authent,authenticator,"authenticator","(optionals NULL)",encode_krb5_authenticator);
+    ktest_empty_authenticator(&authent);
   }
   
   /****************************************************************/
@@ -141,6 +142,7 @@ main(argc, argv)
     krb5_ticket tkt;
     setup(tkt,ticket,"ticket",ktest_make_sample_ticket);
     encode_run(tkt,ticket,"ticket","",encode_krb5_ticket);
+    ktest_empty_ticket(&tkt);
   }
 
   /****************************************************************/
@@ -150,12 +152,14 @@ main(argc, argv)
     setup(keyblk,keyblock,"keyblock",ktest_make_sample_keyblock);
     current_appl_type = 1005;
     encode_run(keyblk,keyblock,"keyblock","",encode_krb5_encryption_key);
+    ktest_empty_keyblock(&keyblk);
   }  
   
   /****************************************************************/
   /* encode_krb5_enc_tkt_part */
   {
     krb5_ticket tkt;
+    memset(&tkt, 0, sizeof(krb5_ticket));
     tkt.enc_part2 = (krb5_enc_tkt_part*)calloc(1,sizeof(krb5_enc_tkt_part));
     if(tkt.enc_part2 == NULL) com_err("allocating enc_tkt_part",errno,"");
     setup(*(tkt.enc_part2),enc_tkt_part,"enc_tkt_part",ktest_make_sample_enc_tkt_part);
@@ -174,13 +178,16 @@ main(argc, argv)
     ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data));
   
     encode_run(*(tkt.enc_part2),enc_tkt_part,"enc_tkt_part","(optionals NULL)",encode_krb5_enc_tkt_part);
+    ktest_empty_ticket(&tkt);
   }  
   
   /****************************************************************/
   /* encode_krb5_enc_kdc_rep_part */
   {
     krb5_kdc_rep kdcr;
-  
+
+    memset(&kdcr, 0, sizeof(kdcr));
+ 
     kdcr.enc_part2 = (krb5_enc_kdc_rep_part*)
       calloc(1,sizeof(krb5_enc_kdc_rep_part));
     if(kdcr.enc_part2 == NULL) com_err("allocating enc_kdc_rep_part",errno,"");
@@ -194,6 +201,8 @@ main(argc, argv)
     ktest_destroy_addresses(&(kdcr.enc_part2->caddrs));
   
     encode_run(*(kdcr.enc_part2),enc_kdc_rep_part,"enc_kdc_rep_part","(optionals NULL)",encode_krb5_enc_kdc_rep_part);
+
+    ktest_empty_kdc_rep(&kdcr);
   }  
 
   /****************************************************************/
@@ -212,6 +221,9 @@ main(argc, argv)
   
     ktest_destroy_pa_data_array(&(kdcr.padata));
     encode_run(kdcr,as_rep,"as_rep","(optionals NULL)",encode_krb5_as_rep);
+
+    ktest_empty_kdc_rep(&kdcr);
+
   }  
   
   /****************************************************************/
@@ -229,6 +241,9 @@ main(argc, argv)
 
     ktest_destroy_pa_data_array(&(kdcr.padata));
     encode_run(kdcr,tgs_rep,"tgs_rep","(optionals NULL)",encode_krb5_tgs_rep);
+
+    ktest_empty_kdc_rep(&kdcr);
+
   }  
   
   /****************************************************************/
@@ -237,6 +252,7 @@ main(argc, argv)
     krb5_ap_req apreq;
     setup(apreq,ap_req,"ap_req",ktest_make_sample_ap_req);
     encode_run(apreq,ap_req,"ap_req","",encode_krb5_ap_req);
+    ktest_empty_ap_req(&apreq);
   }  
 
   /****************************************************************/
@@ -245,6 +261,7 @@ main(argc, argv)
     krb5_ap_rep aprep;
     setup(aprep,ap_rep,"ap_rep",ktest_make_sample_ap_rep);
     encode_run(aprep,ap_rep,"ap_rep","",encode_krb5_ap_rep);
+    ktest_empty_ap_rep(&aprep);
   }  
 
   /****************************************************************/
@@ -257,6 +274,7 @@ main(argc, argv)
     ktest_destroy_keyblock(&(apenc.subkey));
     apenc.seq_number = 0;
     encode_run(apenc,ap_rep_enc_part,"ap_rep_enc_part","(optionals NULL)",encode_krb5_ap_rep_enc_part);
+    ktest_empty_ap_rep_enc_part(&apenc);
   }
   
   /****************************************************************/
@@ -285,6 +303,7 @@ main(argc, argv)
 #endif
     asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
     encode_run(asreq,as_req,"as_req","(optionals NULL except server)",encode_krb5_as_req);
+    ktest_empty_kdc_req(&asreq);
   }
   
   /****************************************************************/
@@ -314,12 +333,15 @@ main(argc, argv)
 #endif
     tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
     encode_run(tgsreq,tgs_req,"tgs_req","(optionals NULL except server)",encode_krb5_tgs_req);
+
+    ktest_empty_kdc_req(&tgsreq);
   }
   
   /****************************************************************/
   /* encode_krb5_kdc_req_body */
   {
     krb5_kdc_req kdcrb;
+    memset(&kdcrb, 0, sizeof(kdcrb));
     setup(kdcrb,kdc_req_body,"kdc_req_body",ktest_make_sample_kdc_req_body);
     kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
     current_appl_type = 1007;	/* Force interpretation as kdc-req-body */
@@ -344,6 +366,8 @@ main(argc, argv)
     kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
     current_appl_type = 1007;	/* Force interpretation as kdc-req-body */
     encode_run(kdcrb,kdc_req_body,"kdc_req_body","(optionals NULL except server)",encode_krb5_kdc_req_body);
+
+    ktest_empty_kdc_req(&kdcrb);
   }
   
   /****************************************************************/
@@ -358,6 +382,8 @@ main(argc, argv)
     s.seq_number = 0;
     ktest_destroy_address(&(s.r_address));
     encode_run(s,safe,"safe","(optionals NULL)",encode_krb5_safe);
+
+    ktest_empty_safe(&s);
   }
   
   /****************************************************************/
@@ -366,6 +392,7 @@ main(argc, argv)
     krb5_priv p;
     setup(p,priv,"priv",ktest_make_sample_priv);
     encode_run(p,priv,"priv","",encode_krb5_priv);
+    ktest_empty_priv(&p);
   }
   
   /****************************************************************/
@@ -380,6 +407,8 @@ main(argc, argv)
     ep.seq_number = 0;
     ktest_destroy_address(&(ep.r_address));
     encode_run(ep,enc_priv_part,"enc_priv_part","(optionals NULL)",encode_krb5_enc_priv_part);
+
+    ktest_empty_priv_enc_part(&ep);
   }
   
   /****************************************************************/
@@ -388,6 +417,7 @@ main(argc, argv)
     krb5_cred c;
     setup(c,cred,"cred",ktest_make_sample_cred);
     encode_run(c,cred,"cred","",encode_krb5_cred);
+    ktest_empty_cred(&c);
   }
   
   /****************************************************************/
@@ -410,6 +440,8 @@ main(argc, argv)
     ktest_destroy_address(&(cep.s_address));
     ktest_destroy_address(&(cep.r_address));
     encode_run(cep,enc_cred_part,"enc_cred_part","(optionals NULL)",encode_krb5_enc_cred_part);
+
+    ktest_empty_cred_enc_part(&cep);
   }
   
   /****************************************************************/
@@ -424,6 +456,8 @@ main(argc, argv)
     ktest_empty_data(&(kerr.text));
     ktest_empty_data(&(kerr.e_data));
     encode_run(kerr,error,"error","(optionals NULL)",encode_krb5_error);
+
+    ktest_empty_error(&kerr);
   }
   
   /****************************************************************/
@@ -439,6 +473,8 @@ main(argc, argv)
     }
     current_appl_type = 1004;	/* Force type to be authdata */
     encoder_print_results(code, "authorization_data", "");
+
+    ktest_destroy_authorization_data(&ad);
   }
   
   /****************************************************************/
@@ -447,6 +483,7 @@ main(argc, argv)
     passwd_phrase_element ppe;
     setup(ppe,passwd_phrase_element,"PasswdSequence",ktest_make_sample_passwd_phrase_element);
     encode_run(ppe,passwd_phrase_element,"pwd_sequence","",encode_krb5_pwd_sequence);
+    ktest_empty_passwd_phrase_element(&ppe);
   }
 
   /****************************************************************/
@@ -455,6 +492,7 @@ main(argc, argv)
     krb5_pwd_data pd;
     setup(pd,krb5_pwd_data,"PasswdData",ktest_make_sample_krb5_pwd_data);
     encode_run(pd,krb5_pwd_data,"pwd_data","",encode_krb5_pwd_data);
+    ktest_empty_pwd_data(&pd);
   }
 
   /****************************************************************/
@@ -469,6 +507,8 @@ main(argc, argv)
 	exit(1);
     }
     encoder_print_results(code, "padata_sequence", "");
+    
+    ktest_destroy_pa_data_array(&pa);
   }
 
   /****************************************************************/
@@ -483,6 +523,8 @@ main(argc, argv)
 	exit(1);
     }
     encoder_print_results(code, "padata_sequence(empty)", "");
+
+    ktest_destroy_pa_data_array(&pa);
   }
 
   /****************************************************************/
@@ -492,9 +534,12 @@ main(argc, argv)
     setup(am,krb5_alt_method,"AltMethod",ktest_make_sample_alt_method);
     encode_run(am,krb5_alt_method,"alt_method","",encode_krb5_alt_method);
     am.length = 0;
+    if (am.data)
+      free(am.data);
     am.data = 0;
     encode_run(am,krb5_alt_method,"alt_method (no data)","",
 	       encode_krb5_alt_method);
+    ktest_empty_alt_method(&am);
   }
 
   /****************************************************************/
@@ -529,7 +574,34 @@ main(argc, argv)
     }
     encoder_print_results(code, "etype_info (no info)", "");
 
-    free(info);
+    ktest_destroy_etype_info(info);
+  }
+
+  /* encode_etype_info 2*/
+  {
+    krb5_etype_info_entry **info;
+    
+    setup(info,krb5_etype_info_entry **,"etype_info2",
+	  ktest_make_sample_etype_info2);
+    retval = encode_krb5_etype_info2((const krb5_etype_info_entry **)info,&(code));
+    if(retval) {
+	com_err("encoding etype_info",retval,"");
+	exit(1);
+    }
+    encoder_print_results(code, "etype_info2", "");
+    ktest_destroy_etype_info_entry(info[2]);      info[2] = 0;
+    ktest_destroy_etype_info_entry(info[1]);      info[1] = 0;
+
+    retval = encode_krb5_etype_info2((const krb5_etype_info_entry **)info,&(code));
+    if(retval) {
+	com_err("encoding etype_info (only 1)",retval,"");
+	exit(1);
+    }
+    encoder_print_results(code, "etype_info2 (only 1)", "");
+
+    ktest_destroy_etype_info(info);
+/*    ktest_destroy_etype_info_entry(info[0]);      info[0] = 0;*/
+    
   }
 
   /****************************************************************/
@@ -549,6 +621,7 @@ main(argc, argv)
     setup(enc_data,krb5_enc_data,"enc_data",ktest_make_sample_enc_data);
     current_appl_type = 1001;
     encode_run(enc_data,krb5_enc_data,"enc_data","",encode_krb5_enc_data);
+    ktest_destroy_enc_data(&enc_data);
   }
   /****************************************************************/
   /* encode_krb5_sam_challenge */
@@ -558,6 +631,7 @@ main(argc, argv)
 	  ktest_make_sample_sam_challenge);
     encode_run(sam_ch,krb5_sam_challenge,"sam_challenge","",
 	       encode_krb5_sam_challenge);
+    ktest_empty_sam_challenge(&sam_ch);
   }
   /****************************************************************/
   /* encode_krb5_sam_response */
@@ -567,6 +641,7 @@ main(argc, argv)
 	  ktest_make_sample_sam_response);
     encode_run(sam_ch,krb5_sam_response,"sam_response","",
 	       encode_krb5_sam_response);
+    ktest_empty_sam_response(&sam_ch);
   }
 #if 0
   /****************************************************************/
@@ -598,6 +673,7 @@ main(argc, argv)
   }
 #endif
 
+  krb5_free_context(test_context);
   exit(error_count);
   return(error_count);
 }
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index af02d1ad7..12ff8fb93 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -71,6 +71,7 @@ krb5_error_code ktest_make_sample_ticket(tkt)
   if(retval) return retval;
   retval = ktest_make_sample_enc_data(&(tkt->enc_part));
   if(retval) return retval;
+  tkt->enc_part2 = NULL;
 
   return 0;
 }
@@ -228,8 +229,6 @@ krb5_error_code ktest_make_sample_last_req(lr)
   *lr = (krb5_last_req_entry**)calloc(3,sizeof(krb5_last_req_entry*));
   if(*lr == NULL) return ENOMEM;
   for(i=0; i<=1; i++){
-    (*lr)[i] = (krb5_last_req_entry*)calloc(1,sizeof(krb5_last_req_entry));
-    if((*lr)[i] == NULL) return ENOMEM;
     retval = ktest_make_sample_last_req_entry(&((*lr)[i]));
     if(retval) return retval;
   }
@@ -628,7 +627,8 @@ krb5_error_code ktest_make_sample_alt_method(p)
      krb5_alt_method * p;
 {
     p->method = 42;
-    p->data = (krb5_octet *) "secret";
+    p->data = (krb5_octet *) strdup("secret");
+    if(p->data == NULL) return ENOMEM;
     p->length = strlen((char *) p->data);
     return 0;
 }
@@ -656,6 +656,8 @@ krb5_error_code ktest_make_sample_etype_info(p)
 	if (info[i]->salt == 0)
 	    goto memfail;
 	strcpy((char *) info[i]->salt, buf);
+	info[i]->s2kparams.data = NULL;
+	info[i]->s2kparams.length = 0;
 	info[i]->magic = KV5M_ETYPE_INFO_ENTRY;
     }
     free(info[1]->salt);
@@ -668,6 +670,49 @@ memfail:
     return ENOMEM;
 }
 
+
+krb5_error_code ktest_make_sample_etype_info2(p)
+     krb5_etype_info_entry *** p;
+{
+    krb5_etype_info_entry **info;
+    int	i;
+    char buf[80];
+
+    info = malloc(sizeof(krb5_etype_info_entry *) * 4);
+    if (!info)
+	return ENOMEM;
+    memset(info, 0, sizeof(krb5_etype_info_entry *) * 4);
+
+    for (i=0; i < 3; i++) {
+	info[i] = malloc(sizeof(krb5_etype_info_entry));
+	if (info[i] == 0)
+	    goto memfail;
+	info[i]->etype = i;
+	sprintf(buf, "Morton's #%d", i);
+	info[i]->length = strlen(buf);
+	info[i]->salt = malloc((size_t) (info[i]->length+1));
+	if (info[i]->salt == 0)
+	    goto memfail;
+	strcpy((char *) info[i]->salt, buf);
+	sprintf(buf, "s2k: %d", i);
+	info[i]->s2kparams.data = malloc(strlen(buf)+1);
+	if (info[i]->s2kparams.data == NULL)
+	    goto memfail;
+	strcpy( info[i]->s2kparams.data, buf);
+	info[i]->s2kparams.length = strlen(buf);
+	info[i]->magic = KV5M_ETYPE_INFO_ENTRY;
+    }
+    free(info[1]->salt);
+    info[1]->length = KRB5_ETYPE_NO_SALT;
+    info[1]->salt = 0;
+    *p = info;
+    return 0;
+memfail:
+    ktest_destroy_etype_info(info);
+    return ENOMEM;
+}
+
+
 krb5_error_code ktest_make_sample_pa_enc_ts(pa_enc)
      krb5_pa_enc_ts * pa_enc;
 {
@@ -685,15 +730,19 @@ krb5_error_code ktest_make_sample_sam_challenge(p)
   p->magic = KV5M_SAM_CHALLENGE;
   p->sam_type = 42; /* information */
   p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; /* KRB5_SAM_* values */
-  p->sam_type_name.data = "type name";
+  p->sam_type_name.data = strdup("type name");
+  if (p->sam_type_name.data == NULL) return ENOMEM;
   p->sam_type_name.length = strlen(p->sam_type_name.data);
   p->sam_track_id.data = 0;
   p->sam_track_id.length = 0;
-  p->sam_challenge_label.data = "challenge label";
+  p->sam_challenge_label.data = strdup("challenge label");
+  if (p->sam_challenge_label.data == NULL) return ENOMEM;
   p->sam_challenge_label.length = strlen(p->sam_challenge_label.data);
-  p->sam_challenge.data = "challenge ipse";
+  p->sam_challenge.data = strdup("challenge ipse");
+  if (p->sam_challenge.data == NULL) return ENOMEM;
   p->sam_challenge.length = strlen(p->sam_challenge.data);
-  p->sam_response_prompt.data = "response_prompt ipse";
+  p->sam_response_prompt.data = strdup("response_prompt ipse");
+  if (p->sam_response_prompt.data == NULL) return ENOMEM;
   p->sam_response_prompt.length = strlen(p->sam_response_prompt.data);
   p->sam_pk_for_sad.data = 0;
   p->sam_pk_for_sad.length = 0;
@@ -710,13 +759,16 @@ krb5_error_code ktest_make_sample_sam_response(p)
   p->magic = KV5M_SAM_RESPONSE;
   p->sam_type = 42; /* information */
   p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; /* KRB5_SAM_* values */
-  p->sam_track_id.data = "track data";
+  p->sam_track_id.data = strdup("track data");
+  if (p->sam_track_id.data == NULL) return ENOMEM;
   p->sam_track_id.length = strlen(p->sam_track_id.data);
-  p->sam_enc_key.ciphertext.data = "key";
+  p->sam_enc_key.ciphertext.data = strdup("key");
+  if (p->sam_enc_key.ciphertext.data == NULL) return ENOMEM;
   p->sam_enc_key.ciphertext.length = strlen(p->sam_enc_key.ciphertext.data);
   p->sam_enc_key.enctype = ENCTYPE_DES_CBC_CRC;
   p->sam_enc_key.kvno = 1942;
-  p->sam_enc_nonce_or_ts.ciphertext.data = "nonce or ts";
+  p->sam_enc_nonce_or_ts.ciphertext.data = strdup("nonce or ts");
+  if (p->sam_enc_nonce_or_ts.ciphertext.data == NULL) return ENOMEM;
   p->sam_enc_nonce_or_ts.ciphertext.length = 
     strlen(p->sam_enc_nonce_or_ts.ciphertext.data);
   p->sam_enc_nonce_or_ts.enctype = ENCTYPE_DES_CBC_CRC;
@@ -764,6 +816,17 @@ void ktest_destroy_checksum(cs)
   }
 }
 
+void ktest_empty_keyblock(kb)
+     krb5_keyblock * kb;
+{
+  if (kb != NULL) {
+    if (kb->contents) {
+      free (kb->contents);
+      kb->contents = NULL;
+    }
+  }
+}
+
 void ktest_destroy_keyblock(kb)
      krb5_keyblock ** kb;
 {
@@ -779,8 +842,10 @@ void ktest_empty_authorization_data(ad)
 {
   int i;
 
-  for(i=0; ad[i] != NULL; i++)
-    ktest_destroy_authdata(&(ad[i]));
+  if(*ad != NULL) {
+    for(i=0; ad[i] != NULL; i++)
+      ktest_destroy_authdata(&(ad[i]));
+  }
 }
 
 void ktest_destroy_authorization_data(ad)
@@ -863,6 +928,8 @@ void ktest_destroy_principal(p)
 
   for(i=0; i<(*p)->length; i++)
     ktest_empty_data(&(((*p)->data)[i]));
+  ktest_empty_data(&((*p)->realm));
+  free((*p)->data);
   free(*p);
   *p = NULL;
 }
@@ -899,10 +966,22 @@ void ktest_destroy_ticket(tkt)
 {
   ktest_destroy_principal(&((*tkt)->server));
   ktest_destroy_enc_data(&((*tkt)->enc_part));
+  /*  ktest_empty_enc_tkt_part(((*tkt)->enc_part2));*/
   free(*tkt);
   *tkt = NULL;
 }  
 
+void ktest_empty_ticket(tkt)
+     krb5_ticket * tkt;
+{
+  if(tkt->server)
+    ktest_destroy_principal(&((tkt)->server));
+  ktest_destroy_enc_data(&((tkt)->enc_part));
+  if (tkt->enc_part2) {
+    ktest_destroy_enc_tkt_part(&(tkt->enc_part2));
+  }
+}  
+
 void ktest_destroy_enc_data(ed)
      krb5_enc_data * ed;
 {
@@ -915,6 +994,7 @@ void ktest_destroy_etype_info_entry(i)
 {
     if (i->salt)
 	free(i->salt);
+    ktest_empty_data(&(i->s2kparams));
     free(i);
 }
 
@@ -929,3 +1009,283 @@ void ktest_destroy_etype_info(info)
 }
     
 
+void ktest_empty_kdc_req(kr)
+     krb5_kdc_req *kr;
+{
+  if (kr->padata)
+      ktest_destroy_pa_data_array(&(kr->padata));
+
+  if (kr->client)
+      ktest_destroy_principal(&(kr->client));
+
+  if (kr->server)
+      ktest_destroy_principal(&(kr->server));
+  if (kr->ktype)
+      free(kr->ktype);
+  if (kr->addresses)
+      ktest_destroy_addresses(&(kr->addresses));
+      ktest_destroy_enc_data(&(kr->authorization_data));
+  if (kr->unenc_authdata)
+      ktest_destroy_authorization_data(&(kr->unenc_authdata));
+  if (kr->second_ticket)
+      ktest_destroy_sequence_of_ticket(&(kr->second_ticket));
+
+}
+
+void ktest_empty_kdc_rep(kr)
+     krb5_kdc_rep *kr;
+{
+  if (kr->padata)
+      ktest_destroy_pa_data_array(&(kr->padata));
+
+  if (kr->client)
+      ktest_destroy_principal(&(kr->client));
+
+  if (kr->ticket)
+      ktest_destroy_ticket(&(kr->ticket));
+
+  ktest_destroy_enc_data(&kr->enc_part);
+
+  if (kr->enc_part2) {
+    ktest_empty_enc_kdc_rep_part(kr->enc_part2);
+    free(kr->enc_part2);
+    kr->enc_part2 = NULL;
+  }
+}
+
+
+void ktest_empty_authenticator(a)
+     krb5_authenticator * a;
+{
+
+  if(a->client) 
+    ktest_destroy_principal(&(a->client));
+  if(a->checksum)
+    ktest_destroy_checksum(&(a->checksum));
+  if(a->subkey)
+    ktest_destroy_keyblock(&(a->subkey));
+  if(a->authorization_data)
+    ktest_destroy_authorization_data(&(a->authorization_data));
+}
+
+void ktest_empty_enc_tkt_part(etp)
+     krb5_enc_tkt_part * etp;
+{
+
+  if(etp->session)
+    ktest_destroy_keyblock(&(etp->session));
+  if(etp->client) 
+    ktest_destroy_principal(&(etp->client));
+  if (etp->caddrs)
+      ktest_destroy_addresses(&(etp->caddrs));
+  if(etp->authorization_data)
+    ktest_destroy_authorization_data(&(etp->authorization_data));
+  ktest_destroy_transited(&(etp->transited));
+}
+
+void ktest_destroy_enc_tkt_part(etp)
+     krb5_enc_tkt_part ** etp;
+{
+  if(*etp) {
+    ktest_empty_enc_tkt_part(*etp);
+    free(*etp);
+    *etp = NULL;
+  }
+}
+
+void ktest_empty_enc_kdc_rep_part(ekr)
+     krb5_enc_kdc_rep_part * ekr;
+{
+
+  if(ekr->session)
+    ktest_destroy_keyblock(&(ekr->session));
+
+  if(ekr->server) 
+    ktest_destroy_principal(&(ekr->server));
+
+  if (ekr->caddrs)
+    ktest_destroy_addresses(&(ekr->caddrs));
+  ktest_destroy_last_req(&(ekr->last_req));
+}
+
+
+void ktest_destroy_transited(t)
+     krb5_transited * t;
+{
+  if(t->tr_contents.data)
+    ktest_empty_data(&(t->tr_contents));
+}
+
+
+void ktest_empty_ap_rep(ar)
+     krb5_ap_rep * ar;
+{
+  ktest_destroy_enc_data(&ar->enc_part);
+}
+
+void ktest_empty_ap_req(ar)
+     krb5_ap_req * ar;
+{
+
+  if(ar->ticket)
+      ktest_destroy_ticket(&(ar->ticket));
+  ktest_destroy_enc_data(&(ar->authenticator));
+}
+
+void ktest_empty_cred_enc_part(cep)
+     krb5_cred_enc_part * cep;
+{
+  if (cep->s_address)
+      ktest_destroy_address(&(cep->s_address));
+  if (cep->r_address)
+      ktest_destroy_address(&(cep->r_address));
+  if (cep->ticket_info)
+    ktest_destroy_sequence_of_cred_info(&(cep->ticket_info));
+}
+
+void ktest_destroy_cred_info(ci)
+     krb5_cred_info ** ci;
+{
+  if((*ci)->session)
+    ktest_destroy_keyblock(&((*ci)->session));
+  if((*ci)->client) 
+    ktest_destroy_principal(&((*ci)->client));
+  if((*ci)->server) 
+    ktest_destroy_principal(&((*ci)->server));
+  if ((*ci)->caddrs)
+    ktest_destroy_addresses(&((*ci)->caddrs));
+  free(*ci);
+  *ci = NULL;
+}
+
+void ktest_destroy_sequence_of_cred_info(soci)
+     krb5_cred_info *** soci;
+{
+  int i;
+
+  for(i=0; (*soci)[i] != NULL; i++)
+    ktest_destroy_cred_info(&((*soci)[i]));
+  free(*soci);
+  *soci = NULL;
+}
+
+
+void ktest_empty_safe(s)
+     krb5_safe * s;
+{
+  ktest_empty_data(&(s->user_data));
+  ktest_destroy_address(&(s->s_address));
+  ktest_destroy_address(&(s->r_address));
+  ktest_destroy_checksum(&(s->checksum));
+}
+
+void ktest_empty_priv_enc_part(pep)
+     krb5_priv_enc_part * pep;
+{
+  ktest_empty_data(&(pep->user_data));
+  ktest_destroy_address(&(pep->s_address));
+  ktest_destroy_address(&(pep->r_address));
+}
+
+void ktest_empty_priv(p)
+     krb5_priv * p;
+{
+  ktest_destroy_enc_data(&(p->enc_part));
+}
+
+void ktest_empty_cred(c)
+     krb5_cred * c;
+{
+
+  ktest_destroy_sequence_of_ticket(&(c->tickets));
+  ktest_destroy_enc_data(&(c->enc_part));
+  /* enc_part2 */
+
+}
+
+void ktest_destroy_last_req(lr)
+     krb5_last_req_entry *** lr;
+{
+  int i;
+
+  if(*lr) {
+    for(i=0; (*lr)[i] != NULL; i++) {
+      free((*lr)[i]);
+    }
+    free(*lr);
+  }
+}
+
+void ktest_empty_error(kerr)
+     krb5_error * kerr;
+{
+  if(kerr->client)
+    ktest_destroy_principal(&(kerr->client));
+  if(kerr->server)
+    ktest_destroy_principal(&(kerr->server));
+  ktest_empty_data(&(kerr->text));
+  ktest_empty_data(&(kerr->e_data));
+}
+
+void ktest_empty_ap_rep_enc_part(arep)
+     krb5_ap_rep_enc_part * arep;
+{
+  ktest_destroy_keyblock(&((arep)->subkey));
+}
+
+void ktest_empty_passwd_phrase_element(ppe)
+     passwd_phrase_element * ppe;
+{
+  ktest_destroy_data(&(ppe->passwd));
+  ktest_destroy_data(&(ppe->phrase));
+}
+
+void ktest_empty_pwd_data(pd)
+     krb5_pwd_data * pd;
+{
+  int i;
+
+  for(i=0; i <= pd->sequence_count; i++){
+    if(pd->element[i]) {
+      ktest_empty_passwd_phrase_element(pd->element[i]);
+      free(pd->element[i]);
+      pd->element[i] = NULL;
+    }
+  }
+  free(pd->element);
+  
+}
+
+void ktest_empty_alt_method(am)
+     krb5_alt_method *am;
+{
+  if (am->data) {
+    free(am->data);
+    am->data = NULL;
+  }
+}
+
+void ktest_empty_sam_challenge(p)
+     krb5_sam_challenge * p;
+{
+  ktest_empty_data(&(p->sam_type_name));
+  ktest_empty_data(&(p->sam_track_id));
+  ktest_empty_data(&(p->sam_challenge_label));
+  ktest_empty_data(&(p->sam_challenge));
+  ktest_empty_data(&(p->sam_response_prompt));
+  ktest_empty_data(&(p->sam_pk_for_sad));
+
+  if(p->sam_cksum.contents != NULL) {
+    free(p->sam_cksum.contents);
+    p->sam_cksum.contents = NULL;
+  }
+
+}
+
+void ktest_empty_sam_response(p)
+     krb5_sam_response * p;
+{
+  ktest_empty_data(&(p->sam_track_id));
+  ktest_empty_data(&(p->sam_enc_key.ciphertext));
+  ktest_empty_data(&(p->sam_enc_nonce_or_ts.ciphertext));
+}
diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h
index 59e87047c..915f36a00 100644
--- a/src/tests/asn.1/ktest.h
+++ b/src/tests/asn.1/ktest.h
@@ -89,6 +89,8 @@ krb5_error_code ktest_make_sample_alt_method
 
 krb5_error_code ktest_make_sample_etype_info
     (krb5_etype_info_entry *** p);
+krb5_error_code ktest_make_sample_etype_info2
+    (krb5_etype_info_entry *** p);
 krb5_error_code ktest_make_sample_pa_enc_ts
 	(krb5_pa_enc_ts *am);
 krb5_error_code ktest_make_sample_sam_challenge
@@ -125,6 +127,8 @@ void ktest_destroy_principal
 	(krb5_principal *p);
 void ktest_destroy_checksum
 	(krb5_checksum **cs);
+void ktest_empty_keyblock
+	(krb5_keyblock *kb);
 void ktest_destroy_keyblock
 	(krb5_keyblock **kb);
 void ktest_destroy_authdata
@@ -135,14 +139,65 @@ void ktest_destroy_sequence_of_ticket
 	(krb5_ticket ***sot);
   void ktest_destroy_ticket
 	(krb5_ticket **tkt);
+void ktest_empty_ticket
+	(krb5_ticket *tkt);
 void ktest_destroy_enc_data
 	(krb5_enc_data *ed);
-
+void ktest_empty_error
+        (krb5_error * kerr);
 void ktest_destroy_etype_info_entry
 	(krb5_etype_info_entry *i);
 void ktest_destroy_etype_info
 	(krb5_etype_info_entry **info);
 
+void ktest_empty_kdc_req
+        (krb5_kdc_req *kr);
+void ktest_empty_kdc_rep
+        (krb5_kdc_rep *kr);
+
+void ktest_empty_authenticator
+        (krb5_authenticator *a);
+void ktest_empty_enc_tkt_part
+        (krb5_enc_tkt_part * etp);
+void ktest_destroy_enc_tkt_part
+        (krb5_enc_tkt_part ** etp);
+void ktest_empty_enc_kdc_rep_part
+        (krb5_enc_kdc_rep_part * ekr);
+void ktest_destroy_transited
+        (krb5_transited * t);
+void ktest_empty_ap_rep
+        (krb5_ap_rep * ar);
+void ktest_empty_ap_req
+        (krb5_ap_req * ar);
+void ktest_empty_cred_enc_part
+        (krb5_cred_enc_part * cep);
+void ktest_destroy_cred_info
+        (krb5_cred_info ** ci);
+void ktest_destroy_sequence_of_cred_info
+        (krb5_cred_info *** soci);
+void ktest_empty_safe
+        (krb5_safe * s);
+void ktest_empty_priv
+        (krb5_priv * p);
+void ktest_empty_priv_enc_part
+        (krb5_priv_enc_part * pep);
+void ktest_empty_cred
+        (krb5_cred * c);
+void ktest_destroy_last_req
+        (krb5_last_req_entry *** lr);
+void ktest_empty_ap_rep_enc_part
+        (krb5_ap_rep_enc_part * arep);
+void ktest_empty_passwd_phrase_element
+        (passwd_phrase_element * ppe);
+void ktest_empty_pwd_data
+        (krb5_pwd_data * pd);
+void ktest_empty_alt_method
+	(krb5_alt_method *am);
+void ktest_empty_sam_challenge
+	(krb5_sam_challenge * p);
+void ktest_empty_sam_response
+	(krb5_sam_response * p);
+
 extern krb5_context test_context;
 extern char *sample_principal_name;
 
diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out
index 0dbfc8d77..a118c050d 100644
--- a/src/tests/asn.1/reference_encode.out
+++ b/src/tests/asn.1/reference_encode.out
@@ -44,6 +44,8 @@ encode_krb5_alt_method (no data): 30 05 A0 03 02 01 2A
 encode_krb5_etype_info: 30 33 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 30 05 A0 03 02 01 01 30 14 A0 03 02 01 02 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 32
 encode_krb5_etype_info (only 1): 30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30
 encode_krb5_etype_info (no info): 30 00
+encode_krb5_etype_info2: 30 51 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 30 0F A0 03 02 01 01 A2 08 04 06 73 32 6B 3A 20 31 30 1E A0 03 02 01 02 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 A2 08 04 06 73 32 6B 3A 20 32
+encode_krb5_etype_info2 (only 1): 30 20 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30
 encode_krb5_pa_enc_ts: 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40
 encode_krb5_pa_enc_ts (no usec): 30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A
 encode_krb5_enc_data: 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65
diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out
index 2287d5fac..95311d3fe 100644
--- a/src/tests/asn.1/trval_reference.out
+++ b/src/tests/asn.1/trval_reference.out
@@ -1124,6 +1124,29 @@ encode_krb5_etype_info (no info):
 
 [Sequence/Sequence Of] 
 
+encode_krb5_etype_info2:
+
+[Sequence/Sequence Of] 
+.  [Sequence/Sequence Of] 
+.  .  [0] [Integer] 0
+.  .  [1] [General string] "Morton's #0"
+.  .  [2] [Octet String] "s2k: 0"
+.  [Sequence/Sequence Of] 
+.  .  [0] [Integer] 1
+.  .  [2] [Octet String] "s2k: 1"
+.  [Sequence/Sequence Of] 
+.  .  [0] [Integer] 2
+.  .  [1] [General string] "Morton's #2"
+.  .  [2] [Octet String] "s2k: 2"
+
+encode_krb5_etype_info2 (only 1):
+
+[Sequence/Sequence Of] 
+.  [Sequence/Sequence Of] 
+.  .  [0] [Integer] 0
+.  .  [1] [General string] "Morton's #0"
+.  .  [2] [Octet String] "s2k: 0"
+
 encode_krb5_pa_enc_ts:
 
 [Sequence/Sequence Of] 
diff --git a/src/tests/asn.1/utility.c b/src/tests/asn.1/utility.c
index 07addc4a1..526cdce2d 100644
--- a/src/tests/asn.1/utility.c
+++ b/src/tests/asn.1/utility.c
@@ -2,6 +2,7 @@
 #include "utility.h"
 #include <stdlib.h>
 #include <stdio.h>
+#include <ctype.h>
 
 char hexchar (const unsigned int digit);
 
@@ -60,33 +61,40 @@ krb5_error_code krb5_data_parse(d, s)
   return 0;
 }
 
-krb5_error_code krb5_data_hex_parse(d, s)
-     krb5_data * d;
-     const char * s;
+krb5_error_code krb5_data_hex_parse(krb5_data *d, const char *s)
 {
-  int i, digit;
-  char *copy; 
-  char *pos;
+    int lo;
+    long v;
+    const char *cp;
+    char *dp;
+    char buf[2];
 
-    /* 
-     * Do a strdup() and use that, because some systems can't handle non
-     * writeable strings being passed to sscanf() --proven.
-     */
-    copy = strdup(s);
-  d->data = (char*)calloc((strlen(copy)+1)/3,sizeof(char));
-  if(d->data == NULL) return ENOMEM;
-  d->length = (strlen(copy)+1)/3;
-  for(i=0,pos=(char*)copy; i<d->length; i++,pos+=3){
-    if(!sscanf(pos,"%x",&digit)) {
-#ifdef KRB5_USE_ISODE
-	    return EINVAL;
-#else
+    d->data = calloc((strlen(s) / 2 + 1), 1);
+    if (d->data == NULL)
+	return ENOMEM;
+    d->length = 0;
+    buf[1] = '\0';
+    for (lo = 0, dp = d->data, cp = s; *cp; cp++) {
+	if (*cp < 0)
 	    return ASN1_PARSE_ERROR;
-#endif
+	else if (isspace(*cp))
+	    continue;
+	else if (isxdigit(*cp)) {
+	    buf[0] = *cp;
+	    v = strtol(buf, NULL, 16);
+	} else
+	    return ASN1_PARSE_ERROR;
+	if (lo) {
+	    *dp++ |= v;
+	    lo = 0;
+	} else {
+	    *dp = v << 4;
+	    lo = 1;
+	}
     }
-    d->data[i] = (char)digit;
-  }
-  return 0;
+
+    d->length = dp - d->data;
+    return 0;
 }
 
 #if 0
diff --git a/src/tests/create/ChangeLog b/src/tests/create/ChangeLog
index 02e46dfbc..001b6b1f4 100644
--- a/src/tests/create/ChangeLog
+++ b/src/tests/create/ChangeLog
@@ -1,3 +1,8 @@
+2003-05-22  Ezra Peisach  <epeisach@mit.edu>
+
+	* kdb5_mkdums.c (main): When attempting to register writable
+	keytab, do not fail if error is KRB5_KT_TYPE_EXISTS.
+
 2002-08-29  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.in: Revert $(S)=>/ change, for Windows support.
diff --git a/src/tests/create/Makefile.in b/src/tests/create/Makefile.in
index babce9eb1..119cef001 100644
--- a/src/tests/create/Makefile.in
+++ b/src/tests/create/Makefile.in
@@ -25,7 +25,8 @@ clean::
 #
 $(OUTPRE)kdb5_mkdums.$(OBJEXT): kdb5_mkdums.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SS_DEPS)
+  $(SS_DEPS)
 
diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c
index d9c34062d..4a1f0e94f 100644
--- a/src/tests/create/kdb5_mkdums.c
+++ b/src/tests/create/kdb5_mkdums.c
@@ -151,9 +151,11 @@ main(argc, argv)
 
 
     if ((retval = krb5_kt_register(test_context, &krb5_ktf_writable_ops))) {
-	com_err(progname, retval,
+        if (retval != KRB5_KT_TYPE_EXISTS) {
+	  com_err(progname, retval,
 		"while registering writable key table functions");
-	exit(1);
+	  exit(1);
+	}
     }
 
     if (!enctypedone)
diff --git a/src/tests/dejagnu/config/ChangeLog b/src/tests/dejagnu/config/ChangeLog
index 7d8589b47..840ae0c1d 100644
--- a/src/tests/dejagnu/config/ChangeLog
+++ b/src/tests/dejagnu/config/ChangeLog
@@ -1,3 +1,70 @@
+2003-06-05  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp (setup_root_shell): Check for "not authorized".  Map
+	eof to unsupported.
+
+2003-06-04  Tom Yu  <tlyu@mit.edu>
+
+	* default.exp (setup_root_shell): Don't try to use the procedure
+	"-" when handling error messages from rlogin.
+
+2003-06-03  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp (setup_root_shell): Handle error messages indicating
+	"-x" isn't supported.
+	(start_kerberos_daemons): "cannont" => "cannot".
+
+2003-06-01  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp: Default RLOGIN_FLAGS to "-x".
+	(start_kerberos_daemons): Watch for "Cannot bind server socket"
+	and log it.  Watch for "no sockets set up" and report an error.
+	(setup_root_shell): Watch for "Cannot assign requested address",
+	log it and give up.
+
+2003-05-21  Tom Yu  <tlyu@mit.edu>
+
+	* default.exp: Be slightly more lenient about matching password
+	prompts.
+
+2003-05-16  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp (spawn_xterm): Add KPASSWD and REALMNAME to the list
+	of exported variables.
+
+2003-04-18  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp: Add passes for testing AES.
+	(start_kerberos_daemons): Add a small delay between starting the
+	"tail -f" processes and appending the markers to their files.
+	(spawn_xterm): Add RLOGIN, RLOGIND, FTP, and FTPD to the list of
+	variables to export to the environment.  Check that variables are
+	defined before exporting them.
+
+2003-03-28  Tom Yu  <tlyu@mit.edu>
+
+	* default.exp (start_kerberos_daemons): If we get a timeout
+	looking for the mark, log out the last 10 lines of the kdc
+	logfile.
+
+2003-03-26  Tom Yu  <tlyu@mit.edu>
+
+	* default.exp (v4kinit): Expect failure when kiniting to a des3
+	TGT, due to fix for MITKRB5-SA-2003-004.
+	(setup_kadmind_srvtab): Remove.  It's not needed anymore.
+
+2003-03-14  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp (setup_root_shell): If we get connection refused
+	messages, followed by no unrecognized errors and then eof, report
+	it as an unsupported test.
+
+2003-03-14  Ken Raeburn  <raeburn@mit.edu>
+
+	* default.exp (setup_root_shell): If we get connection refused
+	messages, followed by no unrecognized errors and then eof, report
+	it as an unsupported test.
+
 2003-02-04  Tom Yu  <tlyu@mit.edu>
 
 	* default.exp (start_kerberos_daemons): Use correct argument to
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
index f025eb763..907c5347b 100644
--- a/src/tests/dejagnu/config/default.exp
+++ b/src/tests/dejagnu/config/default.exp
@@ -85,6 +85,39 @@ set passes {
 	{kdc_supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal}
 	{dummy=[verbose -log "DES3 TGT, DES3 + DES enctypes"]}
     }
+    {
+	aes
+	des3_krbtgt=0
+	{supported_enctypes=aes256-cts-hmac-sha1-96:normal des-cbc-crc:normal}
+	{kdc_supported_enctypes=aes256-cts-hmac-sha1-96:normal des-cbc-crc:normal}
+	{permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des-cbc-crc}
+	{permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des-cbc-crc}
+	{permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des-cbc-crc}
+	{master_key_type=aes256-cts-hmac-sha1-96}
+	{dummy=[verbose -log "AES + DES enctypes"]}
+    }
+    {
+	aes-des3
+	des3_krbtgt=0
+	{supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal}
+	{kdc_supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal}
+	{permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{master_key_type=aes256-cts-hmac-sha1-96}
+	{dummy=[verbose -log "AES + DES enctypes"]}
+    }
+    {
+	des3-aes
+	des3_krbtgt=1
+	{supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal}
+	{kdc_supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal}
+	{permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc}
+	{master_key_type=aes256-cts-hmac-sha1-96}
+	{dummy=[verbose -log "AES + DES enctypes, DES3 TGT"]}
+    }
     {
 	des-v4
 	des3_krbtgt=0
@@ -203,31 +236,30 @@ set unused_passes {
 	all-enctypes
 	des3_krbtgt=1
 	{supported_enctypes=\
-	rijndael256-hmac-sha1:normal rijndael192-hmac-sha1:normal rijndael128-hmac-sha1:normal \
-	serpent256-hmac-sha1:normal serpent192-hmac-sha1:norealm serpent128-hmac-sha1:normal \
-	twofish256-hmac-sha1:normal twofish192-hmac-sha1:norealm twofish128-hmac-sha1:normal \
+	aes256-cts-hmac-sha1-96:normal aes256-cts-hmac-sha1-96:norealm \
+	aes128-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:norealm \
 	des3-cbc-sha1:normal des3-cbc-sha1:none \
 	des-cbc-md5:normal des-cbc-md4:normal des-cbc-crc:normal \
 	des-cbc-md5:v4 des-cbc-md4:v4 des-cbc-crc:v4 \
 	}
 	{kdc_supported_enctypes=\
-	rijndael256-hmac-sha1:normal rijndael192-hmac-sha1:normal rijndael128-hmac-sha1:normal \
-	serpent256-hmac-sha1:normal serpent192-hmac-sha1:norealm serpent128-hmac-sha1:normal \
-	twofish256-hmac-sha1:normal twofish192-hmac-sha1:norealm twofish128-hmac-sha1:normal \
 	des3-cbc-sha1:normal des3-cbc-sha1:none \
 	des-cbc-md5:normal des-cbc-md4:normal des-cbc-crc:normal \
 	des-cbc-md5:v4 des-cbc-md4:v4 des-cbc-crc:v4 \
 	}
 	{dummy=[verbose -log "DES3 TGT, default enctypes"]}
     }
+    # This won't work for anything using GSSAPI until it gets AES support.
     {
-	aes
+	aes-only
 	des3_krbtgt=0
-	{supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal}
-	{kdc_supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal}
-	{default_tgs_enctypes=rijndael256-hmac-sha1 des-cbc-crc}
-	{default_tkt_enctypes=rijndael256-hmac-sha1 des-cbc-crc}
-	{dummy=[verbose -log "DES3 TGT, default enctypes"]}
+	{supported_enctypes=aes256-cts-hmac-sha1-96:normal}
+	{kdc_supported_enctypes=aes256-cts-hmac-sha1-96:normal}
+	{permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96}
+	{permitted_enctypes(client)=aes256-cts-hmac-sha1-96}
+	{permitted_enctypes(server)=aes256-cts-hmac-sha1-96}
+	{master_key_type=aes256-cts-hmac-sha1-96}
+	{dummy=[verbose -log "AES only, no DES or DES3 support"]}
     }
 }
 #	{supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal }
@@ -346,7 +378,7 @@ if ![info exists RLOGIN] {
 }
 
 if ![info exists RLOGIN_FLAGS] {
-    set RLOGIN_FLAGS ""
+    set RLOGIN_FLAGS "-x"
 }
 
 # We use a couple of variables to hold shell prompts which may be
@@ -692,7 +724,6 @@ proc setup_kerberos_files { } {
 	puts $conffile "		database_name = $tmppwd/db"
 	puts $conffile "		admin_database_name = $tmppwd/adb"
 	puts $conffile "		admin_database_lockfile = $tmppwd/adb.lock"
-	puts $conffile "		admin_keytab = $tmppwd/admin-keytab"
 	puts $conffile "		key_stash_file = $tmppwd/stash"
 	puts $conffile "		acl_file = $tmppwd/acl"
 	puts $conffile "		kadmind_port = 3750"
@@ -938,83 +969,6 @@ proc restore_kerberos_env { } {
 
 }
 
-# setup_kadmind_srvtab
-# A procedure to build the srvtab for kadmind5 so that kadmin5 and it
-# may successfully communicate.
-# Returns 1 on success, 0 on failure.
-proc setup_kadmind_srvtab {  } {
-    global REALMNAME
-    global KADMIN_LOCAL
-    global KEY
-    global tmppwd
-
-    catch "exec rm -f $tmppwd/admin-keytab"
-    envstack_push
-    setup_kerberos_env kdc
-    spawn $KADMIN_LOCAL -r $REALMNAME
-    envstack_pop
-    catch expect_after
-    expect_after {
-	-re "(.*)\r\nkadmin.local:  " {
-	    fail "kadmin.local admin-keytab (unmatched output: $expect_out(1,string)"
-	    catch "exec rm -f $tmppwd/admin-keytab"
-	    catch "expect_after"
-	    return 0
-	}
-	timeout {
-	    fail "kadmin.local admin-keytab (timeout)"
-	    catch "exec rm -f $tmppwd/admin-keytab"
-	    catch "expect_after"
-	    return 0
-	}
-	eof {
-	    fail "kadmin.local admin-keytab (eof)"
-	    catch "exec rm -f $tmppwd/admin-keytab"
-	    catch "expect_after"
-	    return 0
-	}
-    }
-    expect "kadmin.local:  "
-    send "xst -k admin-new-srvtab kadmin/admin\r"
-    expect "xst -k admin-new-srvtab kadmin/admin\r\n"
-    expect -re ".*Entry for principal kadmin/admin.* added to keytab WRFILE:admin-new-srvtab."
-    expect "kadmin.local:  "
-
-    catch "exec mv -f admin-new-srvtab changepw-new-srvtab" exec_output
-    if ![string match "" $exec_output] {
-	verbose -log "$exec_output"
-	perror "can't mv admin-new-srvtab"
-	catch expect_after
-	return 0
-    }
-
-    send "xst -k changepw-new-srvtab kadmin/changepw\r"
-    expect "xst -k changepw-new-srvtab kadmin/changepw\r\n"
-    expect -re ".*Entry for principal kadmin/changepw.* added to keytab WRFILE:changepw-new-srvtab."
-    expect "kadmin.local:  "
-    send "quit\r"
-    expect eof
-    catch expect_after
-    if ![check_exit_status "kadmin.local admin-keytab"] {
-	catch "exec rm -f $tmppwd/admin-keytab"
-	perror "kadmin.local admin-keytab exited abnormally"
-	return 0
-    }
-
-    catch "exec mv -f changepw-new-srvtab $tmppwd/admin-keytab" exec_output
-    if ![string match "" $exec_output] {
-	verbose -log "$exec_output"
-	perror "can't mv new admin-keytab"
-	return 0
-    }
-
-    # Make the srvtab file globally readable in case we are using a
-    # root shell and the srvtab is NFS mounted.
-    catch "exec chmod a+r $tmppwd/admin-keytab"
-
-    return 1
-}
-
 # setup_kerberos_db
 # Initialize the Kerberos database.  If the argument is non-zero, call
 # pass at relevant points.  Returns 1 on success, 0 on failure.
@@ -1270,12 +1224,7 @@ proc setup_kerberos_db { standalone } {
 	    }
 	}
     }
-    # XXX should deal with envstack inside setup_kadmind_srvtab too
-    set ret [setup_kadmind_srvtab]
     envstack_pop
-    if !$ret {
-	return 0
-    }
 
     # create the admin database lock file
     catch "exec touch $tmppwd/adb.lock"
@@ -1336,8 +1285,10 @@ proc start_kerberos_daemons { standalone } {
     set tailf_pid [exp_pid]
 
     set markstr "===MARK $tailf_pid [exec date] ==="
+    sleep 2
     set f [open $kdc_lfile a]
     puts $f $markstr
+    flush $f
     close $f
 
     expect {
@@ -1345,6 +1296,8 @@ proc start_kerberos_daemons { standalone } {
 	-ex "$markstr\r\n" { }
 	-re "\[^\r\n\]*\r\n" { exp_continue }
 	timeout {
+	    verbose -log "tail $kdc_lfile output:"
+	    verbose -log [exec tail $kdc_lfile]
 	    if {$standalone} {
 		verbose -log "tail -f timed out ($timeout sec) looking for mark in kdc log"
 		fail "krb5kdc"
@@ -1369,6 +1322,23 @@ proc start_kerberos_daemons { standalone } {
     expect {
 	-i $tailf_spawn_id
 	-re "commencing operation\r\n" { }
+	-re "krb5kdc: \[a-zA-Z\]* - Cannot bind server socket to \[ 0-9a-fA-F:.\]*\r\n" {
+	    verbose -log "warning: $expect_out(0,string)"
+	    exp_continue
+	}
+	"no sockets set up?" {
+	    if {$standalone} {
+		verbose -log "krb5kdc startup failed to bind listening sockets"
+		fail "krb5kdc"
+	    } else {
+		perror "krb5kdc startup failed to bind listening sockets"
+	    }
+	    stop_kerberos_daemons
+	    exec kill $tailf_pid
+	    expect -i $tailf_spawn_id eof
+	    wait -i $tailf_spawn_id
+	    return 0
+	}
 	timeout {
 	    if {$standalone} {
 		verbose -log "krb5kdc startup timed out"
@@ -1413,6 +1383,7 @@ proc start_kerberos_daemons { standalone } {
     set tailf_pid [exp_pid]
 
     set markstr "===MARK $tailf_pid [exec date] ==="
+    sleep 2
     set f [open $kadmind_lfile a]
     puts $f $markstr
     close $f
@@ -1455,7 +1426,7 @@ proc start_kerberos_daemons { standalone } {
     expect {
 	-i $tailf_spawn_id
 	"Seeding random number" exp_continue
-	"cannont initialize network" {
+	"cannot initialize network" {
 	    if {$standalone} {
 		verbose -log "kadmind failed network init"
 		fail "kadmind"
@@ -1588,7 +1559,7 @@ proc add_kerberos_key { kkey standalone } {
 		break
 	    }
 	}
-	expect "Enter password:"
+	expect -re "assword\[^\r\n\]*: *"
 	send "adminpass$KEY\r"
 	expect "Enter password for principal \"$kkey@$REALMNAME\":"
 	send "$kkey"
@@ -1650,7 +1621,7 @@ proc add_random_key { kkey standalone } {
 		break
 	    }
 	}
-	expect "Enter password:"
+	expect -re "assword\[^\r\n\]*: *"
 	send "adminpass$KEY\r"
 	expect {
 	    "Principal \"$kkey@$REALMNAME\" created" { }
@@ -2029,6 +2000,7 @@ proc v4kinit { name pass standalone } {
     global REALMNAME
     global KINIT
     global spawn_id
+    global des3_krbtgt
 
     # Use kinit to get a ticket.
 	#
@@ -2052,10 +2024,20 @@ proc v4kinit { name pass standalone } {
     }
     send "$pass\r"
     expect eof
-    if ![check_exit_status kinit] {
-	return 0
+    if {$des3_krbtgt == 0} {
+	if ![check_exit_status v4kinit] {
+	    return 0
+	}
+    } else {
+	# Fail if kinit is successful with a des3 TGT.
+	set status_list [wait -i $spawn_id]
+	set testname v4kinit
+	verbose "wait -i $spawn_id returned $status_list ($testname)"
+	if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 1 } {
+	    verbose -log "exit status: $status_list"
+	    fail "$testname (exit status)"
+	}
     }
-
     if {$standalone} {
 	pass "v4kinit"
     }
@@ -2234,19 +2216,35 @@ proc setup_root_shell { testname } {
     set rlogin_pid [exp_pid]
     set old_timeout $timeout
     set timeout 300
+    set got_refused 0
 
     expect {
 	-re {connect to address [0-9a-fA-F.:]*: Connection refused} {
 	    note $expect_out(buffer)
+	    set got_refused 1
 	    exp_continue
 	}
-	-re "word:|erberos rlogin failed|ection refused|ection reset by peer" {
+	-re "word:|erberos rlogin failed|ection refused|ection reset by peer|not authorized" {
 	    note "$testname test requires ability to rlogin as root"
 	    unsupported "$testname"
 	    set timeout $old_timeout
 	    stop_root_shell
 	    return 0
 	}
+	"Cannot assign requested address" {
+	    note "$testname: rlogin as root 'cannot assign requested address'"
+	    unsupported "$testname"
+	    set timeout $old_timeout
+	    stop_root_shell
+	    return 0
+	}
+	-re "usage: rlogin|illegal option -- x|invalid option -- x" {
+	    note "$testname: rlogin doesn't like command-line flags"
+	    unsupported "$testname"
+	    set timeout $old_timeout
+	    stop_root_shell
+	    return 0
+	}
 	-re "$ROOT_PROMPT" { }
 	timeout {
 	    perror "timeout from rlogin $hostname -l root"
@@ -2257,7 +2255,17 @@ proc setup_root_shell { testname } {
 	    return 0
 	}
 	eof {
-	    perror "eof from rlogin $hostname -l root"
+	    if {$got_refused} {
+		# reported some errors, continued, and failed
+		note "$testname test requires ability to log in as root"
+		unsupported $testname
+	    } else {
+		# unknown problem?
+#		perror "eof from rlogin $hostname -l root"
+		note "eof (and unrecognized messages?) from rlogin $hostname -l root"
+		note "$testname test requires ability to log in as root"
+		unsupported $testname
+	    }
 	    stop_root_shell
 	    set timeout $old_timeout
 	    catch "expect_after"
@@ -2501,9 +2509,9 @@ proc krb_exit { } {
 # helpful sometimes for debugging the test suite
 proc spawn_xterm { } {
     global env
-    foreach i {KDB5_UTIL KRB5KDC KADMIND KADMIN KADMIN_LOCAL KINIT KTUTIL KLIST} {
+    foreach i {KDB5_UTIL KRB5KDC KADMIND KADMIN KADMIN_LOCAL KINIT KTUTIL KLIST RLOGIN RLOGIND FTP FTPD KPASSWD REALMNAME} {
 	global $i
-	set env($i) [set $i]
+	if [info exists $i] { set env($i) [set $i] }
     }
     exec "xterm"
 }
diff --git a/src/tests/dejagnu/krb-standalone/ChangeLog b/src/tests/dejagnu/krb-standalone/ChangeLog
index fe3f185a6..9755ebf6c 100644
--- a/src/tests/dejagnu/krb-standalone/ChangeLog
+++ b/src/tests/dejagnu/krb-standalone/ChangeLog
@@ -1,3 +1,23 @@
+2004-02-09  Ken Raeburn  <raeburn@mit.edu>
+
+	* gssapi.exp (doit): Run server with additional options to export
+	and re-import the GSSAPI context, and log info to a file in
+	tmpdir.
+
+2003-05-21  Tom Yu  <tlyu@mit.edu>
+
+	* kadmin.exp: Be slightly more lenient about matching password
+	prompts.
+
+2003-03-26  Tom Yu  <tlyu@mit.edu>
+
+	* v4gssftp.exp (v4ftp_test): Return early if $des3_krbtgt set.
+
+	* v4krb524d.exp (doit): Return early if $des3_krbtgt set.
+
+	* v4standalone.exp (check_and_destroy_v4_tix): Return early if
+	$des3_krbtgt set.
+
 2003-01-01  Ezra Peisach  <epeisach@bu.edu>
 
 	* standalone.exp: Only run the keytab to srvtab tests if kerberos 4
diff --git a/src/tests/dejagnu/krb-standalone/gssapi.exp b/src/tests/dejagnu/krb-standalone/gssapi.exp
index fa717282e..b4046a310 100644
--- a/src/tests/dejagnu/krb-standalone/gssapi.exp
+++ b/src/tests/dejagnu/krb-standalone/gssapi.exp
@@ -280,7 +280,7 @@ proc doit { } {
     verbose "KRB5_KTNAME=$env(KRB5_KTNAME)"
 
     # Now start the gss-server.
-    spawn $GSSSERVER -port 5556 gssservice@$hostname
+    spawn $GSSSERVER -export -logfile $tmppwd/gss-server.log -verbose -port 5556 gssservice@$hostname
     set gss_server_pid [exp_pid]
     set gss_server_spawn_id $spawn_id
     sleep 2
diff --git a/src/tests/dejagnu/krb-standalone/kadmin.exp b/src/tests/dejagnu/krb-standalone/kadmin.exp
index d4754e489..ded386d3d 100644
--- a/src/tests/dejagnu/krb-standalone/kadmin.exp
+++ b/src/tests/dejagnu/krb-standalone/kadmin.exp
@@ -52,7 +52,7 @@ proc kadmin_add { pname password } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*:" {
 	send "adminpass$KEY\r"
     }
     expect "Enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" }
@@ -155,7 +155,7 @@ proc kadmin_add_rnd { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect "Principal \"$pname@$REALMNAME\" created." { set good 1 }
@@ -236,7 +236,7 @@ proc kadmin_show { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:"
+    expect -re "assword\[^\r\n\]*: *"
     send "adminpass$KEY\r"
     expect -re "\r.*Principal: $pname@$REALMNAME.*Key: .*Attributes:.*Policy: .*\r"
     expect_after
@@ -277,7 +277,7 @@ proc kadmin_cpw { pname password } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
 
@@ -324,7 +324,7 @@ proc kadmin_cpw_rnd { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     # When in doubt, jam one of these in there.
@@ -368,7 +368,7 @@ proc kadmin_modify { pname flags } {
 	    return 0
 	}
     }
-    expect "Enter password:"
+    expect -re "assword\[^\r\n\]*: *"
     send "adminpass$KEY\r"
     # When in doubt, jam one of these in there.
     expect "\r"
@@ -413,7 +413,7 @@ proc kadmin_list {  } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect -re "\(.*@$REALMNAME\r\n\)*"
@@ -459,7 +459,7 @@ proc kadmin_extract { instance name } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
 #    expect -re "kadmin: Entry for principal $name/$instance with kvno [0-9], encryption type .* added to keytab WRFILE:$tmppwd/keytab."
@@ -504,7 +504,7 @@ proc kadmin_extract { instance name } {
 #	    return 0
 #	}
 #    }
-#    expect "Enter password:" {
+#    expect -re "assword\[^\r\n\]*: *" {
 #	send "adminpass$KEY\r"
 #    }
 #    expect "extracted entry $name to key table $instance-new-v4-srvtab"
@@ -550,7 +550,7 @@ proc kadmin_delete { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect "Principal \"$pname@$REALMNAME\" deleted." { set good 1 }
@@ -676,7 +676,7 @@ proc kadmin_addpol { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect_after
@@ -759,7 +759,7 @@ proc kadmin_delpol { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect_after
@@ -834,7 +834,7 @@ proc kadmin_listpols {  } {
 	    return 0
 	}
     }
-    expect "Enter password:" {
+    expect -re "assword\[^\r\n\]*: *" {
 	send "adminpass$KEY\r"
     }
     expect_after
@@ -875,7 +875,7 @@ proc kadmin_modpol { pname flags } {
 	    return 0
 	}
     }
-    expect "Enter password:"
+    expect -re "assword\[^\r\n\]*: *"
     send "adminpass$KEY\r"
     # When in doubt, jam one of these in there.
     expect "\r"
@@ -918,7 +918,7 @@ proc kadmin_showpol { pname } {
 	    return 0
 	}
     }
-    expect "Enter password:"
+    expect -re "assword\[^\r\n\]*: *"
     send "adminpass$KEY\r"
     expect -re "\r.*Policy: $pname.*Number of old keys kept: .*Reference count: .*\r"
     expect_after
diff --git a/src/tests/dejagnu/krb-standalone/v4gssftp.exp b/src/tests/dejagnu/krb-standalone/v4gssftp.exp
index c0b95d0ae..c4d5fd35c 100644
--- a/src/tests/dejagnu/krb-standalone/v4gssftp.exp
+++ b/src/tests/dejagnu/krb-standalone/v4gssftp.exp
@@ -179,7 +179,11 @@ proc v4ftp_test { } {
     global tmppwd
     global ftp_save_ktname
     global ftp_save_ccname
+    global des3_krbtgt
 
+    if {$des3_krbtgt} {
+	return
+    }
     # Start up the kerberos and kadmind daemons and get a srvtab and a
     # ticket file.
     if {![start_kerberos_daemons 0] \
diff --git a/src/tests/dejagnu/krb-standalone/v4krb524d.exp b/src/tests/dejagnu/krb-standalone/v4krb524d.exp
index 5506a06b7..6e922c7e1 100644
--- a/src/tests/dejagnu/krb-standalone/v4krb524d.exp
+++ b/src/tests/dejagnu/krb-standalone/v4krb524d.exp
@@ -78,7 +78,11 @@ proc doit { } {
     global KDESTROY
     global tmppwd
     global REALMNAME
+    global des3_krbtgt
 
+    if {$des3_krbtgt} {
+	return
+    }
     # Start up the kerberos and kadmind daemons.
     if ![start_kerberos_daemons 1] {
 	return
diff --git a/src/tests/dejagnu/krb-standalone/v4standalone.exp b/src/tests/dejagnu/krb-standalone/v4standalone.exp
index 62db0a794..cc42e8dab 100644
--- a/src/tests/dejagnu/krb-standalone/v4standalone.exp
+++ b/src/tests/dejagnu/krb-standalone/v4standalone.exp
@@ -26,7 +26,12 @@ if ![setup_kerberos_db 1] {
 
 proc check_and_destroy_v4_tix { client server } {
     global REALMNAME
+    global des3_krbtgt
 
+    # Skip this if we're using a des3 TGT, since that's supposed to fail.
+    if {$des3_krbtgt} {
+	return
+    }
     # Make sure that klist can see the ticket.
     if ![v4klist "$client" "$server" "v4klist"] {
 	return
diff --git a/src/tests/hammer/Makefile.in b/src/tests/hammer/Makefile.in
index 67cf97620..a74aee02f 100644
--- a/src/tests/hammer/Makefile.in
+++ b/src/tests/hammer/Makefile.in
@@ -24,7 +24,7 @@ clean::
 #
 $(OUTPRE)kdc5_hammer.$(OBJEXT): kdc5_hammer.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h
 
diff --git a/src/tests/verify/Makefile.in b/src/tests/verify/Makefile.in
index e88913df9..dd923a692 100644
--- a/src/tests/verify/Makefile.in
+++ b/src/tests/verify/Makefile.in
@@ -24,7 +24,8 @@ clean::
 #
 $(OUTPRE)kdb5_verify.$(OBJEXT): kdb5_verify.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
-  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
-  $(BUILDTOP)/include/profile.h $(SS_DEPS)
+  $(SS_DEPS)
 
diff --git a/src/util/ChangeLog b/src/util/ChangeLog
index 926b6c46d..00f8fc5f6 100644
--- a/src/util/ChangeLog
+++ b/src/util/ChangeLog
@@ -1,3 +1,30 @@
+2003-05-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* depfix.sed: Don't check for krb524 headers.
+
+2003-05-18  Ken Raeburn  <raeburn@mit.edu>
+
+	* depgen.sed: Put print command on separate lines from
+	substitution commands, instead of using s///p form.
+
+2003-05-15  Tom Yu  <tlyu@mit.edu>
+
+	* mkrel: Remote autom4te.cache files.
+
+2003-04-24  Ken Raeburn  <raeburn@mit.edu>
+
+	* reconf: Restore support for 2.52; reject older versions.
+
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* reconf: Drop support for 2.52 and earlier.
+
+2003-04-10  Tom Yu  <tlyu@mit.edu>
+
+	* reconf: Warn if autoconf-2.52 is used, as it generates buggy
+	configure scripts that don't work with BSD /bin/sh, and don't
+	comply with POSIX.2 (no conditions inside "case" statement).
+
 2003-02-05  Tom Yu  <tlyu@mit.edu>
 
 	* mkrel: Exclude .rconf files.
diff --git a/src/util/db2/ChangeLog b/src/util/db2/ChangeLog
index acac38ef1..7c9d1dfa9 100644
--- a/src/util/db2/ChangeLog
+++ b/src/util/db2/ChangeLog
@@ -1,3 +1,8 @@
+2003-04-01  Tom Yu  <tlyu@mit.edu>
+
+	* Makefile.in (install-unix): Delete install-libs.  We don't want
+	to install our in-tree libdb.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
 	* configure.in: Don't explicitly invoke AC_PROG_INSTALL.
diff --git a/src/util/db2/Makefile.in b/src/util/db2/Makefile.in
index 0d4634ff0..6ca755097 100644
--- a/src/util/db2/Makefile.in
+++ b/src/util/db2/Makefile.in
@@ -17,7 +17,6 @@ HDRS =	$(HDRDIR)/db.h $(HDRDIR)/db-config.h $(HDRDIR)/db-ndbm.h
 
 all-unix:: all-liblinks includes
 clean-unix:: clean-liblinks clean-libs clean-includes
-install-unix:: install-libs
 
 includes:: $(HDRS)
 
diff --git a/src/util/db2/test/Makefile b/src/util/db2/test/Makefile
deleted file mode 100644
index 6685decb5..000000000
--- a/src/util/db2/test/Makefile
+++ /dev/null
@@ -1,652 +0,0 @@
-############################################################
-## config/pre.in
-## common prefix for all Makefile.in in the Kerberos V5 tree.
-##
-
-WHAT = unix
-SHELL=/bin/sh
-
-all:: all-$(WHAT)
-
-clean:: clean-$(WHAT)
-
-distclean:: distclean-$(WHAT)
-
-install:: install-$(WHAT)
-
-check:: check-$(WHAT)
-
-install-headers:: install-headers-$(WHAT)
-
-##############################
-# Recursion rule support
-#
-
-# The commands for the recursion targets live in config/post.in.
-#
-# General form of recursion rules:
-#
-# Each recursive target foo-unix has related targets: foo-prerecurse,
-# foo-recurse, and foo-postrecurse
-#
-# The foo-recurse rule is in post.in.  It is what actually recursively
-# calls make.
-#
-# foo-recurse depends on foo-prerecurse, so any targets that must be
-# built before descending into subdirectories must be dependencies of
-# foo-prerecurse.
-#
-# foo-postrecurse depends on foo-recurse, but targets that must be
-# built after descending into subdirectories should be have
-# foo-recurse as dependencies in addition to being listed under
-# foo-postrecurse, to avoid ordering issues.
-#
-# The foo-prerecurse, foo-recurse, and foo-postrecurse rules are all
-# single-colon rules, to avoid nasty ordering problems with
-# double-colon rules.
-#
-# e.g.
-# all:: includes foo
-# foo:
-#	echo foo
-# includes::
-#	echo bar
-# includes::
-#	echo baz
-#
-# will result in "bar", "foo", "baz" on AIX, and possibly others.
-all-unix:: all-postrecurse
-all-postrecurse: all-recurse
-all-recurse: all-prerecurse
-
-all-prerecurse:
-all-postrecurse:
-
-clean-unix:: clean-postrecurse
-clean-postrecurse: clean-recurse
-clean-recurse: clean-prerecurse
-
-clean-prerecurse:
-clean-postrecurse:
-
-distclean-unix: distclean-postrecurse
-distclean-postrecurse: distclean-recurse
-distclean-recurse: distclean-prerecurse
-
-distclean-prerecurse:
-distclean-postrecurse:
-
-install-unix:: install-postrecurse
-install-postrecurse: install-recurse
-install-recurse: install-prerecurse
-
-install-prerecurse:
-install-postrecurse:
-
-install-headers-unix:: install-headers-postrecurse
-install-headers-postrecurse: install-headers-recurse
-install-headers-recurse: install-headers-prerecurse
-
-install-headers-prerecurse:
-install-headers-postrecurse:
-
-check-unix:: check-postrecurse
-check-postrecurse: check-recurse
-check-recurse: check-prerecurse
-
-check-prerecurse:
-check-postrecurse:
-
-Makefiles: Makefiles-postrecurse
-Makefiles-postrecurse: Makefiles-recurse
-Makefiles-recurse: Makefiles-prerecurse
-
-Makefiles-prerecurse:
-Makefiles-postrecurse:
-
-#
-# end recursion rule support
-##############################
-
-# Directory syntax:
-#
-# begin relative path
-REL=
-# this is magic... should only be used for preceding a program invocation
-C=./
-# "/" for UNIX, "\" for Windows; *sigh*
-S=/
-
-SUBDIRS =  $(LOCAL_SUBDIRS)
-srcdir = .
-SRCTOP = ./$(BUILDTOP)
-
-CONFIG_RELTOPDIR = ../..
-
-ALL_CFLAGS = $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(CPPFLAGS) $(CFLAGS)
-CFLAGS = -g
-CPPFLAGS = -I$(BUILDTOP)/include -I$(SRCTOP)/include -I$(BUILDTOP)/include/krb5 -I$(SRCTOP)/include/krb5 -I/usr/athena/include  -DKRB5_KRB4_COMPAT -DKRB5_PRIVATE=1
-DEFS = -DHAVE_CONFIG_H
-CC = /usr/gcc/bin/gcc
-LD = $(PURE) /usr/gcc/bin/gcc
-DEPLIBS = @DEPLIBS@
-LDFLAGS = -L/usr/athena/lib 
-LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
-LD_SHLIBDIR_PREFIX = @LD_SHLIBDIR_PREFIX@
-LDARGS = @LDARGS@
-LIBS = -lsocket -lnsl  -lresolv
-SRVLIBS = @SRVLIBS@
-SRVDEPLIBS = @SRVDEPLIBS@
-CLNTLIBS = @CLNTLIBS@
-CLNTDEPLIBS = @CLNTDEPLIBS@
-
-INSTALL=/usr/athena/bin/install -c
-INSTALL_STRIP=
-INSTALL_PROGRAM=${INSTALL} $(INSTALL_STRIP)
-INSTALL_DATA=${INSTALL} -m 644
-INSTALL_SHLIB=$(INSTALL_DATA)
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
-## This is needed because autoconf will sometimes define ${prefix} to be
-## ${prefix}.
-prefix=/usr/local
-INSTALL_PREFIX=$(prefix)
-INSTALL_EXEC_PREFIX=${prefix}
-exec_prefix=${prefix}
-SHLIB_TAIL_COMP=@SHLIB_TAIL_COMP@
-
-KRB5MANROOT = ${prefix}/man
-ADMIN_BINDIR = ${exec_prefix}/sbin
-SERVER_BINDIR = ${exec_prefix}/sbin
-CLIENT_BINDIR =${exec_prefix}/bin
-ADMIN_MANDIR = $(KRB5MANROOT)/man8
-SERVER_MANDIR = $(KRB5MANROOT)/man8
-CLIENT_MANDIR = $(KRB5MANROOT)/man1
-FILE_MANDIR = $(KRB5MANROOT)/man5
-KRB5_LIBDIR = ${exec_prefix}/lib
-KRB5_SHLIBDIR = ${exec_prefix}/lib$(SHLIB_TAIL_COMP)
-KRB5_INCDIR = ${prefix}/include
-KRB5_INCSUBDIRS = \
-	$(KRB5_INCDIR)/gssapi \
-	$(KRB5_INCDIR)/kerberosIV
-
-#
-# Macros used by the KADM5 (OV-based) unit test system.
-# XXX check which of these are actually used!
-#
-TESTDIR		= $(BUILDTOP)/kadmin/testing
-STESTDIR	= $(SRCTOP)/kadmin/testing
-COMPARE_DUMP	= $(TESTDIR)/scripts/compare_dump.pl
-FIX_CONF_FILES	= $(TESTDIR)/scripts/fixup-conf-files.pl
-INITDB		= $(STESTDIR)/scripts/init_db
-MAKE_KEYTAB	= $(TESTDIR)/scripts/make-host-keytab.pl
-LOCAL_MAKE_KEYTAB= $(TESTDIR)/scripts/make-host-keytab.pl
-RESTORE_FILES	= $(STESTDIR)/scripts/restore_files.sh
-SAVE_FILES	= $(STESTDIR)/scripts/save_files.sh
-ENV_SETUP	= $(TESTDIR)/scripts/env-setup.sh
-CLNTTCL		= $(TESTDIR)/util/ovsec_kadm_clnt_tcl
-SRVTCL		= $(TESTDIR)/util/ovsec_kadm_srv_tcl
-# Dejagnu variables.
-# We have to set the host with --host so that setup_xfail will work.
-# If we don't set it, then the host type used is "native", which
-# doesn't match "*-*-*".
-host=sparc-sun-solaris2.8
-DEJAFLAGS	= $(DEJALFLAGS) $(CLFLAGS) --debug --srcdir $(srcdir) --host \
-		   $(host)
-RUNTEST		= runtest $(DEJAFLAGS)
-
-START_SERVERS	= $(STESTDIR)/scripts/start_servers $(TEST_SERVER) $(TEST_PATH)
-START_SERVERS_LOCAL = $(STESTDIR)/scripts/start_servers_local
-
-STOP_SERVERS	= $(STESTDIR)/scripts/stop_servers $(TEST_SERVER) $(TEST_PATH)
-STOP_SERVERS_LOCAL = $(STESTDIR)/scripts/stop_servers_local
-#
-# End of macros for the KADM5 unit test system.
-#
-
-transform = s,x,x,
-
-RM = rm -f
-CP  = cp
-MV = mv -f
-CHMOD=chmod
-RANLIB = ranlib
-ARCHIVE = @ARCHIVE@
-ARADD = @ARADD@
-LN = ln -s
-AWK = @AWK@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-YACC = @YACC@
-AUTOCONF = autoconf
-AUTOCONFFLAGS = 
-AUTOCONFINCFLAGS = --localdir
-AUTOHEADER = autoheader
-AUTOHEADERFLAGS = 
-
-HOST_TYPE = @HOST_TYPE@
-SHEXT = @SHEXT@
-STEXT=@STEXT@
-VEXT=@VEXT@
-DO_MAKE_SHLIB = @DO_MAKE_SHLIB@
-SHLIB_STATIC_TARGET=@SHLIB_STATIC_TARGET@
-
-TOPLIBD = $(BUILDTOP)/lib
-
-OBJEXT = o
-LIBEXT = a
-EXEEXT =
-
-#
-# variables for libraries, for use in linking programs
-# -- this may want to get broken out into a separate frag later
-#
-#
-# Note: the following variables must be set in any Makefile.in that
-# uses KRB5_BUILD_PROGRAM
-#
-# PROG_LIBPATH	list of dirs, in -Ldir form, to search for libraries at link
-# PROG_RPATH	list of dirs, in dir1:dir2 form, for rpath purposes
-#
-# invocation is like:
-# prog: foo.o bar.o $(KRB5_BASE_DEPLIBS)
-# 	$(CC_LINK) -o $@ foo.o bar.o $(KRB5_BASE_LIBS)
-
-
-CC_LINK=$(PURE) $(CC) $(PROG_LIBPATH) $(LDFLAGS)
-
-# prefix (with no spaces after) for rpath flag to cc
-RPATH_FLAG=-R
-
-# this gets set by configure to either $(STLIBEXT) or $(SHLIBEXT),
-# depending on whether we're building with shared libraries.
-DEPLIBEXT=.a
-
-KADMCLNT_DEPLIB	= $(TOPLIBD)/libkadm5clnt$(DEPLIBEXT)
-KADMSRV_DEPLIB	= $(TOPLIBD)/libkadm5srv$(DEPLIBEXT)
-KDB5_DEPLIB	= $(TOPLIBD)/libkdb5$(DEPLIBEXT)
-DB_DEPLIB	= $(DB_DEPLIB-k5)
-DB_DEPLIB-k5	= $(TOPLIBD)/libdb$(DEPLIBEXT)
-DB_DEPLIB-sys	=
-GSSRPC_DEPLIB	= $(TOPLIBD)/libgssrpc$(DEPLIBEXT)
-GSS_DEPLIB	= $(TOPLIBD)/libgssapi_krb5$(DEPLIBEXT)
-KRB4_DEPLIB	= $(TOPLIBD)/libkrb4$(DEPLIBEXT)		# $(TOPLIBD)/libkrb4$(DEPLIBEXT)
-DES425_DEPLIB	= $(TOPLIBD)/libdes425$(DEPLIBEXT)	# $(TOPLIBD)/libdes425$(DEPLIBEXT)
-KRB5_DEPLIB	= $(TOPLIBD)/libkrb5$(DEPLIBEXT)
-CRYPTO_DEPLIB	= $(TOPLIBD)/libk5crypto$(DEPLIBEXT)
-COM_ERR_DEPLIB	= $(COM_ERR_DEPLIB-k5)
-COM_ERR_DEPLIB-sys = # empty
-COM_ERR_DEPLIB-k5 = $(TOPLIBD)/libcom_err$(DEPLIBEXT)
-
-# These are forced to use ".a" as an extension because they're never
-# built shared.
-SS_DEPLIB	= $(SS_DEPLIB-k5)
-SS_DEPLIB-k5	= $(TOPLIBD)/libss.a
-SS_DEPLIB-sys	=
-KRB524_DEPLIB	= $(BUILDTOP)/krb524/libkrb524.a
-PTY_DEPLIB	= $(TOPLIBD)/libpty.a
-
-KRB5_BASE_DEPLIBS	= $(KRB5_DEPLIB) $(CRYPTO_DEPLIB) $(COM_ERR_DEPLIB)
-KRB4COMPAT_DEPLIBS	= $(KRB4_DEPLIB) $(DES425_DEPLIB) $(KRB5_BASE_DEPLIBS)
-KDB5_DEPLIBS		= $(KDB5_DEPLIB) $(DB_DEPLIB)
-GSS_DEPLIBS		= $(GSS_DEPLIB)
-GSSRPC_DEPLIBS		= $(GSSRPC_DEPLIB) $(GSS_DEPLIBS)
-KADM_COMM_DEPLIBS	= $(GSSRPC_DEPLIBS) $(KDB5_DEPLIBS) $(GSSRPC_DEPLIBS)
-KADMSRV_DEPLIBS		= $(KADMSRV_DEPLIB) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS)
-KADMCLNT_DEPLIBS	= $(KADMCLNT_DEPLIB) $(KADM_COMM_DEPLIBS)
-
-# Header file dependencies we might override.
-# See util/depfix.sed.
-# Also see depend-verify-* in post.in, which wants to confirm that we're using
-# the in-tree versions.
-COM_ERR_VERSION = k5
-COM_ERR_DEPS	= $(COM_ERR_DEPS-k5)
-COM_ERR_DEPS-sys =
-COM_ERR_DEPS-k5	= $(BUILDTOP)/include/com_err.h
-SS_VERSION	= k5
-SS_DEPS		= $(SS_DEPS-k5)
-SS_DEPS-sys	=
-SS_DEPS-k5	= $(BUILDTOP)/include/ss/ss.h $(BUILDTOP)/include/ss/ss_err.h
-DB_VERSION	= k5
-DB_DEPS		= $(DB_DEPS-k5)
-DB_DEPS-sys	=
-DB_DEPS-k5	= $(BUILDTOP)/include/db.h $(BUILDTOP)/include/db-config.h
-DB_DEPS-redirect = $(BUILDTOP)/include/db.h
-
-# Header file dependencies that might depend on whether krb4 support
-# is compiled.
-
-KRB_ERR_H_DEP	= $(BUILDTOP)/include/kerberosIV/krb_err.h
-KRB524_H_DEP	= $(BUILDTOP)/include/krb524.h
-KRB524_ERR_H_DEP= $(BUILDTOP)/include/krb524_err.h
-
-# LIBS gets substituted in... e.g. -lnsl -lsocket
-
-# GEN_LIB is -lgen if needed for regexp
-GEN_LIB		= 
-
-SS_LIB		= $(SS_LIB-k5)
-SS_LIB-sys	= 
-SS_LIB-k5	= $(TOPLIBD)/libss.a
-KDB5_LIB	= -lkdb5
-DB_LIB		= -ldb
-
-KRB5_LIB			= -lkrb5
-K5CRYPTO_LIB			= -lk5crypto
-COM_ERR_LIB			= -lcom_err
-GSS_KRB5_LIB			= -lgssapi_krb5
-
-# KRB4_LIB is -lkrb4 if building --with-krb4
-# needs fixing if ever used on Mac OS X!
-KRB4_LIB	= -lkrb4
-
-# DES425_LIB is -ldes425 if building --with-krb4
-# needs fixing if ever used on Mac OS X!
-DES425_LIB	= -ldes425
-
-# KRB524_LIB is $(BUILDTOP)/krb524/libkrb524.a if building --with-krb4
-# needs fixing if ever used on Mac OS X!
-KRB524_LIB	= $(BUILDTOP)/krb524/libkrb524.a
-
-# HESIOD_LIBS is -lhesiod...
-HESIOD_LIBS	= 
-
-KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(GEN_LIB) $(LIBS)
-KRB4COMPAT_LIBS	= $(KRB4_LIB) $(DES425_LIB) $(KRB5_BASE_LIBS)
-KDB5_LIBS	= $(KDB5_LIB) $(DB_LIB)
-GSS_LIBS	= $(GSS_KRB5_LIB)
-# needs fixing if ever used on Mac OS X!
-GSSRPC_LIBS	= -lgssrpc $(GSS_LIBS)
-KADM_COMM_LIBS	= $(GSSRPC_LIBS)
-# need fixing if ever used on Mac OS X!
-KADMSRV_LIBS	= -lkadm5srv $(HESIOD_LIBS) $(KDB5_LIBS) $(KADM_COMM_LIBS)
-KADMCLNT_LIBS	= -lkadm5clnt $(KADM_COMM_LIBS)
-
-# need fixing if ever used on Mac OS X!
-PTY_LIB		= -lpty
-
-#
-# some more stuff for --with-krb4
-KRB4_LIBPATH	= 
-KRB4_INCLUDES	= -I$(SRCTOP)/include/kerberosIV -I$(BUILDTOP)/include/kerberosIV
-
-#
-# variables for --with-tcl=
-TCL_LIBS	= @TCL_LIBS@
-TCL_LIBPATH	= @TCL_LIBPATH@
-TCL_RPATH	= @TCL_RPATH@
-TCL_MAYBE_RPATH = @TCL_MAYBE_RPATH@
-TCL_INCLUDES	= @TCL_INCLUDES@
-
-# error table rules
-#
-### /* these are invoked as $(...) foo.et, which works, but could be better */
-COMPILE_ET= $(COMPILE_ET-k5)
-COMPILE_ET-sys= compile_et
-COMPILE_ET-k5= $(BUILDTOP)/util/et/compile_et -d $(SRCTOP)/util/et
-
-.SUFFIXES:  .h .c .et .ct
-
-# These versions cause both .c and .h files to be generated at once.
-# But GNU make doesn't understand this, and parallel builds can trigger
-# both of them at once, causing them to stomp on each other.  The versions
-# below only update one of the files, so compile_et has to get run twice,
-# but it won't break parallel builds.
-#.et.h: ; $(COMPILE_ET) $<
-#.et.c: ; $(COMPILE_ET) $<
-
-.et.h:
-	d=ettmp$$$$ ; (cp $< $$d.et && $(COMPILE_ET) $$d.et && mv $$d.h $*.h) ; \
-		e=$$? ; rm -f $$d.* ; exit $$e
-
-.et.c:
-	d=ettmp$$$$ ; (cp $< $$d.et && $(COMPILE_ET) $$d.et && mv $$d.c $*.c) ; \
-		e=$$? ; rm -f $$d.* ; exit $$e
-
-# rule to make object files
-#
-.SUFFIXES: .c .o
-.c.o:
-	$(CC) $(ALL_CFLAGS) -c $<
-
-# ss command table rules
-#
-MAKE_COMMANDS= $(MAKE_COMMANDS-k5)
-MAKE_COMMANDS-sys= mk_cmds
-MAKE_COMMANDS-k5= $(BUILDTOP)/util/ss/mk_cmds
-
-.ct.c:
-	$(MAKE_COMMANDS) $<
-
-##
-## end of pre.in
-############################################################
-thisconfigdir=./..
-myfulldir=util/db2/test
-mydir=test
-BUILDTOP=$(REL)..$(S)..$(S)..
-
-FCTSH = /usr/bin/sh
-TMPDIR=.
-
-LOCALINCLUDES=	-I. -I$(srcdir)/../include -I../include -I$(srcdir)/../mpool \
-		-I$(srcdir)/../btree -I$(srcdir)/../hash -I$(srcdir)/../db
-
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-KRB5_RUN_ENV= 
-
-all::
-
-dbtest: dbtest.o $(DB_DEPLIB)
-	$(CC_LINK) -o $@ dbtest.o $(STRERROR_OBJ) $(DB_LIB)
-
-check:: dbtest
-	$(KRB5_RUN_ENV) srcdir=$(srcdir) TMPDIR=$(TMPDIR) $(FCTSH) $(srcdir)/run.test
-
-bttest.o: $(srcdir)/btree.tests/main.c
-	$(CC) $(ALL_CFLAGS) -c $(srcdir)/btree.tests/main.c -o $@
-
-bttest: bttest.o $(DB_DEPLIB)
-	$(CC_LINK) -o $@ bttest.o $(STRERROR_OBJ) $(DB_LIB)
-
-clean-unix::
-	$(RM) dbtest.o dbtest __dbtest
-	$(RM) bttest.o bttest
-############################################################
-## config/post.in
-##
-
-# in case there is no default target (very unlikely)
-all::
-
-check-windows::
-
-##############################
-# dependency generation
-#
-
-depend:: depend-postrecurse
-depend-postrecurse: depend-recurse
-depend-recurse: depend-prerecurse
-
-depend-prerecurse:
-depend-postrecurse:
-
-depend-postrecurse: depend-update-makefile
-
-ALL_DEP_SRCS= $(SRCS) $(EXTRADEPSRCS)
-
-# be sure to check ALL_DEP_SRCS against *what it would be if SRCS and
-# EXTRADEPSRCS are both empty*
-.depend-verify-srcdir:
-	@if test "$(srcdir)" = "." ; then \
-		echo 1>&2 error: cannot build dependencies with srcdir=. ; \
-		echo 1>&2 "(can't distinguish generated files from source files)" ; \
-		exit 1 ; \
-	else \
-		if test -r .depend-verify-srcdir; then :; \
-			else (set -x; touch .depend-verify-srcdir); fi \
-	fi
-.depend-verify-et: depend-verify-et-$(COM_ERR_VERSION)
-depend-verify-et-k5:
-	@if test -r .depend-verify-et; then :; \
-		else (set -x; touch .depend-verify-et); fi
-depend-verify-et-sys:
-	@echo 1>&2 error: cannot build dependencies using system et package
-	@exit 1
-.depend-verify-ss: depend-verify-ss-$(SS_VERSION)
-depend-verify-ss-k5:
-	@if test -r .depend-verify-ss; then :; \
-		else (set -x; touch .depend-verify-ss); fi
-depend-verify-ss-sys:
-	@echo 1>&2 error: cannot build dependencies using system ss package
-	@exit 1
-.depend-verify-db: depend-verify-db-$(DB_VERSION)
-depend-verify-db-k5:
-	@if test -r .depend-verify-db; then :; \
-		else (set -x; touch .depend-verify-db); fi
-depend-verify-db-sys:
-	@echo 1>&2 error: cannot build dependencies using system db package
-	@exit 1
-.depend-verify-gcc: depend-verify-gcc-yes
-depend-verify-gcc-yes:
-	@if test -r .depend-verify-gcc; then :; \
-		else (set -x; touch .depend-verify-gcc); fi
-depend-verify-gcc-no:
-	@echo 1>&2 error: The '"depend"' rules are written for gcc.
-	@echo 1>&2 Please use gcc, or update the rules to handle your compiler.
-	@exit 1
-
-DEP_CFG_VERIFY = .depend-verify-srcdir \
-	.depend-verify-et .depend-verify-ss .depend-verify-db
-DEP_VERIFY = $(DEP_CFG_VERIFY) .depend-verify-gcc
-
-.d: $(ALL_DEP_SRCS) $(DEP_CFG_VERIFY) depend-dependencies
-	if test "$(ALL_DEP_SRCS)" != " " ; then \
-		$(RM) .dtmp && $(MAKE) .dtmp && mv -f .dtmp .d ; \
-	else \
-		touch .d ; \
-	fi
-
-# These are dependencies of the depend target that do not get fed to
-# the compiler.  Examples include generated header files.
-depend-dependencies:
-
-# .dtmp must *always* be out of date so that $? can be used to perform
-# VPATH searches on the sources.
-#
-# NOTE: This will fail when using Make programs whose VPATH support is
-# broken.
-.dtmp: $(ALL_DEP_SRCS)
-	$(CC) -M $(ALL_CFLAGS) $? > .dtmp
-
-# Generate a script for dropping in the appropriate make variables, using
-# directory-specific parameters.  General substitutions independent of local
-# make variables happen in depfix.sed.
-.depfix2.sed: .depend-verify-gcc Makefile $(SRCTOP)/util/depgen.sed
-	x=`$(CC) -print-libgcc-file-name` ; \
-	echo '$(SRCTOP)' '$(myfulldir)' '$(srcdir)' '$(BUILDTOP)' "$$x" | sed -f $(SRCTOP)/util/depgen.sed > .depfix2.tmp
-	mv -f .depfix2.tmp .depfix2.sed
-
-DEPLIBOBJNAMEFIX = sed -e 's;^\$$(OUTPRE)\([a-zA-Z0-9_\-]*\)\.\$$(OBJEXT):;\1.so \1.po &;'
-
-# NOTE: This will also generate spurious $(OUTPRE) and $(OBJEXT)
-# references in rules for non-library objects in a directory where
-# library objects happen to be built.  It's mostly harmless.
-.depend: .d .depfix2.sed $(SRCTOP)/util/depfix.sed
-	sed -f .depfix2.sed < .d | sed -f $(SRCTOP)/util/depfix.sed | \
-	(if test "x$(STLIBOBJS)" != "x"; then $(DEPLIBOBJNAMEFIX) ; else cat; fi ) \
-	> .depend
-
-depend-update-makefile: .depend depend-recurse
-	if test -n "$(SRCS)" ; then \
-		sed -e '/^# +++ Dependency line eater +++/,$$d' \
-			< $(srcdir)/Makefile.in | cat - .depend \
-			> $(srcdir)/Makefile.in.new; \
-	$(SRCTOP)/config/move-if-changed $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in ; \
-	else :; fi
-
-DEPTARGETS = .depend .d .dtmp .depfix2.sed .depfix2.tmp $(DEP_VERIFY)
-
-#
-# end dependency generation
-##############################
-
-clean:: clean-$(WHAT)
-
-clean-unix::
-	$(RM) $(OBJS) $(DEPTARGETS)
-
-clean-windows::
-	$(RM) *.$(OBJEXT)
-	$(RM) msvc.pdb *.err
-
-distclean:: distclean-$(WHAT)
-
-distclean-normal-clean:
-	$(MAKE) NORECURSE=true clean
-distclean-prerecurse: distclean-normal-clean
-distclean-nuke-configure-state:
-	$(RM) config.log config.cache config.status Makefile
-distclean-postrecurse: distclean-nuke-configure-state
-
-Makefiles-prerecurse: Makefile
-
-# thisconfigdir = relative path from this Makefile to config.status
-# mydir = relative path from config.status to this Makefile
-Makefile: $(srcdir)/Makefile.in $(thisconfigdir)/config.status \
-		$(SRCTOP)/config/pre.in $(SRCTOP)/config/post.in
-	cd $(thisconfigdir) && $(SHELL) config.status $(mydir)/Makefile
-$(thisconfigdir)/config.status: $(srcdir)/$(thisconfigdir)/configure
-	cd $(thisconfigdir) && $(SHELL) config.status --recheck
-$(srcdir)/$(thisconfigdir)/configure: $(srcdir)/$(thisconfigdir)/configure.in \
-		$(SRCTOP)/aclocal.m4
-	-$(RM) -r $(srcdir)/$(thisconfigdir)/autom4te.cache
-	cd $(srcdir)/$(thisconfigdir) && \
-		$(AUTOCONF) ${AUTOCONFINCFLAGS}=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS)
-	-$(RM) -r $(srcdir)/$(thisconfigdir)/autom4te.cache
-
-RECURSE_TARGETS=all-recurse clean-recurse distclean-recurse install-recurse \
-	check-recurse depend-recurse Makefiles-recurse install-headers-recurse
-
-# MY_SUBDIRS overrides any setting of SUBDIRS generated by the
-# configure script that generated this Makefile.  This is needed when
-# the configure script that produced this Makefile creates multiple
-# Makefiles in different directories; the setting of SUBDIRS will be
-# the same in each.
-#
-# LOCAL_SUBDIRS seems to account for the case where the configure
-# script doesn't call any other subsidiary configure scripts, but
-# generates multiple Makefiles.
-$(RECURSE_TARGETS):
-	@case "`echo 'x$(MFLAGS)'|sed -e 's/^x//' -e 's/ --.*$$//'`" \
-		in *[ik]*) e="status=1" ;; *) e="exit 1";; esac; \
-	if test -z "$(MY_SUBDIRS)" ; then \
-		do_subdirs="$(SUBDIRS)" ; \
-	else \
-		do_subdirs="$(MY_SUBDIRS)" ; \
-	fi; \
-	status=0; \
-	if test -n "$$do_subdirs" && test -z "$(NORECURSE)"; then \
-	for i in $$do_subdirs ; do \
-		if test -d $$i && test -r $$i/Makefile ; then \
-		case $$i in .);; *) \
-			target=`echo $@|sed s/-recurse//`; \
-			echo "making $$target in $(CURRENT_DIR)$$i..."; \
-			if (cd $$i ; $(MAKE) \
-			    CURRENT_DIR=$(CURRENT_DIR)$$i/ $$target) then :; \
-			else eval $$e; fi; \
-			;; \
-		esac; \
-		else \
-			echo "Skipping missing directory $(CURRENT_DIR)$$i" ; \
-		fi; \
-	done; \
-	else :; \
-	fi;\
-	exit $$status
-
-##
-## end of post.in
-############################################################
diff --git a/src/util/depfix.sed b/src/util/depfix.sed
index 650dda627..22fa394e5 100644
--- a/src/util/depfix.sed
+++ b/src/util/depfix.sed
@@ -53,8 +53,6 @@ s;\$(BUILDTOP)/include/db.h \$(BUILDTOP)/include/db-config.h ;$(DB_DEPS) ;g
 
 # Some krb4 dependencies should only be present if building with krb4 enabled
 s;\$(BUILDTOP)/include/kerberosIV/krb_err.h ;$(KRB_ERR_H_DEP) ;g
-s;\$(BUILDTOP)/include/krb524.h ;$(KRB524_H_DEP) ;g
-s;\$(BUILDTOP)/include/krb524_err.h ;$(KRB524_ERR_H_DEP) ;g
 
 # now delete trailing whitespace
 s; *$;;g
diff --git a/src/util/et/ChangeLog b/src/util/et/ChangeLog
index 1aaaf6ca2..1f43ce031 100644
--- a/src/util/et/ChangeLog
+++ b/src/util/et/ChangeLog
@@ -1,3 +1,23 @@
+2003-07-04  Kenneth Raeburn  <raeburn@mit.edu>
+
+	* test_et.c: Conditionalize sys_nerr declaration on
+	NEED_SYS_ERRLIST, not HAVE_SYS_ERRLIST.
+
+2003-06-12  Alexandra Ellwood  <lxs@mit.edu>
+    * error_table.h, et_c.awk, et_c.pl, et_h.awk, et_c.awk: Removed Mac 
+    OS support because it prevents darwin builds from getting com error 
+    strings via the initialize_*_error_table function
+
+2003-04-29  Ken Raeburn  <raeburn@mit.edu>
+
+	* test_et.c [HAVE_SYS_ERRLIST]: Do declare sys_nerr.
+
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* compile_et.c: Don't declare malloc or errno.  Include stdlib.h
+	and errno.h.
+	* test_et.c: Don't declare errno or sys_nerr.
+
 2003-03-06  Alexandra Ellwood  <lxs@mit.edu>
     * com_err.c, com_err.h, error_message.c, et_c.awk, et_h.awk: 
       Removed Mac OS 9-specific code.
diff --git a/src/util/et/compile_et.c b/src/util/et/compile_et.c
index 23771a0a7..dfaad5f57 100644
--- a/src/util/et/compile_et.c
+++ b/src/util/et/compile_et.c
@@ -12,6 +12,8 @@
 #include <sys/file.h>
 #include <string.h>
 #include <sys/param.h>
+#include <stdlib.h>
+#include <errno.h>
 #include "mit-sipb-copyright.h"
 #include "compiler.h"
 
@@ -27,10 +29,6 @@ char buffer[BUFSIZ];
 char *table_name = (char *)NULL;
 FILE *hfile, *cfile;
 
-/* C library */
-extern char *malloc();
-extern int errno;
-
 /* lex stuff */
 extern FILE *yyin;
 extern int yylineno;
diff --git a/src/util/et/error_table.h b/src/util/et/error_table.h
index 505521dfe..9e1d26fa5 100644
--- a/src/util/et/error_table.h
+++ b/src/util/et/error_table.h
@@ -9,17 +9,13 @@
 
 #include <errno.h>
 
-#if defined(macintosh)
-#define ET_EBUFSIZ 256
-#else
 #define ET_EBUFSIZ 64
-#endif
 
 struct et_list {
     /*@dependent@*//*@null@*/ struct et_list *next;
     /*@dependent@*//*@null@*/ const struct error_table *table;
 };
-#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))
+#if !defined(_WIN32)
 /*@null@*//*@dependent@*/ extern struct et_list * _et_list;
 #endif
 
diff --git a/src/util/et/et_c.awk b/src/util/et/et_c.awk
index 04451366e..fc2e1ac53 100644
--- a/src/util/et/et_c.awk
+++ b/src/util/et/et_c.awk
@@ -113,7 +113,7 @@ c2n["_"]=63
 	print "# include \"win-mac.h\"" > outfile
 	print "#endif" > outfile
 	print "" > outfile
-	print "#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))" > outfile
+	print "#if !defined(_WIN32)" > outfile
 	print "extern void initialize_" table_name "_error_table (void);" > outfile
 	print "#endif" > outfile
 	print "" > outfile
@@ -199,7 +199,7 @@ END {
 		tab_base_low, table_item_count) > outfile
 	}
 	print "" > outfile
-	print "#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))" > outfile
+	print "#if !defined(_WIN32)" > outfile
 	print "void initialize_" table_name "_error_table (void)" > outfile
 	print "    /*@modifies internalState@*/" > outfile
 	print "{" > outfile
diff --git a/src/util/et/et_c.pl b/src/util/et/et_c.pl
index b512252c6..f635bc1ac 100644
--- a/src/util/et/et_c.pl
+++ b/src/util/et/et_c.pl
@@ -146,7 +146,7 @@ line: while (<>) {
 	&Pick('>', $outfile) &&
 	    (print $fh
 
-	      '#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))');
+	      '#if !defined(_WIN32)');
 	&Pick('>', $outfile) &&
 	    (print $fh 'extern void initialize_' . $table_name .
 
@@ -238,18 +238,8 @@ line: while (<>) {
     (print $fh '};');
 &Pick('>', $outfile) &&
     (print $fh '');
-&Pick('>', $outfile) &&
-    (print $fh
-
-      '#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))');
-&Pick('>', $outfile) &&
-    (print $fh '#include <KerberosComErr/KerberosComErr.h>');
-&Pick('>', $outfile) &&
-    (print $fh '#else');
 &Pick('>', $outfile) &&
     (print $fh '#include <com_err.h>');
-&Pick('>', $outfile) &&
-    (print $fh '#endif');
 &Pick('>', $outfile) &&
     (print $fh '');
 if ($tab_base_high == 0) {
@@ -273,7 +263,7 @@ else {
 &Pick('>', $outfile) &&
     (print $fh
 
-      '#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))');
+      '#if !defined(_WIN32)');
 &Pick('>', $outfile) &&
     (print $fh 'void initialize_' . $table_name . '_error_table (void)');
 &Pick('>', $outfile) &&
diff --git a/src/util/et/et_h.awk b/src/util/et/et_h.awk
index 6bccc98e9..7a81dfa3f 100644
--- a/src/util/et/et_h.awk
+++ b/src/util/et/et_h.awk
@@ -148,7 +148,7 @@ END {
 	print "" > outfile
 	print "extern const struct error_table et_" table_name "_error_table;" > outfile
 	print "" > outfile
-	print "#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))" > outfile
+	print "#if !defined(_WIN32)" > outfile
 	print "/* for compatibility with older versions... */" > outfile
 	print "extern void initialize_" table_name "_error_table () /*@modifies internalState@*/;" > outfile
 	print "#else" > outfile
diff --git a/src/util/et/et_h.pl b/src/util/et/et_h.pl
index 5debb4869..110555098 100644
--- a/src/util/et/et_h.pl
+++ b/src/util/et/et_h.pl
@@ -136,18 +136,8 @@ line: while (<>) {
 	    (print $fh ' */');
 	&Pick('>', $outfile) &&
 	    (print $fh '');
-	&Pick('>', $outfile) &&
-	    (print $fh
-
-	      '#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))');
-	&Pick('>', $outfile) &&
-	    (print $fh '#include <KerberosComErr/KerberosComErr.h>');
-	&Pick('>', $outfile) &&
-	    (print $fh '#else');
 	&Pick('>', $outfile) &&
 	    (print $fh '#include <com_err.h>');
-	&Pick('>', $outfile) &&
-	    (print $fh '#endif');
 	&Pick('>', $outfile) &&
 	    (print $fh '');
     }
@@ -203,7 +193,7 @@ else {
 &Pick('>', $outfile) &&
     (print $fh
 
-      '#if !defined(_WIN32) && !defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))');
+      '#if !defined(_WIN32)');
 &Pick('>', $outfile) &&
     (print $fh '/* for compatibility with older versions... */');
 &Pick('>', $outfile) &&
diff --git a/src/util/et/test_et.c b/src/util/et/test_et.c
index 41ac394d5..1089c2166 100644
--- a/src/util/et/test_et.c
+++ b/src/util/et/test_et.c
@@ -4,11 +4,13 @@
 #include "test1.h"
 #include "test2.h"
 
-extern int sys_nerr, errno;
-
 /* XXX Not part of official public API.  */
 extern const char *error_table_name (errcode_t);
 
+#ifdef NEED_SYS_ERRLIST
+extern int sys_nerr;
+#endif
+
 int main()
 {
 	printf("Before initiating error table:\n\n");
diff --git a/src/util/mkrel b/src/util/mkrel
index db58774db..a576fbd22 100644
--- a/src/util/mkrel
+++ b/src/util/mkrel
@@ -136,6 +136,7 @@ echo "Nuking unneeded files..."
 find $reldir \( -name TODO -o -name todo -o -name .cvsignore \
 	-o -name BADSYMS -o -name .Sanitize -o -name .rconf \) -print \
 	| xargs rm -f
+find $reldir -type d -name autom4te.cache -exec rm -rf {} \;
 
 if test $dodoc = t; then
 	echo "Building doc..."
diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog
index 396058b7b..9f7f25960 100644
--- a/src/util/profile/ChangeLog
+++ b/src/util/profile/ChangeLog
@@ -1,3 +1,19 @@
+2004-01-30  Alexandra Ellwood  <lxs@mit.edu>
+
+    * prof-int.h: prof-int.h should include pthread.h when USE_PTHREADS 
+    is defined.
+
+2003-12-14 Jeffrey Altman <jaltman@mit.edu>
+
+   * all files: move prof-int.h to be the first include file
+     in order to obtain platform specific config preprocessor
+     variables which are used to selectively include stdlib.h
+
+2003-07-03 Alexandra Ellwood <lxs@mit.edu>
+
+    * profile.hin: Remove leading spaces in #define and #include 
+    in public headers to support K&R C compilers
+    
 2003-03-06 Alexandra Ellwood <lxs@mit.edu>
     * profile.hin, prof_file.c (profile_flush_file_data): Stop copying
     the resource fork.  We stopped writing resources to the krb5
diff --git a/src/util/profile/Makefile.in b/src/util/profile/Makefile.in
index fc446e3f1..5a7b42500 100644
--- a/src/util/profile/Makefile.in
+++ b/src/util/profile/Makefile.in
@@ -132,20 +132,20 @@ check-windows:: $(OUTPRE)test_profile.exe $(OUTPRE)test_parse.exe
 # the Makefile.in file
 #
 prof_tree.so prof_tree.po $(OUTPRE)prof_tree.$(OBJEXT): prof_tree.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 prof_file.so prof_file.po $(OUTPRE)prof_file.$(OBJEXT): prof_file.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 prof_parse.so prof_parse.po $(OUTPRE)prof_parse.$(OBJEXT): prof_parse.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 prof_get.so prof_get.po $(OUTPRE)prof_get.$(OBJEXT): prof_get.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 prof_set.so prof_set.po $(OUTPRE)prof_set.$(OBJEXT): prof_set.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 prof_err.so prof_err.po $(OUTPRE)prof_err.$(OBJEXT): prof_err.c $(COM_ERR_DEPS)
 prof_init.so prof_init.po $(OUTPRE)prof_init.$(OBJEXT): prof_init.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 test_parse.so test_parse.po $(OUTPRE)test_parse.$(OBJEXT): test_parse.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h
 test_profile.so test_profile.po $(OUTPRE)test_profile.$(OBJEXT): test_profile.c prof_int.h \
-  $(COM_ERR_DEPS) profile.h argv_parse.h
+  $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h argv_parse.h
 
diff --git a/src/util/profile/argv_parse.c b/src/util/profile/argv_parse.c
index 539517ad7..7740d5345 100644
--- a/src/util/profile/argv_parse.c
+++ b/src/util/profile/argv_parse.c
@@ -28,7 +28,11 @@
  * Version 1.1, modified 2/27/1999
  */
 
+#include "prof_int.h"
+
+#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
 #include <ctype.h>
 #include <string.h>
 #include "argv_parse.h"
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
index 8a4d95d71..ad1018779 100644
--- a/src/util/profile/prof_file.c
+++ b/src/util/profile/prof_file.c
@@ -2,6 +2,8 @@
  * prof_file.c ---- routines that manipulate an individual profile file.
  */
 
+#include "prof_int.h"
+
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -11,8 +13,6 @@
 #endif
 #include <string.h>
 
-#include "prof_int.h"
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
diff --git a/src/util/profile/prof_get.c b/src/util/profile/prof_get.c
index d678a25f2..80a18a1fc 100644
--- a/src/util/profile/prof_get.c
+++ b/src/util/profile/prof_get.c
@@ -4,6 +4,7 @@
  *
  */
 
+#include "prof_int.h"
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -11,7 +12,6 @@
 #endif
 #include <errno.h>
 #include <limits.h>
-#include "prof_int.h"
 
 /*
  * These functions --- init_list(), end_list(), and add_to_list() are
diff --git a/src/util/profile/prof_init.c b/src/util/profile/prof_init.c
index 76a4943f2..2dbcd826f 100644
--- a/src/util/profile/prof_init.c
+++ b/src/util/profile/prof_init.c
@@ -3,6 +3,8 @@
  * 	object.
  */
 
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -10,8 +12,6 @@
 #endif
 #include <errno.h>
 
-#include "prof_int.h"
-
 /* Find a 4-byte integer type */
 #if	(SIZEOF_SHORT == 4)
 typedef short	prof_int32;
diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h
index 06fce8757..919141168 100644
--- a/src/util/profile/prof_int.h
+++ b/src/util/profile/prof_int.h
@@ -4,6 +4,7 @@
 
 #include <time.h>
 #include <stdio.h>
+
 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
 #include <TargetConditionals.h>
 #define USE_PTHREADS
@@ -11,6 +12,11 @@
 #define SHARE_TREE_DATA
 #endif
 
+#if defined(USE_PTHREADS)
+#include <sys/types.h>
+#include <pthread.h>
+#endif
+
 #include "com_err.h"
 #include "profile.h"
 
diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c
index 56f1c30f0..b18b8befa 100644
--- a/src/util/profile/prof_parse.c
+++ b/src/util/profile/prof_parse.c
@@ -1,3 +1,5 @@
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -6,8 +8,6 @@
 #include <errno.h>
 #include <ctype.h>
 
-#include "prof_int.h"
-
 #define SECTION_SEP_CHAR '/'
 
 #define STATE_INIT_COMMENT	1
diff --git a/src/util/profile/prof_set.c b/src/util/profile/prof_set.c
index 5abf5ec9a..c121d64da 100644
--- a/src/util/profile/prof_set.c
+++ b/src/util/profile/prof_set.c
@@ -11,6 +11,8 @@
  *
  */
 
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -18,8 +20,6 @@
 #endif
 #include <errno.h>
 
-#include "prof_int.h"
-
 static errcode_t rw_setup(profile)
 	profile_t	profile;
 {
diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c
index 7032a34e9..38b86f368 100644
--- a/src/util/profile/prof_tree.c
+++ b/src/util/profile/prof_tree.c
@@ -17,6 +17,8 @@
  */
 
 
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -25,8 +27,6 @@
 #include <errno.h>
 #include <ctype.h>
 
-#include "prof_int.h"
-
 struct profile_node {
 	errcode_t	magic;
 	char *name;
diff --git a/src/util/profile/profile.hin b/src/util/profile/profile.hin
index 156375c81..581ee10bf 100644
--- a/src/util/profile/profile.hin
+++ b/src/util/profile/profile.hin
@@ -10,17 +10,10 @@
 #endif
 
 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
-	#include <TargetConditionals.h>
-    #if TARGET_RT_MAC_CFM
-        #error "Use KfM 4.0 SDK headers for CFM compilation."
-    #endif
-#endif
-#if TARGET_OS_MAC
-    #if defined(__MWERKS__)
-        #pragma import on
-        #pragma enumsalwaysint on
-    #endif
-    #pragma options align=mac68k
+#    include <TargetConditionals.h>
+#    if TARGET_RT_MAC_CFM
+#        error "Use KfM 4.0 SDK headers for CFM compilation."
+#    endif
 #endif
 
 #ifndef KRB5_CALLCONV
@@ -41,6 +34,12 @@ typedef struct _profile_t *profile_t;
 extern "C" {
 #endif /* __cplusplus */
 
+#if TARGET_OS_MAC
+#    if defined(__MWERKS__)
+#        pragma import on
+#    endif
+#endif
+
 typedef char* profile_filespec_t;	/* path as C string */
 typedef char* profile_filespec_list_t;	/* list of : separated paths, C string */
 typedef const char * const_profile_filespec_t;	/* path as C string */
@@ -115,11 +114,9 @@ long KRB5_CALLCONV profile_add_relation
 		   const char *new_value);
 
 #if TARGET_OS_MAC
-    #if defined(__MWERKS__)
-        #pragma enumsalwaysint reset
-        #pragma import reset
-    #endif
-    #pragma options align=reset
+#    if defined(__MWERKS__)
+#        pragma import reset
+#    endif
 #endif
 
 #ifdef __cplusplus
diff --git a/src/util/profile/test_parse.c b/src/util/profile/test_parse.c
index 7aa0eeb62..961149c80 100644
--- a/src/util/profile/test_parse.c
+++ b/src/util/profile/test_parse.c
@@ -1,3 +1,5 @@
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
@@ -6,8 +8,6 @@
 #include <errno.h>
 #include <ctype.h>
 
-#include "prof_int.h"
-
 void dump_profile (struct profile_node *root, int level);
 
 int main(argc, argv)
diff --git a/src/util/profile/test_profile.c b/src/util/profile/test_profile.c
index 8a97dd2f7..5cdbf7689 100644
--- a/src/util/profile/test_profile.c
+++ b/src/util/profile/test_profile.c
@@ -2,13 +2,14 @@
  * test_profile.c --- testing program for the profile routine
  */
 
+#include "prof_int.h"
+
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
 
-#include "prof_int.h"
 #include "argv_parse.h"
 #include "com_err.h"
 
diff --git a/src/util/pty/Makefile.in b/src/util/pty/Makefile.in
index f29f9df85..e4544552b 100644
--- a/src/util/pty/Makefile.in
+++ b/src/util/pty/Makefile.in
@@ -149,5 +149,5 @@ init.so init.po $(OUTPRE)init.$(OBJEXT): init.c $(COM_ERR_DEPS) libpty.h \
 sane_hostname.so sane_hostname.po $(OUTPRE)sane_hostname.$(OBJEXT): sane_hostname.c $(COM_ERR_DEPS) \
   pty-int.h pty_err.h libpty.h $(SRCTOP)/include/socket-utils.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/port-sockets.h
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/k5-platform.h
 
diff --git a/src/util/reconf b/src/util/reconf
index c24627203..6a5038145 100644
--- a/src/util/reconf
+++ b/src/util/reconf
@@ -24,9 +24,8 @@ do
   esac
 done
 
-# Currently (2000-10-03) we need 2.13 or later.
-# The pattern also recognizes 2.40 and up.
-patb="2.(1[3-9])|([4-9][0-9])"
+# Currently (2003-04-24) we need 2.52 or later.
+patb="2.(1[0-9][0-9])|(5[2-9])|([6-9][0-9])"
 
 # sedcmd1 recognizes the older 2.12 version, and sedcmd2 the newer 2.49
 sedcmd1="s,.*version \(.*\)$,\1,"
@@ -39,18 +38,13 @@ if autoreconf --version | sed -e "$sedcmd1" -e "$sedcmd2" | egrep "$patb" >/dev/
     autoreconfoptions=
     autoconfversion=`autoconf --version | sed -e "$sedcmd1" -e "$sedcmd2"`
 	echo "Using autoconf version $autoconfversion found in your path..."
-	# Determine if localdir needs to be relative or absolute
-	case "$autoconfversion" in
-	  2.1*)
-	       localdir=.
-	       ;;
-	     *)
-	       localdir=`pwd`
-	       ;;
-	esac
+	localdir=`pwd`
 
 	# Determine if we need to patch autoreconf for 2.53
 	case "$autoconfversion" in
+	  2.52)
+	       echo "WARNING: autoconf 2.52 is known to generate buggy configure scripts!"
+	       ;;
 	  2.53)
 	       echo "Patching autoreconf"
 	       # Walk the path to find autoreconf
@@ -89,7 +83,7 @@ if autoreconf --version | sed -e "$sedcmd1" -e "$sedcmd2" | egrep "$patb" >/dev/
 	       ;;
 	esac
 else
-	echo "Couldn't find autoconf 2.13 or higher in your path."
+	echo "Couldn't find autoconf 2.52 or higher in your path."
 	echo " "
 	echo "Please install or add to your path and re-run ./util/reconf"
 	exit 1
diff --git a/src/util/ss/ChangeLog b/src/util/ss/ChangeLog
index 15d6edc6a..66c86c764 100644
--- a/src/util/ss/ChangeLog
+++ b/src/util/ss/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-23  Ken Raeburn  <raeburn@mit.edu>
+
+	* ss.h: Don't declare errno.  Include errno.h.
+
 2003-02-05  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.in (std_rqs.c): Depend on ct_c.sed and ct_c.awk.
diff --git a/src/util/ss/ss.h b/src/util/ss/ss.h
index b2fd21f00..062003d3c 100644
--- a/src/util/ss/ss.h
+++ b/src/util/ss/ss.h
@@ -7,10 +7,9 @@
 #ifndef _ss_h
 #define _ss_h __FILE__
 
+#include <errno.h>
 #include <ss/ss_err.h>
 
-extern int errno;
-
 #ifdef __STDC__
 #define __SS_CONST const
 #define __SS_PROTO (int, const char * const *, int, void *)
diff --git a/src/windows/ChangeLog b/src/windows/ChangeLog
index 5fa15b833..9e816ee17 100644
--- a/src/windows/ChangeLog
+++ b/src/windows/ChangeLog
@@ -1,3 +1,89 @@
+2004-02-11  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: Update for krb5-1.3.2-beta3.
+
+2004-02-03  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: Update for krb5-1.3.2-beta2.
+
+2004-02-02  Jeffrey Altman <jaltman@mit.edu>
+
+    * README: Document PreserveInitialTicketIdentity registry key
+
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+    * README: Update the text to include the details of the new 
+      Windows registry keys necessary to access the TGT session key.
+      Also, provide details on the incompatibility of the gss.exe
+      sample client and the versions distributed by Microsoft.
+
+2004-01-07  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: Update copyright years.  Update for
+	krb5-1.3.2-beta1.
+
+2003-07-30  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3.1 final.
+
+2003-12-22  Jeffrey Altman <jaltman@mit.edu>
+
+    * README: Update to more clearly specify the build environment 
+      requirements.  Supported compilers include MSVC++ 6.0, MSVS.NET,
+      and MSVS.NET 2003.  Clarify requirements for building with DNS
+      support.  Also, add text describing MSLSA: credential cache 
+      and how to configure Windows so it can be used.
+
+2003-07-22  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3.1-beta1.
+
+	* README: Revert previous change, as it was in error; socklen_t
+	was introduced in Aug 2001 Platform SDK, and the actual problem
+	reported was very probably a compilation environment
+	misconfiguration.
+
+2003-07-18  Tom Yu  <tlyu@mit.edu>
+
+	* README: Note requirement for Feb 2003 Platform SDK.  Thanks to
+	Doug Engert and Rodney Dyer.
+
+2003-07-08  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3 final.
+
+2003-06-27  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-beta5.
+
+2003-06-16  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-beta4.
+
+2003-06-09  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-beta3.
+
+2003-05-27  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-beta2.
+
+2003-05-14  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-beta1.
+
+2003-04-29  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-alpha3.
+
+2003-04-11  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-alpha2.
+
+2003-03-14  Tom Yu  <tlyu@mit.edu>
+
+	* version.rc: krb5-1.3-alpha1.
+
 2002-04-10  Danilo Almeida  <dalmeida@mit.edu>
 
 	* Makefile.in: Build ms2mit.
diff --git a/src/windows/README b/src/windows/README
index 81e28431b..96757e925 100644
--- a/src/windows/README
+++ b/src/windows/README
@@ -1,10 +1,10 @@
 	       Building & Running Kerberos 5 on Windows
 	       ----------------------------------------
 
-Kerberos 5 builds on Windows with MSVC++ 6.0.  You will need the
-November 2001 platform SDK or later; this SDK is required to define
-getaddrinfo.  It may or may not build with other compilers or make
-utilities.
+Kerberos 5 builds on Windows with MSVC++ 6.0, MSVS.NET, and 
+MSVS.NET 2003.  You will need the November 2001 platform SDK or 
+later; this SDK is required to define getaddrinfo.  It may or 
+may not build with other compilers or make utilities.
 
 These build instructions assume that you have the standalone source
 distribution of Kerberos 5 rather than the MIT Kerberos for Windows
@@ -22,19 +22,28 @@ Runtime library, which is not found on most Windows systems unless
 they have development tools.  To build a release version, you need to
 define NODEBUG either in the environment or the nmake command-line.
 
-DNS Support: To support DNS lookups, you will need to define
-KRB5_DNS_LOOKUP, KRB5_DNS_LOOKUP_KDC, or KRB5_DNS_LOOKUP_REALMS.  The
-DNS code will default to trying to use the wshelper library.  If you
-would rather use a resolver library whose include files more closely
-match the Unix resolver library, define KRB5_NO_WSHELPER.  You will
-also need to define DNS_INC to point to the include directory for the
-library and DNS_LIB to library itself.  The default is not to support
-DNS because the build cannot know whether there is a DNS resolver
-library around for it to use.
+To configuring the build environment execute first the compiler
+batch file, vcvars32.bat or vsvars32.bat, followed by the SDK
+batch file, setenv.bat.  For example, 
+
+  "c:\program files\microsoft visual studio .net 2003\common7\tools\vsvars32.bat"
+  "c:\program files\microsoft sdk\setenv.bat" /2000 /RETAIL
 
-Building ms2mit requires that you have a reasonably recent Microsoft
-Platform SDK installed.  Anything starting at the Windows 2000 edition
-should be fine.
+or 
+
+  "c:\program files\microsoft visual studio\vc98\bin\vcvars32.bat"
+  "c:\program files\microsoft sdk\setenv.bat" /2000 /DEBUG
+  
+DNS Support: To support DNS lookups, you will need to define
+KRB5_DNS_LOOKUP, KRB5_DNS_LOOKUP_KDC, or KRB5_DNS_LOOKUP_REALMS.  When 
+any of the KRB5_DNS_LOOKUP definitions are used, the default build will use
+the WSHelper library which is part of the Kerberos for Windows (Kfw) 
+distribution.  If you are building outside of KfW and wish to build Krb5 
+with DNS support, you must provide a resolver library whose include files 
+match the Unix resolver library.  You will need to define KRB5_NO_WSHELPER,
+define DNS_INC to point to the include directory for the library and DNS_LIB 
+to library itself.  The default is not to support DNS because the build 
+cannot know whether there is a DNS resolver library around for it to use.
 
 
 Traditional Build Method:
@@ -54,7 +63,7 @@ On the PC side
         - or -
    pkunzip -d kerbsrc.zip
 4) nmake [NODEBUG=1] [DNS-options]     # Build the sources
-5) nmake install [NODEBUG=1]           # Copy headers, libs, executables
+5) nmake install [NODEBUG=1] [options] # Copy headers, libs, executables
 
 
 All-Windows Build Method:
@@ -64,8 +73,8 @@ First, make sure you have sed, gawk, cat, and cp.
 
 1) cd xxx/src                          # Go to where the source lives
 2) nmake -f Makefile.in prep-windows   # Create Makefile for Windows
-3) nmake [NODEBUG=1] [DNS-options      # Build the sources
-4) nmake install [NODEBUG=1]           # Copy headers, libs, executables
+3) nmake [NODEBUG=1] [DNS-options]     # Build the sources
+4) nmake install [NODEBUG=1] [options] # Copy headers, libs, executables
 
 
 Notes on the install Target:
@@ -132,11 +141,160 @@ In addition to standard FILE: (disk file) and MEMORY: (in-process
 non-shared memory) Windows supports the API: cache type, which is a
 shared memory cache.  This is implemented by krbcc32.dll, which is not
 included the the krb5-only distribution.  Rather, it is part of MIT's
-Kerberos for Win32 suite.
-
-
-Othes Issues:
-------------
+Kerberos for Win32 suite.  
+
+As of the 1.3.2 release, a new cache type, MSLSA:, has been added for
+use in accessing the Microsoft Kerberos Logon Session credentials 
+cache.  The MSLSA: cache is available when the user logon is performed
+using Kerberos either to an Active Directory Domain or a non-Microsoft
+KDC.
+
+A user is able to logon to Windows using the Kerberos LSA if the machine
+is part of a Windows 2000 or Windows 2003 Active Directory domain or
+if the machine has been configured to authenticate to a non-Microsoft KDC
+such as MIT.  The instructions for configuring a Windows 2000 XP
+workstation to authenticate to a non-Microsoft KDC are documented
+in TechNet somewhere.  In brief:
+
+  1. Install the Windows 2000 or XP support tools in order to obtain
+     the tools: KSETUP.EXE and KTPASS.EXE.
+  2. Install the Windows 2000 or XP Resource Kit to obtain the tools
+     KERBTRAY.EXE and KLIST.EXE
+  3. Add Realms and associated KDCs with: *KSETUP /AddKdc <realm>
+     [<kdcname>]*.  If you leave off the <kdcname> DNS SRV records will
+     be used.
+  4. Specify the password change service host for the realm with:
+     *KSETUP /AddKpasswd <realm> <Kpwdhost>*
+  5. Assign the realm of the local machine with: *KSETUP /SetRealm
+     <realm>* where realm must be all upper case.   
+  6. Assign the local machine's password with: *KSETUP
+     /SetComputerPassword <Password>
+     *
+  7. Specify the capabilities of the Realm KDC with: *KSETUP
+     /SetRealmFlags <realm> <flag> [<flag> ...]* where flags may be
+     *None, SendAddress, TcpSupported, Delegate, *and *NcSupported*,
+  8. Map principal names to local accounts with: *KSETUP /MapUser
+     <principal> <account>*
+
+On the MIT KDC, you must then create service principals using the "Password" 
+assigned to the machine.  So far the minimum list of principals required appear 
+to be for a machine named "mymachine" in the realm "EXAMPLE.COM" with a 
+domain name of "example.com":
+
+   * host/mymachine@EXAMPLE.COM
+   * host/mymachine.example.com@EXAMPLE.COM
+   * cifs/mymachine@EXAMPLE.COM
+   * cifs/mymachine.example.com@EXAMPLE.COM
+
+There may very well be other serivces for which principals must be created depending 
+on what services are being executed on the machine.
+
+It is very important to note that while you can successfully log into a Windows 
+workstation by authenticating to the KDC without creating a host key; the logon 
+session you receive will not be a Kerberos Logon Session.  There will be no Kerberos 
+principal and no LSA cache to access.
+
+The result of a real KSETUP configuration looks like this:
+
+   [C:\4\4NT]ksetup
+   default realm = KRB5.COLUMBIA.EDU (external)
+   ATHENA.MIT.EDU:
+           kdc = kerberos.mit.edu
+           kdc = kerberos-1.mit.edu
+           kdc = kerberos-2.mit.edu
+           kdc = kerberos-3.mit.edu
+           Realm Flags = 0x0 none
+   CC.COLUMBIA.EDU:
+           kdc = kerberos.cc.columbia.edu
+           Realm Flags = 0x0 none
+   GRAND.CENTRAL.ORG:
+           kdc = penn.central.org
+           kdc = grand-opening.mit.edu
+           Realm Flags = 0x0 none
+   KRB5.COLUMBIA.EDU:
+           kdc = yclept.kermit.columbia.edu
+           Realm Flags = 0x0 none
+   OPENAFS.ORG:
+           kdc = virtue.openafs.org
+           Realm Flags = 0x0 none
+   Mapping jaltman@KRB5.COLUMBIA.EDU to jaltman.
+   Mapping jaltman@CC.COLUMBIA.EDU to jaltman.
+   Mapping jaltman@ATHENA.MIT.EDU to jaltman.
+   Mapping all users (*) to a local account by the same name (*).
+
+The MSLSA: credential cache relies on the ability to extract the entire
+Kerberos ticket including the session key from the Kerberos LSA.  In an
+attempt to increase security Microsoft has begun to implement a feature
+by which they no longer export the session keys for Ticket Getting Tickets.
+This has the side effect of making them useless to the MIT krb5 library
+when attempting to request additional service tickets.
+
+This new feature has been seen in Windows 2003 Server, Windows 2000 Server SP4,
+and Windows XP SP2 Beta.  We assume that it will be implemented in all future
+Microsoft operating systems supporting the Kerberos SSPI.  Microsoft does work
+closely with MIT and has provided a registry key to disable this new feature.
+
+  HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
+    AllowTGTSessionKey = 0x01 (DWORD)
+
+On Windows XP SP2 Beta 1 the key was specified as 
+
+  HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos
+    AllowTGTSessionKey = 0x01 (DWORD)
+
+However, we anticipate that this will be changed to match the Server platforms 
+in time for SP2 RC1.
+
+It has been noted that the Microsoft Kerberos LSA does not provide enough 
+information within its KERB_EXTERNAL_TICKET structure to properly construct
+the Client Principal simply by examining a single ticket. From the MSDN
+Library:
+
+  ClientName 
+    KERB_EXTERNAL_NAME structure that contains the client name in the ticket. 
+    This name is relative to the current domain. 
+
+  DomainName 
+    UNICODE_STRING that contains the name of the domain that corresponds to 
+    the ServiceName member. This is the domain that issued the ticket. 
+
+  TargetDomainName 
+    UNICODE_STRING that contains the name of the domain in which the ticket is
+    valid. For an interdomain ticket, this is the destination domain. 
+
+  AltTargetDomainName 
+    UNICODE_STRING that contains a synonym for the destination domain. Every 
+    domain has two names: a DNS name and a NetBIOS name. If the name returned 
+    in the ticket is different from the name used to request the ticket (the 
+    Kerberos Key Distribution Center (KDC) may do name mapping), this string 
+    contains the original name. 
+
+Unfortunately, there is no field here which contains the domain of the client.
+In order for the krb5_ccache to properly report the client principal name, the 
+client principal name is constructed by utilizing the ClientName and DomainName
+fields of the Initial TGT associated with the Kerberos LSA credential cache.
+To disable the use of the TGT info and instead simply use the "DomainName" field
+of the current ticket define one of the following registry keys depending on
+whether the change should be system global or just for the current user.
+
+   HKLM\Software\MIT\Kerberos5\
+      PreserveInitialTicketIdentity = 0x0 (DWORD)
+
+   HKCU\Software\MIT\Kerberos5\
+      PreserveInitialTicketIdentity = 0x0 (DWORD)
+
+GSSAPI Sample Client:
+---------------------
+
+The GSS API Sample Client provided in this distribution is compatible with the
+gss-server application built on Unix/Linux systems.  This client is not compatible
+with the Platform SDK/Samples/Security/SSPI/GSS/ samples which Microsoft has been
+shipping as of January 2004.  Revised versions of these samples are available upon 
+request to krbdev@mit.edu.  Microsoft is committed to distribute revised samples
+which are compatible with the MIT distributed tools in a future SDK and via MSDN.
+
+Kerberos 4 Library Support:
+---------------------------
 
 The krb4_32.dll that is built (but not installed) is not supported.
 If you need Kerberos 4, you can use the krbv4w32.dll that MIT
diff --git a/src/windows/cns/ChangeLog b/src/windows/cns/ChangeLog
index 54cfa75c4..73960c080 100644
--- a/src/windows/cns/ChangeLog
+++ b/src/windows/cns/ChangeLog
@@ -1,3 +1,9 @@
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+    * options.c, cnsres5.rc, cns.h, cns_reg.c cns_reg.h, cns.c:
+      Add checkbox for requesting "no addresses" if it is not
+      specified in the krb5.ini file.
+
 2003-02-25  Tom Yu  <tlyu@mit.edu>
 
 	* kpasswd.c (k5_change_password): Don't pass a NULL pointer to
diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c
index 13404b736..7a02abba7 100644
--- a/src/windows/cns/cns.c
+++ b/src/windows/cns/cns.c
@@ -58,6 +58,7 @@ char confname[FILENAME_MAX];           /* krb5.conf (or krb.conf for krb4) */
 #ifdef KRB5
 char ccname[FILENAME_MAX];             /* ccache file location */
 BOOL forwardable;                      /* TRUE to get forwardable tickets */
+BOOL noaddresses;
 krb5_context k5_context;
 krb5_ccache k5_ccache;
 #endif
@@ -1224,7 +1225,10 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
     krb5_get_init_creds_opt_init(&opts);
     krb5_get_init_creds_opt_set_forwardable(&opts, forwardable);
     krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime * 60);
-    
+    if (noaddresses) {
+		krb5_get_init_creds_opt_set_address_list(&opts, NULL);
+ 	}    
+
     /*
      * get the initial creds using the password and the options we set above
      */
@@ -1491,7 +1495,6 @@ kwin_paint(HWND hwnd)
 LRESULT CALLBACK
 kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-  int n;
 
 #if 0
   if (message == wm_kerberos_changed) {       /* Message from the ccache */
@@ -1704,6 +1707,7 @@ init_instance(HINSTANCE hinstance, int ncmdshow)
    * ticket options
    */
   forwardable = cns_res.forwardable;
+  noaddresses = cns_res.noaddresses;
 
   /*
    * Load clock icons
diff --git a/src/windows/cns/cns.h b/src/windows/cns/cns.h
index 7cc93ab9a..cdd6da3b3 100644
--- a/src/windows/cns/cns.h
+++ b/src/windows/cns/cns.h
@@ -144,6 +144,7 @@
 #define     IDD_ALERT 312
 #define   IDD_TKOPT 320
 #define   IDD_FORWARDABLE 321
+#define   IDD_NOADDRESSES 322
 
 /*
  * the entire range (400 through 499) is reserved for the blasted variable
@@ -199,6 +200,7 @@ extern krb5_context k5_context;
 extern krb5_ccache k5_ccache;
 extern char ccname[FILENAME_MAX];
 extern BOOL forwardable;
+extern BOOL noaddresses;
 #endif
 
 /*
diff --git a/src/windows/cns/cns_reg.c b/src/windows/cns/cns_reg.c
index 160eb15e3..92255fe4f 100644
--- a/src/windows/cns/cns_reg.c
+++ b/src/windows/cns/cns_reg.c
@@ -45,7 +45,7 @@ cns_load_registry(void)
   cns_res.beep = 0;
   cns_res.lifetime = DEFAULT_TKT_LIFE * 5;
   cns_res.forwardable = 1;
-
+  cns_res.noaddresses = 0;
     
   for (i = 1 ; i < FILE_MENU_MAX_LOGINS ; i++)
     cns_res.logins[i][0] = '\0';
@@ -117,6 +117,9 @@ cns_load_registry(void)
   if (registry_dword_get(key, "forwardable", &tdw) == 0)
 	  cns_res.forwardable = tdw;
 
+  if (registry_dword_get(key, "noaddresses", &tdw) == 0)
+   	  cns_res.noaddresses = tdw;
+ 
   if (registry_dword_get(key, "alert", &tdw) == 0)
 	  cns_res.alert = tdw;
 
@@ -196,6 +199,7 @@ cns_save_registry(void)
   registry_dword_set(key, "beep", cns_res.beep);
   registry_dword_set(key, "lifetime", cns_res.lifetime);
   registry_dword_set(key, "forwardable", cns_res.forwardable);
+  registry_dword_set(key, "noaddresses", cns_res.noaddresses);
 
   registry_string_set(key, "name", cns_res.name);
   registry_string_set(key, "realm", cns_res.realm);
diff --git a/src/windows/cns/cns_reg.h b/src/windows/cns/cns_reg.h
index 7ec726356..9ebed4fe8 100644
--- a/src/windows/cns/cns_reg.h
+++ b/src/windows/cns/cns_reg.h
@@ -17,6 +17,7 @@ typedef struct cns_reg {
   DWORD         forwardable;                     /* get forwardable tickets? */
   DWORD         conf_override;                   /* allow changing of confname */
   DWORD         cc_override;                     /* allow changing of ccname */
+  DWORD         noaddresses;                     /* Don't require address in tickets */
   char          name[MAX_K_NAME_SZ];             /* last user used */
   char          realm[MAX_K_NAME_SZ];            /* last realm used */
   char          confname[FILENAME_MAX];
diff --git a/src/windows/cns/cnsres5.rc b/src/windows/cns/cnsres5.rc
index e56375334..d398078e3 100644
--- a/src/windows/cns/cnsres5.rc
+++ b/src/windows/cns/cnsres5.rc
@@ -161,7 +161,9 @@ BEGIN
                     95,65,39,12
     GROUPBOX        "Ticket options",IDD_TKOPT,5,86,158,23,WS_GROUP
     CONTROL         "&Forwardable",IDD_FORWARDABLE,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,54,95,65,12
+                    WS_TABSTOP,25,95,65,12
+    CONTROL         "&NoAddresses",IDD_NOADDRESSES,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,90,95,65,12
     DEFPUSHBUTTON   "OK",IDOK,19,117,52,14
     PUSHBUTTON      "Cancel",IDCANCEL,95,117,52,14
 END
diff --git a/src/windows/cns/options.c b/src/windows/cns/options.c
index f13314575..9e7c30e94 100644
--- a/src/windows/cns/options.c
+++ b/src/windows/cns/options.c
@@ -74,6 +74,9 @@ opts_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
   forwardable = cns_res.forwardable;
   SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_SETCHECK, forwardable, 0);
 
+  noaddresses = cns_res.noaddresses;
+  SendDlgItemMessage(hwnd, IDD_NOADDRESSES, BM_SETCHECK, noaddresses, 0);
+ 
   return TRUE;
 }
 
@@ -161,6 +164,9 @@ opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
     forwardable = SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_GETCHECK, 0, 0);
     cns_res.forwardable = forwardable;
 
+    noaddresses = SendDlgItemMessage(hwnd, IDD_NOADDRESSES, BM_GETCHECK, 0, 0);
+    cns_res.noaddresses = noaddresses;
+
     EndDialog(hwnd, IDOK);
 
     return; /* TRUE */
diff --git a/src/windows/gss/ChangeLog b/src/windows/gss/ChangeLog
index b426555a3..64d57dd7d 100644
--- a/src/windows/gss/ChangeLog
+++ b/src/windows/gss/ChangeLog
@@ -1,3 +1,42 @@
+2004-02-12  Jeffrey Altman <jaltman@mit.edu>
+
+    * Fix libpath for krbcc32.lib (only affects KRB5_KFW_COMPILE builds)
+
+2004-02-11  Jeffrey Altman <jaltman@mit.edu>
+
+    * gss-misc.h: Add file.  Copy from src/appl/gss-sample/
+
+2004-02-06  Jeffrey Altman <jaltman@mit.edu>
+
+    * resource.h: add new component id values for replay, mutual, sequence
+
+    * gss.rc: add new components for replay, mutual, sequence
+
+    * gss.h, gss.c, gss-client.c: add support for replay, mutual, and sequence
+
+2004-02-04  Jeffrey Altman <jaltman@mit.edu>
+
+    * resource.h: add new component id values for ccache
+
+    * Makefile.in: add conditional linkage to krbcc32.lib (if KRB5_KFW_BUILD)
+
+    * gss.rc: add new component for ccache selection
+ 
+    * gss.h, gss.c, gss-client.c: add support for ccache selection and 
+      if built with USE_LEASH add support for dynamic querying of the 
+      available ccache list
+
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+    * resource.h: new file containing new ui component id values
+    
+    * gss.rc: new user interface definition
+
+    * gss.h, gss-misc.c, gss-client.c: Updates to support new UI and 
+      corrections to add compatibility with the Unix gss-server
+
+    * Makefile.in: add linkage to comctl32.lib
+
 2002-06-13  Ken Raeburn  <raeburn@mit.edu>
 
 	* Makefile.in (SYSLIBS): Use ws2_32.lib instead of wsock32.lib.
diff --git a/src/windows/gss/Makefile.in b/src/windows/gss/Makefile.in
index b545599ae..9c87f185d 100644
--- a/src/windows/gss/Makefile.in
+++ b/src/windows/gss/Makefile.in
@@ -8,7 +8,12 @@ XOBJS	= $(RESFILE)
 ##### Options
 # Set NODEBUG if building release instead of debug
 BUILDTOP=..\..
-LOCALINCLUDES= /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5
+
+!if defined(KRB5_KFW_COMPILE)
+KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
+KFWLIB= $(BUILDTOP)\..\..\..\..\target\lib\$(CPU)\$(OUTPRE_DBG)\krbcc32.lib
+!endif
+LOCALINCLUDES= /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 $(KFWINC)
 
 ##### RC Compiler
 RFLAGS	= $(LOCALINCLUDES)
@@ -17,14 +22,14 @@ RCFLAGS	= $(RFLAGS) -D_WIN32 -DGSS_APP
 ##### Linker
 LINK	= link
 LIBS	= $(GLIB) $(CLIB) $(WLIB)
-SYSLIBS	= kernel32.lib ws2_32.lib user32.lib gdi32.lib comdlg32.lib
+SYSLIBS	= kernel32.lib ws2_32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib
 LFLAGS	= /nologo $(LOPTS)
 
 all:: Makefile $(OUTPRE)gss.exe
 
 $(OUTPRE)gss.exe: gss.def $(OBJS) $(XOBJS) $(LIBS)
 	$(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(XOBJS) \
-	  $(LIBS) $(SYSLIBS)
+	  $(LIBS) $(SYSLIBS) $(KFWLIB)
 
 $(OBJS) $(XOBJS): gss.h
 
diff --git a/src/windows/gss/gss-client.c b/src/windows/gss/gss-client.c
index d5e8972b3..d9c1491c2 100644
--- a/src/windows/gss/gss-client.c
+++ b/src/windows/gss/gss-client.c
@@ -9,7 +9,7 @@
  * in advertising or publicity pertaining to distribution of the software
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
+ * purpose.  It is provided "as is" without express or implied warranty.
  * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
@@ -19,119 +19,52 @@
  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
-
-#include "gss.h"
-
-static const gss_OID_desc oids[] = {
-   {10, "\052\206\110\206\367\022\001\002\001\004"},
-};
-
-const gss_OID_desc * nt_service_name = oids+0;
-
-int
-gss (char *host, char *name, char *oid, char *msg, int port)
-{
-	if (port == 0 || port == -1)
-        port = 4444;
-
-    if (call_server(host, port, name, oid, msg) < 0)
-        return 1;
-
-    return 0;
-}
-
-/*+
- * Function: call_server
- *
- * Purpose: Call the "sign" service.
- *
- * Arguments:
- *
- *		host			(r) the host providing the service
- *		port			(r) the port to connect to on host
- *		service_name	(r) the GSS-API service name to authenticate to 
- *		msg				(r) the message to have "signed"
- *
- * Returns: 0 on success, -1 on failure
+/*
+ * Copyright (C) 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
  *
- * Effects:
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
  * 
- * call_server opens a TCP connection to <host:port> and establishes a
- * GSS-API context with service_name over the connection.  It then
- * seals msg in a GSS-API token with gss_seal, sends it to the server,
- * reads back a GSS-API signature block for msg from the server, and
- * verifies it with gss_verify.	 -1 is returned if any step fails,
- * otherwise 0 is returned.
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
  */
-int
-call_server (char *host, u_short port, char *service_name, char *oid, char *msg)
-{
-    gss_ctx_id_t context;
-    gss_buffer_desc in_buf, out_buf;
-    int s, state;
-    OM_uint32 maj_stat, min_stat;
-
-    /* Open connection */
-    if ((s = connect_to_server(host, port)) < 0)
-        return -1;
-
-    /* Establish context */
-    if (client_establish_context(s, service_name, oid, &context) < 0)
-        return -1;
-
-    /* Seal the message */
-    in_buf.value = msg;
-    in_buf.length = strlen(msg) + 1;
-    maj_stat = gss_seal(&min_stat, context, 1, GSS_C_QOP_DEFAULT,
-        &in_buf, &state, &out_buf);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("sealing message", maj_stat, min_stat);
-        return -1;
-    } else if (! state) {
-        OkMsgBox ("Warning!  Message not encrypted.\n");
-    }
-
-    /* Send to server */
-    if (send_token(s, &out_buf) < 0)
-        return -1;
-    (void) gss_release_buffer(&min_stat, &out_buf);
-
-    /* Read signature block into out_buf */
-    if (recv_token(s, &out_buf) < 0)
-        return -1;
-
-    /* Verify signature block */
-    maj_stat = gss_verify(&min_stat, context, &in_buf, &out_buf, &state);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("verifying signature", maj_stat, min_stat);
-        return -1;
-    }
-    (void) gss_release_buffer(&min_stat, &out_buf);
 
-    OkMsgBox ("Signature verified.");
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+#include <winsock.h>
 
-    /* Delete context */
-    maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("deleting context", maj_stat, min_stat);
-        return -1;
-    }
-    (void) gss_release_buffer(&min_stat, &out_buf);
+#include <gssapi/gssapi_generic.h>
+#include <gssapi\gssapi_krb5.h>
+#include "gss.h"
+#include "gss-misc.h"
 
-    closesocket(s);
-	 
-    return 0;
-}
+static int verbose = 1;
 
-/*+
+/*
  * Function: connect_to_server
  *
  * Purpose: Opens a TCP connection to the name host and port.
  *
  * Arguments:
  *
- *		host			(r) the target host name
- *		port			(r) the target port, in host byte order
+ * 	host		(r) the target host name
+ * 	port		(r) the target port, in host byte order
  *
  * Returns: the established socket file desciptor, or -1 on failure
  *
@@ -141,34 +74,36 @@ call_server (char *host, u_short port, char *service_name, char *oid, char *msg)
  * opened and connected.  If an error occurs, an error message is
  * displayed and -1 is returned.
  */
-int
-connect_to_server (char *host, u_short port)
+static int connect_to_server(host, port)
+     char *host;
+     u_short port;
 {
-    struct sockaddr_in saddr;
-    struct hostent *hp;
-    int s;
-	 
-    if ((hp = gethostbyname(host)) == NULL) {
-        OkMsgBox ("Unknown host: %s\n", host);
-        return -1;
-    }
-	 
-    saddr.sin_family = hp->h_addrtype;
-    memcpy((char *)&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr));
-    saddr.sin_port = htons(port);
+     struct sockaddr_in saddr;
+     struct hostent *hp;
+     int s;
+     
+     if ((hp = gethostbyname(host)) == NULL) {
+	  printf("Unknown host: %s\r\n", host);
+	  return -1;
+     }
+     
+     saddr.sin_family = hp->h_addrtype;
+     memcpy((char *)&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr));
+     saddr.sin_port = htons(port);
 
-    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        my_perror("creating socket");
-        return -1;
-    }
-    if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
-        my_perror("connecting to server");
-        return -1;
-    }
-    return s;
+     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+	  perror("creating socket");
+	  return -1;
+     }
+     if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+	  perror("connecting to server");
+	  (void) closesocket(s);
+	  return -1;
+     }
+     return s;
 }
 
-/*+
+/*
  * Function: client_establish_context
  *
  * Purpose: establishes a GSS-API context with a specified service and
@@ -176,15 +111,19 @@ connect_to_server (char *host, u_short port)
  *
  * Arguments:
  *
- *		s				(r) an established TCP connection to the service
- *		sname	        (r) the ASCII service name of the service
- *		context			(w) the established GSS-API context
+ * 	s		(r) an established TCP connection to the service
+ * 	service_name	(r) the ASCII service name of the service
+ *	gss_flags	(r) GSS-API delegation flag (if any)
+ *	auth_flag	(r) whether to actually do authentication
+ *	oid		(r) OID of the mechanism to use
+ * 	context		(w) the established GSS-API context
+ *	ret_flags	(w) the returned flags from init_sec_context
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  * 
- * sname is imported as a GSS-API name and a GSS-API context is
+ * service_name is imported as a GSS-API name and a GSS-API context is
  * established with the corresponding service; the service should be
  * listening on the TCP connection s.  The default GSS-API mechanism
  * is used, and mutual authentication and replay detection are
@@ -194,100 +133,483 @@ connect_to_server (char *host, u_short port)
  * unsuccessful, the GSS-API error messages are displayed on stderr
  * and -1 is returned.
  */
-int
-client_establish_context (int s, char *sname, char *oid_name,
-			  gss_ctx_id_t *gss_context)
+int client_establish_context( int s, 
+                              char *service_name,
+                              OM_uint32 gss_flags, 
+                              int auth_flag,
+                              int v1_format, 
+                              gss_OID oid, 
+                              gss_ctx_id_t *gss_context, 
+                              OM_uint32 *ret_flags)
 {
-    gss_buffer_desc send_tok, recv_tok, *token_ptr;
-    gss_name_t target_name;
-    OM_uint32 maj_stat, min_stat;
-    gss_OID oid = GSS_C_NULL_OID;
-
-    if (oid_name && oid_name[0]) {
-	    send_tok.value = oid_name;
-	    send_tok.length = strlen(oid_name);
-	    maj_stat = gss_str_to_oid(&min_stat, &send_tok, &oid);
-	    if (maj_stat != GSS_S_COMPLETE) {
-		    display_status("str_to_oid", maj_stat, min_stat);
-		    return -1;
-	    }
-    }
+    if (auth_flag) {
+        gss_buffer_desc send_tok, recv_tok, *token_ptr;
+        gss_name_t target_name;
+        OM_uint32 maj_stat, min_stat, init_sec_min_stat;
+        int token_flags;
 
-    /*
-     * Import the name into target_name.  Use send_tok to save
-     * local variable space.
-     */
-    send_tok.value = sname;
-    send_tok.length = strlen(sname) + 1;
-    maj_stat = gss_import_name(&min_stat, &send_tok,
-        (gss_OID) nt_service_name, &target_name);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("parsing name", maj_stat, min_stat);
-        return -1;
-    }
-	 
-	/*
-	 * Perform the context-establishement loop.
-	 *
-	 * On each pass through the loop, token_ptr points to the token
-	 * to send to the server (or GSS_C_NO_BUFFER on the first pass).
-	 * Every generated token is stored in send_tok which is then
-	 * transmitted to the server; every received token is stored in
-	 * recv_tok, which token_ptr is then set to, to be processed by
-	 * the next call to gss_init_sec_context.
-	 * 
-	 * GSS-API guarantees that send_tok's length will be non-zero
-	 * if and only if the server is expecting another token from us,
-	 * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
-	 * and only if the server has another token to send us.
-	 */
-	 
-    token_ptr = GSS_C_NO_BUFFER;
-    *gss_context = GSS_C_NO_CONTEXT;
-
-    do {
-        maj_stat =
-            gss_init_sec_context(&min_stat,
-			                     GSS_C_NO_CREDENTIAL,
-								 gss_context,
-								 target_name,
-								 oid,
-								 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
-								 0,
-								 NULL,		/* no channel bindings */
-								 token_ptr,
-								 NULL,		/* ignore mech type */
-								 &send_tok,
-								 NULL,		/* ignore ret_flags */
-								 NULL);		/* ignore time_rec */
-
-        if (token_ptr != GSS_C_NO_BUFFER)
-            (void) gss_release_buffer(&min_stat, &recv_tok);
-
-        if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
-            display_status("initializing context", maj_stat, min_stat);
-            (void) gss_release_name(&min_stat, &target_name);
+       /*
+        * Import the name into target_name.  Use send_tok to save
+        * local variable space.
+        */
+        send_tok.value = service_name;
+        send_tok.length = strlen(service_name) ;
+        maj_stat = gss_import_name(&min_stat, &send_tok,
+                                    (gss_OID) gss_nt_service_name, &target_name);
+        if (maj_stat != GSS_S_COMPLETE) {
+            display_status("parsing name", maj_stat, min_stat);
             return -1;
         }
-
-        if (send_tok.length != 0) {
-            if (send_token(s, &send_tok) < 0) {
-                (void) gss_release_buffer(&min_stat, &send_tok);
+     
+        if (!v1_format) {
+            if (send_token(s, TOKEN_NOOP|TOKEN_CONTEXT_NEXT, empty_token) < 0) {
                 (void) gss_release_name(&min_stat, &target_name);
                 return -1;
             }
         }
-        (void) gss_release_buffer(&min_stat, &send_tok);
-		  
-        if (maj_stat == GSS_S_CONTINUE_NEEDED) {
-            if (recv_token(s, &recv_tok) < 0) {
+
+       /*
+        * Perform the context-establishement loop.
+        *
+        * On each pass through the loop, token_ptr points to the token
+        * to send to the server (or GSS_C_NO_BUFFER on the first pass).
+        * Every generated token is stored in send_tok which is then
+        * transmitted to the server; every received token is stored in
+        * recv_tok, which token_ptr is then set to, to be processed by
+        * the next call to gss_init_sec_context.
+        * 
+        * GSS-API guarantees that send_tok's length will be non-zero
+        * if and only if the server is expecting another token from us,
+        * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
+        * and only if the server has another token to send us.
+        */
+
+        token_ptr = GSS_C_NO_BUFFER;
+        *gss_context = GSS_C_NO_CONTEXT;
+
+        do {
+            maj_stat =
+                gss_init_sec_context(&init_sec_min_stat,
+                                      GSS_C_NO_CREDENTIAL,
+                                      gss_context,
+                                      target_name,
+                                      oid,
+                                      gss_flags,
+                                      0,
+                                      NULL,	/* no channel bindings */
+                                      token_ptr,
+                                      NULL,	/* ignore mech type */
+                                      &send_tok,
+                                      ret_flags,
+                                      NULL);	/* ignore time_rec */
+
+            if (token_ptr != GSS_C_NO_BUFFER)
+                free (recv_tok.value);
+
+            if (send_tok.length != 0) {
+                if (verbose)
+                    printf("Sending init_sec_context token (size=%d)...",
+                            (int) send_tok.length);
+                if (send_token(s, v1_format?0:TOKEN_CONTEXT, &send_tok) < 0) {
+                    (void) gss_release_buffer(&min_stat, &send_tok);
+                    (void) gss_release_name(&min_stat, &target_name);
+                    return -1;
+                }
+            }
+            (void) gss_release_buffer(&min_stat, &send_tok);
+
+            if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
+                display_status("initializing context", maj_stat,
+                                init_sec_min_stat);
                 (void) gss_release_name(&min_stat, &target_name);
+                if (*gss_context != GSS_C_NO_CONTEXT)
+                    gss_delete_sec_context(&min_stat, gss_context,
+                                            GSS_C_NO_BUFFER);
                 return -1;
             }
-            token_ptr = &recv_tok;
-        }
-    } while (maj_stat == GSS_S_CONTINUE_NEEDED);
 
-    (void) gss_release_name(&min_stat, &target_name);
+            if (maj_stat == GSS_S_CONTINUE_NEEDED) {
+                if (verbose)
+                    printf("continue needed...");
+                if (recv_token(s, &token_flags, &recv_tok) < 0) {
+                    (void) gss_release_name(&min_stat, &target_name);
+                    return -1;
+                }
+                token_ptr = &recv_tok;
+            }
+            if (verbose)
+                printf("\r\n");
+        } while (maj_stat == GSS_S_CONTINUE_NEEDED);
+
+        (void) gss_release_name(&min_stat, &target_name);
+    }
+    else {
+        if (send_token(s, TOKEN_NOOP, empty_token) < 0)
+            return -1;
+    }
+
     return 0;
 }
+
+static void read_file(file_name, in_buf)
+    char		*file_name;
+    gss_buffer_t	in_buf;
+{
+    int fd, count;
+    struct stat stat_buf;
+    
+    if ((fd = open(file_name, O_RDONLY, 0)) < 0) {
+	perror("open");
+	printf("Couldn't open file %s\r\n", file_name);
+	exit(1);
+    }
+    if (fstat(fd, &stat_buf) < 0) {
+	perror("fstat");
+	exit(1);
+    }
+    in_buf->length = stat_buf.st_size;
+
+    if (in_buf->length == 0) {
+	in_buf->value = NULL;
+	return;
+    }
+
+    if ((in_buf->value = malloc(in_buf->length)) == 0) {
+	printf("Couldn't allocate %d byte buffer for reading file\r\n",
+		(int) in_buf->length);
+	exit(1);
+    }
+
+    /* this code used to check for incomplete reads, but you can't get
+       an incomplete read on any file for which fstat() is meaningful */
+
+    count = read(fd, in_buf->value, in_buf->length);
+    if (count < 0) {
+	perror("read");
+	exit(1);
+    }
+    if (count < in_buf->length)
+	printf("Warning, only read in %d bytes, expected %d\r\n",
+		count, (int) in_buf->length);
+}
+
+/*
+ * Function: call_server
+ *
+ * Purpose: Call the "sign" service.
+ *
+ * Arguments:
+ *
+ * 	host		(r) the host providing the service
+ * 	port		(r) the port to connect to on host
+ * 	service_name	(r) the GSS-API service name to authenticate to
+ *	gss_flags	(r) GSS-API delegation flag (if any)
+ *	auth_flag	(r) whether to do authentication
+ *	wrap_flag	(r) whether to do message wrapping at all
+ *	encrypt_flag	(r) whether to do encryption while wrapping
+ *	mic_flag	(r) whether to request a MIC from the server
+ * 	msg		(r) the message to have "signed"
+ *	use_file	(r) whether to treat msg as an input file name
+ *	mcount		(r) the number of times to send the message
+ *
+ * Returns: 0 on success, -1 on failure
+ *
+ * Effects:
+ * 
+ * call_server opens a TCP connection to <host:port> and establishes a
+ * GSS-API context with service_name over the connection.  It then
+ * seals msg in a GSS-API token with gss_wrap, sends it to the server,
+ * reads back a GSS-API signature block for msg from the server, and
+ * verifies it with gss_verify.  -1 is returned if any step fails,
+ * otherwise 0 is returned.  */
+int call_server(char *host, u_short port, gss_OID oid, char *service_name, 
+                OM_uint32 gss_flags, int auth_flag,
+		        int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, 
+                char *msg, int use_file, int mcount)
+{
+     gss_ctx_id_t context;
+     gss_buffer_desc in_buf, out_buf;
+     int s, state;
+     OM_uint32 ret_flags;
+     OM_uint32 maj_stat, min_stat;
+     gss_name_t		src_name, targ_name;
+     gss_buffer_desc	sname, tname;
+     OM_uint32		lifetime;
+     gss_OID		mechanism, name_type;
+     int		is_local;
+     OM_uint32		context_flags;
+     int		is_open;
+     gss_qop_t		qop_state;
+     gss_OID_set	mech_names;
+     gss_buffer_desc	oid_name;
+     size_t	i;
+     int token_flags;
+
+     /* Open connection */
+     if ((s = connect_to_server(host, port)) < 0)
+	  return -1;
+
+     /* Establish context */
+     if (client_establish_context(s, service_name, gss_flags, auth_flag,
+				  v1_format, oid, &context,
+				  &ret_flags) < 0) {
+	  (void) closesocket(s);
+	  return -1;
+     }
+
+     if (auth_flag) {
+         if (verbose) {
+             /* display the flags */
+             /* display_ctx_flags(ret_flags); */
+
+             /* Get context information */
+             maj_stat = gss_inquire_context(&min_stat, context,
+					&src_name, &targ_name, &lifetime,
+					&mechanism, &context_flags,
+					&is_local,
+					&is_open);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("inquiring context", maj_stat, min_stat);
+                 return -1;
+             }
+
+             maj_stat = gss_display_name(&min_stat, src_name, &sname,
+                                          &name_type);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("displaying source name", maj_stat, min_stat);
+                 return -1;
+             }
+             maj_stat = gss_display_name(&min_stat, targ_name, &tname,
+                                          (gss_OID *) NULL);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("displaying target name", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\r\n",
+                     (int) sname.length, (char *) sname.value,
+                     (int) tname.length, (char *) tname.value, lifetime,
+                     context_flags,
+                     (is_local) ? "locally initiated" : "remotely initiated",
+                     (is_open) ? "open" : "closed");
+
+             (void) gss_release_name(&min_stat, &src_name);
+             (void) gss_release_name(&min_stat, &targ_name);
+             (void) gss_release_buffer(&min_stat, &sname);
+             (void) gss_release_buffer(&min_stat, &tname);
+
+             maj_stat = gss_oid_to_str(&min_stat,
+                                        name_type,
+                                        &oid_name);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("converting oid->string", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("Name type of source name is %.*s.\r\n",
+                     (int) oid_name.length, (char *) oid_name.value);
+             (void) gss_release_buffer(&min_stat, &oid_name);
+
+             /* Now get the names supported by the mechanism */
+             maj_stat = gss_inquire_names_for_mech(&min_stat,
+                                                    mechanism,
+                                                    &mech_names);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("inquiring mech names", maj_stat, min_stat);
+                 return -1;
+             }
+
+             maj_stat = gss_oid_to_str(&min_stat,
+                                        mechanism,
+                                        &oid_name);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("converting oid->string", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("Mechanism %.*s supports %d names\r\n",
+                     (int) oid_name.length, (char *) oid_name.value,
+                     (int) mech_names->count);
+             (void) gss_release_buffer(&min_stat, &oid_name);
+
+             for (i=0; i<mech_names->count; i++) {
+                 maj_stat = gss_oid_to_str(&min_stat,
+                                            &mech_names->elements[i],
+                                            &oid_name);
+                 if (maj_stat != GSS_S_COMPLETE) {
+                     display_status("converting oid->string", maj_stat, min_stat);
+                     return -1;
+                 }
+                 printf("  %d: %.*s\r\n", (int) i,
+                         (int) oid_name.length, (char *) oid_name.value);
+
+                 (void) gss_release_buffer(&min_stat, &oid_name);
+             }
+             (void) gss_release_oid_set(&min_stat, &mech_names);
+         }
+     }
+     
+     if (use_file) {
+         read_file(msg, &in_buf);
+     } else {
+	 /* Seal the message */
+	 in_buf.value = msg;
+	 in_buf.length = strlen(msg);
+     }
+
+     for (i = 0; i < mcount; i++) {
+       if (wrap_flag) {
+	 maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT,
+			     &in_buf, &state, &out_buf);
+	 if (maj_stat != GSS_S_COMPLETE) {
+	   display_status("wrapping message", maj_stat, min_stat);
+	   (void) closesocket(s);
+	   (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+	   return -1;
+	 } else if (encrypt_flag && ! state) {
+	   fprintf(stderr, "Warning!  Message not encrypted.\r\n");
+	 }
+       }
+       else {
+	 out_buf = in_buf;
+       }
+
+       /* Send to server */
+       if (send_token(s, (v1_format?0
+			  :(TOKEN_DATA |
+			  (wrap_flag ? TOKEN_WRAPPED : 0) |
+			  (encrypt_flag ? TOKEN_ENCRYPTED : 0) |
+			  (mic_flag ? TOKEN_SEND_MIC : 0))), &out_buf) < 0) {
+	 (void) closesocket(s);
+	 (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+	 return -1;
+       }
+       if (out_buf.value != in_buf.value)
+	 (void) gss_release_buffer(&min_stat, &out_buf);
+
+       /* Read signature block into out_buf */
+       if (recv_token(s, &token_flags, &out_buf) < 0) {
+	 (void) closesocket(s);
+	 (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+	 return -1;
+       }
+
+       if (mic_flag) {
+	 /* Verify signature block */
+	 maj_stat = gss_verify_mic(&min_stat, context, &in_buf,
+				   &out_buf, &qop_state);
+	 if (maj_stat != GSS_S_COMPLETE) {
+	   display_status("verifying signature", maj_stat, min_stat);
+	   (void) closesocket(s);
+	   (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+	   return -1;
+	 }
+
+	 if (verbose)
+	   printf("Signature verified.\r\n");
+       }
+       else {
+	 if (verbose)
+	   printf("Response received.\r\n");
+       }
+
+       free (out_buf.value);
+     }
+
+     if (use_file)
+       free(in_buf.value);
+
+     /* Send NOOP */
+     if (!v1_format)
+     (void) send_token(s, TOKEN_NOOP, empty_token);
+
+     if (auth_flag) {
+       /* Delete context */
+       maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf);
+       if (maj_stat != GSS_S_COMPLETE) {
+	 display_status("deleting context", maj_stat, min_stat);
+	 (void) closesocket(s);
+	 (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+	 return -1;
+       }
+
+       (void) gss_release_buffer(&min_stat, &out_buf);
+     }
+
+     (void) closesocket(s);
+     return 0;
+}
+
+static void parse_oid(char *mechanism, gss_OID *oid)
+{
+    char	*mechstr = 0, *cp;
+    gss_buffer_desc tok;
+    OM_uint32 maj_stat, min_stat;
+    
+    if (isdigit((int) mechanism[0])) {
+	mechstr = malloc(strlen(mechanism)+5);
+	if (!mechstr) {
+	    printf("Couldn't allocate mechanism scratch!\r\n");
+	    return;
+	}
+	sprintf(mechstr, "{ %s }", mechanism);
+	for (cp = mechstr; *cp; cp++)
+	    if (*cp == '.')
+		*cp = ' ';
+	tok.value = mechstr;
+    } else
+	tok.value = mechanism;
+    tok.length = strlen(tok.value);
+    maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
+    if (maj_stat != GSS_S_COMPLETE) {
+	display_status("str_to_oid", maj_stat, min_stat);
+	return;
+    }
+    if (mechstr)
+	free(mechstr);
+}
+
+int
+gss (char *server_host, char *service_name, char *mechanism, char *msg, int port,
+     int verbose, int delegate, int mutual, int replay, int sequence, 
+     int v1_format, int auth_flag, int wrap_flag,
+     int encrypt_flag, int mic_flag, int ccount, int mcount, char *ccache)
+{
+    int use_file = 0;
+    OM_uint32 gss_flags = 0, min_stat;
+    gss_OID oid = GSS_C_NULL_OID;
+    OM_uint32     minor_status;
+    int i;
+    int rc = 0;
+
+    if (ccount <= 0)  ccount = 1;
+    if (mcount <= 0)  mcount = 1;
+
+    if (mechanism && mechanism[0])
+        parse_oid(mechanism, &oid);
+
+    if ( delegate )
+        gss_flags |= GSS_C_DELEG_FLAG;
+    if ( mutual )
+        gss_flags |= GSS_C_MUTUAL_FLAG;
+    if ( replay )
+        gss_flags |= GSS_C_REPLAY_FLAG;
+    if ( sequence )
+        gss_flags |= GSS_C_SEQUENCE_FLAG;
+
+    /* By using this function the independence between the application and
+     * the underlying authentication system is broken
+     */
+    if ( ccache && ccache[0] )
+        gss_krb5_ccache_name(&minor_status, ccache, NULL);
+
+    for (i = 0; i < ccount; i++) {
+        if (call_server(server_host, port, oid, service_name,
+                         gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag,
+                         v1_format, msg, use_file, mcount) < 0)
+            rc = -1;
+        break;
+    }
+
+    if (oid != GSS_C_NULL_OID)
+        (void) gss_release_oid(&min_stat, &oid);
+	 
+    return rc;
+}
diff --git a/src/windows/gss/gss-misc.c b/src/windows/gss/gss-misc.c
index cb84e9327..28227e248 100644
--- a/src/windows/gss/gss-misc.c
+++ b/src/windows/gss/gss-misc.c
@@ -19,136 +19,270 @@
  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
+/*
+ * Copyright (C) 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 #include "gss.h"
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <sys\timeb.h>
+#include <time.h>
 
-/*+
+FILE *display_file;
+DWORD ws_err;
+
+gss_buffer_desc empty_token_buf = { 0, (void *) "" };
+gss_buffer_t empty_token = &empty_token_buf;
+
+static void display_status_1
+	(char *m, OM_uint32 code, int type);
+
+static int write_all(int fildes, char *buf, unsigned int nbyte)
+{
+    int ret;
+    char *ptr;
+
+    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
+        ret = send(fildes, ptr, nbyte, 0);
+        if (ret < 0) {
+            ws_err = WSAGetLastError();
+            errno = ws_err;
+            return(ret);
+        } else if (ret == 0) {
+            return(ptr-buf);
+        }
+    }
+
+    return(ptr-buf);
+}
+
+static int read_all(int s, char *buf, unsigned int nbyte)
+{
+    int ret;
+    char *ptr;
+    fd_set rfds;
+    struct timeval tv;
+
+    FD_ZERO(&rfds);
+    FD_SET(s, &rfds);
+    tv.tv_sec = 10;
+    tv.tv_usec = 0;
+
+    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
+        if ( select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(s, &rfds) )
+            return(ptr-buf);
+        ret = recv(s, ptr, nbyte, 0);
+        if (ret < 0) {
+            ws_err = WSAGetLastError();
+            errno = ws_err;
+            return(ret);
+        } else if (ret == 0) {
+            return(ptr-buf);
+        }
+    }
+
+    return(ptr-buf);
+}
+
+/*
  * Function: send_token
  *
  * Purpose: Writes a token to a file descriptor.
  *
  * Arguments:
  *
- *	s		(r) an open file descriptor
- *	tok		(r) the token to write
+ * 	s		(r) an open file descriptor
+ *	flags		(r) the flags to write
+ * 	tok		(r) the token to write
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  *
- * send_token writes the token length (as a network long) and then the
- * token data to the file descriptor s.	 It returns 0 on success, and
- * -1 if an error occurs or if it could not write all the data.
+ * If the flags are non-null, send_token writes the token flags (a
+ * single byte, even though they're passed in in an integer). Next,
+ * the token length (as a network long) and then the token data are
+ * written to the file descriptor s.  It returns 0 on success, and -1
+ * if an error occurs or if it could not write all the data.
  */
-int send_token(int s, gss_buffer_t tok) {
-    long len;
-    size_t ret;
-    size_t ws_err;
+int send_token(int s, int flags, gss_buffer_t tok)
+{
+     int len, ret;
+     unsigned char char_flags = (unsigned char) flags;
+     unsigned char lenbuf[4];
 
-    len = htonl(tok->length);
+     if (char_flags) {
+         ret = write_all(s, (char *)&char_flags, 1);
+         if (ret != 1) {
+             my_perror("sending token flags");
+             OkMsgBox ("Winsock error  %d \n", ws_err);
+             return -1;
+         }
+     }
+    if (tok->length > 0xffffffffUL)
+        abort();
+    lenbuf[0] = (tok->length >> 24) & 0xff;
+    lenbuf[1] = (tok->length >> 16) & 0xff;
+    lenbuf[2] = (tok->length >> 8) & 0xff;
+    lenbuf[3] = tok->length & 0xff;
 
-    ret = send (s, (char *) &len, 4, 0);        // Send length over the socket
+    ret = write_all(s, lenbuf, 4);
     if (ret < 0) {
-		ws_err = WSAGetLastError();
-		errno = ws_err;
-		my_perror("sending token length");
+        my_perror("sending token length");
 		OkMsgBox ("Winsock error  %d \n", ws_err);
-		return -1;
+        return -1;
     } else if (ret != 4) {
-	    ws_err = WSAGetLastError();
-	    OkMsgBox("sending token length: %d of %d bytes written\nWinsock error = %d\n",
-		     ret, 4, ws_err);
-	    return -1;
+        if (verbose)
+            printf("sending token length: %d of %d bytes written\r\n", 
+                     ret, 4);
+        return -1;
     }
 
-    ret = send (s, tok->value, tok->length, 0); // Send the data
+    ret = write_all(s, tok->value, tok->length);
     if (ret < 0) {
-	    ws_err = WSAGetLastError();
-	    errno = ws_err;
-	    my_perror("sending token data");
-	    OkMsgBox ("Winsock error  %d \n", ws_err);
-	    return -1;
+        my_perror("sending token data");
+		OkMsgBox ("Winsock error  %d \n", ws_err);
+        return -1;
     } else if (ret != tok->length) {
-	    ws_err = WSAGetLastError();
-	    OkMsgBox ("sending token data: %d of %d bytes written\nWinsock error = %d\n",
-		      ret, tok->length, ws_err);
-	    return -1;
+        if (verbose)
+            printf("sending token data: %d of %d bytes written\r\n", 
+                     ret, (int) tok->length);
+        return -1;
     }
 
     return 0;
 }
 
-/*+
+/*
  * Function: recv_token
  *
  * Purpose: Reads a token from a file descriptor.
  *
  * Arguments:
  *
- *	s		(r) an open file descriptor
- *	tok		(w) the read token
+ * 	s		(r) an open file descriptor
+ *	flags		(w) the read flags
+ * 	tok		(w) the read token
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  * 
- * recv_token reads the token length (as a network long), allocates
- * memory to hold the data, and then reads the token data from the
- * file descriptor s.  It blocks to read the length and data, if
- * necessary.  On a successful return, the token should be freed with
- * gss_release_buffer.	It returns 0 on success, and -1 if an error
- * occurs or if it could not read all the data.
+ * recv_token reads the token flags (a single byte, even though
+ * they're stored into an integer, then reads the token length (as a
+ * network long), allocates memory to hold the data, and then reads
+ * the token data from the file descriptor s.  It blocks to read the
+ * length and data, if necessary.  On a successful return, the token
+ * should be freed with gss_release_buffer.  It returns 0 on success,
+ * and -1 if an error occurs or if it could not read all the data.
  */
-int
-recv_token (int s, gss_buffer_t tok) {
+int recv_token(int s, int * flags, gss_buffer_t tok)
+{
     int ret;
-    unsigned long len;
-	size_t ws_err;
+    unsigned char char_flags;
+    unsigned char lenbuf[4];
 
-    ret = recv (s, (char *) &len, 4, 0);
+    ret = read_all(s, (char *) &char_flags, 1);
     if (ret < 0) {
-	    ws_err = WSAGetLastError();
-	    errno = ws_err;
-	    my_perror("reading token length");
-	    OkMsgBox ("Winsock error  %d \n", ws_err);
+        my_perror("reading token flags");
+		OkMsgBox ("Winsock error  %d \n", ws_err);
         return -1;
-    } else if (ret != 4) {
-	    ws_err = WSAGetLastError();
-	    OkMsgBox ("reading token length: %d of %d bytes written\nWinsock error = %d\n",
-		      ret, 4, ws_err);
-	    return -1;
+    } else if (! ret) {
+        if (display_file)
+            printf("reading token flags: 0 bytes read\r\n", display_file);
+        return -1;
+    } else {
+        *flags = (int) char_flags;
     }
-	  
-    len = ntohl(len);
-    tok->length = (size_t) len;
-    tok->value = (char *) malloc(tok->length);
-    if (tok->value == NULL) {
-        OkMsgBox ("Out of memory allocating token data\n");
+
+    if (char_flags == 0 ) {
+        lenbuf[0] = 0;
+        ret = read_all(s, &lenbuf[1], 3);
+        if (ret < 0) {
+            my_perror("reading token length");
+            OkMsgBox ("Winsock error  %d \n", ws_err);
+            return -1;
+        } else if (ret != 3) {
+            if (verbose)
+                printf("reading token length: %d of %d bytes read\r\n", 
+                         ret, 3);
+            return -1;
+        }
+    }
+    else {
+        ret = read_all(s, lenbuf, 4);
+        if (ret < 0) {
+            my_perror("reading token length");
+            OkMsgBox ("Winsock error  %d \n", ws_err);
+            return -1;
+        } else if (ret != 4) {
+            if (verbose)
+                printf("reading token length: %d of %d bytes read\r\n", 
+                         ret, 4);
+            return -1;
+        }
+    }
+
+    tok->length = ((lenbuf[0] << 24)
+                    | (lenbuf[1] << 16)
+                    | (lenbuf[2] << 8)
+                    | lenbuf[3]);
+    tok->value = (char *) malloc(tok->length ? tok->length : 1);
+    if (tok->length && tok->value == NULL) {
+        if (verbose)
+            printf("Out of memory allocating token data\r\n");
         return -1;
     }
 
-    ret = recv (s, (char *) tok->value, tok->length, 0);
+    ret = read_all(s, (char *) tok->value, tok->length);
     if (ret < 0) {
-	    ws_err = WSAGetLastError();
-	    errno = ws_err;
-	    my_perror("reading token data");
-	    OkMsgBox ("Winsock error  %d \n", ws_err);
-	    free(tok->value);
-	    return -1;
-    } else if ((size_t) ret != tok->length) {
-	    ws_err = WSAGetLastError();
-	    OkMsgBox ("reading token data: %d of %d bytes written\nWinsock error = %d\n",
-		      ret, tok->length, ws_err);
-	    free(tok->value);
-	    return -1;
+        my_perror("reading token data");
+		OkMsgBox ("Winsock error  %d \n", ws_err);
+        free(tok->value);
+        return -1;
+    } else if (ret != tok->length) {
+        printf("sending token data: %d of %d bytes written\r\n", 
+                 ret, (int) tok->length);
+        free(tok->value);
+        return -1;
     }
 
     return 0;
 }
 
+void 
+free_token(gss_buffer_t tok)
+{
+    if (tok->length <= 0 || tok->value == NULL)
+        return;
+
+    free(tok->value);
+    tok->value = NULL;
+    tok->length = 0;
+}
+
 /*+
  * Function: display_status
  *
@@ -183,6 +317,9 @@ display_status_1(char *m, OM_uint32 code, int type) {
         maj_stat = gss_display_status(&min_stat, code,
                                       type, GSS_C_NULL_OID,
                                       &msg_ctx, &msg);
+        if (verbose)
+            printf("GSS-API error %s: %s\r\n", m,
+                     (char *)msg.value); 
         OkMsgBox ("GSS-API error %s: %s\n", m,
             (char *)msg.value);
         (void) gss_release_buffer(&min_stat, &msg);
@@ -191,6 +328,70 @@ display_status_1(char *m, OM_uint32 code, int type) {
             break;
     }
 }
+
+/*
+ * Function: display_ctx_flags
+ *
+ * Purpose: displays the flags returned by context initation in
+ *	    a human-readable form
+ *
+ * Arguments:
+ *
+ * 	int		ret_flags
+ *
+ * Effects:
+ *
+ * Strings corresponding to the context flags are printed on
+ * stdout, preceded by "context flag: " and followed by a newline
+ */
+
+void display_ctx_flags(flags)
+     OM_uint32 flags;
+{
+     if (flags & GSS_C_DELEG_FLAG)
+	  printf("context flag: GSS_C_DELEG_FLAG\r\n");
+     if (flags & GSS_C_MUTUAL_FLAG)
+	  printf("context flag: GSS_C_MUTUAL_FLAG\r\n");
+     if (flags & GSS_C_REPLAY_FLAG)
+	  printf("context flag: GSS_C_REPLAY_FLAG\r\n");
+     if (flags & GSS_C_SEQUENCE_FLAG)
+	  printf("context flag: GSS_C_SEQUENCE_FLAG\r\n");
+     if (flags & GSS_C_CONF_FLAG )
+	  printf("context flag: GSS_C_CONF_FLAG \r\n");
+     if (flags & GSS_C_INTEG_FLAG )
+	  printf("context flag: GSS_C_INTEG_FLAG \r\n");
+}
+
+void print_token(tok)
+     gss_buffer_t tok;
+{
+    int i;
+    unsigned char *p = tok->value;
+
+    if (!verbose)
+	return;
+    for (i=0; i < tok->length; i++, p++) {
+	printf("%02x ", *p);
+	if ((i % 16) == 15) {
+	    printf("\r\n");
+	}
+    }
+    printf("\r\n");
+}
+
+
+int gettimeofday (struct timeval *tv, void *ignore_tz)
+{
+    struct _timeb tb;
+    _tzset();
+    _ftime(&tb);
+    if (tv) {
+	tv->tv_sec = tb.time;
+	tv->tv_usec = tb.millitm * 1000;
+    }
+    return 0;
+}
+
 /*+*************************************************************************
 ** 
 ** OkMsgBox
diff --git a/src/krb524/misc.c b/src/windows/gss/gss-misc.h
similarity index 63%
rename from src/krb524/misc.c
rename to src/windows/gss/gss-misc.h
index 7e3f4e3bc..35b3b7390 100644
--- a/src/krb524/misc.c
+++ b/src/windows/gss/gss-misc.h
@@ -20,21 +20,41 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <krb5.h>
+/*
+ * $Id$
+ */
+
+#ifndef _GSSMISC_H_
+#define _GSSMISC_H_
+
+#include <gssapi/gssapi_generic.h>
 #include <stdio.h>
-#include <sys/types.h>
 
-#ifndef _WIN32
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-#endif
+extern FILE *display_file;
 
-#include <krb.h>
-#include "krb524.h"
+int send_token
+	(int s, int flags, gss_buffer_t tok);
+int recv_token
+	(int s, int *flags, gss_buffer_t tok);
+void display_status
+	(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat);
+void display_ctx_flags
+	(OM_uint32 flags);
+void print_token
+	(gss_buffer_t tok);
 
-void krb524_init_ets(context)
-     krb5_context context;
-{
-     initialize_k524_error_table();
-}
+/* Token types */
+#define TOKEN_NOOP		(1<<0)
+#define TOKEN_CONTEXT		(1<<1)
+#define TOKEN_DATA		(1<<2)
+#define TOKEN_MIC		(1<<3)
+
+/* Token flags */
+#define TOKEN_CONTEXT_NEXT	(1<<4)
+#define TOKEN_WRAPPED		(1<<5)
+#define TOKEN_ENCRYPTED		(1<<6)
+#define TOKEN_SEND_MIC		(1<<7)
+
+extern gss_buffer_t empty_token;
+
+#endif
diff --git a/src/windows/gss/gss.c b/src/windows/gss/gss.c
index 2a9b93dcf..f42d293ea 100644
--- a/src/windows/gss/gss.c
+++ b/src/windows/gss/gss.c
@@ -1,3 +1,26 @@
+/*
+ * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
 /*+*************************************************************************
 **
 ** GSS test	- Windows scaffolding to test the gssapi dll
@@ -9,28 +32,75 @@
 #include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <commctrl.h>
 #include "gss.h"
+#include <krb5.h>
+#ifdef USE_LEASH
+#include <cacheapi.h>
+#endif
 
-#define GSS_CONNECT_NAME            102
-#define GSS_OK                      100
-#define GSS_CANCEL                  101
+#include "resource.h"
 
-#define GSSAPI_INI	"kerberos.ini"				// Which INI file
+#define GSSAPI_INI	"gsstest.ini"				// Which INI file
 #define INI_HOSTS	"GSSAPI Hosts"				// INI file section
 #define INI_HOST	"Host"						// INI file line label
+#define INI_SVCS	"GSSAPI Services"			// INI file section
+#define INI_SVC	    "Service"					// INI file line label
+#define INI_MSGS	"GSSAPI Messages"			// INI file section
+#define INI_MSG	    "Message"					// INI file line label
+#define INI_MECHS	"GSSAPI Mechanisms"			// INI file section
+#define INI_MECH	"Mech"  					// INI file line label
+#define INI_LAST    "GSSAPI Most Recent" 
+#define INI_LAST_HOST "Host"
+#define INI_LAST_PORT "Port"
+#define INI_LAST_SVC  "Service"
+#define INI_LAST_MECH "Mechanism"
+#define INI_LAST_MSG  "Message"
+#define INI_LAST_DELEGATE  "Delegation"
+#define INI_LAST_SEQUENCE  "Sequence"
+#define INI_LAST_MUTUAL    "Mutual"
+#define INI_LAST_REPLAY    "Replay"
+#define INI_LAST_VERBOSE   "Verbose"
+#define INI_LAST_CCOUNT    "Call Count"
+#define INI_LAST_MCOUNT    "Message Count"
+#define INI_LAST_VER1      "Version One"
+#define INI_LAST_NOAUTH    "No Auth"
+#define INI_LAST_NOWRAP    "No Wrap"
+#define INI_LAST_NOCRYPT   "No Encrypt"
+#define INI_LAST_NOMIC     "No Mic"
+#define INI_LAST_CCACHE    "CCache"
 
-#define MAX_HOSTS 9
-char hosts[MAX_HOSTS][256];
+#define MAX_SAVED 9
+char hosts[MAX_SAVED][256];
+char svcs[MAX_SAVED][256];
+char msgs[MAX_SAVED][256];
+char mechs[MAX_SAVED][256];
 char szHost[256];			// GSSAPI Host to connect to
-char szServiceName[256];		// Service to do
-char szOID[256];			// OID to use	
+char szService[256];		// Service to do
+char szMessage[256];        // Message to send
+char szMech[256];			// OID to use
+char szCCache[256];         // CCache to use
 int port = 0;				// Which port to use
+int delegate = 0;           // Delegate?
+int replay = 1;             // Replay?
+int mutual = 1;             // Mutual?
+int sequence = 0;           // Sequence?
+int verbose = 1;            // Verbose?
+int ccount = 1;             // Call Count
+int mcount = 1;             // Message Count
+int gssv1 = 0;              // Version 1?
+int noauth = 0;             // No Auth?
+int nowrap = 0;             // No Wrap?
+int nocrypt = 0;            // No Crypt?
+int nomic = 0;              // No Mic?
 
-static void do_gssapi_test (char *name);
+HWND hDialog = 0;
+
+static void do_gssapi_test (void);
 static void parse_name (char *name);
-static int read_hosts(void);
-static void write_hosts (void);
-static void	update_hosts (char *name);
+static void read_saved(void);
+static void write_saved (void);
+static void	update_saved (void);
 static void fill_combo (HWND hDlg);
 
 /*+*************************************************************************
@@ -40,17 +110,15 @@ static void fill_combo (HWND hDlg);
 ** Sets up the Dialog that drives our program
 **
 ***************************************************************************/
-int PASCAL
-WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
-HANDLE hInstance, hPrevInstance;
-LPSTR lpszCmdLine;
-int nCmdShow;
+int __stdcall
+WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
 {
-	FARPROC lpfnDlgProc;
 	WSADATA wsadata;
 	WORD versionrequested;
 	int rc;
 
+	InitCommonControls();
+
 	versionrequested = 0x0101;		/* Version 1.1 */
 	rc = WSAStartup(versionrequested, &wsadata);
 	if (rc) {
@@ -65,9 +133,8 @@ int nCmdShow;
 	    return FALSE;
 	}
 	
-	lpfnDlgProc = MakeProcInstance(OpenGssapiDlg, hInstance);
-	DialogBox (hInstance, "OPENGSSAPIDLG", NULL, lpfnDlgProc);
-	FreeProcInstance(lpfnDlgProc);
+	rc = DialogBoxParam (hInstance, "GSSAPIDLG", HWND_DESKTOP, OpenGssapiDlg, 0L);
+	rc = GetLastError();
 
 	WSACleanup();
 	return 0;
@@ -80,14 +147,15 @@ int nCmdShow;
 **
 ***************************************************************************/
 void
-do_gssapi_test (char *name) {
+do_gssapi_test (void) {
 	int n;										// Return value
 	HCURSOR hcursor;							// For the hourglass cursor
 
-	parse_name(name);							// Get host, service and port
-
 	hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
-	n = gss (szHost, szServiceName, szOID, "Test Gssapi Message", port);
+	n = gss (szHost, szService, szMech, szMessage[0] ? szMessage : "Test Gssapi Message", port,
+             verbose, delegate, mutual, replay, sequence, 
+             gssv1, !noauth, !nowrap, !nocrypt, !nomic, ccount, mcount,
+             szCCache);
 	SetCursor(hcursor);
 
 	if (n)
@@ -105,19 +173,21 @@ do_gssapi_test (char *name) {
 ** 	WM_COMMAND    - Input received
 **
 ***************************************************************************/
-BOOL PASCAL
+INT_PTR CALLBACK
 OpenGssapiDlg(
 	HWND hDlg,
-	WORD message,
-	WORD wParam,
-	LONG lParam)
+	UINT message,
+	WPARAM wParam,
+	LPARAM lParam)
 {
 	HDC hDC;									// For getting graphic info
 	DWORD Ext;									// Size of dialog
 	int xExt, yExt;								// Size broken apart
-	char hostname[256];							// What the user typed
+    char buff[64];
+
 	switch (message) {
 	case WM_INITDIALOG:
+        hDialog = hDlg;
 		/*
 		** First center the dialog
 		*/
@@ -131,12 +201,56 @@ OpenGssapiDlg(
 			0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
 		ReleaseDC(hDlg, hDC);
 
-		read_hosts ();							// Get the host list
+        SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_LIMITTEXT, sizeof(szHost), 0);
+		read_saved ();							// Get the host list
 		fill_combo (hDlg);						// Put into combo box
 
-		SendMessage(hDlg, WM_SETFOCUS, NULL, NULL);
+		SendMessage(hDlg, WM_SETFOCUS, 0, 0);
 		return (TRUE);
 
+    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 == GSS_CALL_COUNT) {
+                    sprintf(buff,"Call Count: %d",pos);
+					SetWindowText(GetDlgItem(hDialog, IDC_STATIC_CCOUNT),buff);
+				}
+				if (ctrlID == GSS_MESSAGE_COUNT) {
+                    sprintf(buff,"Message Count: %d",pos);
+					SetWindowText(GetDlgItem(hDialog, IDC_STATIC_MSG_COUNT),buff);
+				}
+			}
+			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 == GSS_CALL_COUNT) {
+                    sprintf(buff,"Call Count: %d",pos);
+					SetWindowText(GetDlgItem(hDialog, IDC_STATIC_CCOUNT),buff);
+				}
+				if (ctrlID == GSS_MESSAGE_COUNT) {
+                    sprintf(buff,"Message Count: %d",pos);
+					SetWindowText(GetDlgItem(hDialog, IDC_STATIC_MSG_COUNT),buff);
+				}
+			}
+		}
+        break;
+
+
 	case WM_COMMAND:
 		switch (wParam) {
 		case GSS_CANCEL:						// Only way out of the dialog
@@ -145,22 +259,75 @@ OpenGssapiDlg(
 			break;
 
 		case GSS_OK:
-			GetDlgItemText(hDlg, GSS_CONNECT_NAME, hostname, 256);
-			SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_SHOWDROPDOWN,
-				FALSE, NULL);
+			GetDlgItemText(hDlg, GSS_HOST_NAME, szHost, 256);
+			SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_SHOWDROPDOWN, FALSE, 0);
 
-			if (! *hostname) {
-				MessageBox(hDlg, "You must enter a host name",
-					NULL, MB_OK);
+			if (!*szHost) {
+				MessageBox(hDlg, "You must enter a host name", NULL, MB_OK);
 				break;
 			}
-			do_gssapi_test (hostname);			// Test GSSAPI
-			update_hosts (hostname);			// Add it to the host list
+
+			GetDlgItemText(hDlg, GSS_SERVICE_NAME, szService, 256);
+			SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_SHOWDROPDOWN, FALSE, 0);
+
+			if (!*szService) {
+				MessageBox(hDlg, "You must enter a service name", NULL, MB_OK);
+				break;
+			}
+
+            GetDlgItemText(hDlg, GSS_MECHANISM, szMech, 256);
+            GetDlgItemText(hDlg, GSS_CCACHE_NAME, szCCache, 256);
+            GetDlgItemText(hDlg, GSS_MESSAGE, szMessage, 256);
+            GetDlgItemText(hDlg, GSS_PORT, buff, 32);
+            if (!*buff) {
+				MessageBox(hDlg, "You must enter a valid port number", NULL, MB_OK);
+				break;
+            }
+            port = atoi(buff);
+            if (port == 0 || port == -1)
+                port = 4444;
+
+            ccount = SendDlgItemMessage( hDlg, GSS_CALL_COUNT, TBM_GETPOS, 0, 0);
+            mcount = SendDlgItemMessage( hDlg, GSS_MESSAGE_COUNT, TBM_GETPOS, 0, 0);
+
+            verbose = IsDlgButtonChecked(hDlg, GSS_VERBOSE);
+            delegate = IsDlgButtonChecked(hDlg, GSS_DELEGATION);
+            mutual = IsDlgButtonChecked(hDlg, GSS_MUTUAL);
+            replay = IsDlgButtonChecked(hDlg, GSS_REPLAY);
+            sequence = IsDlgButtonChecked(hDlg, GSS_SEQUENCE);
+            gssv1 = IsDlgButtonChecked(hDlg, GSS_VERSION_ONE);
+
+            noauth = IsDlgButtonChecked(hDlg, GSS_NO_AUTH);
+            if ( noauth ) {
+                nowrap = nocrypt = nomic = 0;
+            } else {
+                nowrap = IsDlgButtonChecked(hDlg, GSS_NO_WRAP);
+                nocrypt = IsDlgButtonChecked(hDlg, GSS_NO_ENCRYPT);
+                nomic = IsDlgButtonChecked(hDlg, GSS_NO_MIC);
+            }
+
+			update_saved ();        			// Add it to the host list
 			fill_combo (hDlg);					// Update the combo box
+            SetDlgItemText(hDlg, GSS_OUTPUT, "");
+            do_gssapi_test ();      			// Test GSSAPI
 
 			//EndDialog(hDlg, TRUE);
 			break;
-		}
+		
+        case GSS_NO_AUTH:
+            if ( IsDlgButtonChecked(hDlg, GSS_NO_AUTH) ) {
+                // disable the other no_xxx options
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), FALSE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), FALSE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), FALSE);
+            } else {
+                // enable the other no_xxx options
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), TRUE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), TRUE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), TRUE);
+            }
+            break;
+        }
 		return FALSE;
 	}
 	return FALSE;
@@ -199,84 +366,221 @@ parse_name (char *name) {
 	    ptr = strtok( NULL, seps);
 	}
 	if( ptr ){
-	    strcpy( szServiceName, ptr );
+	    strcpy( szService, ptr );
 	}else{
-	    wsprintf (szServiceName, "sample@%s", szHost); // Make the service name
+	    wsprintf (szService, "sample@%s", szHost); // Make the service name
 	}
 	if( ptr ){
 	    ptr = strtok( NULL, seps);
 	}
 	if( ptr ){
-	    wsprintf (szOID, "{ %s }", ptr); // Put in the OID
-	    for (ptr = szOID; *ptr; ptr++)
+	    wsprintf (szMech, "{ %s }", ptr); // Put in the OID
+	    for (ptr = szMech; *ptr; ptr++)
 		    if (*ptr == '.')
 			    *ptr = ' ';
     } else {
-	   szOID[0] = 0;
+	   szMech[0] = 0;
 	}
 
 }
 /*+*************************************************************************
 **
-** Read_hosts
+** read_saved
 **
 ** Reads all the hosts listed in the INI file.
 **
 ***************************************************************************/
-static int
-read_hosts (void) {
+static void
+read_saved (void) {
 	int i;					/* Index */
-	char buff[10];
+	char buff[32];
 	
-	for (i = 0; MAX_HOSTS; ++i) {		/* Read this many entries */
+	for (i = 0; MAX_SAVED; ++i) {		/* Read this many entries */
 		wsprintf (buff, INI_HOST "%d", i);
 		GetPrivateProfileString(INI_HOSTS, buff, "", hosts[i], 256, GSSAPI_INI);
 		if (*hosts[i] == '\0')		/* No more entries??? */
 			break;
 	}
-
-	return i;
+	for (i = 0; MAX_SAVED; ++i) {		/* Read this many entries */
+		wsprintf (buff, INI_SVC "%d", i);
+		GetPrivateProfileString(INI_SVCS, buff, "", svcs[i], 256, GSSAPI_INI);
+		if (*svcs[i] == '\0')		/* No more entries??? */
+			break;
+	}
+	for (i = 0; MAX_SAVED; ++i) {		/* Read this many entries */
+		wsprintf (buff, INI_MSG "%d", i);
+		GetPrivateProfileString(INI_MSGS, buff, "", msgs[i], 256, GSSAPI_INI);
+		if (*msgs[i] == '\0')		/* No more entries??? */
+			break;
+	}
+	for (i = 0; MAX_SAVED; ++i) {		/* Read this many entries */
+		wsprintf (buff, INI_MECH "%d", i);
+		GetPrivateProfileString(INI_MECHS, buff, "", mechs[i], 256, GSSAPI_INI);
+		if (*mechs[i] == '\0')		/* No more entries??? */
+			break;
+	}
+    GetPrivateProfileString(INI_LAST, INI_LAST_HOST, "", szHost, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_PORT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        port = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_SVC, "", szService, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MSG, "", szMessage, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MECH, "", szMech, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_CCACHE, "", szCCache, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_DELEGATE, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        delegate = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MUTUAL, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        mutual = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_REPLAY, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        replay = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_SEQUENCE, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        sequence = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_VERBOSE, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        verbose = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_CCOUNT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        ccount = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MCOUNT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        mcount = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_VER1, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        gssv1 = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOAUTH, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        noauth = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOWRAP, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nowrap = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOCRYPT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nocrypt = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOMIC, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nomic = atoi(buff);
 }
+
 /*+*************************************************************************
 **
-** Write_hosts
+** write_saved
 **
 ** Writes the hosts list back to the ini file.
 **
 ***************************************************************************/
 static void
-write_hosts () {
+write_saved () {
 	int i;										// Index
-	char buff[10];
+	char buff[32];
 
-	for (i = 0; i < MAX_HOSTS; ++i) {
+	for (i = 0; i < MAX_SAVED; ++i) {
 		if (*hosts[i] == '\0')					// End of the list?
 			break;
 		wsprintf (buff, INI_HOST "%d", i);
 		WritePrivateProfileString(INI_HOSTS, buff, hosts[i], GSSAPI_INI);
 	}
+	for (i = 0; i < MAX_SAVED; ++i) {
+		if (*svcs[i] == '\0')					// End of the list?
+			break;
+		wsprintf (buff, INI_SVC "%d", i);
+		WritePrivateProfileString(INI_SVCS, buff, svcs[i], GSSAPI_INI);
+	}
+	for (i = 0; i < MAX_SAVED; ++i) {
+		if (*msgs[i] == '\0')					// End of the list?
+			break;
+		wsprintf (buff, INI_MSG "%d", i);
+		WritePrivateProfileString(INI_MSGS, buff, msgs[i], GSSAPI_INI);
+	}
+	for (i = 0; i < MAX_SAVED; ++i) {
+		if (*mechs[i] == '\0')					// End of the list?
+			break;
+		wsprintf (buff, INI_MECH "%d", i);
+		WritePrivateProfileString(INI_MECHS, buff, mechs[i], GSSAPI_INI);
+	}
+    WritePrivateProfileString(INI_LAST, INI_LAST_HOST, szHost, GSSAPI_INI);
+    wsprintf(buff, "%d", port);
+    WritePrivateProfileString(INI_LAST, INI_LAST_PORT, buff, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_SVC, szService, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MECH, szMech, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_CCACHE, szCCache, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MSG, szMessage, GSSAPI_INI);
+    wsprintf(buff, "%d", delegate);
+    WritePrivateProfileString(INI_LAST, INI_LAST_DELEGATE, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", mutual);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MUTUAL, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", replay);
+    WritePrivateProfileString(INI_LAST, INI_LAST_REPLAY, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", sequence);
+    WritePrivateProfileString(INI_LAST, INI_LAST_SEQUENCE, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", verbose);
+    WritePrivateProfileString(INI_LAST, INI_LAST_VERBOSE, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", ccount);
+    WritePrivateProfileString(INI_LAST, INI_LAST_CCOUNT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", mcount);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MCOUNT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", gssv1);
+    WritePrivateProfileString(INI_LAST, INI_LAST_VER1, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", noauth);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOAUTH, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nowrap);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOWRAP, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nocrypt);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOCRYPT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nomic);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOMIC, buff, GSSAPI_INI);
 }
 /*+*************************************************************************
 **
-** Update_hosts
+** Update_saved
 **
 ** Updates the host list with the new NAME the user typed.
 **
 ***************************************************************************/
 static void
-update_hosts (char *name) {
+update_saved (void) {
 	int i;										// Index
 
-	for (i = 0; i < MAX_HOSTS-1; ++i) {			// Find it in the list
-		if (! _stricmp (name, hosts[i])) 		// A match
+	for (i = 0; i < MAX_SAVED-1; ++i) {			// Find it in the list
+		if (! _stricmp (szHost, hosts[i])) 		// A match
 			break;
 		if (*hosts[i] == '\0')					// End of the list
 			break;
 	}
 	memmove (hosts[1], hosts[0], i * sizeof(hosts[0])); // Move the data down
-	strcpy (hosts[0], name);					// Insert this item
+	strcpy (hosts[0], szHost);					// Insert this item
+
+    for (i = 0; i < MAX_SAVED-1; ++i) {			// Find it in the list
+		if (! _stricmp (szService, svcs[i])) 		// A match
+			break;
+		if (*svcs[i] == '\0')					// End of the list
+			break;
+	}
+	memmove (svcs[1], svcs[0], i * sizeof(svcs[0])); // Move the data down
+	strcpy (svcs[0], szService);					// Insert this item
 
-	write_hosts ();
+	for (i = 0; i < MAX_SAVED-1; ++i) {			// Find it in the list
+		if (! _stricmp (szMessage, msgs[i])) 		// A match
+			break;
+		if (*msgs[i] == '\0')					// End of the list
+			break;
+	}
+	memmove (msgs[1], msgs[0], i * sizeof(msgs[0])); // Move the data down
+	strcpy (msgs[0], szMessage);					// Insert this item
+
+	for (i = 0; i < MAX_SAVED-1; ++i) {			// Find it in the list
+		if (! _stricmp (szMech, mechs[i])) 		// A match
+			break;
+		if (*mechs[i] == '\0')					// End of the list
+			break;
+	}
+	memmove (mechs[1], mechs[0], i * sizeof(hosts[0])); // Move the data down
+	strcpy (mechs[0], szMech);					// Insert this item
+
+	write_saved ();
 }
 /*+*************************************************************************
 **
@@ -289,16 +593,130 @@ update_hosts (char *name) {
 static void
 fill_combo (HWND hDlg) {
 	int i;										// Index
+    char buff[256];
+#ifdef USE_LEASH
+    krb5_error_code retval;
+    apiCB * cc_ctx = 0;
+    struct _infoNC ** pNCi = 0;
+#endif
 
-	SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_RESETCONTENT, NULL, NULL);
+	SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_RESETCONTENT, 0, 0);
+	SetDlgItemText(hDlg, GSS_HOST_NAME, szHost);
+	SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_SETEDITSEL, 0, 0);
+	for (i = 1; i < MAX_SAVED; ++i) {			// Fill in the list box
+		if (*hosts[i] == '\0')
+			break;
+		SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) hosts[i]));
+	}
 
-	SetDlgItemText(hDlg, GSS_CONNECT_NAME, hosts[0]);
-	SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_SETEDITSEL, NULL, NULL);
+	SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_RESETCONTENT, 0, 0);
+	SetDlgItemText(hDlg, GSS_SERVICE_NAME, szService);
+	SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_SETEDITSEL, 0, 0);
+	for (i = 1; i < MAX_SAVED; ++i) {			// Fill in the list box
+		if (*svcs[i] == '\0')
+			break;
+		SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) svcs[i]));
+	}
 
-	for (i = 1; i < MAX_HOSTS; ++i) {			// Fill in the list box
-		if (*hosts[i] == '\0')
+	SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_RESETCONTENT, 0, 0);
+	SetDlgItemText(hDlg, GSS_MECHANISM, szMech);
+	SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_SETEDITSEL, 0, 0);
+	for (i = 1; i < MAX_SAVED; ++i) {			// Fill in the list box
+		if (*mechs[i] == '\0')
 			break;
-		SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_ADDSTRING, 0,
-			(LPARAM) ((LPSTR) hosts[i]));
+		SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) mechs[i]));
 	}
+
+    SendDlgItemMessage(hDlg, GSS_CCACHE_NAME, CB_RESETCONTENT, 0, 0);
+	SetDlgItemText(hDlg, GSS_CCACHE_NAME, szCCache);
+	SendDlgItemMessage(hDlg, GSS_CCACHE_NAME, CB_SETEDITSEL, 0, 0);
+
+#ifdef USE_LEASH
+    retval = cc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
+    if (retval)
+        goto skip_ccache;
+
+    retval = cc_get_NC_info(cc_ctx, &pNCi);
+    if (retval) 
+        goto clean_ccache;
+
+    for ( i=0; pNCi[i]; i++ ) {
+        if (pNCi[i]->vers == CC_CRED_V5) {
+            sprintf(buff,"API:%s",pNCi[i]->name);
+            SendDlgItemMessage(hDlg, GSS_CCACHE_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) buff));
+        }
+    }
+
+  clean_ccache:
+    if (pNCi)
+        cc_free_NC_info(cc_ctx, &pNCi);
+    if (cc_ctx)
+        cc_shutdown(&cc_ctx);
+  skip_ccache:
+#endif /* USE_LEASH */
+    if ( szCCache[0] )
+        SendDlgItemMessage(hDlg, GSS_CCACHE_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) szCCache));
+    SendDlgItemMessage(hDlg, GSS_CCACHE_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) "MSLSA:"));
+
+	SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_RESETCONTENT, 0, 0);
+	SetDlgItemText(hDlg, GSS_MESSAGE, szMessage);
+	SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_SETEDITSEL, 0, 0);
+	for (i = 1; i < MAX_SAVED; ++i) {			// Fill in the list box
+		if (*msgs[i] == '\0')
+			break;
+		SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) msgs[i]));
+	}
+
+    wsprintf(buff, "%d", port);
+    SetDlgItemText(hDlg, GSS_PORT, buff);
+
+    CheckDlgButton(hDlg, GSS_VERBOSE, verbose);
+    CheckDlgButton(hDlg, GSS_DELEGATION, delegate);
+    CheckDlgButton(hDlg, GSS_MUTUAL, mutual);
+    CheckDlgButton(hDlg, GSS_REPLAY, replay);
+    CheckDlgButton(hDlg, GSS_SEQUENCE, sequence);
+    CheckDlgButton(hDlg, GSS_VERSION_ONE, gssv1);
+    CheckDlgButton(hDlg, GSS_NO_AUTH, noauth);
+    CheckDlgButton(hDlg, GSS_NO_WRAP, nowrap);
+    CheckDlgButton(hDlg, GSS_NO_ENCRYPT, nocrypt);
+    CheckDlgButton(hDlg, GSS_NO_MIC, nomic);
+
+    if ( noauth ) {
+        // disable the other no_xxx options
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), FALSE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), FALSE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), FALSE);
+    } else {
+        // enable the other no_xxx options
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), TRUE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), TRUE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), TRUE);
+    }
+
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 1);
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) 20);
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETPOS, (WPARAM) FALSE, (LPARAM) ccount);
+    sprintf(buff,"Call Count: %d",ccount);
+    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_CCOUNT),buff);
+
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 1);
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) 20);
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETPOS, (WPARAM) FALSE, (LPARAM) mcount);
+    sprintf(buff,"Message Count: %d",mcount);
+    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_MSG_COUNT),buff);
+}
+
+int
+gss_printf (const char *format, ...) {
+    static char myprtfstr[4096];
+    int i, len, rc=0;
+    char *cp;
+    va_list ap;
+
+    va_start(ap, format);
+    rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
+    va_end(ap);
+
+    SendDlgItemMessage(hDialog, GSS_OUTPUT, EM_REPLACESEL, FALSE, (LPARAM) myprtfstr);
+    return rc;
 }
diff --git a/src/windows/gss/gss.h b/src/windows/gss/gss.h
index e9b43c507..60d91bf6b 100644
--- a/src/windows/gss/gss.h
+++ b/src/windows/gss/gss.h
@@ -12,18 +12,32 @@
 #include <gssapi/gssapi_generic.h>
 
 // gss.c
-BOOL PASCAL OpenGssapiDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam);
+INT_PTR CALLBACK OpenGssapiDlg(	HWND hDlg,	UINT message,	WPARAM wParam,	LPARAM lParam);
 
 // gss-misc.c
-int send_token(int s, gss_buffer_t tok);
-int recv_token(int s, gss_buffer_t tok);
+int send_token(int s, int flags, gss_buffer_t tok);
+int recv_token(int s, int *flags, gss_buffer_t tok);
+void free_token(gss_buffer_t tok);
 void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat);
 static void display_status_1(char *m, OM_uint32 code, int type);
 void OkMsgBox (char *format, ...);
 void my_perror (char *msg);
 
 // gss-client.c
-int gss (char *host, char *name, char *msg, char *oid, int port);
-int call_server(char *host, u_short port, char *service_name, char *oid, char *msg);
+int
+gss (char *server_host, char *service_name, char *mechanism, char *msg, int port,
+     int verbose, int delegate, int mutual, int replay, int sequence, 
+     int v1_format, int auth_flag, int wrap_flag,
+     int encrypt_flag, int mic_flag, int ccount, int mcount, char * ccache);
+int call_server(char *host, u_short port, gss_OID oid, char *service_name, 
+                OM_uint32 deleg_flag, int auth_flag,
+		        int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, 
+                char *msg, int use_file, int mcount);
 int connect_to_server(char *host, u_short port);
-int client_establish_context(int s, char *service_name, char *oid, gss_ctx_id_t *gss_context);
+int client_establish_context(int s, char *service_name, OM_uint32 deleg_flag,
+                             int auth_flag, int v1_format, gss_OID oid, 
+                             gss_ctx_id_t *gss_context, OM_uint32 *ret_flags);
+
+
+extern int verbose;
+#define printf  gss_printf
diff --git a/src/windows/gss/gss.rc b/src/windows/gss/gss.rc
index 95458df6f..46cf6424e 100644
--- a/src/windows/gss/gss.rc
+++ b/src/windows/gss/gss.rc
@@ -1,33 +1,148 @@
-/*+*************************************************************************
-**
-**	Gss
-**	
-**	Tests the gssapi dll.
-**
-***************************************************************************/
-
-#include <windows.h>
-#include <winver.h>
+// Microsoft Visual C++ generated resource script.
+//
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "resource.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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+GSS                     ICON                    "gss.ico"
 
-#define GSS_CONNECT_NAME            102
-#define GSS_OK                      100
-#define GSS_CANCEL                  101
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
 
-gss ICON gss.ico
+GSSAPIDLG DIALOGEX 63, 65, 330, 311
+STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "Test GSSAPI Connection"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    RTEXT           "Hostname:",IDC_STATIC_HOST,5,12,60,10,NOT WS_GROUP
+    COMBOBOX        GSS_HOST_NAME,70,9,245,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | 
+                    WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    DEFPUSHBUTTON   "Test",GSS_OK,80,290,51,14,WS_GROUP
+    PUSHBUTTON      "Exit",GSS_CANCEL,185,290,51,14
+    RTEXT           "Port:",IDC_STATIC_PORT,16,27,50,8
+    EDITTEXT        GSS_PORT,70,25,40,14,ES_RIGHT | ES_AUTOHSCROLL | 
+                    ES_NUMBER
+    COMBOBOX        GSS_SERVICE_NAME,70,41,245,60,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    RTEXT           "GSS Service Name:",IDC_STATIC_SERVICE,1,44,64,8
+    COMBOBOX        GSS_CCACHE_NAME,70,69,245,60,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    RTEXT           "CCache Name:",IDC_STATIC_CCACHE,16,71,49,8
+    COMBOBOX        GSS_MECHANISM,70,110,245,60,CBS_DROPDOWN | 
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    RTEXT           "Mechanism (OID):",IDC_STATIC_MECH,0,115,65,8
+    RTEXT           "Test Message:",IDC_STATIC_MSG,0,55,65,8
+    COMBOBOX        GSS_MESSAGE,70,55,245,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | 
+                    CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "The following items are optional and should only be altered by those who understand their implications.",
+                    IDC_STATIC_OPTIONS,10,85,305,20
+    CONTROL         "Verbose Output",GSS_VERBOSE,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,72,138,65,10
+    CONTROL         "Delegation",GSS_DELEGATION,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,72,150,50,10
+    CONTROL         "Version 1",GSS_VERSION_ONE,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,150,138,45,10
+    CONTROL         "No Auth",GSS_NO_AUTH,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,72,162,42,10
+    CONTROL         "No Wrap",GSS_NO_WRAP,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,132,162,45,10
+    CONTROL         "No Encrypt",GSS_NO_ENCRYPT,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,198,162,51,10
+    CONTROL         "No Mic",GSS_NO_MIC,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,270,162,39,10
+    CONTROL         "Slider1",GSS_CALL_COUNT,"msctls_trackbar32",TBS_BOTH | 
+                    WS_TABSTOP,66,174,100,15
+    CONTROL         "Slider2",GSS_MESSAGE_COUNT,"msctls_trackbar32",TBS_BOTH | 
+                    WS_TABSTOP,204,174,100,15
+    CTEXT           "Call Count",IDC_STATIC_CCOUNT,72,192,90,8
+    CTEXT           "Message Count",IDC_STATIC_MSG_COUNT,210,192,90,8
+    GROUPBOX        "Output",IDC_GROUP_OUTPUT,0,210,325,75
+    GROUPBOX        "Configuration Options",IDC_GROUP_OPTIONS,0,0,325,205
+    EDITTEXT        GSS_OUTPUT,0,220,320,60,ES_MULTILINE | ES_AUTOVSCROLL | 
+                    ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
+    CONTROL         "Mutual",GSS_MUTUAL,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,132,150,37,10
+    CONTROL         "Replay",GSS_REPLAY,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,198,150,38,10
+    CONTROL         "Sequence",GSS_SEQUENCE,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,270,150,49,10
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resrc1.h\0"
+END
 
-OPENGSSAPIDLG DIALOG 63, 65, 330, 71
-STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Open GSSAPI Connection"
-FONT 8, "MS Sans Serif"
+2 TEXTINCLUDE 
 BEGIN
-	CONTROL "Host Port Service:", -1, "STATIC", NOT WS_GROUP, 5, 10, 60, 10
-	CONTROL "Example: foo 34000 sample@foo.bar.com", -1, "STATIC", NOT WS_GROUP, 70, 25, 256, 10
-	CONTROL "", GSS_CONNECT_NAME, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 70, 9, 256, 60
-	CONTROL "Test", GSS_OK, "BUTTON", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 70, 50, 51, 14
-	CONTROL "Exit", GSS_CANCEL, "BUTTON", WS_TABSTOP, 150, 50, 51, 14
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""resource.h""\r\n"
+    "\0"
 END
 
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
+
+#include <winver.h>
 #include "..\version.rc"
 
 TestTrackerMOTD TEXT ver_serv.txt
-
diff --git a/src/windows/gss/resource.h b/src/windows/gss/resource.h
new file mode 100644
index 000000000..de7b2c127
--- /dev/null
+++ b/src/windows/gss/resource.h
@@ -0,0 +1,50 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by gss.rc
+//
+#define GSS_HOST_NAME                   1000
+#define GSS_PORT                        1001
+#define GSS_SERVICE_NAME                1003
+#define IDC_STATIC_SERVICE              1004
+#define GSS_MECHANISM                   1005
+#define IDC_STATIC_MECH                 1006
+#define IDC_STATIC_MSG                  1007
+#define GSS_MESSAGE                     1008
+#define IDC_STATIC_OPTIONS              1009
+#define GSS_VERBOSE                     1010
+#define GSS_DELEGATION                  1011
+#define GSS_VERSION_ONE                 1012
+#define GSS_NO_AUTH                     1013
+#define GSS_NO_WRAP                     1014
+#define GSS_NO_ENCRYPT                  1015
+#define GSS_NO_MIC                      1016
+#define GSS_CALL_COUNT                  1017
+#define GSS_MESSAGE_COUNT               1018
+#define IDC_STATIC_CCOUNT               1019
+#define IDC_STATIC_MSG_COUNT            1020
+#define IDC_GROUP_OUTPUT                1021
+#define IDC_GROUP_OPTIONS               1022
+#define GSS_OUTPUT                      1023
+#define GSS_OK                          1024
+#define GSS_CANCEL                      1025
+#define IDC_STATIC_PORT                 1026
+#define IDC_STATIC_HOST                 1027
+#define GSS_CCACHE_NAME                 1028
+#define IDC_STATIC_CCACHE               1029
+#define GSS_MUTUAL                      1030
+#define GSS_REPLAY                      1031
+#define GSS_SEQUENCE                    1032
+
+#define IDD_GSSAPIDLG                   101
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1033
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/src/windows/ms2mit/ChangeLog b/src/windows/ms2mit/ChangeLog
index b68c646d3..d7ac6af44 100644
--- a/src/windows/ms2mit/ChangeLog
+++ b/src/windows/ms2mit/ChangeLog
@@ -1,14 +1,95 @@
+2004-01-31  Jeffrey Altman <jaltman@mit.edu>
+
+    * ms2mit.c: Do not allow ticket importing of the Initial TGT cannot
+      be obtained.  The MSLSA krb5_ccache will not export the Initial TGT
+      if the session key enctype is NULL.  
+
+2003-12-11  Jeffrey Altman <jaltman@mit.edu>
+
+    * ms2mit.c, Makefile.in:
+
+    Remove all of the code that manipulates the MS LSA cache.  Instead
+    of reading in the TGT directly we now take advantage of the new
+    "MSLSA:" krb5_ccache type.  We open the MS LSA cache as a read-only
+    ccache and copy it to the default ccache for the system.
+
+    This removes the dependency on secur32.dll from this file.
+
+2003-10-21  Jeffrey Altman <jaltman@mit.edu>
+
+    * ms2mit.c:
+
+    Because of the failure of Windows 2000 and Windows XP to perform 
+    proper ticket expiration time management, the MS Kerberos LSA will 
+    return tickets to a calling application with lifetimes as short as 
+    one second.  Tickets with lifetimes less than five minutes can cause 
+    problems for most apps.  Tickets with lifetimes less than 20 minutes 
+    will trigger the Leash ticket lifetime warnings.
+
+    Instead of accepting whatever tickets are returned by MS LSA from 
+    the cache, if the ticket lifetime is less than 20 minutes force a 
+    retrieval operation bypassing the LSA ticket cache.
+
+
+2003-07-16  Jeffrey Altman <jaltman@mit.edu>
+
+    * ms2mit.c: 
+
+    Functional changes:
+    (1) do not restrict ourselves to DES-CBC-CRC instead support any
+        ticket with an enctype we support.  as of this date (rev 1.3)
+        this includes all but RC4-MD4.
+    (2) do not accept invalid tickets
+    (3) when attempting to retrieve tickets do not specify either the
+        enctype or cache options (if possible).  doing so will force a 
+        TGS request and prevent the results from being stored into the 
+        cache.
+    (4) when the LSA cache contains a TGT which has expired Microsoft will 
+        not perform a new TGS request until the cache has been purged.
+        Instead the expired ticket continues to be used along with its
+        embedded authorization data.  When PURGE_ENABLED is defined, if the 
+        tickets are expired, the cache will be purged before requesting
+        new tickets, else we ignore the contents of the cache and force 
+        a new TGS request.
+    (5) when the LSA cache is empty do not abort.  On XP or 2003, use
+        the SecurityLogonSessionData to determine the Realm (UserDnsDomain
+        in MS-speak) and request an appropriate TGT.  On 2000, check the
+        Registry for the HKCU\"Volatile Environment":"USERDNSDOMAIN" 
+        instead.  This will allow ms2mit to be used to repopulate the
+        LSA cache.  If the current session is not Kerberos authenticated
+        an appropriate error message will be generated.
+
+    Code changes:
+    (1) several memory leaks plugged
+    (2) several support functions copied from the Leashw32.dll sources
+    (3) get_STRING_from_registry() uses the ANSI versions of the Registry
+        functions and should at a later date be converted to use the 
+        Unicode versions.
+
+    Notes: an ms2mit.exe based on the Leash_import() function
+    should be considered.  Leash_import() not only imports the TGT from
+    the LSA but also performs the krb524 conversion and AFS token retrieval.
+    Of course, that version of ms2mit.exe could not exist within the krb5
+    source tree.
+
+2003-06-20  Jeffrey Altman <jaltman@mit.edu>
+
+    * ms2mit.c: Windows Credentials are addressless. Do not store the
+	credentials in the MIT cache with addresses since they do not
+	contain addresses in the encrypted portion of the credential.
+	Instead generate a valid empty address list.
+
 2002-08-29  Ken Raeburn  <raeburn@mit.edu>
 
-	* Makefile.in: Revert $(S)=>/ change, for Windows support.
+    * Makefile.in: Revert $(S)=>/ change, for Windows support.
 
 2002-08-23  Ken Raeburn  <raeburn@mit.edu>
 
-	* Makefile.in: Change $(S)=>/ and $(U)=>.. globally.
+    * Makefile.in: Change $(S)=>/ and $(U)=>.. globally.
 
 2001-11-28  Danilo Almeida  <dalmeida@mit.edu>
 
-	* ms2mit.c: Make sure we get a des-cbc-crc session key instead of
+    * ms2mit.c: Make sure we get a des-cbc-crc session key instead of
 	potentially getting whatever happens to be in the cache.  Remove
 	unnecessary static variables.  Make function headers use a
 	consistent format.  Rename ShowLastError() to ShowWinError() and
diff --git a/src/windows/ms2mit/Makefile.in b/src/windows/ms2mit/Makefile.in
index a7c6c1ed9..45004e14a 100644
--- a/src/windows/ms2mit/Makefile.in
+++ b/src/windows/ms2mit/Makefile.in
@@ -13,7 +13,7 @@ PROG_LIBPATH=-L$(TOPLIBD) -L$(KRB5_LIBDIR)
 all-windows:: $(OUTPRE)ms2mit.exe
 
 $(OUTPRE)ms2mit.exe: $(OUTPRE)ms2mit.obj
-    link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)ms2mit.obj user32.lib secur32.lib advapi32.lib $(KLIB) $(CLIB)
+    link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)ms2mit.obj user32.lib advapi32.lib $(KLIB) $(CLIB)
 
 install::
 	copy $(OUTPRE)ms2mit.exe $(DESTDIR)
diff --git a/src/windows/ms2mit/ms2mit.c b/src/windows/ms2mit/ms2mit.c
index 4ec6941ad..eba52e793 100644
--- a/src/windows/ms2mit/ms2mit.c
+++ b/src/windows/ms2mit/ms2mit.c
@@ -2,559 +2,122 @@
  * ms2mit.c
  *
  */
-/***********************************************************
-        Copyright 2000 by Carnegie Mellon University
-
-                      All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Carnegie Mellon
-University not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
-ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-******************************************************************/
-
-
-#define UNICODE
-#define _UNICODE
+/*
+ * Copyright (C) 2003 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
 
-#include <windows.h>
+#include "krb5.h"
 #include <stdio.h>
-#include <stdlib.h>
-#include <conio.h>
-#include <time.h>
-#define SECURITY_WIN32
-#include <security.h>
-#include <ntsecapi.h>
-
-#include <krb5.h>
-#include <com_err.h>
-#include <assert.h>
-
-VOID
-ShowWinError(
-    LPSTR szAPI,
-    DWORD dwError
-    )
-{
-#define MAX_MSG_SIZE 256
-
-    // TODO - Write errors to event log so that scripts that don't
-    // check for errors will still get something in the event log
-
-    WCHAR szMsgBuf[MAX_MSG_SIZE];
-    DWORD dwRes;
-
-    printf("Error calling function %s: %lu\n", szAPI, dwError);
-
-    dwRes = FormatMessage (
-        FORMAT_MESSAGE_FROM_SYSTEM,
-        NULL,
-        dwError,
-        MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
-        szMsgBuf,
-        MAX_MSG_SIZE,
-        NULL);
-    if (0 == dwRes) {
-        printf("FormatMessage failed with %d\n", GetLastError());
-        ExitProcess(EXIT_FAILURE);
-    }
-
-    printf("%S",szMsgBuf);
-}
-
-VOID
-ShowLsaError(
-    LPSTR szAPI,
-    NTSTATUS Status
-    )
-{
-    //
-    // Convert the NTSTATUS to Winerror. Then call ShowWinError().
-    //
-    ShowWinError(szAPI, LsaNtStatusToWinError(Status));
-}
-
-
-
-BOOL
-WINAPI
-UnicodeToANSI(
-    LPTSTR lpInputString,
-    LPSTR lpszOutputString,
-    int nOutStringLen
-    )
-{
-#ifndef WIN32S
-    CPINFO CodePageInfo;
-
-    GetCPInfo(CP_ACP, &CodePageInfo);
-
-    if (CodePageInfo.MaxCharSize > 1)
-        // Only supporting non-Unicode strings
-        return FALSE;
-    else if (((LPBYTE) lpInputString)[1] == '\0')
-    {
-        // Looks like unicode, better translate it
-        WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) lpInputString, -1,
-                            lpszOutputString, nOutStringLen, NULL, NULL);
-    }
-    else
-        lstrcpyA(lpszOutputString, (LPSTR) lpInputString);
-#else
-    lstrcpy(lpszOutputString, (LPSTR) lpInputString);
-#endif
-    return TRUE;
-}  // UnicodeToANSI
-
-VOID
-WINAPI
-ANSIToUnicode(
-    LPSTR  lpInputString,
-    LPTSTR lpszOutputString,
-    int nOutStringLen
-    )
-{
-
-#ifndef WIN32S
-    CPINFO CodePageInfo;
-
-    lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
-
-    GetCPInfo(CP_ACP, &CodePageInfo);
-
-    if (CodePageInfo.MaxCharSize > 1)
-        // It must already be a Unicode string
-        return;
-    else if (((LPBYTE) lpInputString)[1] != '\0')
-    {
-        // Looks like ANSI, better translate it
-        MultiByteToWideChar(CP_ACP, 0, (LPCSTR) lpInputString, -1,
-                            (LPWSTR) lpszOutputString, nOutStringLen);
-    }
-    else
-        lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
-#endif
-}  // ANSIToUnicode
-
 
 void
-MSPrincToMITPrinc(
-    KERB_EXTERNAL_NAME *msprinc,
-    WCHAR *realm,
-    krb5_context context,
-    krb5_principal *principal
-    )
-{
-    WCHAR princbuf[512],tmpbuf[128];
-    char aname[512];
-    USHORT i;
-    princbuf[0]=0;
-    for (i=0;i<msprinc->NameCount;i++) {
-        wcsncpy(tmpbuf, msprinc->Names[i].Buffer,
-                msprinc->Names[i].Length/sizeof(WCHAR));
-        tmpbuf[msprinc->Names[i].Length/sizeof(WCHAR)]=0;
-        if (princbuf[0])
-            wcscat(princbuf, L"/");
-        wcscat(princbuf, tmpbuf);
-    }
-    wcscat(princbuf, L"@");
-    wcscat(princbuf, realm);
-    UnicodeToANSI(princbuf, aname, sizeof(aname));
-    krb5_parse_name(context, aname, principal);
-}
-
-
-time_t
-FileTimeToUnixTime(
-    LARGE_INTEGER *ltime
-    )
-{
-    FILETIME filetime, localfiletime;
-    SYSTEMTIME systime;
-    struct tm utime;
-    filetime.dwLowDateTime=ltime->LowPart;
-    filetime.dwHighDateTime=ltime->HighPart;
-    FileTimeToLocalFileTime(&filetime, &localfiletime);
-    FileTimeToSystemTime(&localfiletime, &systime);
-    utime.tm_sec=systime.wSecond;
-    utime.tm_min=systime.wMinute;
-    utime.tm_hour=systime.wHour;
-    utime.tm_mday=systime.wDay;
-    utime.tm_mon=systime.wMonth-1;
-    utime.tm_year=systime.wYear-1900;
-    utime.tm_isdst=-1;
-    return(mktime(&utime));
-}
-
-void
-MSSessionKeyToMITKeyblock(
-    KERB_CRYPTO_KEY *mskey,
-    krb5_context context,
-    krb5_keyblock *keyblock
-    )
-{
-    krb5_keyblock tmpblock;
-    tmpblock.magic=KV5M_KEYBLOCK;
-    tmpblock.enctype=mskey->KeyType;
-    tmpblock.length=mskey->Length;
-    tmpblock.contents=mskey->Value;
-    krb5_copy_keyblock_contents(context, &tmpblock, keyblock);
-}
-
-
-void
-MSFlagsToMITFlags(
-    ULONG msflags,
-    ULONG *mitflags
-    )
-{
-    *mitflags=msflags;
-}
-
-void
-MSTicketToMITTicket(
-    KERB_EXTERNAL_TICKET *msticket,
-    krb5_context context,
-    krb5_data *ticket
-    )
-{
-    krb5_data tmpdata, *newdata;
-    tmpdata.magic=KV5M_DATA;
-    tmpdata.length=msticket->EncodedTicketSize;
-    tmpdata.data=msticket->EncodedTicket;
-    // todo: fix this up a little. this is ugly and will break krb_free_data()
-    krb5_copy_data(context, &tmpdata, &newdata);
-    memcpy(ticket, newdata, sizeof(krb5_data));
-}
-
-void
-MSCredToMITCred(
-    KERB_EXTERNAL_TICKET *msticket,
-    krb5_context context,
-    krb5_creds *creds
-    )
-{
-    WCHAR wtmp[128];
-    ZeroMemory(creds, sizeof(krb5_creds));
-    creds->magic=KV5M_CREDS;
-    wcsncpy(wtmp, msticket->TargetDomainName.Buffer,
-            msticket->TargetDomainName.Length/sizeof(WCHAR));
-    wtmp[msticket->TargetDomainName.Length/sizeof(WCHAR)]=0;
-    MSPrincToMITPrinc(msticket->ClientName, wtmp, context, &creds->client);
-    wcsncpy(wtmp, msticket->DomainName.Buffer,
-            msticket->DomainName.Length/sizeof(WCHAR));
-    wtmp[msticket->DomainName.Length/sizeof(WCHAR)]=0;
-    MSPrincToMITPrinc(msticket->ServiceName, wtmp, context, &creds->server);
-    MSSessionKeyToMITKeyblock(&msticket->SessionKey, context, 
-                              &creds->keyblock);
-    MSFlagsToMITFlags(msticket->TicketFlags, &creds->ticket_flags);
-    creds->times.starttime=FileTimeToUnixTime(&msticket->StartTime);
-    creds->times.endtime=FileTimeToUnixTime(&msticket->EndTime);
-    creds->times.renew_till=FileTimeToUnixTime(&msticket->RenewUntil);
-
-    // krb5_cc_store_cred crashes downstream if creds->addresses is NULL.
-    // unfortunately, the MS interface doesn't seem to return a list of
-    // addresses as part of the credentials information. for now i'll just
-    // use krb5_os_localaddr to mock up the address list. is this sufficient?
-    krb5_os_localaddr(context, &creds->addresses);
-
-    MSTicketToMITTicket(msticket, context, &creds->ticket);
-}
-
-BOOL
-PackageConnectLookup(
-    HANDLE *pLogonHandle,
-    ULONG *pPackageId
-    )
-{
-    LSA_STRING Name;
-    NTSTATUS Status;
-
-    Status = LsaConnectUntrusted(
-        pLogonHandle
-        );
-
-    if (FAILED(Status))
-    {
-        ShowLsaError("LsaConnectUntrusted", Status);
-        return FALSE;
-    }
-
-    Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
-    Name.Length = strlen(Name.Buffer);
-    Name.MaximumLength = Name.Length + 1;
-
-    Status = LsaLookupAuthenticationPackage(
-        *pLogonHandle,
-        &Name,
-        pPackageId
-        );
-
-    if (FAILED(Status))
-    {
-        ShowLsaError("LsaLookupAuthenticationPackage", Status);
-        return FALSE;
-    }
-
-    return TRUE;
-
-}
-
-
-DWORD
-ConcatenateUnicodeStrings(
-    UNICODE_STRING *pTarget,
-    UNICODE_STRING Source1,
-    UNICODE_STRING Source2
-    )
-{
-    //
-    // The buffers for Source1 and Source2 cannot overlap pTarget's
-    // buffer.  Source1.Length + Source2.Length must be <= 0xFFFF,
-    // otherwise we overflow...
-    //
-
-    USHORT TotalSize = Source1.Length + Source2.Length;
-    PBYTE buffer = (PBYTE) pTarget->Buffer;
-
-    if (TotalSize > pTarget->MaximumLength)
-        return ERROR_INSUFFICIENT_BUFFER;
-
-    pTarget->Length = TotalSize;
-    memcpy(buffer, Source1.Buffer, Source1.Length);
-    memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
-    return ERROR_SUCCESS;
-}
-
-BOOL
-GetMSTGT(
-    HANDLE LogonHandle,
-    ULONG PackageId,
-    KERB_EXTERNAL_TICKET **ticket
+main(
+    int argc,
+    char *argv[]
     )
 {
-    //
-    // INVARIANTS:
-    //
-    //   (FAILED(Status) || FAILED(SubStatus)) ==> error
-    //   bIsLsaError ==> LsaCallAuthenticationPackage() error
-    //
-
-    //
-    // NOTE:
-    //
-    // The updated code leaks memory, but so does the old code.  The
-    // whole program is full of leaks.  Since it's short-lived
-    // process, it is ok.
-    //
-
-    BOOL bIsLsaError = FALSE;
-    NTSTATUS Status = 0;
-    NTSTATUS SubStatus = 0;
-
-    UNICODE_STRING TargetPrefix;
-
-    KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
-    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest;
-    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
-    ULONG RequestSize;
-    ULONG ResponseSize;
-    USHORT TargetSize;
-
-    CacheRequest.MessageType = KerbRetrieveTicketMessage;
-    CacheRequest.LogonId.LowPart = 0;
-    CacheRequest.LogonId.HighPart = 0;
-
-    pTicketResponse = NULL;
-
-    Status = LsaCallAuthenticationPackage(
-        LogonHandle,
-        PackageId,
-        &CacheRequest,
-        sizeof(CacheRequest),
-        &pTicketResponse,
-        &ResponseSize,
-        &SubStatus
-        );
-
-    if (FAILED(Status) || FAILED(SubStatus))
-    {
-        bIsLsaError = TRUE;
-        goto cleanup;
-    }
+    krb5_context kcontext;
+    krb5_error_code code;
+    krb5_ccache ccache=NULL;
+    krb5_ccache mslsa_ccache=NULL;
+    krb5_cc_cursor cursor;
+    krb5_creds creds;
+    krb5_principal princ;
+    int initial_ticket = 0;
 
-    if (pTicketResponse->Ticket.SessionKey.KeyType == KERB_ETYPE_DES_CBC_CRC)
-    {
-        // all done!
-        goto cleanup;
+    if (code = krb5_init_context(&kcontext)) {
+        com_err(argv[0], code, "while initializing kerberos library");
+        exit(1);
     }
-
-    //
-    // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
-    // can easily concatenate it later.
-    //
-
-    TargetPrefix.Buffer = L"krbtgt/";
-    TargetPrefix.Length = wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
-    TargetPrefix.MaximumLength = TargetPrefix.Length;
-
-    //
-    // We will need to concatenate the "krbtgt/" prefix and the previous
-    // response's target domain into our request's target name.
-    //
-    // Therefore, first compute the necessary buffer size for that.
-    //
-    // Note that we might theoretically have integer overflow.
-    //
-
-    TargetSize = TargetPrefix.Length +
-        pTicketResponse->Ticket.TargetDomainName.Length;
-
-    //
-    // The ticket request buffer needs to be a single buffer.  That buffer
-    // needs to include the buffer for the target name.
-    //
-
-    RequestSize = sizeof(*pTicketRequest) + TargetSize;
-
-    //
-    // Allocate the request buffer and make sure it's zero-filled.
-    //
-
-    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
-        LocalAlloc(LMEM_ZEROINIT, RequestSize);
-    if (!pTicketRequest)
-    {
-        Status = GetLastError();
-        goto cleanup;
+  
+    if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) {
+        com_err(argv[0], code, "while opening MS LSA ccache");
+        krb5_free_context(kcontext);
+        exit(1);
     }
 
-    //
-    // Concatenate the target prefix with the previous reponse's
-    // target domain.
-    //
-
-    pTicketRequest->TargetName.Length = 0;
-    pTicketRequest->TargetName.MaximumLength = TargetSize;
-    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
-    Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
-                                       TargetPrefix,
-                                       pTicketResponse->Ticket.TargetDomainName);
-    assert(SUCCEEDED(Status));
-
-    //
-    // Intialize the requst of the request.
-    //
-
-    pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
-    pTicketRequest->LogonId.LowPart = 0;
-    pTicketRequest->LogonId.HighPart = 0;
-    // Note: pTicketRequest->TargetName set up above
-    pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;
-    pTicketRequest->TicketFlags = 0L;
-    pTicketRequest->EncryptionType = ENCTYPE_DES_CBC_CRC;
-
-    //
-    // Free the previous response buffer so we can get the new response.
-    //
-
-    LsaFreeReturnBuffer(pTicketResponse);
-    pTicketResponse = NULL;
-
-    Status = LsaCallAuthenticationPackage(
-        LogonHandle,
-        PackageId,
-        pTicketRequest,
-        RequestSize,
-        &pTicketResponse,
-        &ResponseSize,
-        &SubStatus
-        );
-
-    if (FAILED(Status) || FAILED(SubStatus))
-    {
-        bIsLsaError = TRUE;
-        goto cleanup;
+    /* Enumerate tickets from cache looking for an initial ticket */
+    if ((code = krb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) {
+        com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache");
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_free_context(kcontext);
+        exit(1);
     }
 
- cleanup:
-    if (FAILED(Status) || FAILED(SubStatus))
+    while (!(code = krb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds))) 
     {
-        if (bIsLsaError)
-        {
-            // XXX - Will be fixed later
-            if (FAILED(Status))
-                ShowLsaError("LsaCallAuthenticationPackage", Status);
-            if (FAILED(SubStatus))
-                ShowLsaError("LsaCallAuthenticationPackage", SubStatus);
-        }
-        else
-        {
-            ShowWinError("GetMSTGT", Status);
+        if ( creds.ticket_flags & TKT_FLG_INITIAL ) {
+            krb5_free_cred_contents(kcontext, &creds);
+            initial_ticket = 1;
+            break;
         }
-
-        if (pTicketResponse)
-            LsaFreeReturnBuffer(pTicketResponse);
-
-        return(FALSE);
+        krb5_free_cred_contents(kcontext, &creds);
     }
+    krb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor);
 
-    *ticket = &(pTicketResponse->Ticket);
-    return(TRUE);
-}
-
-void
-main(
-    int argc,
-    char *argv[]
-    )
-{
-    krb5_context kcontext;
-    krb5_error_code code;
-    krb5_creds creds;
-    krb5_ccache ccache=NULL;
-    krb5_get_init_creds_opt opts;
-    char *cache_name=NULL;
-    HANDLE LogonHandle=NULL;
-    ULONG PackageId;
-
-    KERB_EXTERNAL_TICKET *msticket;
-    if(!PackageConnectLookup(&LogonHandle, &PackageId))
+    if ( !initial_ticket ) {
+        fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MS LSA\n",
+                argv[0]);
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_free_context(kcontext);
         exit(1);
+    }
 
-    if (GetMSTGT(LogonHandle, PackageId, &msticket)==FALSE)
-        exit(1);
-    if (code = krb5_init_context(&kcontext)) {
-        com_err(argv[0], code, "while initializing kerberos library");
+    if (code = krb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) {
+        com_err(argv[0], code, "while obtaining MS LSA principal");
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_free_context(kcontext);
         exit(1);
     }
-    krb5_get_init_creds_opt_init(&opts);
-    MSCredToMITCred(msticket, kcontext, &creds);
+
     if (code = krb5_cc_default(kcontext, &ccache)) {
         com_err(argv[0], code, "while getting default ccache");
+        krb5_free_principal(kcontext, princ);
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_free_context(kcontext);
         exit(1);
     }
-    if (code = krb5_cc_initialize(kcontext, ccache, creds.client)) {
-        com_err (argv[0], code, "when initializing cache %s",
-                 cache_name?cache_name:"");
+    if (code = krb5_cc_initialize(kcontext, ccache, princ)) {
+        com_err (argv[0], code, "when initializing ccache");
+        krb5_free_principal(kcontext, princ);
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_cc_close(kcontext, ccache);
+        krb5_free_context(kcontext);
         exit(1);
     }
-    if (code = krb5_cc_store_cred(kcontext, ccache, &creds)) {
-        com_err (argv[0], code, "while storing credentials");
+
+    if (code = krb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) {
+        com_err (argv[0], code, "while copying MS LSA ccache to default ccache");
+        krb5_free_principal(kcontext, princ);
+        krb5_cc_close(kcontext, ccache);
+        krb5_cc_close(kcontext, mslsa_ccache);
+        krb5_free_context(kcontext);
         exit(1);
     }
+
+    krb5_free_principal(kcontext, princ);
     krb5_cc_close(kcontext, ccache);
+    krb5_cc_close(kcontext, mslsa_ccache);
     krb5_free_context(kcontext);
+    return(0);
 }
diff --git a/src/windows/version.rc b/src/windows/version.rc
index 1b8ca9d9f..abdc8edf7 100644
--- a/src/windows/version.rc
+++ b/src/windows/version.rc
@@ -8,7 +8,7 @@
 #define PRE_RELEASE
 
 #ifdef PRE_RELEASE
-#define BETA_STR  " beta"
+#define BETA_STR  " beta 3"
 #define BETA_FLAG VS_FF_PRERELEASE
 #else
 #define BETA_STR  ""
@@ -23,10 +23,10 @@
 
 /* we're going to stamp all the DLLs with the same version number */
 
-#define K5_PRODUCT_VERSION_STRING "1.3 (TEST)" BETA_STR "\0"
-#define K5_PRODUCT_VERSION        1, 3, 0, 0
+#define K5_PRODUCT_VERSION_STRING "1.3.2" BETA_STR "\0"
+#define K5_PRODUCT_VERSION        1, 3, 2, 0
 
-#define K5_COPYRIGHT "Copyright (C) 1997-2000 by the Massachusetts Institute of Technology\0"
+#define K5_COPYRIGHT "Copyright (C) 1997-2004 by the Massachusetts Institute of Technology\0"
 #define K5_COMPANY_NAME "Massachusetts Institute of Technology.\0"
 
 /*