mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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:
parent
5155280bb4
commit
e28ec76898
@ -1,9 +1,11 @@
|
|||||||
|
AM_CPPFLAGS := -I$(top_srcdir)/util
|
||||||
AM_CFLAGS := @LDAP_CFLAGS@ @LIBVERTO_CFLAGS@ @KRB5_CFLAGS@ @NSPR_CFLAGS@
|
AM_CFLAGS := @LDAP_CFLAGS@ @LIBVERTO_CFLAGS@ @KRB5_CFLAGS@ @NSPR_CFLAGS@
|
||||||
AM_LDFLAGS := @LDAP_LIBS@ @LIBVERTO_LIBS@ @KRAD_LIBS@ @KRB5_LIBS@
|
AM_LDFLAGS := @LDAP_LIBS@ @LIBVERTO_LIBS@ @KRAD_LIBS@ @KRB5_LIBS@
|
||||||
|
|
||||||
noinst_HEADERS = internal.h
|
noinst_HEADERS = internal.h
|
||||||
appdir = $(libexecdir)/ipa/
|
appdir = $(libexecdir)/ipa/
|
||||||
app_PROGRAMS = ipa-otpd
|
app_PROGRAMS = ipa-otpd
|
||||||
|
ipa_otpd_LDADD = $(top_builddir)/util/libutil.la
|
||||||
dist_noinst_DATA = ipa-otpd.socket.in ipa-otpd@.service.in test.py
|
dist_noinst_DATA = ipa-otpd.socket.in ipa-otpd@.service.in test.py
|
||||||
systemdsystemunit_DATA = ipa-otpd.socket ipa-otpd@.service
|
systemdsystemunit_DATA = ipa-otpd.socket ipa-otpd@.service
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "ipa_hostname.h"
|
||||||
|
|
||||||
/* Our global state. */
|
/* Our global state. */
|
||||||
struct otpd_context ctx;
|
struct otpd_context ctx;
|
||||||
@ -212,7 +213,7 @@ static krb5_error_code setup_ldap(const char *uri, krb5_boolean bind,
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char hostname[HOST_NAME_MAX + 1];
|
char hostname[IPA_HOST_NAME_LEN];
|
||||||
krb5_error_code retval;
|
krb5_error_code retval;
|
||||||
krb5_data hndata;
|
krb5_data hndata;
|
||||||
verto_ev *sig;
|
verto_ev *sig;
|
||||||
@ -227,7 +228,7 @@ int main(int argc, char **argv)
|
|||||||
memset(&ctx, 0, sizeof(ctx));
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
ctx.exitstatus = 1;
|
ctx.exitstatus = 1;
|
||||||
|
|
||||||
if (gethostname(hostname, sizeof(hostname)) < 0) {
|
if (ipa_gethostfqdn(hostname) < 0) {
|
||||||
otpd_log_err(errno, "Unable to get hostname");
|
otpd_log_err(errno, "Unable to get hostname");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ char *smb_xstrdup(const char *s);
|
|||||||
#include <sasl/sasl.h>
|
#include <sasl/sasl.h>
|
||||||
#include <krb5/krb5.h>
|
#include <krb5/krb5.h>
|
||||||
#include <sss_idmap.h>
|
#include <sss_idmap.h>
|
||||||
|
#include "ipa_hostname.h"
|
||||||
#include "ipa_asn1.h"
|
#include "ipa_asn1.h"
|
||||||
#include "ipa_pwd.h"
|
#include "ipa_pwd.h"
|
||||||
#include "ipa_mspac.h"
|
#include "ipa_mspac.h"
|
||||||
@ -4440,7 +4441,7 @@ static char *sec_key(TALLOC_CTX *mem_ctx, const char *d)
|
|||||||
|
|
||||||
static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
|
static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
|
||||||
{
|
{
|
||||||
char hostname[255];
|
char hostname[IPA_HOST_NAME_LEN];
|
||||||
int ret;
|
int ret;
|
||||||
char *p;
|
char *p;
|
||||||
TALLOC_CTX *tmp_ctx;
|
TALLOC_CTX *tmp_ctx;
|
||||||
@ -4466,13 +4467,12 @@ static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gethostname(hostname, sizeof(hostname));
|
ret = ipa_gethostfqdn(hostname);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
DEBUG(1, ("gethostname failed.\n"));
|
DEBUG(1, ("gethostname failed.\n"));
|
||||||
status = NT_STATUS_UNSUCCESSFUL;
|
status = NT_STATUS_UNSUCCESSFUL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
hostname[sizeof(hostname)-1] = '\0';
|
|
||||||
p = strchr(hostname, '.');
|
p = strchr(hostname, '.');
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
@ -4724,7 +4724,7 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state)
|
|||||||
int ret;
|
int ret;
|
||||||
krb5_context context;
|
krb5_context context;
|
||||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||||
char hostname[255];
|
char hostname[IPA_HOST_NAME_LEN];
|
||||||
char *default_realm = NULL;
|
char *default_realm = NULL;
|
||||||
|
|
||||||
if (!ipasam_state) {
|
if (!ipasam_state) {
|
||||||
@ -4736,12 +4736,11 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gethostname(hostname, sizeof(hostname));
|
ret = ipa_gethostfqdn(hostname);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
DEBUG(1, ("gethostname failed.\n"));
|
DEBUG(1, ("gethostname failed.\n"));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
hostname[sizeof(hostname)-1] = '\0';
|
|
||||||
|
|
||||||
rc = krb5_get_default_realm(context, &default_realm);
|
rc = krb5_get_default_realm(context, &default_realm);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -5,6 +5,7 @@ PLUGIN_COMMON_DIR = $(srcdir)/../common
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(srcdir) \
|
-I$(srcdir) \
|
||||||
-I$(PLUGIN_COMMON_DIR) \
|
-I$(PLUGIN_COMMON_DIR) \
|
||||||
|
-I$(top_srcdir)/util \
|
||||||
-DPREFIX=\""$(prefix)"\" \
|
-DPREFIX=\""$(prefix)"\" \
|
||||||
-DBINDIR=\""$(bindir)"\" \
|
-DBINDIR=\""$(bindir)"\" \
|
||||||
-DLIBDIR=\""$(libdir)"\" \
|
-DLIBDIR=\""$(libdir)"\" \
|
||||||
@ -31,6 +32,7 @@ libipa_cldap_la_SOURCES = \
|
|||||||
libipa_cldap_la_LDFLAGS = -avoid-version
|
libipa_cldap_la_LDFLAGS = -avoid-version
|
||||||
|
|
||||||
libipa_cldap_la_LIBADD = \
|
libipa_cldap_la_LIBADD = \
|
||||||
|
$(top_builddir)/util/libutil.la \
|
||||||
$(LDAP_LIBS) \
|
$(LDAP_LIBS) \
|
||||||
$(NDRNBT_LIBS) \
|
$(NDRNBT_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
@ -49,6 +51,7 @@ ipa_cldap_tests_LDFLAGS = \
|
|||||||
-rpath $(shell pkg-config --libs-only-L dirsrv | sed -e 's/-L//') \
|
-rpath $(shell pkg-config --libs-only-L dirsrv | sed -e 's/-L//') \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
ipa_cldap_tests_LDADD = \
|
ipa_cldap_tests_LDADD = \
|
||||||
|
$(top_builddir)/util/libutil.la \
|
||||||
$(CMOCKA_LIBS) \
|
$(CMOCKA_LIBS) \
|
||||||
$(NDRNBT_LIBS) \
|
$(NDRNBT_LIBS) \
|
||||||
$(DIRSRV_LIBS) \
|
$(DIRSRV_LIBS) \
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
* END COPYRIGHT BLOCK **/
|
* END COPYRIGHT BLOCK **/
|
||||||
|
|
||||||
#include "ipa_cldap.h"
|
#include "ipa_cldap.h"
|
||||||
|
#include "ipa_hostname.h"
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <talloc.h>
|
#include <talloc.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -236,7 +237,7 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx,
|
|||||||
struct ipa_cldap_req *req,
|
struct ipa_cldap_req *req,
|
||||||
struct berval *reply)
|
struct berval *reply)
|
||||||
{
|
{
|
||||||
char hostname[MAXHOSTNAMELEN + 1]; /* NOTE: lenght hardcoded in kernel */
|
char hostname[IPA_HOST_NAME_LEN];
|
||||||
char *domain = NULL;
|
char *domain = NULL;
|
||||||
char *our_domain = NULL;
|
char *our_domain = NULL;
|
||||||
char *guid = NULL;
|
char *guid = NULL;
|
||||||
@ -321,13 +322,11 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gethostname(hostname, MAXHOSTNAMELEN);
|
ret = ipa_gethostfqdn(hostname);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
ret = errno;
|
ret = errno;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Make double sure it is terminated */
|
|
||||||
hostname[MAXHOSTNAMELEN] = '\0';
|
|
||||||
dot = strchr(hostname, '.');
|
dot = strchr(hostname, '.');
|
||||||
if (!dot) {
|
if (!dot) {
|
||||||
/* this name is not fully qualified, therefore invalid */
|
/* this name is not fully qualified, therefore invalid */
|
||||||
|
@ -30,6 +30,7 @@ from ipaplatform.paths import paths
|
|||||||
from ipaserver.install import (replication, installutils, bindinstance,
|
from ipaserver.install import (replication, installutils, bindinstance,
|
||||||
cainstance)
|
cainstance)
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipalib.util import has_managed_topology
|
from ipalib.util import has_managed_topology
|
||||||
from ipapython import ipautil, ipaldap, version
|
from ipapython import ipautil, ipaldap, version
|
||||||
from ipapython.admintool import ScriptError
|
from ipapython.admintool import ScriptError
|
||||||
@ -343,7 +344,7 @@ def re_initialize(realm, options):
|
|||||||
if not options.fromhost:
|
if not options.fromhost:
|
||||||
sys.exit("re-initialize requires the option --from <host name>")
|
sys.exit("re-initialize requires the option --from <host name>")
|
||||||
|
|
||||||
thishost = installutils.get_fqdn()
|
thishost = FQDN
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repl = replication.get_cs_replication_manager(realm, options.fromhost,
|
repl = replication.get_cs_replication_manager(realm, options.fromhost,
|
||||||
@ -383,7 +384,7 @@ def force_sync(realm, thishost, fromhost, dirman_passwd):
|
|||||||
|
|
||||||
def set_renewal_master(realm, replica):
|
def set_renewal_master(realm, replica):
|
||||||
if not replica:
|
if not replica:
|
||||||
replica = installutils.get_fqdn()
|
replica = FQDN
|
||||||
|
|
||||||
ca = cainstance.CAInstance(realm)
|
ca = cainstance.CAInstance(realm)
|
||||||
if ca.is_renewal_master(replica):
|
if ca.is_renewal_master(replica):
|
||||||
@ -434,7 +435,7 @@ def main():
|
|||||||
if options.host:
|
if options.host:
|
||||||
host = options.host
|
host = options.host
|
||||||
else:
|
else:
|
||||||
host = installutils.get_fqdn()
|
host = FQDN
|
||||||
|
|
||||||
options.host = host
|
options.host = host
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import argparse
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import socket
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from custodia.message.kem import KEY_USAGE_SIG, KEY_USAGE_ENC, KEY_USAGE_MAP
|
from custodia.message.kem import KEY_USAGE_SIG, KEY_USAGE_ENC, KEY_USAGE_MAP
|
||||||
@ -136,7 +135,6 @@ class IPACustodiaTester:
|
|||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
self.status()
|
self.status()
|
||||||
self.check_fqdn()
|
|
||||||
self.check_files()
|
self.check_files()
|
||||||
self.check_client()
|
self.check_client()
|
||||||
self.check_jwk()
|
self.check_jwk()
|
||||||
@ -156,13 +154,6 @@ class IPACustodiaTester:
|
|||||||
if self.host == self.args.server:
|
if self.host == self.args.server:
|
||||||
self.warning("Performing self-test only.")
|
self.warning("Performing self-test only.")
|
||||||
|
|
||||||
def check_fqdn(self):
|
|
||||||
fqdn = socket.getfqdn()
|
|
||||||
if self.host != fqdn:
|
|
||||||
self.warning(
|
|
||||||
"socket.getfqdn() reports hostname '{}'".format(fqdn)
|
|
||||||
)
|
|
||||||
|
|
||||||
def check_files(self):
|
def check_files(self):
|
||||||
for filename in self.files:
|
for filename in self.files:
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
|
@ -28,6 +28,7 @@ from ipapython.dn import DN
|
|||||||
from ipapython import version
|
from ipapython import version
|
||||||
from ipapython import ipautil, certdb
|
from ipapython import ipautil, certdb
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipaserver.install import installutils
|
from ipaserver.install import installutils
|
||||||
# pylint: disable=deprecated-module
|
# pylint: disable=deprecated-module
|
||||||
from optparse import OptionGroup, OptionValueError
|
from optparse import OptionGroup, OptionValueError
|
||||||
@ -205,7 +206,7 @@ def parse_options():
|
|||||||
parser.error("No action: you should select either --replica or --master option.")
|
parser.error("No action: you should select either --replica or --master option.")
|
||||||
|
|
||||||
if not options.hostname:
|
if not options.hostname:
|
||||||
options.hostname = socket.getfqdn()
|
options.hostname = FQDN
|
||||||
|
|
||||||
return safe_options, options
|
return safe_options, options
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ from ipaserver.install import bindinstance, cainstance
|
|||||||
from ipaserver.install import opendnssecinstance, dnskeysyncinstance
|
from ipaserver.install import opendnssecinstance, dnskeysyncinstance
|
||||||
from ipapython import version, ipaldap
|
from ipapython import version, ipaldap
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipalib.util import has_managed_topology, verify_host_resolvable
|
from ipalib.util import has_managed_topology, verify_host_resolvable
|
||||||
from ipapython.ipa_log_manager import standard_logging_setup
|
from ipapython.ipa_log_manager import standard_logging_setup
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
@ -1525,7 +1526,7 @@ def main(options, args):
|
|||||||
if options.host:
|
if options.host:
|
||||||
host = options.host
|
host = options.host
|
||||||
else:
|
else:
|
||||||
host = installutils.get_fqdn()
|
host = FQDN
|
||||||
|
|
||||||
options.host = host
|
options.host = host
|
||||||
|
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import socket
|
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from dns import rdatatype
|
from dns import rdatatype
|
||||||
from dns.exception import DNSException
|
from dns.exception import DNSException
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipalib.util import validate_domain_name
|
from ipalib.util import validate_domain_name
|
||||||
from ipapython.dnsutil import query_srv, resolve
|
from ipapython.dnsutil import query_srv, resolve
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ class IPADiscovery:
|
|||||||
if not domain: # domain not provided do full DNS discovery
|
if not domain: # domain not provided do full DNS discovery
|
||||||
# get the local host name
|
# get the local host name
|
||||||
if not hostname:
|
if not hostname:
|
||||||
hostname = socket.getfqdn()
|
hostname = FQDN
|
||||||
logger.debug('Hostname: %s', hostname)
|
logger.debug('Hostname: %s', hostname)
|
||||||
if not hostname:
|
if not hostname:
|
||||||
return BAD_HOST_CONFIG
|
return BAD_HOST_CONFIG
|
||||||
|
@ -36,7 +36,7 @@ from urllib.parse import urlparse, urlunparse
|
|||||||
|
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib import sysrestore
|
from ipalib import sysrestore
|
||||||
from ipalib.constants import IPAAPI_USER, MAXHOSTNAMELEN
|
from ipalib.constants import FQDN, IPAAPI_USER, MAXHOSTNAMELEN
|
||||||
from ipalib.install import certmonger, certstore, service
|
from ipalib.install import certmonger, certstore, service
|
||||||
from ipalib.install import hostname as hostname_
|
from ipalib.install import hostname as hostname_
|
||||||
from ipalib.facts import is_ipa_client_configured, is_ipa_configured
|
from ipalib.facts import is_ipa_client_configured, is_ipa_configured
|
||||||
@ -2121,7 +2121,7 @@ def install_check(options):
|
|||||||
hostname = options.hostname
|
hostname = options.hostname
|
||||||
hostname_source = 'Provided as option'
|
hostname_source = 'Provided as option'
|
||||||
else:
|
else:
|
||||||
hostname = socket.getfqdn()
|
hostname = FQDN
|
||||||
hostname_source = "Machine's FQDN"
|
hostname_source = "Machine's FQDN"
|
||||||
if hostname != hostname.lower():
|
if hostname != hostname.lower():
|
||||||
raise ScriptError(
|
raise ScriptError(
|
||||||
@ -3270,7 +3270,7 @@ def uninstall(options):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if hostname is None:
|
if hostname is None:
|
||||||
hostname = socket.getfqdn()
|
hostname = FQDN
|
||||||
|
|
||||||
ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
|
ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
|
||||||
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
|
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
|
||||||
|
@ -23,18 +23,14 @@ All constants centralised in one file.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
from ipaplatform.constants import constants as _constants
|
from ipaplatform.constants import constants as _constants
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
|
from ipapython.fqdn import gethostfqdn
|
||||||
from ipapython.version import VERSION, API_VERSION
|
from ipapython.version import VERSION, API_VERSION
|
||||||
|
|
||||||
try:
|
|
||||||
FQDN = socket.getfqdn()
|
FQDN = gethostfqdn()
|
||||||
except Exception:
|
|
||||||
try:
|
|
||||||
FQDN = socket.gethostname()
|
|
||||||
except Exception:
|
|
||||||
FQDN = None
|
|
||||||
|
|
||||||
# TLS related constants
|
# TLS related constants
|
||||||
# * SSL2 and SSL3 are broken.
|
# * SSL2 and SSL3 are broken.
|
||||||
|
@ -25,7 +25,6 @@ from optparse import (
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from configparser import SafeConfigParser
|
from configparser import SafeConfigParser
|
||||||
from urllib.parse import urlsplit
|
from urllib.parse import urlsplit
|
||||||
import socket
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from dns.exception import DNSException
|
from dns.exception import DNSException
|
||||||
@ -211,8 +210,11 @@ def __discover_config(discover_server = True):
|
|||||||
servers = query_srv(name)
|
servers = query_srv(name)
|
||||||
except DNSException:
|
except DNSException:
|
||||||
# try cycling on domain components of FQDN
|
# try cycling on domain components of FQDN
|
||||||
|
# pylint: disable=ipa-forbidden-import
|
||||||
|
from ipalib.constants import FQDN
|
||||||
|
# pylint: enable=ipa-forbidden-import
|
||||||
try:
|
try:
|
||||||
domain = dns.name.from_text(socket.getfqdn())
|
domain = dns.name.from_text(FQDN)
|
||||||
except DNSException:
|
except DNSException:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
30
ipapython/fqdn.py
Normal file
30
ipapython/fqdn.py
Normal 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]
|
@ -30,11 +30,11 @@ import time
|
|||||||
|
|
||||||
from ipalib import api, _
|
from ipalib import api, _
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipapython import ipautil
|
from ipapython import ipautil
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.dnsutil import query_srv
|
from ipapython.dnsutil import query_srv
|
||||||
from ipapython.ipaldap import ldap_initialize
|
from ipapython.ipaldap import ldap_initialize
|
||||||
from ipaserver.install import installutils
|
|
||||||
from ipaserver.dcerpc_common import (TRUST_BIDIRECTIONAL,
|
from ipaserver.dcerpc_common import (TRUST_BIDIRECTIONAL,
|
||||||
TRUST_JOIN_EXTERNAL,
|
TRUST_JOIN_EXTERNAL,
|
||||||
trust_type_string)
|
trust_type_string)
|
||||||
@ -1645,7 +1645,7 @@ class TrustDomainJoins:
|
|||||||
ld.creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
|
ld.creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
|
||||||
ld.creds.guess(ld.parm)
|
ld.creds.guess(ld.parm)
|
||||||
ld.creds.set_workstation(ld.hostname)
|
ld.creds.set_workstation(ld.hostname)
|
||||||
ld.retrieve(installutils.get_fqdn())
|
ld.retrieve(FQDN)
|
||||||
self.local_domain = ld
|
self.local_domain = ld
|
||||||
|
|
||||||
def populate_remote_domain(self, realm, realm_server=None,
|
def populate_remote_domain(self, realm, realm_server=None,
|
||||||
|
@ -50,7 +50,7 @@ import ipaplatform
|
|||||||
from ipapython import ipautil, admintool, version, ipaldap
|
from ipapython import ipautil, admintool, version, ipaldap
|
||||||
from ipapython.admintool import ScriptError, SERVER_NOT_CONFIGURED # noqa: E402
|
from ipapython.admintool import ScriptError, SERVER_NOT_CONFIGURED # noqa: E402
|
||||||
from ipapython.certdb import EXTERNAL_CA_TRUST_FLAGS
|
from ipapython.certdb import EXTERNAL_CA_TRUST_FLAGS
|
||||||
from ipalib.constants import MAXHOSTNAMELEN
|
from ipalib.constants import FQDN, MAXHOSTNAMELEN
|
||||||
from ipalib.util import validate_hostname
|
from ipalib.util import validate_hostname
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib.install import dnsforwarders
|
from ipalib.install import dnsforwarders
|
||||||
@ -118,16 +118,16 @@ class ReplicaConfig:
|
|||||||
|
|
||||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||||
|
|
||||||
|
|
||||||
def get_fqdn():
|
def get_fqdn():
|
||||||
fqdn = ""
|
"""Get fully qualified domain name of current host
|
||||||
try:
|
|
||||||
fqdn = socket.getfqdn()
|
:note: used by ansible_freeipa
|
||||||
except Exception:
|
:deprecated: use ipalib.constants.FQDN
|
||||||
try:
|
:return: str
|
||||||
fqdn = socket.gethostname()
|
"""
|
||||||
except Exception:
|
return FQDN
|
||||||
fqdn = ""
|
|
||||||
return fqdn
|
|
||||||
|
|
||||||
def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
|
def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
|
||||||
"""
|
"""
|
||||||
|
@ -24,9 +24,9 @@ import ldap.schema
|
|||||||
|
|
||||||
import ipapython.version
|
import ipapython.version
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipaserver.install.ldapupdate import connect
|
from ipaserver.install.ldapupdate import connect
|
||||||
from ipaserver.install import installutils
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMA_ELEMENT_CLASSES = (
|
SCHEMA_ELEMENT_CLASSES = (
|
||||||
@ -105,9 +105,7 @@ def update_schema(schema_files, ldapi=False):
|
|||||||
"""
|
"""
|
||||||
SCHEMA_ELEMENT_CLASSES_KEYS = [x[0] for x in SCHEMA_ELEMENT_CLASSES]
|
SCHEMA_ELEMENT_CLASSES_KEYS = [x[0] for x in SCHEMA_ELEMENT_CLASSES]
|
||||||
|
|
||||||
conn = connect(ldapi=ldapi,
|
conn = connect(ldapi=ldapi, realm=api.env.realm, fqdn=FQDN)
|
||||||
realm=api.env.realm,
|
|
||||||
fqdn=installutils.get_fqdn())
|
|
||||||
|
|
||||||
old_schema = conn.schema
|
old_schema = conn.schema
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ from ipaplatform import services
|
|||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipaplatform.tasks import tasks
|
from ipaplatform.tasks import tasks
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib.constants import DOMAIN_LEVEL_0
|
from ipalib.constants import DOMAIN_LEVEL_0, FQDN
|
||||||
from ipalib.facts import is_ipa_configured, is_ipa_client_configured
|
from ipalib.facts import is_ipa_configured, is_ipa_client_configured
|
||||||
from ipalib.util import (
|
from ipalib.util import (
|
||||||
validate_domain_name,
|
validate_domain_name,
|
||||||
@ -44,7 +44,7 @@ from ipaserver.install import (
|
|||||||
otpdinstance, custodiainstance, replication, service,
|
otpdinstance, custodiainstance, replication, service,
|
||||||
sysupgrade, cainstance)
|
sysupgrade, cainstance)
|
||||||
from ipaserver.install.installutils import (
|
from ipaserver.install.installutils import (
|
||||||
BadHostError, get_fqdn, get_server_ip_address,
|
BadHostError, get_server_ip_address,
|
||||||
load_pkcs12, read_password, verify_fqdn, update_hosts_file,
|
load_pkcs12, read_password, verify_fqdn, update_hosts_file,
|
||||||
validate_mask)
|
validate_mask)
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ def install_check(installer):
|
|||||||
if options.host_name:
|
if options.host_name:
|
||||||
host_default = options.host_name
|
host_default = options.host_name
|
||||||
else:
|
else:
|
||||||
host_default = get_fqdn()
|
host_default = FQDN
|
||||||
|
|
||||||
if installer.interactive and not options.host_name:
|
if installer.interactive and not options.host_name:
|
||||||
host_name = read_host_name(host_default)
|
host_name = read_host_name(host_default)
|
||||||
|
@ -22,7 +22,6 @@ from __future__ import absolute_import
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -35,6 +34,7 @@ from ipapython import ipautil
|
|||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython import kerberos
|
from ipapython import kerberos
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.constants import User
|
from ipaplatform.constants import User
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
@ -291,7 +291,7 @@ class Service:
|
|||||||
self.steps = []
|
self.steps = []
|
||||||
self.output_fd = sys.stdout
|
self.output_fd = sys.stdout
|
||||||
|
|
||||||
self.fqdn = socket.gethostname()
|
self.fqdn = FQDN
|
||||||
|
|
||||||
if sstore:
|
if sstore:
|
||||||
self.sstore = sstore
|
self.sstore = sstore
|
||||||
|
@ -28,8 +28,8 @@ import pytest
|
|||||||
|
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
|
from ipalib.constants import FQDN
|
||||||
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax
|
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax
|
||||||
from ipaserver.install import installutils
|
|
||||||
from ipapython import ipaldap
|
from ipapython import ipaldap
|
||||||
from ipaplatform.constants import constants as platformconstants
|
from ipaplatform.constants import constants as platformconstants
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
@ -56,7 +56,6 @@ class TestUpdate:
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def update_setup(self, request):
|
def update_setup(self, request):
|
||||||
fqdn = installutils.get_fqdn()
|
|
||||||
pwfile = api.env.dot_ipa + os.sep + ".dmpw"
|
pwfile = api.env.dot_ipa + os.sep + ".dmpw"
|
||||||
if os.path.isfile(pwfile):
|
if os.path.isfile(pwfile):
|
||||||
with open(pwfile, "r") as fp:
|
with open(pwfile, "r") as fp:
|
||||||
@ -64,7 +63,7 @@ class TestUpdate:
|
|||||||
else:
|
else:
|
||||||
pytest.skip("No directory manager password")
|
pytest.skip("No directory manager password")
|
||||||
self.updater = LDAPUpdate()
|
self.updater = LDAPUpdate()
|
||||||
self.ld = ipaldap.LDAPClient.from_hostname_secure(fqdn)
|
self.ld = ipaldap.LDAPClient.from_hostname_secure(FQDN)
|
||||||
self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
|
self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
|
||||||
bind_password=self.dm_password)
|
bind_password=self.dm_password)
|
||||||
self.testdir = os.path.abspath(os.path.dirname(__file__))
|
self.testdir = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
|
NULL =
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = 1.7 subdir-objects
|
AUTOMAKE_OPTIONS = 1.7 subdir-objects
|
||||||
|
|
||||||
AM_CPPFLAGS = $(CRYPTO_CFLAGS) $(KRB5_CFLAGS) $(LDAP_CFLAGS) $(PWQUALITY_CFLAGS)
|
AM_CPPFLAGS = $(CRYPTO_CFLAGS) $(KRB5_CFLAGS) $(LDAP_CFLAGS) $(PWQUALITY_CFLAGS)
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libutil.la
|
noinst_LTLIBRARIES = libutil.la
|
||||||
|
|
||||||
libutil_la_SOURCES = ipa_krb5.c \
|
libutil_la_SOURCES = \
|
||||||
|
ipa_hostname.c \
|
||||||
|
ipa_hostname.h \
|
||||||
|
ipa_krb5.c \
|
||||||
ipa_krb5.h \
|
ipa_krb5.h \
|
||||||
ipa_mspac.h \
|
ipa_mspac.h \
|
||||||
ipa_ldap.c \
|
ipa_ldap.c \
|
||||||
ipa_ldap.h \
|
ipa_ldap.h \
|
||||||
ipa_pwd.c \
|
ipa_pwd.c \
|
||||||
ipa_pwd.h \
|
ipa_pwd.h \
|
||||||
ipa_pwd_ntlm.c
|
ipa_pwd_ntlm.c \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
libutil_la_LIBADD = $(CRYPTO_LIBS) $(KRB5_LIBS) $(LDAP_LIBS) $(PWQUALITY_LIBS)
|
libutil_la_LIBADD = $(CRYPTO_LIBS) $(KRB5_LIBS) $(LDAP_LIBS) $(PWQUALITY_LIBS)
|
||||||
|
|
||||||
|
111
util/ipa_hostname.c
Normal file
111
util/ipa_hostname.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "ipa_hostname.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ipa_gethostname(char *name)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = gethostname(name, IPA_HOST_NAME_LEN - 1);
|
||||||
|
|
||||||
|
/* Make double sure it is terminated */
|
||||||
|
name[IPA_HOST_NAME_LEN - 1] = '\0';
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_get_fqdn(char *fqdn)
|
||||||
|
{
|
||||||
|
char hostname[IPA_HOST_NAME_LEN];
|
||||||
|
char *canonname = NULL;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *ai = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = ipa_gethostname(hostname);
|
||||||
|
if (r != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
|
/* use IPv4 or IPv6 */
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
/* optimize, RAW and STREAM return same kind of information */
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
/* any protocol */
|
||||||
|
hints.ai_protocol = 0;
|
||||||
|
/* get canonical name
|
||||||
|
* only use IPv4/6 when at least one interface for proto is configured */
|
||||||
|
hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
|
||||||
|
|
||||||
|
r = getaddrinfo(hostname, NULL, &hints, &ai);
|
||||||
|
if (r != 0) {
|
||||||
|
/* getaddrinfo() for gethostname() should never fail. The
|
||||||
|
* nss-myhostname provider should always add a positive match. */
|
||||||
|
errno = ENOENT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only the first addrinfo struct holds a canonical name value */
|
||||||
|
canonname = ai->ai_canonname;
|
||||||
|
|
||||||
|
/* check that canon name is filled and not too long */
|
||||||
|
if (!canonname) {
|
||||||
|
errno = ENOENT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (strlen(canonname) >= IPA_HOST_NAME_LEN) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
/* refuse non-qualified short names and localhost */
|
||||||
|
if ((strchr(canonname, '.') == NULL) ||
|
||||||
|
(strcasecmp(canonname, "localhost.localdomain") == 0)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcpy(fqdn, canonname);
|
||||||
|
/* Make double sure it is terminated */
|
||||||
|
fqdn[IPA_HOST_NAME_LEN - 1] = '\0';
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
fqdn[0] = '\0';
|
||||||
|
if (ai != NULL) {
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipa_gethostfqdn(char *name)
|
||||||
|
{
|
||||||
|
static char cached_fqdn[IPA_HOST_NAME_LEN] = {0};
|
||||||
|
|
||||||
|
if (!cached_fqdn) {
|
||||||
|
int res = _get_fqdn(cached_fqdn);
|
||||||
|
if (res != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy(name, cached_fqdn);
|
||||||
|
return 0;
|
||||||
|
}
|
19
util/ipa_hostname.h
Normal file
19
util/ipa_hostname.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* host name length including NULL byte
|
||||||
|
*
|
||||||
|
* NOTE: length hardcoded in kernel
|
||||||
|
*/
|
||||||
|
#define IPA_HOST_NAME_LEN (HOST_NAME_MAX + 1)
|
||||||
|
|
||||||
|
int
|
||||||
|
ipa_gethostname(char *name);
|
||||||
|
|
||||||
|
int
|
||||||
|
ipa_gethostfqdn(char *name);
|
Loading…
Reference in New Issue
Block a user