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_LDFLAGS := @LDAP_LIBS@ @LIBVERTO_LIBS@ @KRAD_LIBS@ @KRB5_LIBS@
|
||||
|
||||
noinst_HEADERS = internal.h
|
||||
appdir = $(libexecdir)/ipa/
|
||||
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
|
||||
systemdsystemunit_DATA = ipa-otpd.socket ipa-otpd@.service
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include "ipa_hostname.h"
|
||||
|
||||
/* Our global state. */
|
||||
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)
|
||||
{
|
||||
char hostname[HOST_NAME_MAX + 1];
|
||||
char hostname[IPA_HOST_NAME_LEN];
|
||||
krb5_error_code retval;
|
||||
krb5_data hndata;
|
||||
verto_ev *sig;
|
||||
@ -227,7 +228,7 @@ int main(int argc, char **argv)
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.exitstatus = 1;
|
||||
|
||||
if (gethostname(hostname, sizeof(hostname)) < 0) {
|
||||
if (ipa_gethostfqdn(hostname) < 0) {
|
||||
otpd_log_err(errno, "Unable to get hostname");
|
||||
goto error;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ char *smb_xstrdup(const char *s);
|
||||
#include <sasl/sasl.h>
|
||||
#include <krb5/krb5.h>
|
||||
#include <sss_idmap.h>
|
||||
#include "ipa_hostname.h"
|
||||
#include "ipa_asn1.h"
|
||||
#include "ipa_pwd.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)
|
||||
{
|
||||
char hostname[255];
|
||||
char hostname[IPA_HOST_NAME_LEN];
|
||||
int ret;
|
||||
char *p;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
@ -4466,13 +4467,12 @@ static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = gethostname(hostname, sizeof(hostname));
|
||||
ret = ipa_gethostfqdn(hostname);
|
||||
if (ret == -1) {
|
||||
DEBUG(1, ("gethostname failed.\n"));
|
||||
status = NT_STATUS_UNSUCCESSFUL;
|
||||
goto done;
|
||||
}
|
||||
hostname[sizeof(hostname)-1] = '\0';
|
||||
p = strchr(hostname, '.');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
@ -4724,7 +4724,7 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state)
|
||||
int ret;
|
||||
krb5_context context;
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
char hostname[255];
|
||||
char hostname[IPA_HOST_NAME_LEN];
|
||||
char *default_realm = NULL;
|
||||
|
||||
if (!ipasam_state) {
|
||||
@ -4736,12 +4736,11 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state)
|
||||
return status;
|
||||
}
|
||||
|
||||
ret = gethostname(hostname, sizeof(hostname));
|
||||
ret = ipa_gethostfqdn(hostname);
|
||||
if (ret == -1) {
|
||||
DEBUG(1, ("gethostname failed.\n"));
|
||||
goto done;
|
||||
}
|
||||
hostname[sizeof(hostname)-1] = '\0';
|
||||
|
||||
rc = krb5_get_default_realm(context, &default_realm);
|
||||
if (rc) {
|
||||
|
@ -5,6 +5,7 @@ PLUGIN_COMMON_DIR = $(srcdir)/../common
|
||||
AM_CPPFLAGS = \
|
||||
-I$(srcdir) \
|
||||
-I$(PLUGIN_COMMON_DIR) \
|
||||
-I$(top_srcdir)/util \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DBINDIR=\""$(bindir)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
@ -31,6 +32,7 @@ libipa_cldap_la_SOURCES = \
|
||||
libipa_cldap_la_LDFLAGS = -avoid-version
|
||||
|
||||
libipa_cldap_la_LIBADD = \
|
||||
$(top_builddir)/util/libutil.la \
|
||||
$(LDAP_LIBS) \
|
||||
$(NDRNBT_LIBS) \
|
||||
$(NULL)
|
||||
@ -49,6 +51,7 @@ ipa_cldap_tests_LDFLAGS = \
|
||||
-rpath $(shell pkg-config --libs-only-L dirsrv | sed -e 's/-L//') \
|
||||
$(NULL)
|
||||
ipa_cldap_tests_LDADD = \
|
||||
$(top_builddir)/util/libutil.la \
|
||||
$(CMOCKA_LIBS) \
|
||||
$(NDRNBT_LIBS) \
|
||||
$(DIRSRV_LIBS) \
|
||||
|
@ -38,6 +38,7 @@
|
||||
* END COPYRIGHT BLOCK **/
|
||||
|
||||
#include "ipa_cldap.h"
|
||||
#include "ipa_hostname.h"
|
||||
#include <endian.h>
|
||||
#include <talloc.h>
|
||||
#include <ctype.h>
|
||||
@ -236,7 +237,7 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx,
|
||||
struct ipa_cldap_req *req,
|
||||
struct berval *reply)
|
||||
{
|
||||
char hostname[MAXHOSTNAMELEN + 1]; /* NOTE: lenght hardcoded in kernel */
|
||||
char hostname[IPA_HOST_NAME_LEN];
|
||||
char *domain = NULL;
|
||||
char *our_domain = NULL;
|
||||
char *guid = NULL;
|
||||
@ -321,13 +322,11 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = gethostname(hostname, MAXHOSTNAMELEN);
|
||||
ret = ipa_gethostfqdn(hostname);
|
||||
if (ret == -1) {
|
||||
ret = errno;
|
||||
goto done;
|
||||
}
|
||||
/* Make double sure it is terminated */
|
||||
hostname[MAXHOSTNAMELEN] = '\0';
|
||||
dot = strchr(hostname, '.');
|
||||
if (!dot) {
|
||||
/* this name is not fully qualified, therefore invalid */
|
||||
|
@ -30,6 +30,7 @@ from ipaplatform.paths import paths
|
||||
from ipaserver.install import (replication, installutils, bindinstance,
|
||||
cainstance)
|
||||
from ipalib import api, errors
|
||||
from ipalib.constants import FQDN
|
||||
from ipalib.util import has_managed_topology
|
||||
from ipapython import ipautil, ipaldap, version
|
||||
from ipapython.admintool import ScriptError
|
||||
@ -343,7 +344,7 @@ def re_initialize(realm, options):
|
||||
if not options.fromhost:
|
||||
sys.exit("re-initialize requires the option --from <host name>")
|
||||
|
||||
thishost = installutils.get_fqdn()
|
||||
thishost = FQDN
|
||||
|
||||
try:
|
||||
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):
|
||||
if not replica:
|
||||
replica = installutils.get_fqdn()
|
||||
replica = FQDN
|
||||
|
||||
ca = cainstance.CAInstance(realm)
|
||||
if ca.is_renewal_master(replica):
|
||||
@ -434,7 +435,7 @@ def main():
|
||||
if options.host:
|
||||
host = options.host
|
||||
else:
|
||||
host = installutils.get_fqdn()
|
||||
host = FQDN
|
||||
|
||||
options.host = host
|
||||
|
||||
|
@ -9,7 +9,6 @@ import argparse
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import socket
|
||||
import warnings
|
||||
|
||||
from custodia.message.kem import KEY_USAGE_SIG, KEY_USAGE_ENC, KEY_USAGE_MAP
|
||||
@ -136,7 +135,6 @@ class IPACustodiaTester:
|
||||
|
||||
def check(self):
|
||||
self.status()
|
||||
self.check_fqdn()
|
||||
self.check_files()
|
||||
self.check_client()
|
||||
self.check_jwk()
|
||||
@ -156,13 +154,6 @@ class IPACustodiaTester:
|
||||
if self.host == self.args.server:
|
||||
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):
|
||||
for filename in self.files:
|
||||
if not os.path.isfile(filename):
|
||||
|
@ -28,6 +28,7 @@ from ipapython.dn import DN
|
||||
from ipapython import version
|
||||
from ipapython import ipautil, certdb
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib.constants import FQDN
|
||||
from ipaserver.install import installutils
|
||||
# pylint: disable=deprecated-module
|
||||
from optparse import OptionGroup, OptionValueError
|
||||
@ -205,7 +206,7 @@ def parse_options():
|
||||
parser.error("No action: you should select either --replica or --master option.")
|
||||
|
||||
if not options.hostname:
|
||||
options.hostname = socket.getfqdn()
|
||||
options.hostname = FQDN
|
||||
|
||||
return safe_options, options
|
||||
|
||||
|
@ -38,6 +38,7 @@ from ipaserver.install import bindinstance, cainstance
|
||||
from ipaserver.install import opendnssecinstance, dnskeysyncinstance
|
||||
from ipapython import version, ipaldap
|
||||
from ipalib import api, errors
|
||||
from ipalib.constants import FQDN
|
||||
from ipalib.util import has_managed_topology, verify_host_resolvable
|
||||
from ipapython.ipa_log_manager import standard_logging_setup
|
||||
from ipapython.dn import DN
|
||||
@ -1525,7 +1526,7 @@ def main(options, args):
|
||||
if options.host:
|
||||
host = options.host
|
||||
else:
|
||||
host = installutils.get_fqdn()
|
||||
host = FQDN
|
||||
|
||||
options.host = host
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import socket
|
||||
|
||||
import six
|
||||
|
||||
from dns import rdatatype
|
||||
from dns.exception import DNSException
|
||||
from ipalib import errors
|
||||
from ipalib.constants import FQDN
|
||||
from ipalib.util import validate_domain_name
|
||||
from ipapython.dnsutil import query_srv, resolve
|
||||
|
||||
@ -222,7 +222,7 @@ class IPADiscovery:
|
||||
if not domain: # domain not provided do full DNS discovery
|
||||
# get the local host name
|
||||
if not hostname:
|
||||
hostname = socket.getfqdn()
|
||||
hostname = FQDN
|
||||
logger.debug('Hostname: %s', hostname)
|
||||
if not hostname:
|
||||
return BAD_HOST_CONFIG
|
||||
|
@ -36,7 +36,7 @@ from urllib.parse import urlparse, urlunparse
|
||||
|
||||
from ipalib import api, errors, x509
|
||||
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 hostname as hostname_
|
||||
from ipalib.facts import is_ipa_client_configured, is_ipa_configured
|
||||
@ -2121,7 +2121,7 @@ def install_check(options):
|
||||
hostname = options.hostname
|
||||
hostname_source = 'Provided as option'
|
||||
else:
|
||||
hostname = socket.getfqdn()
|
||||
hostname = FQDN
|
||||
hostname_source = "Machine's FQDN"
|
||||
if hostname != hostname.lower():
|
||||
raise ScriptError(
|
||||
@ -3270,7 +3270,7 @@ def uninstall(options):
|
||||
pass
|
||||
|
||||
if hostname is None:
|
||||
hostname = socket.getfqdn()
|
||||
hostname = FQDN
|
||||
|
||||
ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
|
||||
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
|
||||
|
@ -23,18 +23,14 @@ All constants centralised in one file.
|
||||
"""
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
||||
from ipaplatform.constants import constants as _constants
|
||||
from ipapython.dn import DN
|
||||
from ipapython.fqdn import gethostfqdn
|
||||
from ipapython.version import VERSION, API_VERSION
|
||||
|
||||
try:
|
||||
FQDN = socket.getfqdn()
|
||||
except Exception:
|
||||
try:
|
||||
FQDN = socket.gethostname()
|
||||
except Exception:
|
||||
FQDN = None
|
||||
|
||||
FQDN = gethostfqdn()
|
||||
|
||||
# TLS related constants
|
||||
# * SSL2 and SSL3 are broken.
|
||||
|
@ -25,7 +25,6 @@ from optparse import (
|
||||
from copy import copy
|
||||
from configparser import SafeConfigParser
|
||||
from urllib.parse import urlsplit
|
||||
import socket
|
||||
import functools
|
||||
|
||||
from dns.exception import DNSException
|
||||
@ -211,8 +210,11 @@ def __discover_config(discover_server = True):
|
||||
servers = query_srv(name)
|
||||
except DNSException:
|
||||
# try cycling on domain components of FQDN
|
||||
# pylint: disable=ipa-forbidden-import
|
||||
from ipalib.constants import FQDN
|
||||
# pylint: enable=ipa-forbidden-import
|
||||
try:
|
||||
domain = dns.name.from_text(socket.getfqdn())
|
||||
domain = dns.name.from_text(FQDN)
|
||||
except DNSException:
|
||||
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 errors
|
||||
from ipalib.constants import FQDN
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
from ipapython.dnsutil import query_srv
|
||||
from ipapython.ipaldap import ldap_initialize
|
||||
from ipaserver.install import installutils
|
||||
from ipaserver.dcerpc_common import (TRUST_BIDIRECTIONAL,
|
||||
TRUST_JOIN_EXTERNAL,
|
||||
trust_type_string)
|
||||
@ -1645,7 +1645,7 @@ class TrustDomainJoins:
|
||||
ld.creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
|
||||
ld.creds.guess(ld.parm)
|
||||
ld.creds.set_workstation(ld.hostname)
|
||||
ld.retrieve(installutils.get_fqdn())
|
||||
ld.retrieve(FQDN)
|
||||
self.local_domain = ld
|
||||
|
||||
def populate_remote_domain(self, realm, realm_server=None,
|
||||
|
@ -50,7 +50,7 @@ import ipaplatform
|
||||
from ipapython import ipautil, admintool, version, ipaldap
|
||||
from ipapython.admintool import ScriptError, SERVER_NOT_CONFIGURED # noqa: E402
|
||||
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 import api, errors, x509
|
||||
from ipalib.install import dnsforwarders
|
||||
@ -118,16 +118,16 @@ class ReplicaConfig:
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
|
||||
def get_fqdn():
|
||||
fqdn = ""
|
||||
try:
|
||||
fqdn = socket.getfqdn()
|
||||
except Exception:
|
||||
try:
|
||||
fqdn = socket.gethostname()
|
||||
except Exception:
|
||||
fqdn = ""
|
||||
return fqdn
|
||||
"""Get fully qualified domain name of current host
|
||||
|
||||
:note: used by ansible_freeipa
|
||||
:deprecated: use ipalib.constants.FQDN
|
||||
:return: str
|
||||
"""
|
||||
return FQDN
|
||||
|
||||
|
||||
def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
|
||||
"""
|
||||
|
@ -24,9 +24,9 @@ import ldap.schema
|
||||
|
||||
import ipapython.version
|
||||
from ipalib import api
|
||||
from ipalib.constants import FQDN
|
||||
from ipapython.dn import DN
|
||||
from ipaserver.install.ldapupdate import connect
|
||||
from ipaserver.install import installutils
|
||||
|
||||
|
||||
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]
|
||||
|
||||
conn = connect(ldapi=ldapi,
|
||||
realm=api.env.realm,
|
||||
fqdn=installutils.get_fqdn())
|
||||
conn = connect(ldapi=ldapi, realm=api.env.realm, fqdn=FQDN)
|
||||
|
||||
old_schema = conn.schema
|
||||
|
||||
|
@ -31,7 +31,7 @@ from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.tasks import tasks
|
||||
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.util import (
|
||||
validate_domain_name,
|
||||
@ -44,7 +44,7 @@ from ipaserver.install import (
|
||||
otpdinstance, custodiainstance, replication, service,
|
||||
sysupgrade, cainstance)
|
||||
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,
|
||||
validate_mask)
|
||||
|
||||
@ -493,7 +493,7 @@ def install_check(installer):
|
||||
if options.host_name:
|
||||
host_default = options.host_name
|
||||
else:
|
||||
host_default = get_fqdn()
|
||||
host_default = FQDN
|
||||
|
||||
if installer.interactive and not options.host_name:
|
||||
host_name = read_host_name(host_default)
|
||||
|
@ -22,7 +22,6 @@ from __future__ import absolute_import
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
import traceback
|
||||
import tempfile
|
||||
@ -35,6 +34,7 @@ from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
from ipapython import kerberos
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib.constants import FQDN
|
||||
from ipaplatform import services
|
||||
from ipaplatform.constants import User
|
||||
from ipaplatform.paths import paths
|
||||
@ -291,7 +291,7 @@ class Service:
|
||||
self.steps = []
|
||||
self.output_fd = sys.stdout
|
||||
|
||||
self.fqdn = socket.gethostname()
|
||||
self.fqdn = FQDN
|
||||
|
||||
if sstore:
|
||||
self.sstore = sstore
|
||||
|
@ -28,8 +28,8 @@ import pytest
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import errors
|
||||
from ipalib.constants import FQDN
|
||||
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax
|
||||
from ipaserver.install import installutils
|
||||
from ipapython import ipaldap
|
||||
from ipaplatform.constants import constants as platformconstants
|
||||
from ipapython.dn import DN
|
||||
@ -56,7 +56,6 @@ class TestUpdate:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def update_setup(self, request):
|
||||
fqdn = installutils.get_fqdn()
|
||||
pwfile = api.env.dot_ipa + os.sep + ".dmpw"
|
||||
if os.path.isfile(pwfile):
|
||||
with open(pwfile, "r") as fp:
|
||||
@ -64,7 +63,7 @@ class TestUpdate:
|
||||
else:
|
||||
pytest.skip("No directory manager password")
|
||||
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,
|
||||
bind_password=self.dm_password)
|
||||
self.testdir = os.path.abspath(os.path.dirname(__file__))
|
||||
|
@ -1,17 +1,23 @@
|
||||
NULL =
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.7 subdir-objects
|
||||
|
||||
AM_CPPFLAGS = $(CRYPTO_CFLAGS) $(KRB5_CFLAGS) $(LDAP_CFLAGS) $(PWQUALITY_CFLAGS)
|
||||
|
||||
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_mspac.h \
|
||||
ipa_ldap.c \
|
||||
ipa_ldap.h \
|
||||
ipa_pwd.c \
|
||||
ipa_pwd.h \
|
||||
ipa_pwd_ntlm.c
|
||||
ipa_pwd_ntlm.c \
|
||||
$(NULL)
|
||||
|
||||
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