-------------------------------
Several aspects of Kerberos rely on name service. When a hostname is
-used to name a service, the Kerberos library canonicalizes the
-hostname using forward and reverse name resolution. (The reverse name
-resolution step can be turned off using the **rdns** variable in
-:ref:`libdefaults`.) The result of this canonicalization must match
-the principal entry in the host's keytab, or authentication will fail.
-
-Each host's canonical name must be the fully-qualified host name
-(including the domain), and each host's IP address must
+used to name a service, clients may canonicalize the hostname using
+forward and possibly reverse name resolution. The result of this
+canonicalization must match the principal entry in the host's keytab,
+or authentication will fail. To work with all client canonicalization
+configurations, 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.
Configuration of hostnames varies by operating system. On the
hostnames for use in service principal names. Setting this flag
to false can improve security by reducing reliance on DNS, but
means that short hostnames will not be canonicalized to
- fully-qualified hostnames. The default value is true.
-
- If this option is set to ``fallback`` (new in release 1.18), DNS
- canonicalization will only be performed the server hostname is not
- found with the original name when requesting credentials.
+ fully-qualified hostnames. If this option is set to ``fallback`` (new
+ in release 1.18), DNS canonicalization will only be performed the
+ server hostname is not found with the original name when
+ requesting credentials. The default value is ``fallback``.
**dns_lookup_kdc**
Indicate whether DNS SRV records should be used to locate the KDCs
Service principal canonicalization
----------------------------------
-MIT Kerberos clients currently always do forward resolution (looking
-up the IPv4 and possibly IPv6 addresses using ``getaddrinfo()``) of
-the hostname part of a host-based service principal to canonicalize
-the hostname. They obtain the "canonical" name of the host when doing
-so. By default, MIT Kerberos clients will also then do reverse DNS
-resolution (looking up the hostname associated with the IPv4 or IPv6
-address using ``getnameinfo()``) of the hostname. Using the
-:ref:`krb5.conf(5)` setting::
+In the MIT krb5 client library, canonicalization of host-based service
+principals is controlled by the **dns_canonicalize_hostname**,
+**rnds**, and **qualify_shortname** variables in :ref:`libdefaults`.
+
+If **dns_canonicalize_hostname** is set to ``true`` (the default value
+before release 1.19), the client performs forward resolution by
+looking up the IPv4 and/or IPv6 addresses of the hostname using
+``getaddrinfo()``. This process will typically add a domain suffix to
+the hostname if needed, and follow CNAME records in the DNS. If
+**rdns** is also set to ``true`` (the default), the client will then
+perform a reverse lookup of the first returned Internet address using
+``getnameinfo()``, finding the name associated with the PTR record.
+
+If **dns_canonicalize_hostname** is set to ``false``, the hostname is
+not canonicalized using DNS. If the hostname has only one component
+(i.e. it contains no "." characters), the host's primary DNS search
+domain will be appended, if there is one. The **qualify_shortname**
+variable can be used to override or disable this suffix.
+
+If **dns_canonicalize_hostname** is set to ``fallback`` (the default
+value in release 1.19 and later), the hostname is initially treated
+according to the rules for ``dns_canonicalize_hostname=false``. If a
+ticket request fails because the service principal is unknown, it the
+hostname will be canonicalized according to the rules for
+``dns_canonicalize_hostname=true`` and the request will be retried.
+
+In all cases, the hostname is converted to lowercase, and any trailing
+dot is removed.
- [libdefaults]
- rdns = false
-
-will disable reverse DNS lookup on clients. The default setting is
-"true".
-
-Operating system bugs may prevent a setting of ``rdns = false`` from
-disabling reverse DNS lookup. Some versions of GNU libc have a bug in
-``getaddrinfo()`` that cause them to look up ``PTR`` records even when
-not required. MIT Kerberos releases krb5-1.10.2 and newer have a
-workaround for this problem, as does the krb5-1.9.x series as of
-release krb5-1.9.4.
Reverse DNS mismatches
default_realm = __REALM__
default_keytab_name = FILE:__K5ROOT__/keytab
dns_fallback = no
+ qualify_shortname = ""
plugin_base_dir = __PLUGIN_DIR__
allow_weak_crypto = true
[realms]
__REALM__ = {
- kdc = __KDCHOST__:1750
- admin_server = __KDCHOST__:1751
+ kdc = __HOSTNAME__:1750
+ admin_server = __HOSTNAME__:1751
database_module = foobar_db2_module_blah
}
[domain_realm]
- __LOCALHOST__ = __REALM__
- __KDCHOST__ = __REALM__
+ __HOSTNAME__ = __REALM__
[logging]
admin_server = FILE:__K5ROOT__/syslog
CLNTTCL=$TESTDIR/util/kadm5_clnt_tcl; export CLNTTCL
SRVTCL=$TESTDIR/util/kadm5_srv_tcl; export SRVTCL
-QUALNAME=`$BUILDTOP/tests/resolve/resolve -q | tr '[A-Z]' '[a-z]'`
-export QUALNAME
+HOSTNAME=`hostname | tr '[A-Z]' '[a-z]'`
+export HOSTNAME
KRB5_CONFIG=$K5ROOT/krb5.conf; export KRB5_CONFIG
KRB5_KDC_PROFILE=$K5ROOT/kdc.conf; export KRB5_KDC_PROFILE
# done
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
- -e "s/__KDCHOST__/$QUALNAME/g" \
- -e "s/__LOCALHOST__/$QUALNAME/g" \
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
-e "s#__MODDIR__#$MODDIR#g" \
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
# Fix up the local krb5.conf to point to the remote
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
- -e "s/__KDCHOST__/$hostname/g" \
- -e "s/__LOCALHOST__/$QUALNAME/g" \
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
-e "s#__MODDIR__#$TOP/../plugins/kdb#g"\
-e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
if { [catch {
source $env(STOP)/testing/tcl/util.t
set r $env(REALM)
- set q $env(QUALNAME)
+ set q $env(HOSTNAME)
puts stdout [kadm5_init $env(SRVTCL) mrroot null \
[config_params {KADM5_CONFIG_REALM} $r] \
$KADM5_STRUCT_VERSION $KADM5_API_VERSION_3 server_handle]
api_exit
api_start
-if ![info exists RESOLVE] {
- set RESOLVE [findfile $objdir/../../../tests/resolve/resolve]
-}
proc get_hostname { } {
- global RESOLVE
global hostname
if {[info exists hostname]} {
return 1
}
- catch "exec $RESOLVE -q >myname" exec_output
+ catch "exec hostname >myname" exec_output
if ![string match "" $exec_output] {
send_log "$exec_output\n"
verbose $exec_output
ctx->enforce_ok_as_delegate = tmp;
retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback",
- CANONHOST_FALLBACK, 1, &tmp);
+ CANONHOST_FALLBACK, CANONHOST_FALLBACK, &tmp);
if (retval)
goto cleanup;
ctx->dns_canonicalize_hostname = tmp;
{KTUTIL $objdir/../../kadmin/ktutil/ktutil}
{KLIST $objdir/../../clients/klist/klist}
{KDESTROY $objdir/../../clients/kdestroy/kdestroy}
- {RESOLVE $objdir/../resolve/resolve}
{T_INETD $objdir/t_inetd}
{KPROPLOG $objdir/../../kprop/kproplog}
{KPASSWD $objdir/../../clients/kpasswd/kpasswd}
# 0 on failure.
proc get_hostname { } {
- global RESOLVE
global hostname
global tmppwd
envstack_push
setup_runtime_env
- catch "exec $RESOLVE -q >$tmppwd/hostname" exec_output
+ catch "exec hostname >$tmppwd/hostname" exec_output
envstack_pop
if ![string match "" $exec_output] {
verbose -log $exec_output
puts $conffile "\[libdefaults\]"
puts $conffile " default_realm = $REALMNAME"
puts $conffile " dns_lookup_kdc = false"
+ puts $conffile " qualify_shortname = \"\""
if [info exists allow_weak_crypto($type)] {
puts $conffile " allow_weak_crypto = $allow_weak_crypto($type)"
} else {
offline = (len(args) > 0 and args[0] != "no")
-conf = {'domain_realm': {'kerberos.org': 'R1',
+conf = {'libdefaults': {'dns_canonicalize_hostname': 'true'},
+ 'domain_realm': {'kerberos.org': 'R1',
'example.com': 'R2',
'mit.edu': 'R3'}}
no_rdns_conf = {'libdefaults': {'rdns': 'false'}}
fail('Expected %s, got %s' % (expected, out))
def test(host, princhost, princrealm):
- # Test with the host-based name type in the default environment.
+ # Test with the host-based name type with canonicalization enabled.
testbase(host, 'srv-hst', princhost, princrealm)
def testnc(host, princhost, princrealm):
* plugins: The plugin directory in the build tree (absolute path).
-* hostname: This machine's fully-qualified domain name.
+* hostname: The local hostname as it will initially appear in
+ krb5_sname_to_principal() results. (Shortname qualification is
+ turned off in the test environment to make this value easy to
+ discover from Python.)
* null_input: A file opened to read /dev/null.
return os.path.abspath(root)
-# Return the local hostname as it will be canonicalized by
-# krb5_sname_to_principal. We can't simply use socket.getfqdn()
-# because it explicitly prefers results containing periods and
-# krb5_sname_to_principal doesn't care.
-def _get_hostname():
- hostname = socket.gethostname()
- try:
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
- except socket.gaierror as e:
- fail('Local hostname "%s" does not resolve: %s.' % (hostname, e[1]))
- (family, socktype, proto, canonname, sockaddr) = ai[0]
- try:
- name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
- except socket.gaierror:
- return canonname.lower()
- return name[0].lower()
-
# Parse command line arguments, setting global option variables. Also
# sets the global variable args to the positional arguments, which may
# be used by the test script.
'libdefaults': {
'default_realm': '$realm',
'dns_lookup_kdc': 'false',
+ 'qualify_shortname': '',
'plugin_base_dir': '$plugins'},
'realms': {'$realm': {
'kdc': '$hostname:$port0',
srctop = _find_srctop()
plugins = os.path.join(buildtop, 'plugins')
runenv = _import_runenv()
-hostname = _get_hostname()
+hostname = socket.gethostname().lower()
null_input = open(os.devnull, 'r')
# A DB pass is a tuple of: name, kdc_conf.