LKDC
The local KDC in Leopard is pretty rad. In the absence of any real documentation, this page exists as a jumble of observations and theories.
Contents
Positioning and Use in Leoaprd
The Local KDC (LKDC) is a Kerberos implementation that extends "single sign-on" capabilities into ad-hoc networks. The LKDC supports the AFP, CIFS, and VNC services included in Mac OS X and Mac OS X Server. At the surface, the LKDC looks pretty much just like a regular Kerberos setup... you can log into one of the above named services and get Kerberos tickets, use standard tools like klist to manage tickets, use kadmin to administer the KDC, etc, etc. Some examples:
{3} andre@donk [~] % sudo klist -k Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD 3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
{10} andre@donk [~] % sudo kadmin.local -q listprincs Authenticating as principal andre/admin@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B with password. K/M@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD andre@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD kadmin/admin@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD kadmin/changepw@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD kadmin/donk.local@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD kadmin/history@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD krbtgt/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
{13} andre@donk [~] % sudo kadmin.local -q 'get_principal andre' Authenticating as principal andre/admin@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B with password. Principal: andre@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD Expiration date: [never] Last password change: Sat May 10 21:43:57 PDT 2008 Password expiration date: [none] Maximum ticket life: 0 days 10:00:00 Maximum renewable life: 7 days 00:00:00 Last modified: Sat May 10 21:43:57 PDT 2008 (root/admin@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 4 Key: vno 1, Triple DES cbc mode with HMAC/sha1, no salt Key: vno 1, ArcFour with HMAC/md5, no salt Key: vno 1, DES cbc mode with CRC-32, no salt Key: vno 1, DES cbc mode with CRC-32, Version 4 Attributes: REQUIRES_PRE_AUTH Policy: [none]
{106} andre@donk [~] % klist Kerberos 5 ticket cache: 'API:Initial default ccache' Default principal: andre@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B Valid Starting Expires Service Principal 05/13/08 00:35:00 05/13/08 10:34:58 krbtgt/LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B renew until 05/20/08 00:34:58 05/13/08 00:35:00 05/13/08 10:34:58 vnc/LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B renew until 05/20/08 00:34:58
Standard Deviation
The crux of the LKDC implementation is the use of a SHA1 hash in place of the server name portion of a kerberos principal, effectively insulating Kerberos from dynamic network conditions. This significant re-definition of a kerberos principal is really cool, but also not standard. The standard kerberos libraries pretty much assume and require that the server name portion of a kerberos principal be just that: a server name (or IP address).
This presents two primary challenges:
- Advertising and discovering LKDC realm information in an ad-hoc, peer to peer context
- Harnessing the authentication process to construct the special kerberos principal and then handing it off to Kerberos
Advertising and Discovering
Not surprisingly, the mechanism used is multicast DNS, as it is very well suited to ad-hoc networks. In other more standard Kerberos deployments, it it not unusual to use DNS to discover Kerberos information in the absence of local configuration (see references at the bottom of the page), but with standard kerberos, the discovery is limited to realm name or KDC name. From the krb5.conf man page [libdefaults] section:
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 for the realm. The default is to use these records. dns_lookup_realm Indicate whether DNS TXT records should be used to determine the Ker- beros realm of a host. The default is not to use these records.
At some point during or after startup, the LKDC realm name is read from Directory Services, e.g.
dscl . -read /Config/KerberosKDC RealName
The LKDC realm name is then advertised in the txt portion of a multicast DNS record called _kerberos in the .local name space, which may be manually queried as follows:
dns-sd -Q "_kerberos.donk.local" txt
Replace "donk" with the bonjour name of a Leopard machine on your local network (can test on yourself if needed).
The result is a string of hex characters. This command does not terminate, so control-C to stop it. Now take the hex and run it through xxd -r -c 256.
xxd -r -c 256
<paste in the hex string, press return>
The result is the LKDC realm name, such as LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
Harnessing Authentication
The notion of using a unique hash as the realm name and sever name portion of the principal name is a new idea. Accordingly, we cannot rely on standard Kerberos libraries to be able to construct the correct principal name based on the LKDC's realm name. Accordingly, the authentication process is brokered for supported service clients, in order to perform the LKDC realm name discovery and then construct a kerberos principal name that is correct for the remote LKDC. Once the correct service principal is obtained, it is handed off to Kerberos.
The client-side authentication broker (for supported services!) is called NetAuthAgent, and you'll see it get fired up whenever you use vnc, afp, cifs. Think of this as a session manager, of sorts.
Most of the advertisement, discovery, and management functions involving the LKDC are provided by a private framework called KerberosHelper, and a Kerberos framework plugin called LKDCLocate.
Using KerberosHelper
Some of the basic methods provided by KerberosHelper might be exercised as follows (big ups to landonf)!
krb.c contains the following:
#include <stdio.h> #include <unistd.h> #include <stdint.h> #include <stdlib.h> extern int LKDCGetLocalRealm(char **realm); extern int LKDCDiscoverRealm(const char *host, char **realm); // XXX arg1 - 1 seems to trigger the dump to syslog. extern int LKDCDumpStatus(int32_t arg1); void find_realm (const char *host) { char *realm; char *kdc; uint32_t arg3; /* Find the realm */ if (LKDCDiscoverRealm(host, &realm) == 0) { printf("Disovered Realm (%s): %s\n", host, realm); } free(realm); } int main(int argc, char *argv[]) { char *local_realm; if (LKDCGetLocalRealm(&local_realm) == 0) { printf("Local Realm: %s\n", local_realm); free(local_realm); } /* Dump to syslog. XXX argument '1' is a guess */ LKDCDumpStatus(1); if (argc < 2) { printf("Usage: %s <hostname>\n", argv[0]); return 1; } find_realm(argv[1]); return 0; }
Compile with:
gcc krb.c -o krb -F/System/Library/PrivateFrameworks -framework KerberosHelper
Run it with one argument: a bonjour name of a leopard machine on your network. e.g.
{33} andre@donk [work/krb] % ./krb dude.local Local Realm: LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD Disovered Realm (dude.local): LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B
Also, check your system.log. LKDCDumpStatus produces something like:
May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: Cache root node = 0x1034f0 May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: node = 0x1034f0 { May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: realmName = (0x1059d0) LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: serviceHost = (0x104d50) donk.local May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: servicePort = 88 May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: TTL = 7200 May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: } May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: node = 0x106030 { May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: realmName = (0x106460) LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: serviceHost = (0x105fd0) dude.local May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: servicePort = 88 May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: TTL = 7200 May 13 02:38:56 donk LKDCHelper[30484]: LKDCDumpCacheStatus: }
Interesting Files
NetAuthAgent
This appears to be a service client helper that manages the authentication process at a high level on behalf of various clients included with Mac OS X. A string dump reveals the following chunk of kerberos service names:
vncserver webdaveserver ftpsserver ftpserver cifs afpserver
vncserver, cifs, and afpserver are the only 3 services that are kerberized in the LKDC by default, though NetAuthAgent appears to support others as well. Looking at all strings matching 'kerb', we see:
{5} andre@donk [~] % strings /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent | grep -i kerb KerberosSession BypassKerberos kerberosClientPrincipalCredentials kerberosRelease kerberosClientPrincipal kerberosKeychainRealm kerberosPrincipalInfo MountedByKerberos SupportsKerberos /System/Library/CoreServices/Kerberos.app mInvalidKerberosUserName checkForKerberosUserName: isValidKerberosUserName: useKerberos kerberosServiceName kerberosServicePrincipalHint kerberosSession kerberosServicePrincipal kerberosAcquireTicket Kerberos AllowKerberosUI KerberosInfo kerberosUIOption kerberosHostDisplayName kerberosHostAddress kerberosAlreadyHasTicket
{14} andre@donk [~] % otool -L /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent | cut -d ' ' -f1 /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent: /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa /System/Library/Frameworks/Security.framework/Versions/A/Security /System/Library/PrivateFrameworks/URLMount.framework/Versions/A/URLMount /System/Library/Frameworks/SecurityInterface.framework/Versions/A/SecurityInterface /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper /usr/lib/libgcc_s.1.dylib /usr/lib/libSystem.B.dylib /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices /usr/lib/libobjc.A.dylib /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
NetAuthAgent.app also includes NetAuthSysAgent, which appears to be a variant of NetAuthAgent for handling system-level operations that do not require user interface. It contains lots of filesystem semantics, and also appears to deal with certificates.
{108} andre@donk [~] % otool -L /System/Library/CoreServices/NetAuthAgent.app/Contents/Resources/NetAuthSysAgent | cut -d ' ' -f1 /System/Library/CoreServices/NetAuthAgent.app/Contents/Resources/NetAuthSysAgent: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation /System/Library/PrivateFrameworks/URLMount.framework/Versions/A/URLMount /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper /System/Library/Frameworks/SecurityInterface.framework/Versions/A/SecurityInterface /System/Library/Frameworks/Security.framework/Versions/A/Security /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices /usr/lib/libgcc_s.1.dylib /usr/lib/libSystem.B.dylib /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices /usr/lib/libobjc.A.dylib /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
LKDCLocate
This (non-private?) Kerberos framework plugin looks like it's able to perform DNS queries to retrieve LKDC info. It also seems to interact with a mach service created by LKDCHelper called com.apple.KerberosHelper.LKDCHelper.
{14} andre@donk [~] % strings /System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate %s: LKDCLookup Declined to handle address family %d svc = %d, realm = %s, family= %d, socktype = %d KDC|MasterKDC LKDC: getaddrinfo () == %d 0x%08p: family = %d, socktype = %d, protocol = %d Running callback 0x%08p Unexpected address family %d Callback done 0x%08p, err=%d inet_ntop failed: %s addr = %s, port = %d failed %d LKDCGetHelperPort com.apple.KerberosHelper.LKDCHelper %s: cannot contact helper LKDCHelperExit Mach communication failed: %s LKDCDumpStatus LKDCSetLogLevel LKDCGetLocalRealm [[[ %s Local realm = %s ]]] %s = %d (%s) LKDCDiscoverRealm No place to store discovered realm. realm = %s LKDCFindKDCForRealm No place to store discovered KDC hostname. KDC Hostname = %s:%u Communication to the helper failed Not authorized Input parameter error Serializing object failed Unserializing object failed Object passed is not a dictionary A Local KDC was not found Lookup of the KDC for the requested realm failed %s: Success <unknown error> [...]
{112} andre@donk [~] % otool -L /System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate /System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate: /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
KerberosHelper
This private framework appears to provide API that can be used on behalf of service clients (or their agents) to discover the LKDC information of a remote realm.
{6} root@donk [~] # strings /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper LKDCGetHelperPort com.apple.KerberosHelper.LKDCHelper %s: cannot contact helper LKDCHelperExit Mach communication failed: %s LKDCDumpStatus LKDCSetLogLevel LKDCGetLocalRealm [[[ %s Local realm = %s ]]] %s = %d (%s) LKDCDiscoverRealm No place to store discovered realm. realm = %s LKDCFindKDCForRealm No place to store discovered KDC hostname. KDC Hostname = %s:%u LKDC: %s: krb5 call got %d (%s) on %s:%d realm_for_host (null) [[[ %s: hostname=%s hintrealm=%s /SourceCache/KerberosHelper/KerberosHelper-31/Source/KerberosHelper.c %s: krb5_get_host_realm success %s: krb5_get_host_realm returned unusable realm! %s: LKDCDiscoverRealm success ]]] %s: returning realm=%s ]]] %s: failed to determine realm [[[ KRBCopyRealm () - required parameters okay ]]] KRBCopyRealm () = %d [[[ KRBCopyKeychainLookupInfo () - required parameters okay Username KeychainAccountName DisableSaveToKeychain edu.mit.Kerberos.KerberosAgent SavePasswordDisabled KRBCopyKeychainLookupInfo: DisableSaveToKeychainKey = TRUE KRBCopyKeychainLookupInfo: CFPreferencesCopyAppValue == NULL ]]] KRBCopyKeychainLookupInfo () = %d [[[ KRBCopyServicePrincipal () - required parameters okay KRBCopyServicePrincipal: svcName mismatch inService = "%s", svcName = "%s" KRBCopyServicePrincipal: useName = "%s" LKDC: KRBCopyServicePrincipal: realm is Local KDC. KRBCopyServicePrincipal: Bad inHostName, using svcInstance = "%s" KRBCopyServicePrincipal: useInstance = "%s" KRBCopyServicePrincipal: Fatal - Bad inHostName & no inAdvertisedPrincipal %s/%s@%s KRBCopyServicePrincipal: principal = "%s/%s@%s" ]]] KRBCopyServicePrincipal () = %d KRBCopyClientPrincipalInfo [[[ KRBCopyClientPrincipalInfo () - required parameters okay Certificate KRBCopyClientPrincipalInfo: Certificate information in dictionary KRBCopyClientPrincipalInfo: Certificate not present in dictionary .Mac Sharing Certificate %@@%@ KRBCopyClientPrincipalInfo: Using login name = "%s" KRBCopyClientPrincipalInfo: principal guess = "%s" KRBCopyClientPrincipalInfo: ccache principal match = "%s" KRBCopyClientPrincipalInfo: found a single ticket for realm, replacing principal & username KRBCopyClientPrincipalInfo: Setting found Username to = "%s" KRBCopyClientPrincipalInfo: using principal = "%s" ClientPrincipal KRBCopyClientPrincipalInfo: usingCertificate == %d UsingCertificate CetificateHash CertificateInferredLabel KRBCopyClientPrincipalInfo: InferredLabel = "%s" ]]] KRBCopyClientPrincipalInfo () = %d %@@%s [[[ KRBTestForExistingTicket () - required parameters okay KRBTestForExistingTicket: principal = "%s" KRBTestForExistingTicket: Valid Ticket, ccacheName = "%s" ]]] KRBTestForExistingTicket () = %d KRBAcquireTicket [[[ KRBAcquireTicket () - required parameters okay KRBAcquireTicket: Using a certificate Password ]]] KRBAcquireTicket () = %d [[[ KRBCloseSession () - required parameters okay ]]] KRBCloseSession () = %d parse_principal_name KRBCreateSession [[[ %s () - required parameters okay %s: LocalKDC realm lookup only %s: __KRBCreateUTF8StringFromCFString failed [[[ %s () decomposing %s ]]] %s () - %d %s: processed host name = %s %s.local %s: last char of host name = 0x%02x success %s: getaddrinfo = %s (%d) %s: canonical host name = %s %s: secondary match = %s %s: primary match = %s %s: could not find a suitable host/realm mapping %s: Using host name = %s, realm = %s ]]] %s () = %d KerberosKDC dsRecTypeStandard:Config realname Communication to the helper failed Not authorized Input parameter error Serializing object failed Unserializing object failed Object passed is not a dictionary A Local KDC was not found Lookup of the KDC for the requested realm failed %s: Success <unknown error>
LKDCHelper
This executable is part of the KerberosHelper framework and is a launch agent that runs in the user's namespace. This appears to fire up a mach service called com.apple.KerberosHelper.LKDCHelper that is used for IPC with other interested parties (see: elsewhere on this page).
{34} andre@donk [~] % strings /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/Resources/LKDCHelper Idle exit do_LKDCDumpStatus [[[ %s do_LKDCSetLogLevel do_LKDCGetLocalRealm Cached lookup LocalKDCRealm = %s do_LKDCDiscoverRealm Looking up realm for %s do_LKDCFindKDCForRealm Looking up host for %s %s: Unauthorized access by euid=%lu pid=%lu update_idle_timer 0 == gettimeofday(&last_message, NULL) /SourceCache/KerberosHelper/KerberosHelper-31/Source/LKDCHelper-main.c idletimer_main 0 == gettimeofday(&now, NULL) Invalid idle timeout: %s Usage: [-d] [-t maxidle] Could not initialize ASL logging. Starting (uid=%ul) mach_port_allocate: %s mach_port_insert_right: %s com.apple.KerberosHelper.LKDCHelper bootstrap_register2 failed: %s CheckIn Could not create checkin message for launchd. Could not message launchd. Launchd checkin failed: %s. MachServices Launchd reply does not contain %s dictionary. Launchd reply does not contain %s Mach port. Launchd gave me a null Mach port. Failed to start idletimer thread: %s mach_msg_server: %s KerberosKDC dsRecTypeStandard:Config realname _kerberos LookupRealmCallBack mDNSError = %d More than one record, last one wins!!! LKDCAddLocatorDetails New entry for (realm=%s host=%s) Replacing existing entry (realm=%s host=%s) with (realm=%s host=%s) ]]] %s = %d (%s) LKDCHostnameForRealm Cache hit Cache miss HandleEvents LKDCLookupRealm LKDCRealmForHostname %s.%s mDNSResult CallbackError = %d Timeout! LKDCDumpCacheStatus Cache root node = %08p node = %08p { realmName = (%08p) %s serviceHost = (%08p) %s servicePort = %u TTL = %u } Communication to the helper failed Not authorized Input parameter error Serializing object failed Unserializing object failed Object passed is not a dictionary A Local KDC was not found Lookup of the KDC for the requested realm failed %s: Success <unknown error>
- /usr/libexec/configureLocalKDC - this is a perl script that creates the LKDC at installation time, including creating service principals, editing service config files, and installing a kerberos certificate into the system keychain.
Resources
- http://www.felipe-alfaro.org/blog/2007/12/07/kerberizing-leopards-ssh/ This documents how to kerberize ssh / sshd, in Leopard, but uses a static configuration instead of dynamically discovering the remote realm name, as is done by the services kerberized in the LKDC by default.
- http://www.mactech.com/articles/mactech/Vol.23/23.11/ExploringLeopardwithDTrace/index.html Exploring Leopard with DTrace - was useful in determining how some of the service clients interact with Kerberos.
- http://developer.apple.com/technotes/tn2005/tn2083.html Daemons and Agents. Fantastic technote by Quinn. This helped me understand a bit more about the mach service that is provided by LKDCHelper.
- http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/129443 Multicast DNS libraries for Ruby
- http://www.ldap.com/1/commentary/wahl/20070511_01.shtml Discovering local identity services. Outlines several methods for dynamic discovery of how to bootstrap authentication sessions with a remote system.
- http://www.cybersafe.ltd.uk/docs_standards/draft-ietf-krb-wg-krb-dns-locate-03.txt This expired draft documents how kerberos realm information might be discovered using multicast dns.
- http://www.dns-sd.org/ServiceTypes.html multicast DNS service types
- http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt This expired draft documents multicast DNS in general
- http://web.mit.edu/kerberos/www/krb5-1.2/krb5-1.2.6/doc/install.html#SEC9 Kerberos install document; this section documents how Kerberos finds realm information.