[Pkg-freeipa-devel] freeipa: Changes to 'upstream'
Timo Aaltonen
tjaalton at moszumanska.debian.org
Mon Aug 29 23:29:52 UTC 2016
Rebased ref, commits from common ancestor:
commit 78a6434e323ebc357472745d97627065ae5b8169
Author: Petr Vobornik <pvoborni at redhat.com>
Date: Fri Jul 22 15:46:51 2016 +0200
Become IPA 4.3.2
diff --git a/VERSION b/VERSION
index 92ecb6d..e135abf 100644
--- a/VERSION
+++ b/VERSION
@@ -21,7 +21,7 @@
########################################################
IPA_VERSION_MAJOR=4
IPA_VERSION_MINOR=3
-IPA_VERSION_RELEASE=1
+IPA_VERSION_RELEASE=2
########################################################
# For 'alpha' releases the version will be #
commit 64bbbb52a20200025017d0b29c9fa2dcdd7ad83d
Author: Martin Basti <mbasti at redhat.com>
Date: Thu Jul 21 18:49:57 2016 +0200
Use copy when replacing files to keep SELinux context
When installer replaces any file with newer, it must use 'copy' instead of
'mv' to keep SELinux context valid.
https://fedorahosted.org/freeipa/ticket/6111
Reviewed-By: Petr Spacek <pspacek at redhat.com>
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index b329cdb..1a868b1 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -539,10 +539,14 @@ def dir_exists(filename):
except:
return False
+
def install_file(fname, dest):
+ # SELinux: use copy to keep the right context
if file_exists(dest):
os.rename(dest, dest + ".orig")
- shutil.move(fname, dest)
+ shutil.copy(fname, dest)
+ os.remove(fname)
+
def backup_file(fname):
if file_exists(fname):
commit 268d835556e677c80501349fc96a531ccd63f3f6
Author: Florence Blanc-Renaud <flo at redhat.com>
Date: Thu Jul 21 16:54:43 2016 +0200
Fix session cookies
The CLI was not using session cookies for communication with IPA API.
The kernel_keyring code was expecting the keyname to be a string, but
in python 2 a unicode was supplied (the key is built using
ipa_session_cookie:%principal and principal is a unicode).
The patch fixes the assertions, allowing to store and retrieve the cookie.
It also adds a test with unicode key name.
https://fedorahosted.org/freeipa/ticket/5984
Reviewed-By: Petr Spacek <pspacek at redhat.com>
diff --git a/ipapython/kernel_keyring.py b/ipapython/kernel_keyring.py
index ed4868a..651fd70 100644
--- a/ipapython/kernel_keyring.py
+++ b/ipapython/kernel_keyring.py
@@ -18,6 +18,7 @@
#
import os
+import six
from ipapython.ipautil import run
@@ -45,7 +46,7 @@ def get_real_key(key):
One cannot request a key based on the description it was created with
so find the one we're looking for.
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
result = run(['keyctl', 'search', KEYRING, KEYTYPE, key],
raiseonerr=False, capture_output=True)
if result.returncode:
@@ -53,7 +54,7 @@ def get_real_key(key):
return result.raw_output.rstrip()
def get_persistent_key(key):
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
result = run(['keyctl', 'get_persistent', KEYRING, key],
raiseonerr=False, capture_output=True)
if result.returncode:
@@ -73,7 +74,7 @@ def has_key(key):
"""
Returns True/False whether the key exists in the keyring.
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
try:
get_real_key(key)
return True
@@ -86,7 +87,7 @@ def read_key(key):
Use pipe instead of print here to ensure we always get the raw data.
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
real_key = get_real_key(key)
result = run(['keyctl', 'pipe', real_key], raiseonerr=False,
capture_output=True)
@@ -99,7 +100,7 @@ def update_key(key, value):
"""
Update the keyring data. If they key doesn't exist it is created.
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
assert isinstance(value, bytes)
if has_key(key):
real_key = get_real_key(key)
@@ -114,7 +115,7 @@ def add_key(key, value):
"""
Add a key to the kernel keyring.
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
assert isinstance(value, bytes)
if has_key(key):
raise ValueError('key %s already exists' % key)
@@ -127,7 +128,7 @@ def del_key(key):
"""
Remove a key from the keyring
"""
- assert isinstance(key, str)
+ assert isinstance(key, six.string_types)
real_key = get_real_key(key)
result = run(['keyctl', 'unlink', real_key, KEYRING],
raiseonerr=False)
diff --git a/ipatests/test_ipapython/test_keyring.py b/ipatests/test_ipapython/test_keyring.py
index 02fd29e..5ab5191 100644
--- a/ipatests/test_ipapython/test_keyring.py
+++ b/ipatests/test_ipapython/test_keyring.py
@@ -28,6 +28,7 @@ import pytest
pytestmark = pytest.mark.tier0
TEST_KEY = 'ipa_test'
+TEST_UNICODEKEY = u'ipa_unicode'
TEST_VALUE = b'abc123'
UPDATE_VALUE = b'123abc'
@@ -49,6 +50,10 @@ class test_keyring(object):
kernel_keyring.del_key(SIZE_256)
except ValueError:
pass
+ try:
+ kernel_keyring.del_key(TEST_UNICODEKEY)
+ except ValueError:
+ pass
def test_01(self):
"""
@@ -150,3 +155,13 @@ class test_keyring(object):
assert(result == SIZE_1024.encode('ascii'))
kernel_keyring.del_key(TEST_KEY)
+
+ def test_10(self):
+ """
+ Test a unicode key
+ """
+ kernel_keyring.add_key(TEST_UNICODEKEY, TEST_VALUE)
+ result = kernel_keyring.read_key(TEST_UNICODEKEY)
+ assert(result == TEST_VALUE)
+
+ kernel_keyring.del_key(TEST_UNICODEKEY)
commit 844364bd2770b267c6e913de75b7caa926489c75
Author: Oleg Fayans <ofayans at redhat.com>
Date: Fri Jul 1 16:52:22 2016 +0200
Test for incorrect client domain
https://fedorahosted.org/freeipa/ticket/5976
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index 1f683b6..7bc1d52 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -377,3 +377,55 @@ class TestOldReplicaWorksAfterDomainUpgrade(IntegrationTest):
result1 = self.master.run_command(['ipa', 'user-show', self.username],
raiseonerr=False)
assert_error(result1, "%s: user not found" % self.username, 2)
+
+
+class TestWrongClientDomain(IntegrationTest):
+ topology = "star"
+ num_clients = 1
+ domain_name = 'exxample.test'
+
+ @classmethod
+ def install(cls, mh):
+ tasks.install_master(cls.master, domain_level=cls.domain_level)
+
+ def teardown_method(self, method):
+ self.clients[0].run_command(['ipa-client-install',
+ '--uninstall', '-U'],
+ raiseonerr=False)
+ tasks.kinit_admin(self.master)
+ self.master.run_command(['ipa', 'host-del',
+ self.clients[0].hostname],
+ raiseonerr=False)
+
+ def test_wrong_client_domain(self):
+ client = self.clients[0]
+ client.run_command(['ipa-client-install', '-U',
+ '--domain', self.domain_name,
+ '--realm', self.master.domain.realm,
+ '-p', 'admin',
+ '-w', self.master.config.admin_password,
+ '--server', self.master.hostname,
+ '--force-join'])
+ result = client.run_command(['ipa-replica-install', '-U', '-w',
+ self.master.config.dirman_password],
+ raiseonerr=False)
+ assert_error(result,
+ "Cannot promote this client to a replica. Local domain "
+ "'%s' does not match IPA domain "
+ "'%s'" % (self.domain_name, self.master.domain.name))
+
+ def test_upcase_client_domain(self):
+ client = self.clients[0]
+ result = client.run_command(['ipa-client-install', '-U', '--domain',
+ self.master.domain.name.upper(), '-w',
+ self.master.config.admin_password,
+ '-p', 'admin',
+ '--server', self.master.hostname,
+ '--force-join'], raiseonerr=False)
+ assert(result.returncode == 0), (
+ 'Failed to setup client with the upcase domain name')
+ result1 = client.run_command(['ipa-replica-install', '-U', '-w',
+ self.master.config.dirman_password],
+ raiseonerr=False)
+ assert(result1.returncode == 0), (
+ 'Failed to promote the client installed with the upcase domain name')
commit b8d5881ba93b00653ba42c61369f19ca27fb7a64
Author: Petr Spacek <pspacek at redhat.com>
Date: Thu Jun 30 20:41:48 2016 +0200
Fix internal errors in host-add and other commands caused by DNS resolution
Previously resolver was returning CheckedIPAddress objects. This
internal server error in cases where DNS actually returned reserved IP
addresses.
Now the resolver is returning UnsafeIPAddress objects which do syntactic
checks but do not filter IP addresses.
From now on we can decide if some IP address should be accepted as-is or
if it needs to be contrained to some subset of IP addresses using
CheckedIPAddress class.
This regression was caused by changes for
https://fedorahosted.org/freeipa/ticket/5710
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
index aca5061..16549c8 100644
--- a/ipapython/dnsutil.py
+++ b/ipapython/dnsutil.py
@@ -24,7 +24,7 @@ import copy
import six
-from ipapython.ipautil import CheckedIPAddress
+from ipapython.ipautil import UnsafeIPAddress
from ipapython.ipa_log_manager import root_logger
if six.PY3:
@@ -323,18 +323,12 @@ def resolve_rrsets(fqdn, rdtypes):
def resolve_ip_addresses(fqdn):
"""Get IP addresses from DNS A/AAAA records for given host (using DNS).
:returns:
- list of IP addresses as CheckedIPAddress objects
+ list of IP addresses as UnsafeIPAddress objects
"""
rrsets = resolve_rrsets(fqdn, ['A', 'AAAA'])
ip_addresses = set()
for rrset in rrsets:
- ip_addresses.update({CheckedIPAddress(ip, # accept whatever is in DNS
- parse_netmask=False,
- allow_network=True,
- allow_loopback=True,
- allow_broadcast=True,
- allow_multicast=True)
- for ip in rrset})
+ ip_addresses.update({UnsafeIPAddress(ip) for ip in rrset})
return ip_addresses
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 041951d..b329cdb 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -86,102 +86,132 @@ def get_domain_name():
return domain_name
-class CheckedIPAddress(netaddr.IPAddress):
+
+class UnsafeIPAddress(netaddr.IPAddress):
+ """Any valid IP address with or without netmask."""
# Use inet_pton() rather than inet_aton() for IP address parsing. We
# will use the same function in IPv4/IPv6 conversions + be stricter
# and don't allow IP addresses such as '1.1.1' in the same time
netaddr_ip_flags = netaddr.INET_PTON
+ def __init__(self, addr):
+ if isinstance(addr, UnsafeIPAddress):
+ self._net = addr._net
+ super(UnsafeIPAddress, self).__init__(addr,
+ flags=self.netaddr_ip_flags)
+ return
+
+ elif isinstance(addr, netaddr.IPAddress):
+ self._net = None # no information about netmask
+ super(UnsafeIPAddress, self).__init__(addr,
+ flags=self.netaddr_ip_flags)
+ return
+
+ elif isinstance(addr, netaddr.IPNetwork):
+ self._net = addr
+ super(UnsafeIPAddress, self).__init__(self._net.ip,
+ flags=self.netaddr_ip_flags)
+ return
+
+ # option of last resort: parse it as string
+ self._net = None
+ addr = str(addr)
+ try:
+ try:
+ addr = netaddr.IPAddress(addr, flags=self.netaddr_ip_flags)
+ except netaddr.AddrFormatError:
+ # netaddr.IPAddress doesn't handle zone indices in textual
+ # IPv6 addresses. Try removing zone index and parse the
+ # address again.
+ addr, sep, foo = addr.partition('%')
+ if sep != '%':
+ raise
+ addr = netaddr.IPAddress(addr, flags=self.netaddr_ip_flags)
+ if addr.version != 6:
+ raise
+ except ValueError:
+ self._net = netaddr.IPNetwork(addr, flags=self.netaddr_ip_flags)
+ addr = self._net.ip
+ super(UnsafeIPAddress, self).__init__(addr,
+ flags=self.netaddr_ip_flags)
+
+
+class CheckedIPAddress(UnsafeIPAddress):
+ """IPv4 or IPv6 address with additional constraints.
+
+ Reserved or link-local addresses are never accepted.
+ """
def __init__(self, addr, match_local=False, parse_netmask=True,
allow_network=False, allow_loopback=False,
allow_broadcast=False, allow_multicast=False):
+
+ super(CheckedIPAddress, self).__init__(addr)
if isinstance(addr, CheckedIPAddress):
- super(CheckedIPAddress, self).__init__(addr, flags=self.netaddr_ip_flags)
self.prefixlen = addr.prefixlen
return
- net = None
- iface = None
-
- if isinstance(addr, netaddr.IPNetwork):
- net = addr
- addr = net.ip
- elif isinstance(addr, netaddr.IPAddress):
- pass
- else:
- try:
- try:
- addr = netaddr.IPAddress(str(addr), flags=self.netaddr_ip_flags)
- except netaddr.AddrFormatError:
- # netaddr.IPAddress doesn't handle zone indices in textual
- # IPv6 addresses. Try removing zone index and parse the
- # address again.
- if not isinstance(addr, six.string_types):
- raise
- addr, sep, foo = addr.partition('%')
- if sep != '%':
- raise
- addr = netaddr.IPAddress(str(addr), flags=self.netaddr_ip_flags)
- if addr.version != 6:
- raise
- except ValueError:
- net = netaddr.IPNetwork(str(addr), flags=self.netaddr_ip_flags)
- if not parse_netmask:
- raise ValueError("netmask and prefix length not allowed here")
- addr = net.ip
+ if not parse_netmask and self._net:
+ raise ValueError(
+ "netmask and prefix length not allowed here: {}".format(addr))
- if addr.version not in (4, 6):
- raise ValueError("unsupported IP version")
+ if self.version not in (4, 6):
+ raise ValueError("unsupported IP version {}".format(self.version))
- if not allow_loopback and addr.is_loopback():
- raise ValueError("cannot use loopback IP address")
- if (not addr.is_loopback() and addr.is_reserved()) \
- or addr in netaddr.ip.IPV4_6TO4:
- raise ValueError("cannot use IANA reserved IP address")
+ if not allow_loopback and self.is_loopback():
+ raise ValueError("cannot use loopback IP address {}".format(addr))
+ if (not self.is_loopback() and self.is_reserved()) \
+ or self in netaddr.ip.IPV4_6TO4:
+ raise ValueError(
+ "cannot use IANA reserved IP address {}".format(addr))
- if addr.is_link_local():
- raise ValueError("cannot use link-local IP address")
- if not allow_multicast and addr.is_multicast():
- raise ValueError("cannot use multicast IP address")
+ if self.is_link_local():
+ raise ValueError(
+ "cannot use link-local IP address {}".format(addr))
+ if not allow_multicast and self.is_multicast():
+ raise ValueError("cannot use multicast IP address {}".format(addr))
if match_local:
- if addr.version == 4:
+ if self.version == 4:
family = 'inet'
- elif addr.version == 6:
+ elif self.version == 6:
family = 'inet6'
result = run(
[paths.IP, '-family', family, '-oneline', 'address', 'show'],
capture_output=True)
lines = result.output.split('\n')
+ iface = None
for line in lines:
fields = line.split()
if len(fields) < 4:
continue
ifnet = netaddr.IPNetwork(fields[3])
- if ifnet == net or (net is None and ifnet.ip == addr):
- net = ifnet
+ if ifnet == self._net or (self._net is None and ifnet.ip == self):
+ self._net = ifnet
iface = fields[1]
break
if iface is None:
- raise ValueError('No network interface matches the provided IP address and netmask')
+ raise ValueError('no network interface matches the IP address '
+ 'and netmask {}'.format(addr))
+
+ if self._net is None:
+ if self.version == 4:
+ self._net = netaddr.IPNetwork(
+ netaddr.cidr_abbrev_to_verbose(str(self)))
+ elif self.version == 6:
+ self._net = netaddr.IPNetwork(str(self) + '/64')
- if net is None:
- if addr.version == 4:
- net = netaddr.IPNetwork(netaddr.cidr_abbrev_to_verbose(str(addr)))
- elif addr.version == 6:
- net = netaddr.IPNetwork(str(addr) + '/64')
+ if not allow_network and self == self._net.network:
+ raise ValueError("cannot use IP network address {}".format(addr))
+ if not allow_broadcast and (self.version == 4 and
+ self == self._net.broadcast):
+ raise ValueError("cannot use broadcast IP address {}".format(addr))
- if not allow_network and addr == net.network:
- raise ValueError("cannot use IP network address")
- if not allow_broadcast and addr.version == 4 and addr == net.broadcast:
- raise ValueError("cannot use broadcast IP address")
+ self.prefixlen = self._net.prefixlen
- super(CheckedIPAddress, self).__init__(addr, flags=self.netaddr_ip_flags)
- self.prefixlen = net.prefixlen
def valid_ip(addr):
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 49336a8..ec1d9de 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -450,7 +450,7 @@ def create_keytab(path, principal):
def resolve_ip_addresses_nss(fqdn):
"""Get list of IP addresses for given host (using NSS/getaddrinfo).
:returns:
- list of IP addresses as CheckedIPAddress objects
+ list of IP addresses as UnsafeIPAddress objects
"""
# make sure the name is fully qualified
# so search path from resolv.conf does not apply
@@ -470,13 +470,7 @@ def resolve_ip_addresses_nss(fqdn):
ip_addresses = set()
for ai in addrinfos:
try:
- ip = ipautil.CheckedIPAddress(ai[4][0],
- parse_netmask=False,
- # these are unreliable, disable them
- allow_network=True,
- allow_loopback=True,
- allow_broadcast=True,
- allow_multicast=True)
+ ip = ipautil.UnsafeIPAddress(ai[4][0])
except ValueError as ex:
# getaddinfo may return link-local address other similar oddities
# which are not accepted by CheckedIPAddress - skip these
@@ -503,8 +497,7 @@ def get_host_name(no_host_dns):
def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
hostaddr = resolve_ip_addresses_nss(host_name)
if hostaddr.intersection(
- {ipautil.CheckedIPAddress(ip, allow_loopback=True)
- for ip in ['127.0.0.1', '::1']}):
+ {ipautil.UnsafeIPAddress(ip) for ip in ['127.0.0.1', '::1']}):
print("The hostname resolves to the localhost address (127.0.0.1/::1)", file=sys.stderr)
print("Please change your /etc/hosts file so that the hostname", file=sys.stderr)
print("resolves to the ip address of your network interface.", file=sys.stderr)
commit 0db277eb224b92319aede319999d1840db781c10
Author: Petr Spacek <pspacek at redhat.com>
Date: Thu Jun 30 13:57:52 2016 +0200
Remove unused is_local(), interface, and defaultnet from CheckedIPAddress
All these were unused so I'm removing them to keep the code clean and
easier to read. At this point it is clear that only difference between
netaddr.IPAddress and CheckedIPAddress is prefixlen attribute.
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 55386ac..041951d 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -99,13 +99,10 @@ class CheckedIPAddress(netaddr.IPAddress):
if isinstance(addr, CheckedIPAddress):
super(CheckedIPAddress, self).__init__(addr, flags=self.netaddr_ip_flags)
self.prefixlen = addr.prefixlen
- self.defaultnet = addr.defaultnet
- self.interface = addr.interface
return
net = None
iface = None
- defnet = False
if isinstance(addr, netaddr.IPNetwork):
net = addr
@@ -173,7 +170,6 @@ class CheckedIPAddress(netaddr.IPAddress):
raise ValueError('No network interface matches the provided IP address and netmask')
if net is None:
- defnet = True
if addr.version == 4:
net = netaddr.IPNetwork(netaddr.cidr_abbrev_to_verbose(str(addr)))
elif addr.version == 6:
@@ -186,11 +182,6 @@ class CheckedIPAddress(netaddr.IPAddress):
super(CheckedIPAddress, self).__init__(addr, flags=self.netaddr_ip_flags)
self.prefixlen = net.prefixlen
- self.defaultnet = defnet
- self.interface = iface
-
- def is_local(self):
- return self.interface is not None
def valid_ip(addr):
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
commit 4edd39fb05dfd92924fc7f0c37fee3d269edf298
Author: Martin Basti <mbasti at redhat.com>
Date: Thu Jun 30 16:00:08 2016 +0200
Fix replica install with CA
The incorrect api was used, and CA record updated was duplicated.
https://fedorahosted.org/freeipa/ticket/5966
Reviewed-By: Petr Spacek <pspacek at redhat.com>
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index abd1452..0068ff3 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -1082,6 +1082,9 @@ class BindInstance(service.Service):
self.__add_ipa_ca_record()
def add_ipa_ca_dns_records(self, fqdn, domain_name, ca_configured=True):
+ if not self.api.Backend.ldap2.isconnected():
+ self.api.Backend.ldap2.connect(autobind=True)
+
host, zone = fqdn.split(".", 1)
if dns_zone_exists(zone, self.api):
addrs = get_fwd_rr(zone, host, api=self.api)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index fa92aec..3d6c1c0 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -309,7 +309,7 @@ class CAInstance(DogtagInstance):
server_cert_name = 'Server-Cert cert-pki-ca'
def __init__(self, realm=None, ra_db=None, host_name=None,
- dm_password=None, ldapi=True):
+ dm_password=None, ldapi=True, api=api):
super(CAInstance, self).__init__(
realm=realm,
subsystem="CA",
@@ -325,6 +325,7 @@ class CAInstance(DogtagInstance):
self.cert_file = None
self.cert_chain_file = None
self.create_ra_agent_db = True
+ self.api = api
if realm is not None:
self.canickname = get_ca_nickname(realm)
@@ -1294,7 +1295,7 @@ class CAInstance(DogtagInstance):
if bindinstance.dns_container_exists(
api.env.host, api.env.basedn, ldapi=True, realm=api.env.realm
):
- bind = bindinstance.BindInstance(ldapi=True)
+ bind = bindinstance.BindInstance(ldapi=True, api=self.api)
bind.add_ipa_ca_dns_records(api.env.host, api.env.domain)
def configure_replica(self, master_host, subject_base=None,
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 9ed6ef4..7601ce1 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -1477,7 +1477,8 @@ def promote(installer):
ca = cainstance.CAInstance(config.realm_name, certs.NSS_DIR,
host_name=config.host_name,
- dm_password=config.dirman_password)
+ dm_password=config.dirman_password,
+ api=remote_api)
ca.configure_replica(config.ca_host_name,
subject_base=config.subject_base,
ca_cert_bundle=ca_data)
commit 8ce40940300e0e37191251a8a26bb8a4b5fcd604
Author: Fraser Tweedale <ftweedal at redhat.com>
Date: Thu Jun 30 14:30:30 2016 +1000
Move normalize_hostname to where it is expected
Commit 3d71c43504ea7837ea14bb9dd4a469c07337293f broke
ipa-client-install by importing normalize_hostname from the wrong
module. Move the function.
https://fedorahosted.org/freeipa/ticket/5976
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 3fe9c5f..0bb5a53 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -44,7 +44,7 @@ from ipalib import x509
from ipalib import output
from ipalib.request import context
from ipalib.util import (normalize_sshpubkey, validate_sshpubkey_no_options,
- convert_sshpubkey_post, validate_hostname)
+ convert_sshpubkey_post, validate_hostname, normalize_hostname)
from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
from ipapython.dnsutil import DNSName
from ipapython.ssh import SSHPublicKey
@@ -267,14 +267,6 @@ def validate_ipaddr(ugettext, ipaddr):
return None
-def normalize_hostname(hostname):
- """Use common fqdn form without the trailing dot"""
- if hostname.endswith(u'.'):
- hostname = hostname[:-1]
- hostname = hostname.lower()
- return hostname
-
-
def _hostname_validator(ugettext, value):
try:
validate_hostname(value)
diff --git a/ipalib/util.py b/ipalib/util.py
index 7a99149..6caf396 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -844,3 +844,11 @@ def detect_dns_zone_realm_type(api, domain):
def has_managed_topology(api):
domainlevel = api.Command['domainlevel_get']().get('result', DOMAIN_LEVEL_0)
return domainlevel > DOMAIN_LEVEL_0
+
+
+def normalize_hostname(hostname):
+ """Use common fqdn form without the trailing dot"""
+ if hostname.endswith(u'.'):
+ hostname = hostname[:-1]
+ hostname = hostname.lower()
+ return hostname
commit 4ce0ff61a8e46de4a2f2dfca41610323f9569d8a
Author: Florence Blanc-Renaud <frenaud at redhat.com>
Date: Mon Jun 27 10:23:14 2016 +0200
Do not allow installation in FIPS mode
https://fedorahosted.org/freeipa/ticket/5761
Reviewed-By: Martin Basti <mbasti at redhat.com>
Reviewed-By: Rob Crittenden <rcritten at redhat.com>
diff --git a/client/ipa-client-install b/client/ipa-client-install
index b900eca..088e794 100755
--- a/client/ipa-client-install
+++ b/client/ipa-client-install
@@ -45,7 +45,7 @@ try:
import ipaclient.ntpconf
from ipapython.ipautil import (
run, user_input, CalledProcessError, file_exists, dir_exists,
- realm_to_suffix)
+ realm_to_suffix, is_fips_enabled)
from ipaplatform.tasks import tasks
from ipaplatform import services
from ipaplatform.paths import paths
@@ -3064,6 +3064,9 @@ def main():
if not os.getegid() == 0:
sys.exit("\nYou must be root to run ipa-client-install.\n")
+ if is_fips_enabled():
+ sys.exit("Installing IPA client in FIPS mode is not supported")
+
tasks.check_selinux_status()
logging_setup(options)
root_logger.debug(
diff --git a/install/tools/ipactl b/install/tools/ipactl
index 9c2d5b2..51d9ff8 100755
--- a/install/tools/ipactl
+++ b/install/tools/ipactl
@@ -31,7 +31,8 @@ from ipaserver.install.dsinstance import config_dirname
from ipaserver.install.installutils import is_ipa_configured, ScriptError
from ipalib import api, errors
from ipapython.ipaldap import IPAdmin
-from ipapython.ipautil import wait_for_open_ports, wait_for_open_socket
+from ipapython.ipautil import (
+ wait_for_open_ports, wait_for_open_socket, is_fips_enabled)
from ipapython import config, dogtag
from ipaplatform.tasks import tasks
from ipapython.dn import DN
@@ -537,6 +538,9 @@ def main():
elif args[0] != "start" and args[0] != "stop" and args[0] != "restart" and args[0] != "status":
raise IpactlError("Unrecognized action [" + args[0] + "]", 2)
+ if is_fips_enabled():
+ raise IpactlError("Starting IPA server in FIPS mode is not supported")
+
# check if IPA is configured at all
try:
check_IPA_configuration()
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 6b0ec9b..c005cd3 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -133,6 +133,7 @@ class BasePathNamespace(object):
SYSTEMD_PKI_TOMCAT_SERVICE = "/etc/systemd/system/pki-tomcatd.target.wants/pki-tomcatd at pki-tomcat.service"
DNSSEC_TRUSTED_KEY = "/etc/trusted-key.key"
HOME_DIR = "/home"
+ PROC_FIPS_ENABLED = "/proc/sys/crypto/fips_enabled"
ROOT_IPA_CACHE = "/root/.ipa_cache"
ROOT_PKI = "/root/.pki"
DOGTAG_ADMIN_P12 = "/root/ca-agent.p12"
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 7740986..55386ac 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -1452,3 +1452,22 @@ if six.PY2:
type(value).__name__))
else:
fsdecode = os.fsdecode #pylint: disable=no-member
+
+
+def is_fips_enabled():
+ """
+ Checks whether this host is FIPS-enabled.
+
+ Returns a boolean indicating if the host is FIPS-enabled, i.e. if the
+ file /proc/sys/crypto/fips_enabled contains a non-0 value. Otherwise,
+ or if the file /proc/sys/crypto/fips_enabled does not exist,
+ the function returns False.
+ """
+ try:
+ with open(paths.PROC_FIPS_ENABLED, 'r') as f:
+ if f.read().strip() != '0':
+ return True
+ except IOError:
+ # Consider that the host is not fips-enabled if the file does not exist
+ pass
+ return False
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 6c906c9..056a6a9 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -23,7 +23,8 @@ from ipapython.install.common import step
from ipapython.install.core import Knob
from ipapython.ipa_log_manager import root_logger
from ipapython.ipautil import (
- decrypt_file, format_netloc, ipa_generate_password, run, user_input)
+ decrypt_file, format_netloc, ipa_generate_password, run, user_input,
+ is_fips_enabled)
from ipaplatform import services
from ipaplatform.paths import paths
from ipaplatform.tasks import tasks
@@ -437,6 +438,10 @@ def install_check(installer):
external_ca_file = installer._external_ca_file
http_ca_cert = installer._ca_cert
+ if is_fips_enabled():
+ raise RuntimeError(
+ "Installing IPA server in FIPS mode is not supported")
+
tasks.check_selinux_status()
if options.master_password:
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index fa23fe8..9ed6ef4 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -497,6 +497,10 @@ def install_check(installer):
options = installer
filename = installer.replica_file
+ if ipautil.is_fips_enabled():
+ raise RuntimeError(
+ "Installing IPA server in FIPS mode is not supported")
+
tasks.check_selinux_status()
if is_ipa_configured():
commit ced5124508a47415b3ff86159eb55b96f57bb29a
Author: Petr Spacek <pspacek at redhat.com>
Date: Tue Jun 28 18:18:01 2016 +0200
DNS: Remove unnecessary DNS check from installer
Previously we were checking content of DNS before actually adding DNS
records for replicas. This is causing cycle in logic and adds weird
corner cases to the installer which can blow up on DNS timeout or so.
The check was completely unnecessary because the installer knows IP
addresses and name of the machine. Removal of the check makes
the installer more reliable.
https://fedorahosted.org/freeipa/ticket/5962
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index efabab1..abd1452 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -50,7 +50,7 @@ from ipalib.util import (validate_zonemgr_str, normalize_zonemgr,
normalize_zone, get_reverse_zone_default,
zone_is_reverse, validate_dnssec_global_forwarder,
DNSSECSignatureMissingError, EDNS0UnsupportedError,
- UnresolvableRecordError, verify_host_resolvable)
+ UnresolvableRecordError)
from ipalib.constants import CACERT
if six.PY3:
@@ -877,14 +877,6 @@ class BindInstance(service.Service):
add_rr(self.domain, rname, "SRV", rdata, self.dns_backup,
api=self.api)
- if not dns_zone_exists(zone, self.api):
- # check if master hostname is resolvable
- try:
- verify_host_resolvable(fqdn)
- except errors.DNSNotARecordError:
- root_logger.warning("Master FQDN (%s) is not resolvable.",
- fqdn)
-
# Add forward and reverse records to self
for addr in addrs:
try:
commit dc7413234361eed1a63d78c9ac932a38b53d838b
Author: Petr Spacek <pspacek at redhat.com>
Date: Tue Jun 28 13:53:58 2016 +0200
Use NSS for name->resolution in IPA installer
This fixes scenarios where IPA server is not able to resolve own name
and option --ip-address was not specified by the user.
This partially reverts changes from commit
dc405005f537cf278fd6ddfe6b87060bd13d9a67
https://fedorahosted.org/freeipa/ticket/5962
Reviewed-By: Martin Basti <mbasti at redhat.com>
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
index 6aa0e07..aca5061 100644
--- a/ipapython/dnsutil.py
+++ b/ipapython/dnsutil.py
@@ -321,7 +321,7 @@ def resolve_rrsets(fqdn, rdtypes):
def resolve_ip_addresses(fqdn):
- """Get IP addresses from DNS A/AAAA records for given host.
+ """Get IP addresses from DNS A/AAAA records for given host (using DNS).
:returns:
list of IP addresses as CheckedIPAddress objects
"""
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 3e6e26c..efabab1 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -910,9 +910,7 @@ class BindInstance(service.Service):
if fqdn == self.fqdn:
continue
- addrs = dnsutil.resolve_ip_addresses(fqdn)
- # hack, will go away with locations
- addrs = [str(addr) for addr in addrs]
+ addrs = installutils.resolve_ip_addresses_nss(fqdn)
root_logger.debug("Adding DNS records for master %s" % fqdn)
self.__add_master_records(fqdn, addrs)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index baa0d3d..49336a8 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -447,6 +447,46 @@ def create_keytab(path, principal):
kadmin("ktadd -k " + path + " " + principal)
+def resolve_ip_addresses_nss(fqdn):
+ """Get list of IP addresses for given host (using NSS/getaddrinfo).
+ :returns:
+ list of IP addresses as CheckedIPAddress objects
+ """
+ # make sure the name is fully qualified
+ # so search path from resolv.conf does not apply
+ fqdn = str(dnsutil.DNSName(fqdn).make_absolute())
+ try:
+ addrinfos = socket.getaddrinfo(fqdn, None,
+ socket.AF_UNSPEC, socket.SOCK_STREAM)
+ except socket.error as ex:
+ if ex.errno == socket.EAI_NODATA or ex.errno == socket.EAI_NONAME:
+ root_logger.debug('Name %s does not have any address: %s',
+ fqdn, ex)
+ return set()
+ else:
+ raise
+
+ # accept whatever we got from NSS
+ ip_addresses = set()
+ for ai in addrinfos:
+ try:
+ ip = ipautil.CheckedIPAddress(ai[4][0],
+ parse_netmask=False,
+ # these are unreliable, disable them
+ allow_network=True,
+ allow_loopback=True,
+ allow_broadcast=True,
+ allow_multicast=True)
+ except ValueError as ex:
+ # getaddinfo may return link-local address other similar oddities
+ # which are not accepted by CheckedIPAddress - skip these
+ root_logger.warning('Name %s resolved to an unacceptable IP '
+ 'address %s: %s', fqdn, ai[4][0], ex)
More information about the Pkg-freeipa-devel
mailing list