Unify access to FQDN

FreeIPA's Python and C code used different approaches to get the FQDN of
the host. Some places assumed that gethostname() returns a FQDN. Other
code paths used glibc's resolver to resolve the current node name to a
FQDN.

Python code now uses the ipalib.constants.FQDN where a fully qualified
domain name is expected. The variable is initialized only once and avoids
potential DNS lookups.

C code uses a new helper function ipa_gethostfqdn() in util package. The
function implements similar logic as gethostfqdn() except it uses more
modern getaddrinfo(). The result is cached as well.

Fixes: https://pagure.io/freeipa/issue/8501
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
This commit is contained in:
Christian Heimes
2020-09-11 14:49:16 +02:00
committed by Fraser Tweedale
parent 5155280bb4
commit e28ec76898
23 changed files with 226 additions and 67 deletions

30
ipapython/fqdn.py Normal file
View File

@@ -0,0 +1,30 @@
#
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
#
"""Get host's FQDN
"""
import socket
def gethostfqdn():
hostname = socket.gethostname()
# optional optimization, consider hostname with dot as FQDN
if "." in hostname:
return hostname
# this call can never fail except for misconfigured nsswitch.conf
# without nss-myhostname provider. The myhostname provider translates
# gethostname() to local interfaces.
gai = socket.getaddrinfo(
hostname,
None, # service/port is irrelevant
family=socket.AF_UNSPEC, # IPv4 or IPv6
type=socket.SOCK_DGRAM, # optimization, TCP/RAW gives same result
# include canonical name in first addrinfo struct
# only use address family when at least one non-local interface
# is configured with that address family
flags=socket.AI_CANONNAME | socket.AI_ADDRCONFIG
)
# first addrinfo struct, fourth field is canonical name
return gai[0][3]