diff --git a/SOURCES/0160-Fix-version-comparison.patch b/SOURCES/0160-Fix-version-comparison.patch new file mode 100644 index 0000000..a3857f1 --- /dev/null +++ b/SOURCES/0160-Fix-version-comparison.patch @@ -0,0 +1,114 @@ +From 30902db32fcc04dccbaf40839f44cdf4f505f588 Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Wed, 9 Dec 2015 18:53:35 +0100 +Subject: [PATCH] Fix version comparison + +Use RPM library to compare vendor versions of IPA for redhat platform + +https://fedorahosted.org/freeipa/ticket/5535 + +Reviewed-By: Tomas Babej +--- + freeipa.spec.in | 1 + + ipaplatform/redhat/tasks.py | 53 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 6527109b422a1e3065d5a540c3e2a3af670f2ebf..01d42bc621c83541af7517d6d91eb37fd5b5c5cc 100644 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -159,6 +159,7 @@ Requires: p11-kit + Requires: systemd-python + Requires: %{etc_systemd_dir} + Requires: gzip ++Requires: rpm-python + + Conflicts: %{alt_name}-server + Obsoletes: %{alt_name}-server < %{version} +diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py +index db31cd04cb234fac8fee97f3579ba2ca919f3262..2e894d776dcd5542e6c11cc0210add8ad9d90298 100644 +--- a/ipaplatform/redhat/tasks.py ++++ b/ipaplatform/redhat/tasks.py +@@ -30,6 +30,8 @@ import socket + import sys + import urllib + import base64 ++import rpm ++from functools import total_ordering + + from subprocess import CalledProcessError + from nss.error import NSPRError +@@ -46,6 +48,35 @@ from ipaplatform.redhat.authconfig import RedHatAuthConfig + from ipaplatform.base.tasks import BaseTaskNamespace + + ++# copied from rpmUtils/miscutils.py ++def stringToVersion(verstring): ++ if verstring in [None, '']: ++ return (None, None, None) ++ i = verstring.find(':') ++ if i != -1: ++ try: ++ epoch = str(long(verstring[:i])) ++ except ValueError: ++ # look, garbage in the epoch field, how fun, kill it ++ epoch = '0' # this is our fallback, deal ++ else: ++ epoch = '0' ++ j = verstring.find('-') ++ if j != -1: ++ if verstring[i + 1:j] == '': ++ version = None ++ else: ++ version = verstring[i + 1:j] ++ release = verstring[j + 1:] ++ else: ++ if verstring[i + 1:] == '': ++ version = None ++ else: ++ version = verstring[i + 1:] ++ release = None ++ return (epoch, version, release) ++ ++ + log = log_mgr.get_logger(__name__) + + +@@ -65,6 +96,21 @@ def selinux_enabled(): + return False + + ++@total_ordering ++class IPAVersion(object): ++ ++ def __init__(self, version): ++ self.version_tuple = stringToVersion(version) ++ ++ def __eq__(self, other): ++ assert isinstance(other, IPAVersion) ++ return rpm.labelCompare(self.version_tuple, other.version_tuple) == 0 ++ ++ def __lt__(self, other): ++ assert isinstance(other, IPAVersion) ++ return rpm.labelCompare(self.version_tuple, other.version_tuple) == -1 ++ ++ + class RedHatTaskNamespace(BaseTaskNamespace): + + def restore_context(self, filepath, restorecon=paths.SBIN_RESTORECON): +@@ -422,5 +468,12 @@ class RedHatTaskNamespace(BaseTaskNamespace): + super(RedHatTaskNamespace, self).create_system_user(name, group, + homedir, shell, uid, gid, comment, create_homedir) + ++ def parse_ipa_version(self, version): ++ """ ++ :param version: textual version ++ :return: object implementing proper __cmp__ method for version compare ++ """ ++ return IPAVersion(version) ++ + + tasks = RedHatTaskNamespace() +-- +2.4.3 + diff --git a/SOURCES/0161-DNS-fix-file-permissions.patch b/SOURCES/0161-DNS-fix-file-permissions.patch new file mode 100644 index 0000000..d8a0304 --- /dev/null +++ b/SOURCES/0161-DNS-fix-file-permissions.patch @@ -0,0 +1,40 @@ +From 7aae209ba77a09de7cb09792d6ac16bb80683a2f Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Wed, 9 Dec 2015 12:12:22 +0100 +Subject: [PATCH] DNS: fix file permissions + +With non default umask named-pkcs11 cannot access the softhsm token storage + +https://fedorahosted.org/freeipa/ticket/5520 + +Reviewed-By: Tomas Babej +--- + ipaserver/install/dnskeysyncinstance.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py +index 7d1351ccc57a5dbd7d537741545ad44d0dcd5eb1..590343c4e97fc882f296ac1aa69e43de9d35ed65 100644 +--- a/ipaserver/install/dnskeysyncinstance.py ++++ b/ipaserver/install/dnskeysyncinstance.py +@@ -200,7 +200,9 @@ class DNSKeySyncInstance(service.Service): + # create dnssec directory + if not os.path.exists(paths.IPA_DNSSEC_DIR): + self.logger.debug("Creating %s directory", paths.IPA_DNSSEC_DIR) +- os.mkdir(paths.IPA_DNSSEC_DIR, 0770) ++ os.mkdir(paths.IPA_DNSSEC_DIR) ++ os.chmod(paths.IPA_DNSSEC_DIR, 0770) ++ + # chown ods:named + os.chown(paths.IPA_DNSSEC_DIR, self.ods_uid, self.named_gid) + +@@ -217,6 +219,7 @@ class DNSKeySyncInstance(service.Service): + named_fd.truncate(0) + named_fd.write(softhsm_conf_txt) + named_fd.close() ++ os.chmod(paths.DNSSEC_SOFTHSM2_CONF, 0644) + + # setting up named to use softhsm2 + if not self.fstore.has_file(paths.SYSCONFIG_NAMED): +-- +2.4.3 + diff --git a/SOURCES/0162-Explicitly-call-chmod-on-newly-created-directories.patch b/SOURCES/0162-Explicitly-call-chmod-on-newly-created-directories.patch new file mode 100644 index 0000000..e85ee8f --- /dev/null +++ b/SOURCES/0162-Explicitly-call-chmod-on-newly-created-directories.patch @@ -0,0 +1,121 @@ +From 7d7bb4789504a3f84e8ccf52abc06e8de109289a Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Wed, 9 Dec 2015 13:40:04 +0100 +Subject: [PATCH] Explicitly call chmod on newly created directories + +Without calling os.chmod(), umask is effective and may cause that +directory is created with permission that causes failure. + +This can be related to https://fedorahosted.org/freeipa/ticket/5520 + +Reviewed-By: Tomas Babej +--- + ipaplatform/base/services.py | 2 +- + ipaserver/install/cainstance.py | 1 + + ipaserver/install/ipa_backup.py | 7 ++++--- + ipaserver/install/ipa_replica_prepare.py | 3 ++- + ipaserver/install/ipa_restore.py | 10 ++++++---- + 5 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/ipaplatform/base/services.py b/ipaplatform/base/services.py +index 56e959e919e42281431240451071a2d4b8048e4a..b068a2f3b00549fffa20feffb6a3158382fc7e9a 100644 +--- a/ipaplatform/base/services.py ++++ b/ipaplatform/base/services.py +@@ -421,7 +421,7 @@ class SystemdService(PlatformService): + + try: + if not ipautil.dir_exists(srv_tgt): +- os.mkdir(srv_tgt) ++ os.mkdir(srv_tgt, 0755) + if os.path.exists(srv_lnk): + # Remove old link + os.unlink(srv_lnk) +diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py +index c20bf39c12cff0777d90efad2b0d8d136ee37ec9..d9bf4f31af5a922dd6f977a5011f50ce7cea8896 100644 +--- a/ipaserver/install/cainstance.py ++++ b/ipaserver/install/cainstance.py +@@ -978,6 +978,7 @@ class CAInstance(DogtagInstance): + + if not ipautil.dir_exists(self.ra_agent_db): + os.mkdir(self.ra_agent_db) ++ os.chmod(self.ra_agent_db, 0755) + + # Create the password file for this db + hex_str = binascii.hexlify(os.urandom(10)) +diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py +index 3bd2ef0203c1b5b596e092987acd894491ecae26..a5a4bef0a17f641fcea565d9a79c3e6887a064a7 100644 +--- a/ipaserver/install/ipa_backup.py ++++ b/ipaserver/install/ipa_backup.py +@@ -279,8 +279,8 @@ class Backup(admintool.AdminTool): + os.chown(self.top_dir, pent.pw_uid, pent.pw_gid) + os.chmod(self.top_dir, 0750) + self.dir = os.path.join(self.top_dir, "ipa") +- os.mkdir(self.dir, 0750) +- ++ os.mkdir(self.dir) ++ os.chmod(self.dir, 0750) + os.chown(self.dir, pent.pw_uid, pent.pw_gid) + + self.header = os.path.join(self.top_dir, 'header') +@@ -605,7 +605,8 @@ class Backup(admintool.AdminTool): + backup_dir = os.path.join(paths.IPA_BACKUP_DIR, time.strftime('ipa-full-%Y-%m-%d-%H-%M-%S')) + filename = os.path.join(backup_dir, "ipa-full.tar") + +- os.mkdir(backup_dir, 0700) ++ os.mkdir(backup_dir) ++ os.chmod(backup_dir, 0700) + + cwd = os.getcwd() + os.chdir(self.dir) +diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py +index 5246f5f5469c85571d04c99d872f38018802abaa..b9ae60e9bc9d40be5f86e312980846b2ad80f67d 100644 +--- a/ipaserver/install/ipa_replica_prepare.py ++++ b/ipaserver/install/ipa_replica_prepare.py +@@ -345,7 +345,8 @@ class ReplicaPrepare(admintool.AdminTool): + + self.top_dir = tempfile.mkdtemp("ipa") + self.dir = os.path.join(self.top_dir, "realm_info") +- os.mkdir(self.dir, 0700) ++ os.mkdir(self.dir) ++ os.chmod(self.dir, 0700) + try: + self.copy_ds_certificate() + +diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py +index 57d5deb1e68af6e9ceb51f4dd751b8a59d9ac513..cdc460301ad8aeb658fec18da565238a376d1c0c 100644 +--- a/ipaserver/install/ipa_restore.py ++++ b/ipaserver/install/ipa_restore.py +@@ -300,8 +300,8 @@ class Restore(admintool.AdminTool): + os.chown(self.top_dir, pent.pw_uid, pent.pw_gid) + os.chmod(self.top_dir, 0750) + self.dir = os.path.join(self.top_dir, "ipa") +- os.mkdir(self.dir, 0750) +- ++ os.mkdir(self.dir) ++ os.chmod(self.dir, 0750) + os.chown(self.dir, pent.pw_uid, pent.pw_gid) + + cwd = os.getcwd() +@@ -527,7 +527,8 @@ class Restore(admintool.AdminTool): + + if not os.path.exists(ldifdir): + pent = pwd.getpwnam(DS_USER) +- os.mkdir(ldifdir, 0770) ++ os.mkdir(ldifdir) ++ os.chmod(ldifdir, 0770) + os.chown(ldifdir, pent.pw_uid, pent.pw_gid) + + ipautil.backup_file(ldiffile) +@@ -804,7 +805,8 @@ class Restore(admintool.AdminTool): + for dir in dirs: + try: + self.log.debug('Creating %s' % dir) +- os.mkdir(dir, 0770) ++ os.mkdir(dir) ++ os.chmod(dir, 0770) + os.chown(dir, pent.pw_uid, pent.pw_gid) + tasks.restore_context(dir) + except Exception, e: +-- +2.4.3 + diff --git a/SOURCES/0163-Fix-replace-mkdir-with-chmod.patch b/SOURCES/0163-Fix-replace-mkdir-with-chmod.patch new file mode 100644 index 0000000..433a1d6 --- /dev/null +++ b/SOURCES/0163-Fix-replace-mkdir-with-chmod.patch @@ -0,0 +1,31 @@ +From a600614ba36e192b168fcb4f9547c70fdc304707 Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Tue, 22 Dec 2015 16:34:32 +0100 +Subject: [PATCH] Fix: replace mkdir with chmod + +In original patches, extra mkdir has been added instead of chmod. + +https://fedorahosted.org/freeipa/ticket/5520 + +Reviewed-By: Martin Basti +--- + ipaplatform/base/services.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ipaplatform/base/services.py b/ipaplatform/base/services.py +index b068a2f3b00549fffa20feffb6a3158382fc7e9a..d280557c4f1c8ba353ba093736d577cc6c2a47a9 100644 +--- a/ipaplatform/base/services.py ++++ b/ipaplatform/base/services.py +@@ -421,7 +421,8 @@ class SystemdService(PlatformService): + + try: + if not ipautil.dir_exists(srv_tgt): +- os.mkdir(srv_tgt, 0755) ++ os.mkdir(srv_tgt) ++ os.chmod(srv_tgt, 0755) + if os.path.exists(srv_lnk): + # Remove old link + os.unlink(srv_lnk) +-- +2.4.3 + diff --git a/SOURCES/0164-DNSSEC-Improve-error-reporting-from-ipa-ods-exporter.patch b/SOURCES/0164-DNSSEC-Improve-error-reporting-from-ipa-ods-exporter.patch new file mode 100644 index 0000000..b646527 --- /dev/null +++ b/SOURCES/0164-DNSSEC-Improve-error-reporting-from-ipa-ods-exporter.patch @@ -0,0 +1,38 @@ +From 06df4a281c5e4b2be4840fb42129478279792a9d Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Thu, 26 Nov 2015 14:56:00 +0100 +Subject: [PATCH] DNSSEC: Improve error reporting from ipa-ods-exporter + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index f30a2253a713d857aa4e7566e52a0a45f7bd50c2..12a9294ae05d2ce8d206a2bbf74cc00d81259efa 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -31,6 +31,7 @@ import systemd.daemon + import systemd.journal + import sqlite3 + import time ++import traceback + + import ipalib + from ipapython.dn import DN +@@ -576,7 +577,8 @@ try: + sync_zone(log, ldap, dns_dn, zone_row['name']) + + except Exception as ex: +- msg = "ipa-ods-exporter exception: %s" % ex ++ msg = "ipa-ods-exporter exception: %s" % traceback.format_exc(ex) ++ log.exception(ex) + raise ex + + finally: +-- +2.4.3 + diff --git a/SOURCES/0165-DNSSEC-Make-sure-that-current-state-in-OpenDNSSEC-ma.patch b/SOURCES/0165-DNSSEC-Make-sure-that-current-state-in-OpenDNSSEC-ma.patch new file mode 100644 index 0000000..a8906ff --- /dev/null +++ b/SOURCES/0165-DNSSEC-Make-sure-that-current-state-in-OpenDNSSEC-ma.patch @@ -0,0 +1,174 @@ +From 6c012544655b3730ebb0a1551cdbce04ab686cfb Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Tue, 24 Nov 2015 12:49:40 +0100 +Subject: [PATCH] DNSSEC: Make sure that current state in OpenDNSSEC matches + key state in LDAP + +Previously we published timestamps of planned state changes in LDAP. +This led to situations where state transition in OpenDNSSEC was blocked +by an additional condition (or unavailability of OpenDNSSEC) but BIND +actually did the transition as planned. + +Additionally key state mapping was incorrect for KSK so sometimes KSK +was not used for signing when it should. + +Example (for code without this fix): +- Add a zone and let OpenDNSSEC to generate keys. +- Wait until keys are in state "published" and next state is "inactive". +- Shutdown OpenDNSSEC or break replication from DNSSEC key master. +- See that keys on DNS replicas will transition to state "inactive" even + though it should not happen because OpenDNSSEC is not available + (i.e. new keys may not be available). +- End result is that affected zone will not be signed anymore, even + though it should stay signed with the old keys. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 105 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 95 insertions(+), 10 deletions(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index 12a9294ae05d2ce8d206a2bbf74cc00d81259efa..6ed7588847042e742abeef724940eec31f23ca8f 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -57,6 +57,14 @@ ODS_DB_LOCK_PATH = "%s%s" % (paths.OPENDNSSEC_KASP_DB, '.our_lock') + SECRETKEY_WRAPPING_MECH = 'rsaPkcsOaep' + PRIVKEY_WRAPPING_MECH = 'aesKeyWrapPad' + ++# Constants from OpenDNSSEC's enforcer/ksm/include/ksm/ksm.h ++KSM_STATE_PUBLISH = 2 ++KSM_STATE_READY = 3 ++KSM_STATE_ACTIVE = 4 ++KSM_STATE_RETIRE = 5 ++KSM_STATE_DEAD = 6 ++KSM_STATE_KEYPUBLISH = 10 ++ + # DNSKEY flag constants + dnskey_flag_by_value = { + 0x0001: 'SEP', +@@ -122,6 +130,77 @@ def sql2ldap_keyid(sql_keyid): + #uri += '%'.join(sql_keyid[i:i+2] for i in range(0, len(sql_keyid), 2)) + return {"idnsSecKeyRef": uri} + ++def ods2bind_timestamps(key_state, key_type, ods_times): ++ """Transform (timestamps and key states) from ODS to set of BIND timestamps ++ with equivalent meaning. At the same time, remove timestamps ++ for future/planned state transitions to prevent ODS & BIND ++ from desynchronizing. ++ ++ OpenDNSSEC database may contain timestamps for state transitions planned ++ in the future, but timestamp itself is not sufficient information because ++ there could be some additional condition which is guaded by OpenDNSSEC ++ itself. ++ ++ BIND works directly with timestamps without any additional conditions. ++ This difference causes problem when state transition planned in OpenDNSSEC ++ does not happen as originally planned for some reason. ++ ++ At the same time, this difference causes problem when OpenDNSSEC on DNSSEC ++ key master and BIND instances on replicas are not synchronized. This ++ happens when DNSSEC key master is down, or a replication is down. Even ++ a temporary desynchronization could cause DNSSEC validation failures ++ which could have huge impact. ++ ++ To prevent this problem, this function removes all timestamps corresponding ++ to future state transitions. As a result, BIND will not do state transition ++ until it happens in OpenDNSSEC first and until the change is replicated. ++ ++ Also, timestamp mapping depends on key type and is not 1:1. ++ For detailed description of the mapping please see ++ https://fedorahosted.org/bind-dyndb-ldap/wiki/BIND9/Design/DNSSEC/OpenDNSSEC2BINDKeyStates ++ """ ++ bind_times = {} ++ # idnsSecKeyCreated is equivalent to SQL column 'created' ++ bind_times['idnsSecKeyCreated'] = ods_times['idnsSecKeyCreated'] ++ ++ # set of key states where publishing in DNS zone is desired is taken from ++ # opendnssec/enforcer/ksm/ksm_request.c:KsmRequestIssueKeys() ++ # TODO: support for RFC 5011, requires OpenDNSSEC v1.4.8+ ++ if ('idnsSecKeyPublish' in ods_times and ++ key_state in {KSM_STATE_PUBLISH, KSM_STATE_READY, KSM_STATE_ACTIVE, ++ KSM_STATE_RETIRE, KSM_STATE_KEYPUBLISH}): ++ bind_times['idnsSecKeyPublish'] = ods_times['idnsSecKeyPublish'] ++ ++ # ZSK and KSK handling differs in enforcerd, see ++ # opendnssec/enforcer/enforcerd/enforcer.c:commKeyConfig() ++ if key_type == 'ZSK': ++ # idnsSecKeyActivate cannot be set before the key reaches ACTIVE state ++ if ('idnsSecKeyActivate' in ods_times and ++ key_state in {KSM_STATE_ACTIVE, KSM_STATE_RETIRE, KSM_STATE_DEAD}): ++ bind_times['idnsSecKeyActivate'] = ods_times['idnsSecKeyActivate'] ++ ++ # idnsSecKeyInactive cannot be set before the key reaches RETIRE state ++ if ('idnsSecKeyInactive' in ods_times and ++ key_state in {KSM_STATE_RETIRE, KSM_STATE_DEAD}): ++ bind_times['idnsSecKeyInactive'] = ods_times['idnsSecKeyInactive'] ++ ++ elif key_type == 'KSK': ++ # KSK is special: it is used for signing as long as it is in zone ++ if ('idnsSecKeyPublish' in ods_times and ++ key_state in {KSM_STATE_PUBLISH, KSM_STATE_READY, KSM_STATE_ACTIVE, ++ KSM_STATE_RETIRE, KSM_STATE_KEYPUBLISH}): ++ bind_times['idnsSecKeyActivate'] = ods_times['idnsSecKeyPublish'] ++ # idnsSecKeyInactive is ignored for KSK on purpose ++ ++ else: ++ assert False, "unsupported key type %s" % key_type ++ ++ # idnsSecKeyDelete is relevant only in DEAD state ++ if 'idnsSecKeyDelete' in ods_times and key_state == KSM_STATE_DEAD: ++ bind_times['idnsSecKeyDelete'] = ods_times['idnsSecKeyDelete'] ++ ++ return bind_times ++ + class ods_db_lock(object): + def __enter__(self): + self.f = open(ODS_DB_LOCK_PATH, 'w') +@@ -172,18 +251,20 @@ def get_ods_keys(zone_name): + assert len(rows) == 1, "exactly one DNS zone should exist in ODS DB" + zone_id = rows[0][0] + +- # get all keys for given zone ID +- cur = db.execute("SELECT kp.HSMkey_id, kp.generate, kp.algorithm, dnsk.publish, dnsk.active, dnsk.retire, dnsk.dead, dnsk.keytype " +- "FROM keypairs AS kp JOIN dnsseckeys AS dnsk ON kp.id = dnsk.keypair_id " +- "WHERE dnsk.zone_id = ?", (zone_id,)) ++ # get relevant keys for given zone ID: ++ # ignore keys which were generated but not used yet ++ # key state check is using constants from ++ # OpenDNSSEC's enforcer/ksm/include/ksm/ksm.h ++ # WARNING! OpenDNSSEC version 1 and 2 are using different constants! ++ cur = db.execute("SELECT kp.HSMkey_id, kp.generate, kp.algorithm, " ++ "dnsk.publish, dnsk.active, dnsk.retire, dnsk.dead, " ++ "dnsk.keytype, dnsk.state " ++ "FROM keypairs AS kp " ++ "JOIN dnsseckeys AS dnsk ON kp.id = dnsk.keypair_id " ++ "WHERE dnsk.zone_id = ?", (zone_id,)) + keys = {} + for row in cur: +- key_data = sql2datetimes(row) +- if 'idnsSecKeyDelete' in key_data \ +- and key_data['idnsSecKeyDelete'] > datetime.now(): +- continue # ignore deleted keys +- +- key_data.update(sql2ldap_flags(row['keytype'])) ++ key_data = sql2ldap_flags(row['keytype']) + assert key_data.get('idnsSecKeyZONE', None) == 'TRUE', \ + 'unexpected key type 0x%x' % row['keytype'] + if key_data.get('idnsSecKeySEP', 'FALSE') == 'TRUE': +@@ -191,6 +272,10 @@ def get_ods_keys(zone_name): + else: + key_type = 'ZSK' + ++ # transform key state to timestamps for BIND with equivalent semantics ++ ods_times = sql2datetimes(row) ++ key_data.update(ods2bind_timestamps(row['state'], key_type, ods_times)) ++ + key_data.update(sql2ldap_algorithm(row['algorithm'])) + key_id = "%s-%s-%s" % (key_type, + datetime2ldap(key_data['idnsSecKeyCreated']), +-- +2.4.3 + diff --git a/SOURCES/0166-DNSSEC-Make-sure-that-current-key-state-in-LDAP-matc.patch b/SOURCES/0166-DNSSEC-Make-sure-that-current-key-state-in-LDAP-matc.patch new file mode 100644 index 0000000..532001c --- /dev/null +++ b/SOURCES/0166-DNSSEC-Make-sure-that-current-key-state-in-LDAP-matc.patch @@ -0,0 +1,51 @@ +From 31a9cec3fc366954b3cb8943621834fdfce04bd3 Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Thu, 26 Nov 2015 15:19:03 +0100 +Subject: [PATCH] DNSSEC: Make sure that current key state in LDAP matches key + state in BIND + +We have to explicitly specify "none" value to prevent dnssec-keyfromlabel +utility from using current time for keys without "publish" and "activate" +timestamps. + +Previously this lead to situation where key was in (intermediate) state +"generated" in OpenDNSSEC but BIND started to use this key for signing. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + ipapython/dnssec/bindmgr.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ipapython/dnssec/bindmgr.py b/ipapython/dnssec/bindmgr.py +index 2c6781609594fa27812af3a01d16318198a3e120..70caaf4ee74f594c652cd82bccb8964e172bc719 100644 +--- a/ipapython/dnssec/bindmgr.py ++++ b/ipapython/dnssec/bindmgr.py +@@ -58,6 +58,8 @@ class BINDMgr(object): + return dt.strftime(time_bindfmt) + + def dates2params(self, ldap_attrs): ++ """Convert LDAP timestamps to list of parameters suitable ++ for dnssec-keyfromlabel utility""" + attr2param = {'idnsseckeypublish': '-P', + 'idnsseckeyactivate': '-A', + 'idnsseckeyinactive': '-I', +@@ -65,10 +67,12 @@ class BINDMgr(object): + + params = [] + for attr, param in attr2param.items(): ++ params.append(param) + if attr in ldap_attrs: +- params.append(param) + assert len(ldap_attrs[attr]) == 1, 'Timestamp %s is expected to be single-valued' % attr + params.append(self.time_ldap2bindfmt(ldap_attrs[attr][0])) ++ else: ++ params.append('none') + + return params + +-- +2.4.3 + diff --git a/SOURCES/0167-DNSSEC-remove-obsolete-TODO-note.patch b/SOURCES/0167-DNSSEC-remove-obsolete-TODO-note.patch new file mode 100644 index 0000000..55a9a89 --- /dev/null +++ b/SOURCES/0167-DNSSEC-remove-obsolete-TODO-note.patch @@ -0,0 +1,28 @@ +From bb592115d2fbab6ca9a1b664c3d9bf1bcad5ba0f Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Wed, 2 Dec 2015 12:58:23 +0100 +Subject: [PATCH] DNSSEC: remove obsolete TODO note + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + ipapython/dnssec/ldapkeydb.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ipapython/dnssec/ldapkeydb.py b/ipapython/dnssec/ldapkeydb.py +index 23e6b019c2f2d2644bd389ffec4772b99b8cfc37..74371ae19ca2fb7564a343cc79be20798b99f6d2 100644 +--- a/ipapython/dnssec/ldapkeydb.py ++++ b/ipapython/dnssec/ldapkeydb.py +@@ -181,7 +181,6 @@ class MasterKey(Key): + # TODO: replace this with 'autogenerate' to prevent collisions + uuid_rdn = DN('ipk11UniqueId=%s' % uuid.uuid1()) + entry_dn = DN(uuid_rdn, self.ldapkeydb.base_dn) +- # TODO: add ipaWrappingMech attribute + entry = self.ldap.make_entry(entry_dn, + objectClass=['ipaSecretKeyObject', 'ipk11Object'], + ipaSecretKey=data, +-- +2.4.3 + diff --git a/SOURCES/0168-DNSSEC-add-debug-mode-to-ldapkeydb.py.patch b/SOURCES/0168-DNSSEC-add-debug-mode-to-ldapkeydb.py.patch new file mode 100644 index 0000000..7c1e7fb --- /dev/null +++ b/SOURCES/0168-DNSSEC-add-debug-mode-to-ldapkeydb.py.patch @@ -0,0 +1,105 @@ +From 3daffad0d0e14790147fb7a3ba9be7072b79f3e2 Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Tue, 15 Dec 2015 14:13:23 +0100 +Subject: [PATCH] DNSSEC: add debug mode to ldapkeydb.py + +ldapkeydb.py can be executed directly now. In that case it will print +out key metadata as obtained using IPA LDAP API. + +Kerberos credential cache has to be filled with principal posessing +appropriate access rights before the script is execured. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + ipapython/dnssec/ldapkeydb.py | 54 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 52 insertions(+), 2 deletions(-) + +diff --git a/ipapython/dnssec/ldapkeydb.py b/ipapython/dnssec/ldapkeydb.py +index 74371ae19ca2fb7564a343cc79be20798b99f6d2..54a1fba1d2db8f27c9c9b881ff42201365852587 100644 +--- a/ipapython/dnssec/ldapkeydb.py ++++ b/ipapython/dnssec/ldapkeydb.py +@@ -4,6 +4,8 @@ + + from binascii import hexlify + import collections ++import logging ++from pprint import pprint + import sys + import time + +@@ -11,6 +13,7 @@ import ipalib + from ipapython.dn import DN + from ipapython import ipaldap + from ipapython import ipautil ++from ipapython import ipa_log_manager + from ipaplatform.paths import paths + + from abshsm import attrs_name2id, attrs_id2name, bool_attr_names, populate_pkcs11_metadata, AbstractHSM +@@ -135,8 +138,12 @@ class Key(collections.MutableMapping): + def __len__(self): + return len(self.entry) + +- def __str__(self): +- return str(self.entry) ++ def __repr__(self): ++ sanitized = dict(self.entry) ++ for attr in ['ipaPrivateKey', 'ipaPublicKey', 'ipk11publickeyinfo']: ++ if attr in sanitized: ++ del sanitized[attr] ++ return repr(sanitized) + + def _cleanup_key(self): + """remove default values from LDAP entry""" +@@ -347,3 +354,46 @@ class LdapKeyDB(AbstractHSM): + '(&(objectClass=ipk11PrivateKey)(objectClass=ipaPrivateKeyObject)(objectClass=ipk11PublicKey)(objectClass=ipaPublicKeyObject))')) + + return self.cache_zone_keypairs ++ ++if __name__ == '__main__': ++ # this is debugging mode ++ # print information we think are useful to stdout ++ # other garbage goes via logger to stderr ++ ipa_log_manager.standard_logging_setup(debug=True) ++ log = ipa_log_manager.root_logger ++ ++ # IPA framework initialization ++ ipalib.api.bootstrap(in_server=True, log=None) # no logging to file ++ ipalib.api.finalize() ++ ++ # LDAP initialization ++ dns_dn = DN(ipalib.api.env.container_dns, ipalib.api.env.basedn) ++ ldap = ipaldap.LDAPClient(ipalib.api.env.ldap_uri) ++ log.debug('Connecting to LDAP') ++ # GSSAPI will be used, used has to be kinited already ++ ldap.gssapi_bind() ++ log.debug('Connected') ++ ++ ldapkeydb = LdapKeyDB(log, ldap, DN(('cn', 'keys'), ('cn', 'sec'), ++ ipalib.api.env.container_dns, ++ ipalib.api.env.basedn)) ++ ++ print('replica public keys: CKA_WRAP = TRUE') ++ print('====================================') ++ for pubkey_id, pubkey in ldapkeydb.replica_pubkeys_wrap.items(): ++ print(hexlify(pubkey_id)) ++ pprint(pubkey) ++ ++ print('') ++ print('master keys') ++ print('===========') ++ for mkey_id, mkey in ldapkeydb.master_keys.items(): ++ print(hexlify(mkey_id)) ++ pprint(mkey) ++ ++ print('') ++ print('zone key pairs') ++ print('==============') ++ for key_id, key in ldapkeydb.zone_keypairs.items(): ++ print(hexlify(key_id)) ++ pprint(key) +-- +2.4.3 + diff --git a/SOURCES/0169-DNSSEC-logging-improvements-in-ipa-ods-exporter.patch b/SOURCES/0169-DNSSEC-logging-improvements-in-ipa-ods-exporter.patch new file mode 100644 index 0000000..1c357a0 --- /dev/null +++ b/SOURCES/0169-DNSSEC-logging-improvements-in-ipa-ods-exporter.patch @@ -0,0 +1,69 @@ +From 7398819200c9a3a32effa52793240a054bc4b10f Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Tue, 15 Dec 2015 14:16:52 +0100 +Subject: [PATCH] DNSSEC: logging improvements in ipa-ods-exporter + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index 6ed7588847042e742abeef724940eec31f23ca8f..051fa53a950f7afbea5e9b1e541a9435aa02bc17 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -491,6 +491,11 @@ def cmd2ods_zone_name(cmd): + return zone_name + + def sync_zone(log, ldap, dns_dn, zone_name): ++ """synchronize metadata about zone keys for single DNS zone ++ ++ Key material has to be synchronized elsewhere. ++ Keep in mind that keys could be shared among multiple zones!""" ++ log.getChild("%s.%s" % (__name__, zone_name)) + log.debug('synchronizing zone "%s"', zone_name) + ods_keys = get_ods_keys(zone_name) + ods_keys_id = set(ods_keys.keys()) +@@ -523,30 +528,30 @@ def sync_zone(log, ldap, dns_dn, zone_name): + ldap_keys_id = set(ldap_keys.keys()) + + new_keys_id = ods_keys_id - ldap_keys_id +- log.info('new keys from ODS: %s', new_keys_id) ++ log.info('new key metadata from ODS: %s', new_keys_id) + for key_id in new_keys_id: + cn = "cn=%s" % key_id + key_dn = DN(cn, keys_dn) +- log.debug('adding key "%s" to LDAP', key_dn) ++ log.debug('adding key metadata "%s" to LDAP', key_dn) + ldap_key = ldap.make_entry(key_dn, + objectClass=['idnsSecKey'], + **ods_keys[key_id]) + ldap.add_entry(ldap_key) + + deleted_keys_id = ldap_keys_id - ods_keys_id +- log.info('deleted keys in LDAP: %s', deleted_keys_id) ++ log.info('deleted key metadata in LDAP: %s', deleted_keys_id) + for key_id in deleted_keys_id: + cn = "cn=%s" % key_id + key_dn = DN(cn, keys_dn) +- log.debug('deleting key "%s" from LDAP', key_dn) ++ log.debug('deleting key metadata "%s" from LDAP', key_dn) + ldap.delete_entry(key_dn) + + update_keys_id = ldap_keys_id.intersection(ods_keys_id) +- log.info('keys in LDAP & ODS: %s', update_keys_id) ++ log.info('key metadata in LDAP & ODS: %s', update_keys_id) + for key_id in update_keys_id: + ldap_key = ldap_keys[key_id] + ods_key = ods_keys[key_id] +- log.debug('updating key "%s" in LDAP', ldap_key.dn) ++ log.debug('updating key metadata "%s" in LDAP', ldap_key.dn) + ldap_key.update(ods_key) + try: + ldap.update_entry(ldap_key) +-- +2.4.3 + diff --git a/SOURCES/0170-DNSSEC-remove-keys-purged-by-OpenDNSSEC-from-master-.patch b/SOURCES/0170-DNSSEC-remove-keys-purged-by-OpenDNSSEC-from-master-.patch new file mode 100644 index 0000000..c204e3c --- /dev/null +++ b/SOURCES/0170-DNSSEC-remove-keys-purged-by-OpenDNSSEC-from-master-.patch @@ -0,0 +1,248 @@ +From db24ab9357ea63deaf25e8b9c5b3ad2d08a0c82b Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Tue, 15 Dec 2015 15:22:45 +0100 +Subject: [PATCH] DNSSEC: remove keys purged by OpenDNSSEC from master HSM from + LDAP + +Key purging has to be only only after key metadata purging so +ipa-dnskeysyncd on replices does not fail while dereferencing +non-existing keys. + +https://fedorahosted.org/freeipa/ticket/5334 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 45 ++++++++++++++++++++++---- + ipapython/dnssec/ldapkeydb.py | 72 ++++++++++++++++++++++++++++++++++------- + 2 files changed, 99 insertions(+), 18 deletions(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index 051fa53a950f7afbea5e9b1e541a9435aa02bc17..2a1cc4315355569b24ec6ef42a68f4d64fee9f4f 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -387,7 +387,10 @@ def master2ldap_master_keys_sync(log, ldapkeydb, localhsm): + ldapkeydb.flush() + + def master2ldap_zone_keys_sync(log, ldapkeydb, localhsm): +- # synchroniza zone keys ++ """add and update zone key material from local HSM to LDAP ++ ++ No key material will be removed, only new keys will be added or updated. ++ Key removal is hanled by master2ldap_zone_keys_purge().""" + log = log.getChild('master2ldap_zone_keys') + keypairs_ldap = ldapkeydb.zone_keypairs + log.debug("zone keys in LDAP: %s", hex_set(keypairs_ldap)) +@@ -396,10 +399,10 @@ def master2ldap_zone_keys_sync(log, ldapkeydb, localhsm): + privkeys_local = localhsm.zone_privkeys + log.debug("zone keys in local HSM: %s", hex_set(privkeys_local)) + +- assert set(pubkeys_local) == set(privkeys_local), \ +- "IDs of private and public keys for DNS zones in local HSM does " \ +- "not match to key pairs: %s vs. %s" % \ +- (hex_set(pubkeys_local), hex_set(privkeys_local)) ++ assert set(pubkeys_local) == set(privkeys_local), ( ++ "IDs of private and public keys for DNS zones in local HSM does " ++ "not match to key pairs: %s vs. %s" % ++ (hex_set(pubkeys_local), hex_set(privkeys_local))) + + new_keys = set(pubkeys_local) - set(keypairs_ldap) + log.debug("new zone keys in local HSM: %s", hex_set(new_keys)) +@@ -420,6 +423,29 @@ def master2ldap_zone_keys_sync(log, ldapkeydb, localhsm): + sync_set_metadata_2ldap(log, privkeys_local, keypairs_ldap) + ldapkeydb.flush() + ++def master2ldap_zone_keys_purge(log, ldapkeydb, localhsm): ++ """purge removed key material from LDAP (but not metadata) ++ ++ Keys which are present in LDAP but not in local HSM will be removed. ++ Key metadata must be removed first so references to removed key material ++ are removed before actually removing the keys.""" ++ keypairs_ldap = ldapkeydb.zone_keypairs ++ log.debug("zone keys in LDAP: %s", hex_set(keypairs_ldap)) ++ ++ pubkeys_local = localhsm.zone_pubkeys ++ privkeys_local = localhsm.zone_privkeys ++ log.debug("zone keys in local HSM: %s", hex_set(privkeys_local)) ++ assert set(pubkeys_local) == set(privkeys_local), \ ++ "IDs of private and public keys for DNS zones in local HSM does " \ ++ "not match to key pairs: %s vs. %s" % \ ++ (hex_set(pubkeys_local), hex_set(privkeys_local)) ++ ++ deleted_key_ids = set(keypairs_ldap) - set(pubkeys_local) ++ log.debug("zone keys deleted from local HSM but present in LDAP: %s", ++ hex_set(deleted_key_ids)) ++ for zkey_id in deleted_key_ids: ++ keypairs_ldap[zkey_id].schedule_deletion() ++ ldapkeydb.flush() + + def hex_set(s): + out = set() +@@ -600,7 +626,7 @@ ldap.connect(ccache=ccache_name) + log.debug('Connected') + + +-### DNSSEC master: key synchronization ++### DNSSEC master: key material upload & synchronization (but not deletion) + ldapkeydb = LdapKeyDB(log, ldap, DN(('cn', 'keys'), ('cn', 'sec'), + ipalib.api.env.container_dns, + ipalib.api.env.basedn)) +@@ -612,7 +638,7 @@ master2ldap_master_keys_sync(log, ldapkeydb, localhsm) + master2ldap_zone_keys_sync(log, ldapkeydb, localhsm) + + +-### DNSSEC master: DNSSEC key metadata upload ++### DNSSEC master: DNSSEC key metadata upload & synchronization & deletion + # command receive is delayed so the command will stay in socket queue until + # the problem with LDAP server or HSM is fixed + try: +@@ -666,6 +692,11 @@ try: + for zone_row in db.execute("SELECT name FROM zones"): + sync_zone(log, ldap, dns_dn, zone_row['name']) + ++ ### DNSSEC master: DNSSEC key material purging ++ # references to old key material were removed above in sync_zone() ++ # so now we can purge old key material from LDAP ++ master2ldap_zone_keys_purge(log, ldapkeydb, localhsm) ++ + except Exception as ex: + msg = "ipa-ods-exporter exception: %s" % traceback.format_exc(ex) + log.exception(ex) +diff --git a/ipapython/dnssec/ldapkeydb.py b/ipapython/dnssec/ldapkeydb.py +index 54a1fba1d2db8f27c9c9b881ff42201365852587..2131508cc6779d1cc99c417a31da866b7fdcf2c2 100644 +--- a/ipapython/dnssec/ldapkeydb.py ++++ b/ipapython/dnssec/ldapkeydb.py +@@ -105,40 +105,56 @@ def get_default_attrs(object_classes): + result.update(defaults[cls]) + return result + ++ + class Key(collections.MutableMapping): + """abstraction to hide LDAP entry weirdnesses: + - non-normalized attribute names + - boolean attributes returned as strings ++ - planned entry deletion prevents subsequent use of the instance + """ + def __init__(self, entry, ldap, ldapkeydb): + self.entry = entry ++ self._delentry = None # indicates that object was deleted + self.ldap = ldap + self.ldapkeydb = ldapkeydb + self.log = ldap.log.getChild(__name__) + ++ def __assert_not_deleted(self): ++ assert self.entry and not self._delentry, ( ++ "attempt to use to-be-deleted entry %s detected" ++ % self._delentry.dn) ++ + def __getitem__(self, key): ++ self.__assert_not_deleted() + val = self.entry.single_value[key] + if key.lower() in bool_attr_names: + val = ldap_bool(val) + return val + + def __setitem__(self, key, value): ++ self.__assert_not_deleted() + self.entry[key] = value + + def __delitem__(self, key): ++ self.__assert_not_deleted() + del self.entry[key] + + def __iter__(self): + """generates list of ipa names of all PKCS#11 attributes present in the object""" ++ self.__assert_not_deleted() + for ipa_name in self.entry.keys(): + lowercase = ipa_name.lower() + if lowercase in attrs_name2id: + yield lowercase + + def __len__(self): ++ self.__assert_not_deleted() + return len(self.entry) + + def __repr__(self): ++ if self._delentry: ++ return 'deleted entry: %s' % repr(self._delentry) ++ + sanitized = dict(self.entry) + for attr in ['ipaPrivateKey', 'ipaPublicKey', 'ipk11publickeyinfo']: + if attr in sanitized: +@@ -153,6 +169,49 @@ class Key(collections.MutableMapping): + if self.get(attr, empty) == default_attrs[attr]: + del self[attr] + ++ def _update_key(self): ++ """remove default values from LDAP entry and write back changes""" ++ if self._delentry: ++ self._delete_key() ++ return ++ ++ self._cleanup_key() ++ ++ try: ++ self.ldap.update_entry(self.entry) ++ except ipalib.errors.EmptyModlist: ++ pass ++ ++ def _delete_key(self): ++ """remove key metadata entry from LDAP ++ ++ After calling this, the python object is no longer valid and all ++ subsequent method calls on it will fail. ++ """ ++ assert not self.entry, ( ++ "Key._delete_key() called before Key.schedule_deletion()") ++ assert self._delentry, "Key._delete_key() called more than once" ++ self.log.debug('deleting key id 0x%s DN %s from LDAP', ++ hexlify(self._delentry.single_value['ipk11id']), ++ self._delentry.dn) ++ self.ldap.delete_entry(self._delentry) ++ self._delentry = None ++ self.ldap = None ++ self.ldapkeydb = None ++ ++ def schedule_deletion(self): ++ """schedule key deletion from LDAP ++ ++ Calling schedule_deletion() will make this object incompatible with ++ normal Key. After that the object must not be read or modified. ++ Key metadata will be actually deleted when LdapKeyDB.flush() is called. ++ """ ++ assert not self._delentry, ( ++ "Key.schedule_deletion() called more than once") ++ self._delentry = self.entry ++ self.entry = None ++ ++ + class ReplicaKey(Key): + # TODO: object class assert + def __init__(self, entry, ldap, ldapkeydb): +@@ -239,21 +298,12 @@ class LdapKeyDB(AbstractHSM): + self._update_keys() + return keys + +- def _update_key(self, key): +- """remove default values from LDAP entry and write back changes""" +- key._cleanup_key() +- +- try: +- self.ldap.update_entry(key.entry) +- except ipalib.errors.EmptyModlist: +- pass +- + def _update_keys(self): + for cache in [self.cache_masterkeys, self.cache_replica_pubkeys_wrap, +- self.cache_zone_keypairs]: ++ self.cache_zone_keypairs]: + if cache: + for key in cache.itervalues(): +- self._update_key(key) ++ key._update_key() + + def flush(self): + """write back content of caches to LDAP""" +-- +2.4.3 + diff --git a/SOURCES/0171-DNSSEC-ipa-dnskeysyncd-Skip-zones-with-old-DNSSEC-me.patch b/SOURCES/0171-DNSSEC-ipa-dnskeysyncd-Skip-zones-with-old-DNSSEC-me.patch new file mode 100644 index 0000000..d248eb3 --- /dev/null +++ b/SOURCES/0171-DNSSEC-ipa-dnskeysyncd-Skip-zones-with-old-DNSSEC-me.patch @@ -0,0 +1,125 @@ +From 96695bb8e414be941e07d43652516a99cfd89a24 Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Sun, 20 Dec 2015 18:36:48 +0100 +Subject: [PATCH] DNSSEC: ipa-dnskeysyncd: Skip zones with old DNSSEC metadata + in LDAP + +This filtering is useful in cases where LDAP contains DNS zones which +have old metadata objects and DNSSEC disabled. Such zones must be +ignored to prevent errors while calling dnssec-keyfromlabel or rndc. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + ipapython/dnssec/bindmgr.py | 16 +++++++++++++--- + ipapython/dnssec/keysyncer.py | 24 ++++++++++++++++++------ + 2 files changed, 31 insertions(+), 9 deletions(-) + +diff --git a/ipapython/dnssec/bindmgr.py b/ipapython/dnssec/bindmgr.py +index 70caaf4ee74f594c652cd82bccb8964e172bc719..d81dad940df49e79f4534c2224c10ecf192794ba 100644 +--- a/ipapython/dnssec/bindmgr.py ++++ b/ipapython/dnssec/bindmgr.py +@@ -191,10 +191,20 @@ class BINDMgr(object): + + self.notify_zone(zone) + +- def sync(self): +- """Synchronize list of zones in LDAP with BIND.""" ++ def sync(self, dnssec_zones): ++ """Synchronize list of zones in LDAP with BIND. ++ ++ dnssec_zones lists zones which should be processed. All other zones ++ will be ignored even though they were modified using ldap_event(). ++ ++ This filter is useful in cases where LDAP contains DNS zones which ++ have old metadata objects and DNSSEC disabled. Such zones must be ++ ignored to prevent errors while calling dnssec-keyfromlabel or rndc. ++ """ + self.log.debug('Key metadata in LDAP: %s' % self.ldap_keys) +- for zone in self.modified_zones: ++ self.log.debug('Zones modified but skipped during bindmgr.sync: %s', ++ self.modified_zones - dnssec_zones) ++ for zone in self.modified_zones.intersection(dnssec_zones): + self.sync_zone(zone) + + self.modified_zones = set() +diff --git a/ipapython/dnssec/keysyncer.py b/ipapython/dnssec/keysyncer.py +index de5b5aa5f670db4c58fb92b989e181d45d887b55..5ba9baaab30b07d2f4e4ae3a3507898d08a0d6c1 100644 +--- a/ipapython/dnssec/keysyncer.py ++++ b/ipapython/dnssec/keysyncer.py +@@ -6,6 +6,8 @@ import logging + import ldap.dn + import os + ++import dns.name ++ + from ipaplatform.paths import paths + from ipapython import ipautil + +@@ -33,6 +35,7 @@ class KeySyncer(SyncReplConsumer): + + self.bindmgr = BINDMgr(self.api) + self.init_done = False ++ self.dnssec_zones = set() + SyncReplConsumer.__init__(self, *args, **kwargs) + + def _get_objclass(self, attrs): +@@ -112,7 +115,7 @@ class KeySyncer(SyncReplConsumer): + self.ods_sync() + self.hsm_replica_sync() + self.hsm_master_sync() +- self.bindmgr.sync() ++ self.bindmgr.sync(self.dnssec_zones) + + # idnsSecKey wrapper + # Assumption: metadata points to the same key blob all the time, +@@ -121,23 +124,29 @@ class KeySyncer(SyncReplConsumer): + def key_meta_add(self, uuid, dn, newattrs): + self.hsm_replica_sync() + self.bindmgr.ldap_event('add', uuid, newattrs) +- self.bindmgr_sync() ++ self.bindmgr_sync(self.dnssec_zones) + + def key_meta_del(self, uuid, dn, oldattrs): + self.bindmgr.ldap_event('del', uuid, oldattrs) +- self.bindmgr_sync() ++ self.bindmgr_sync(self.dnssec_zones) + self.hsm_replica_sync() + + def key_metadata_sync(self, uuid, dn, oldattrs, newattrs): + self.bindmgr.ldap_event('mod', uuid, newattrs) +- self.bindmgr_sync() ++ self.bindmgr_sync(self.dnssec_zones) + +- def bindmgr_sync(self): ++ def bindmgr_sync(self, dnssec_zones): + if self.init_done: +- self.bindmgr.sync() ++ self.bindmgr.sync(dnssec_zones) + + # idnsZone wrapper + def zone_add(self, uuid, dn, newattrs): ++ zone = dns.name.from_text(newattrs['idnsname'][0]) ++ if self.__is_dnssec_enabled(newattrs): ++ self.dnssec_zones.add(zone) ++ else: ++ self.dnssec_zones.discard(zone) ++ + if not self.ismaster: + return + +@@ -146,6 +155,9 @@ class KeySyncer(SyncReplConsumer): + self.ods_sync() + + def zone_del(self, uuid, dn, oldattrs): ++ zone = dns.name.from_text(oldattrs['idnsname'][0]) ++ self.dnssec_zones.discard(zone) ++ + if not self.ismaster: + return + +-- +2.4.3 + diff --git a/SOURCES/0172-DNSSEC-ipa-ods-exporter-add-ldap-cleanup-command.patch b/SOURCES/0172-DNSSEC-ipa-ods-exporter-add-ldap-cleanup-command.patch new file mode 100644 index 0000000..d28cb57 --- /dev/null +++ b/SOURCES/0172-DNSSEC-ipa-ods-exporter-add-ldap-cleanup-command.patch @@ -0,0 +1,142 @@ +From a5687f3070877fc28435d9db4d5fed8c521dbf41 Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Sun, 20 Dec 2015 19:19:28 +0100 +Subject: [PATCH] DNSSEC: ipa-ods-exporter: add ldap-cleanup command + +Command "ldap-cleanup " will remove all key metadata from +LDAP. This can be used manually in sequence like: +ldap-cleanup +update +to delete all key metadata from LDAP and re-export them from OpenDNSSEC. + +ldap-cleanup command should be called when disabling DNSSEC on a DNS +zone to remove stale key metadata from LDAP. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 60 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 48 insertions(+), 12 deletions(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index 2a1cc4315355569b24ec6ef42a68f4d64fee9f4f..8abb5cf7c6d1e5e8ea996b8925d2e8cffc44133c 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -227,7 +227,9 @@ def get_ldap_zone(ldap, dns_base, name): + except ipalib.errors.NotFound: + continue + +- assert ldap_zone is not None, 'DNS zone "%s" should exist in LDAP' % name ++ if ldap_zone is None: ++ raise ipalib.errors.NotFound( ++ reason='DNS zone "%s" not found in LDAP' % name) + + return ldap_zone + +@@ -481,25 +483,37 @@ def parse_command(cmd): + if cmd == 'ipa-hsm-update': + return (0, + 'HSM synchronization finished, skipping zone synchronization.', +- None) ++ None, ++ cmd) + + elif cmd == 'ipa-full-update': + return (None, + 'Synchronization of all zones was finished.', +- None) ++ None, ++ cmd) ++ ++ elif cmd.startswith('ldap-cleanup '): ++ zone_name = cmd2ods_zone_name(cmd) ++ return (None, ++ 'Zone "%s" metadata will be removed from LDAP.\n' % zone_name, ++ zone_name, ++ 'ldap-cleanup') + +- elif not cmd.startswith('update '): ++ elif cmd.startswith('update '): ++ zone_name = cmd2ods_zone_name(cmd) ++ return (None, ++ 'Zone "%s" metadata will be updated in LDAP.\n' % zone_name, ++ zone_name, ++ 'update') ++ ++ else: + return (0, + 'Command "%s" is not supported by IPA; ' + 'HSM synchronization was finished and the command ' + 'will be ignored.' % cmd, ++ None, + None) + +- else: +- zone_name = cmd2ods_zone_name(cmd) +- return (None, +- 'Zone was "%s" updated.\n' % zone_name, +- zone_name) + + def send_systemd_reply(conn, reply): + # Reply & close connection early. +@@ -510,7 +524,7 @@ def send_systemd_reply(conn, reply): + + def cmd2ods_zone_name(cmd): + # ODS stores zone name without trailing period +- zone_name = cmd[7:].strip() ++ zone_name = cmd.split(' ', 1)[1].strip() + if len(zone_name) > 1 and zone_name[-1] == '.': + zone_name = zone_name[:-1] + +@@ -584,6 +598,25 @@ def sync_zone(log, ldap, dns_dn, zone_name): + except ipalib.errors.EmptyModlist: + continue + ++def cleanup_ldap_zone(log, ldap, dns_dn, zone_name): ++ """delete all key metadata about zone keys for single DNS zone ++ ++ Key material has to be synchronized elsewhere. ++ Keep in mind that keys could be shared among multiple zones!""" ++ log = log.getChild("%s.%s" % (__name__, zone_name)) ++ log.debug('cleaning up key metadata from zone "%s"', zone_name) ++ ++ try: ++ ldap_zone = get_ldap_zone(ldap, dns_dn, zone_name) ++ ldap_keys = get_ldap_keys(ldap, ldap_zone.dn) ++ except ipalib.errors.NotFound as ex: ++ # zone or cn=keys container does not exist, we are done ++ log.debug(str(ex)) ++ return ++ ++ for ldap_key in ldap_keys: ++ log.debug('deleting key metadata "%s"', ldap_key.dn) ++ ldap.delete_entry(ldap_key) + + log = logging.getLogger('root') + # this service is usually socket-activated +@@ -656,7 +689,7 @@ except KeyError as e: + conn = None + cmd = sys.argv[1] + +-exitcode, msg, zone_name = parse_command(cmd) ++exitcode, msg, zone_name, cmd = parse_command(cmd) + + if exitcode is not None: + if conn: +@@ -686,7 +719,10 @@ try: + + if zone_name is not None: + # only one zone should be processed +- sync_zone(log, ldap, dns_dn, zone_name) ++ if cmd == 'update': ++ sync_zone(log, ldap, dns_dn, zone_name) ++ elif cmd == 'ldap-cleanup': ++ cleanup_ldap_zone(log, ldap, dns_dn, zone_name) + else: + # process all zones + for zone_row in db.execute("SELECT name FROM zones"): +-- +2.4.3 + diff --git a/SOURCES/0173-DNSSEC-ipa-dnskeysyncd-call-ods-signer-ldap-cleanup-.patch b/SOURCES/0173-DNSSEC-ipa-dnskeysyncd-call-ods-signer-ldap-cleanup-.patch new file mode 100644 index 0000000..2f5d404 --- /dev/null +++ b/SOURCES/0173-DNSSEC-ipa-dnskeysyncd-call-ods-signer-ldap-cleanup-.patch @@ -0,0 +1,44 @@ +From dbb7b91bf052bc4d5a4f545044e8949b67b511db Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Sun, 20 Dec 2015 19:35:55 +0100 +Subject: [PATCH] DNSSEC: ipa-dnskeysyncd: call ods-signer ldap-cleanup on zone + removal + +Command "ldap-cleanup " is called to remove all key metadata from +LDAP. This command is now called when disabling DNSSEC on a DNS zone. The stale +metadata were causing problems when re-enabling DNSSEC on the same zone. + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + ipapython/dnssec/odsmgr.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/ipapython/dnssec/odsmgr.py b/ipapython/dnssec/odsmgr.py +index efbe16cc6ebf050d9cf347ed97b2b2e4b37c8a6e..44d94ac3ab9e68feba067e8f14530894bda22855 100644 +--- a/ipapython/dnssec/odsmgr.py ++++ b/ipapython/dnssec/odsmgr.py +@@ -152,12 +152,18 @@ class ODSMgr(object): + output = self.ksmutil(cmd) + self.log.info(output) + self.notify_enforcer() ++ self.cleanup_signer(name) + + def notify_enforcer(self): + cmd = ['notify'] + output = self.ksmutil(cmd) + self.log.info(output) + ++ def cleanup_signer(self, zone_name): ++ cmd = ['ods-signer', 'ldap-cleanup', str(zone_name)] ++ output = ipautil.run(cmd, capture_output=True) ++ self.log.info(output) ++ + def ldap_event(self, op, uuid, attrs): + """Record single LDAP event - zone addition or deletion. + +-- +2.4.3 + diff --git a/SOURCES/0174-DNSSEC-Log-debug-messages-at-log-level-DEBUG.patch b/SOURCES/0174-DNSSEC-Log-debug-messages-at-log-level-DEBUG.patch new file mode 100644 index 0000000..1388c9d --- /dev/null +++ b/SOURCES/0174-DNSSEC-Log-debug-messages-at-log-level-DEBUG.patch @@ -0,0 +1,29 @@ +From d3c3377ecf597787af7d8975f6d0a822798585f9 Mon Sep 17 00:00:00 2001 +From: Petr Spacek +Date: Tue, 24 Nov 2015 12:49:16 +0100 +Subject: [PATCH] DNSSEC: Log debug messages at log level DEBUG + +https://fedorahosted.org/freeipa/ticket/5348 + +Reviewed-By: Martin Basti +Reviewed-By: Martin Basti +--- + daemons/dnssec/ipa-ods-exporter | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter +index 8abb5cf7c6d1e5e8ea996b8925d2e8cffc44133c..2b71b0c38eeb9c5f61adecdb802c081433e3db27 100755 +--- a/daemons/dnssec/ipa-ods-exporter ++++ b/daemons/dnssec/ipa-ods-exporter +@@ -310,7 +310,7 @@ def ldap2master_replica_keys_sync(log, ldapkeydb, localhsm): + log.info("new replica keys in LDAP: %s", hex_set(new_replica_keys)) + for key_id in new_replica_keys: + new_key_ldap = ldapkeydb.replica_pubkeys_wrap[key_id] +- log.error('label=%s, id=%s, data=%s', ++ log.debug('label=%s, id=%s, data=%s', + new_key_ldap['ipk11label'], + hexlify(new_key_ldap['ipk11id']), + hexlify(new_key_ldap['ipapublickey'])) +-- +2.4.3 + diff --git a/SOURCES/0175-Allow-to-used-mixed-case-for-sysrestore.patch b/SOURCES/0175-Allow-to-used-mixed-case-for-sysrestore.patch new file mode 100644 index 0000000..24d9208 --- /dev/null +++ b/SOURCES/0175-Allow-to-used-mixed-case-for-sysrestore.patch @@ -0,0 +1,86 @@ +From f7e06707be5c590ce03a50117da483931a0680c6 Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Tue, 5 Jan 2016 17:58:49 +0100 +Subject: [PATCH] Allow to used mixed case for sysrestore + +This commit allows to use mixed case of keys for sysrestore, before this +commit all keys were saved in lowercase what prevents to accesing them. + +Original usage of mixed case for sysretore key in opendssecinstance had +to be changed to lowercase to prevent issues on already installed +systems. + +https://fedorahosted.org/freeipa/ticket/5574 + +Reviewed-By: Martin Babinsky +--- + ipapython/sysrestore.py | 4 ++++ + ipaserver/install/opendnssecinstance.py | 6 ++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ipapython/sysrestore.py b/ipapython/sysrestore.py +index 1a111258bc0f6dd503673028d3a990821f077fef..97f0d760ae58c8d4bd0409565bf47167a689a06c 100644 +--- a/ipapython/sysrestore.py ++++ b/ipapython/sysrestore.py +@@ -67,6 +67,7 @@ class FileStore: + self.files = {} + + p = ConfigParser.SafeConfigParser() ++ p.optionxform = str + p.read(self._index) + + for section in p.sections(): +@@ -88,6 +89,7 @@ class FileStore: + return + + p = ConfigParser.SafeConfigParser() ++ p.optionxform = str + + p.add_section('files') + for (key, value) in self.files.items(): +@@ -324,6 +326,7 @@ class StateFile: + self.modules = {} + + p = ConfigParser.SafeConfigParser() ++ p.optionxform = str + p.read(self._path) + + for module in p.sections(): +@@ -352,6 +355,7 @@ class StateFile: + return + + p = ConfigParser.SafeConfigParser() ++ p.optionxform = str + + for module in self.modules.keys(): + p.add_section(module) +diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py +index c5377d910d8f38a1ea0e05461ecf1b92f05ca2ca..2ab320b8e5db6c7c4e03850ecfe26e0e178d04a1 100644 +--- a/ipaserver/install/opendnssecinstance.py ++++ b/ipaserver/install/opendnssecinstance.py +@@ -265,11 +265,11 @@ class OpenDNSSECInstance(service.Service): + + def __setup_dnssec(self): + # run once only +- if self.get_state("KASP_DB_configured") and not self.kasp_db_file: ++ if self.get_state("kasp_db_configured") and not self.kasp_db_file: + root_logger.debug("Already configured, skipping step") + return + +- self.backup_state("KASP_DB_configured", True) ++ self.backup_state("kasp_db_configured", True) + + if not self.fstore.has_file(paths.OPENDNSSEC_KASP_DB): + self.fstore.backup_file(paths.OPENDNSSEC_KASP_DB) +@@ -368,6 +368,8 @@ class OpenDNSSECInstance(service.Service): + root_logger.debug(error) + pass + ++ self.restore_state("kasp_db_configured") # just eat state ++ + # disabled by default, by ldap_enable() + if enabled: + self.enable() +-- +2.4.3 + diff --git a/SOURCES/0176-prevent-crash-of-CA-less-server-upgrade-due-to-absen.patch b/SOURCES/0176-prevent-crash-of-CA-less-server-upgrade-due-to-absen.patch new file mode 100644 index 0000000..b24e5d7 --- /dev/null +++ b/SOURCES/0176-prevent-crash-of-CA-less-server-upgrade-due-to-absen.patch @@ -0,0 +1,77 @@ +From 61f54afcde1df217fec01aa9ab38b0b9b704c501 Mon Sep 17 00:00:00 2001 +From: Martin Babinsky +Date: Tue, 5 Jan 2016 13:00:24 +0100 +Subject: [PATCH] prevent crash of CA-less server upgrade due to absent + certmonger + +ipa-server-upgrade tests whether certmonger service is running before +attempting to upgrade IPA master. This causes the upgrader to always fail when +there is no CA installer and certmonger is not needed, effectively preventing +CA-less IPA master to upgrade succefuly. + +This test is now skipped if CA is not enabled. + +https://fedorahosted.org/freeipa/ticket/5519 + +Reviewed-By: Jan Cholasta +--- + ipaserver/install/server/upgrade.py | 29 +++++++++++++++++++++++++++-- + 1 file changed, 27 insertions(+), 2 deletions(-) + +diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py +index 945cb3ebd63767cb1d57083e1da7c5605ac5a2f9..616fba5c1a5b3737481aecbb09ab5344641a3b04 100644 +--- a/ipaserver/install/server/upgrade.py ++++ b/ipaserver/install/server/upgrade.py +@@ -292,6 +292,24 @@ def setup_firefox_extension(fstore): + http.setup_firefox_extension(realm, domain) + + ++def is_ca_enabled(): ++ """ ++ check whether there is an active CA master ++ :return: True if there is an active CA in topology, False otherwise ++ """ ++ ldap2 = api.Backend.ldap2 ++ was_connected = ldap2.isconnected() ++ ++ if not was_connected: ++ ldap2.connect() ++ ++ try: ++ return api.Command.ca_is_enabled()['result'] ++ finally: ++ if not was_connected: ++ ldap2.disconnect() ++ ++ + def ca_configure_profiles_acl(ca): + root_logger.info('[Authorizing RA Agent to modify profiles]') + +@@ -1416,7 +1434,9 @@ def upgrade_configuration(): + http = httpinstance.HTTPInstance(fstore) + http.configure_selinux_for_httpd() + http.change_mod_nss_port_from_http() +- http.configure_certmonger_renewal_guard() ++ ++ if is_ca_enabled(): ++ http.configure_certmonger_renewal_guard() + + ds.configure_dirsrv_ccache() + +@@ -1562,7 +1582,12 @@ def upgrade_check(options): + print unicode(e) + sys.exit(1) + +- if not services.knownservices.certmonger.is_running(): ++ try: ++ ca_is_enabled = is_ca_enabled() ++ except Exception as e: ++ raise RuntimeError("Cannot connect to LDAP server: {0}".format(e)) ++ ++ if not services.knownservices.certmonger.is_running() and ca_is_enabled: + raise RuntimeError('Certmonger is not running. Start certmonger and run upgrade again.') + + if not options.skip_version_check: +-- +2.4.3 + diff --git a/SOURCES/0177-Upgrade-Fix-upgrade-of-NIS-Server-configuration.patch b/SOURCES/0177-Upgrade-Fix-upgrade-of-NIS-Server-configuration.patch new file mode 100644 index 0000000..6dd6c5d --- /dev/null +++ b/SOURCES/0177-Upgrade-Fix-upgrade-of-NIS-Server-configuration.patch @@ -0,0 +1,251 @@ +From e22b4320033803331ce8960d05113666fe9192ec Mon Sep 17 00:00:00 2001 +From: Martin Basti +Date: Wed, 6 Jan 2016 19:47:22 +0100 +Subject: [PATCH] Upgrade: Fix upgrade of NIS Server configuration + +Former upgrade file always created the NIS Server container, that caused +the ipa-nis-manage did not set all required NIS maps. Default creation +of container has been removed. + +Updating of NIS Server configuration and +NIS maps is done only if the NIS Server container exists. + +https://fedorahosted.org/freeipa/ticket/5507 + +Reviewed-By: Alexander Bokovoy +--- + install/share/Makefile.am | 1 + + install/share/nis-update.uldif | 38 +++++++++++++++ + install/updates/50-nis.update | 58 ++-------------------- + ipaplatform/base/paths.py | 1 + + ipaserver/install/plugins/update_nis.py | 86 +++++++++++++++++++++++++++++++++ + 5 files changed, 129 insertions(+), 55 deletions(-) + create mode 100644 install/share/nis-update.uldif + create mode 100644 ipaserver/install/plugins/update_nis.py + +diff --git a/install/share/Makefile.am b/install/share/Makefile.am +index e4cca8708ab0042d6cb37eba31341e53e3cdac4d..09a341ce177e16e14e7d606e5628e6ca21ddf872 100644 +--- a/install/share/Makefile.am ++++ b/install/share/Makefile.am +@@ -60,6 +60,7 @@ app_DATA = \ + memberof-task.ldif \ + memberof-conf.ldif \ + nis.uldif \ ++ nis-update.uldif \ + opendnssec_conf.template \ + opendnssec_kasp.template \ + unique-attributes.ldif \ +diff --git a/install/share/nis-update.uldif b/install/share/nis-update.uldif +new file mode 100644 +index 0000000000000000000000000000000000000000..e602c1de061fbcece349b2d86970c4db5051473b +--- /dev/null ++++ b/install/share/nis-update.uldif +@@ -0,0 +1,38 @@ ++# Updates for NIS ++ ++# Correct syntax error that caused users to not appear ++dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config ++replace:nis-value-format: %merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})") ++ ++# Correct syntax error that caused nested netgroups to not work ++# https://bugzilla.redhat.com/show_bug.cgi?id=788625 ++dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config ++replace:nis-value-format: %merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})") ++ ++# Make the padding an expression so usercat and hostcat always gets ++# evaluated when displaying entries. ++# https://bugzilla.redhat.com/show_bug.cgi?id=767372 ++dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config ++replace:nis-value-format: %merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"-\\\")\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"-\\\")\"),%{nisDomainName:-})") ++ ++dn: nis-domain=$DOMAIN+nis-map=ethers.byaddr, cn=NIS Server, cn=plugins, cn=config ++default:objectclass: top ++default:objectclass: extensibleObject ++default:nis-domain: $DOMAIN ++default:nis-map: ethers.byaddr ++default:nis-base: cn=computers, cn=accounts, $SUFFIX ++default:nis-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost)) ++default:nis-keys-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6") ++default:nis-values-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6 %7") ++default:nis-secure: no ++ ++dn: nis-domain=$DOMAIN+nis-map=ethers.byname, cn=NIS Server, cn=plugins, cn=config ++default:objectclass: top ++default:objectclass: extensibleObject ++default:nis-domain: $DOMAIN ++default:nis-map: ethers.byname ++default:nis-base: cn=computers, cn=accounts, $SUFFIX ++default:nis-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost)) ++default:nis-keys-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%7") ++default:nis-values-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6 %7") ++default:nis-secure: no +diff --git a/install/updates/50-nis.update b/install/updates/50-nis.update +index 149889ec7bdb38073eb6df88628792526cfe58e6..05a166f003aefc50fc25f10f01f7364d752425bc 100644 +--- a/install/updates/50-nis.update ++++ b/install/updates/50-nis.update +@@ -1,55 +1,3 @@ +-# NIS Server plugin must be disabled by default +-# command 'ipa-nis-manage enable' enables NIS server +-dn: cn=NIS Server,cn=plugins,cn=config +-default:objectclass: top +-default:objectclass: nsSlapdPlugin +-default:objectclass: extensibleObject +-default:cn: NIS Server +-default:nsslapd-pluginpath: /usr/lib$LIBARCH/dirsrv/plugins/nisserver-plugin.so +-default:nsslapd-plugininitfunc: nis_plugin_init +-default:nsslapd-plugintype: object +-default:nsslapd-pluginbetxn: on +-default:nsslapd-pluginenabled: off +-default:nsslapd-pluginid: nis-server +-default:nsslapd-pluginversion: 0.10 +-default:nsslapd-pluginvendor: redhat.com +-default:nsslapd-plugindescription: NIS Server Plugin +-default:nis-tcp-wrappers-name: nis-server +- +-# Correct syntax error that caused users to not appear +-dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config +-replace:nis-value-format: %merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})") +- +-# Correct syntax error that caused nested netgroups to not work +-# https://bugzilla.redhat.com/show_bug.cgi?id=788625 +-dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config +-replace:nis-value-format: %merge(" ","%{memberNisNetgroup}","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})") +- +-# Make the padding an expression so usercat and hostcat always gets +-# evaluated when displaying entries. +-# https://bugzilla.redhat.com/show_bug.cgi?id=767372 +-dn: nis-domain=$DOMAIN+nis-map=netgroup, cn=NIS Server, cn=plugins, cn=config +-replace:nis-value-format: %merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"-\"),%{nisDomainName:-})")::%merge(" ","%deref_f(\"member\",\"(objectclass=ipanisNetgroup)\",\"cn\")","(%link(\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%{externalHost}\\\\\\\",\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberHost\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"fqdn\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"%ifeq(\\\"hostCategory\\\",\\\"all\\\",\\\"\\\",\\\"-\\\")\",\",\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"%collect(\\\\\\\"%deref(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\",\\\\\\\"%deref_r(\\\\\\\\\\\\\\\"memberUser\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"member\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"uid\\\\\\\\\\\\\\\")\\\\\\\")\\\")\",\"%ifeq(\\\"userCategory\\\",\\\"all\\\",\\\"\\\",\\\"-\\\")\"),%{nisDomainName:-})") +- +-dn: nis-domain=$DOMAIN+nis-map=ethers.byaddr, cn=NIS Server, cn=plugins, cn=config +-default:objectclass: top +-default:objectclass: extensibleObject +-default:nis-domain: $DOMAIN +-default:nis-map: ethers.byaddr +-default:nis-base: cn=computers, cn=accounts, $SUFFIX +-default:nis-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost)) +-default:nis-keys-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6") +-default:nis-values-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6 %7") +-default:nis-secure: no +- +-dn: nis-domain=$DOMAIN+nis-map=ethers.byname, cn=NIS Server, cn=plugins, cn=config +-default:objectclass: top +-default:objectclass: extensibleObject +-default:nis-domain: $DOMAIN +-default:nis-map: ethers.byname +-default:nis-base: cn=computers, cn=accounts, $SUFFIX +-default:nis-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost)) +-default:nis-keys-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%7") +-default:nis-values-format: %mregsub("%{macAddress} %{fqdn}","(..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..)[:\\\|-](..) (.*)","%1:%2:%3:%4:%5:%6 %7") +-default:nis-secure: no +- ++# Updates are applied only if NIS plugin has been configured ++# update definitions are located in install/share/nis-update.uldif ++plugin: update_nis_configuration +diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py +index 215caf90ea1ca4e5db8f43f8f09002ce5d5cd280..12eb50bb2edd1680313c1e23c7ec83ede9fbd70c 100644 +--- a/ipaplatform/base/paths.py ++++ b/ipaplatform/base/paths.py +@@ -247,6 +247,7 @@ class BasePathNamespace(object): + HTML_KRBREALM_CON = "/usr/share/ipa/html/krbrealm.con" + PREFERENCES_HTML = "/usr/share/ipa/html/preferences.html" + NIS_ULDIF = "/usr/share/ipa/nis.uldif" ++ NIS_UPDATE_ULDIF = "/usr/share/ipa/nis-update.uldif" + IPA_PLUGINS = "/usr/share/ipa/plugins" + SCHEMA_COMPAT_ULDIF = "/usr/share/ipa/schema_compat.uldif" + IPA_JS_PLUGINS_DIR = "/usr/share/ipa/ui/js/plugins" +diff --git a/ipaserver/install/plugins/update_nis.py b/ipaserver/install/plugins/update_nis.py +new file mode 100644 +index 0000000000000000000000000000000000000000..6e12fed8c26cd3b12052700f4d4be5734121fc64 +--- /dev/null ++++ b/ipaserver/install/plugins/update_nis.py +@@ -0,0 +1,86 @@ ++# ++# Copyright (C) 2015 FreeIPA Contributors see COPYING for license ++# ++ ++from ipalib.plugable import Registry ++from ipalib import errors ++from ipalib import Updater ++from ipaplatform.paths import paths ++from ipapython.dn import DN ++from ipaserver.install import sysupgrade ++from ipaserver.install.ldapupdate import LDAPUpdate ++ ++register = Registry() ++ ++ ++@register() ++class update_nis_configuration(Updater): ++ """Update NIS configuration ++ ++ NIS configuration can be updated only if NIS Server was configured via ++ ipa-nis-manage command. ++ """ ++ ++ def __recover_from_missing_maps(self, ldap): ++ # https://fedorahosted.org/freeipa/ticket/5507 ++ # if all following DNs are missing, but 'NIS Server' container exists ++ # we are experiencig bug and maps should be fixed ++ ++ if sysupgrade.get_upgrade_state('nis', ++ 'done_recover_from_missing_maps'): ++ # this recover must be done only once, a user may deleted some ++ # maps, we do not want to restore them again ++ return ++ ++ self.log.debug("Recovering from missing NIS maps bug") ++ ++ suffix = "cn=NIS Server,cn=plugins,cn=config" ++ domain = self.api.env.domain ++ missing_dn_list = [ ++ DN(nis_map.format(domain=domain, suffix=suffix)) for nis_map in [ ++ "nis-domain={domain}+nis-map=passwd.byname,{suffix}", ++ "nis-domain={domain}+nis-map=passwd.byuid,{suffix}", ++ "nis-domain={domain}+nis-map=group.byname,{suffix}", ++ "nis-domain={domain}+nis-map=group.bygid,{suffix}", ++ "nis-domain={domain}+nis-map=netid.byname,{suffix}", ++ "nis-domain={domain}+nis-map=netgroup,{suffix}", ++ ] ++ ] ++ ++ for dn in missing_dn_list: ++ try: ++ ldap.get_entry(dn, attrs_list=['cn']) ++ except errors.NotFound: ++ pass ++ else: ++ # bug is not effective, at least one of 'possible missing' ++ # maps was detected ++ return ++ ++ sysupgrade.set_upgrade_state('nis', 'done_recover_from_missing_maps', ++ True) ++ ++ # bug is effective run update to recreate missing maps ++ ld = LDAPUpdate(sub_dict={}, ldapi=True) ++ ld.update([paths.NIS_ULDIF]) ++ ++ def execute(self, **options): ++ ldap = self.api.Backend.ldap2 ++ dn = DN(('cn', 'NIS Server'), ('cn', 'plugins'), ('cn', 'config')) ++ try: ++ ldap.get_entry(dn, attrs_list=['cn']) ++ except errors.NotFound: ++ # NIS is not configured on system, do not execute update ++ self.log.debug("Skipping NIS update, NIS Server is not configured") ++ ++ # container does not exist, bug #5507 is not effective ++ sysupgrade.set_upgrade_state( ++ 'nis', 'done_recover_from_missing_maps', True) ++ else: ++ self.__recover_from_missing_maps(ldap) ++ ++ self.log.debug("Executing NIS Server update") ++ ld = LDAPUpdate(sub_dict={}, ldapi=True) ++ ld.update([paths.NIS_UPDATE_ULDIF]) ++ ++ return False, () +-- +2.4.3 + diff --git a/SOURCES/0178-use-FFI-call-to-rpmvercmp-function-for-version-compa.patch b/SOURCES/0178-use-FFI-call-to-rpmvercmp-function-for-version-compa.patch new file mode 100644 index 0000000..efe0431 --- /dev/null +++ b/SOURCES/0178-use-FFI-call-to-rpmvercmp-function-for-version-compa.patch @@ -0,0 +1,112 @@ +From fcdfeb962a0643dca7f2e1a32f0a5e9f8ff5595d Mon Sep 17 00:00:00 2001 +From: Martin Babinsky +Date: Mon, 11 Jan 2016 16:22:40 +0100 +Subject: [PATCH] use FFI call to rpmvercmp function for version comparison + +Stop using rpm-python to compare package versions since the implicit NSS +initialization upon the module import breaks NSS handling in IPA code. Call +rpm-libs C-API function via CFFI instead. + +Big thanks to Martin Kosek for sharing the code snippet +that spurred this patch. + +https://fedorahosted.org/freeipa/ticket/5572 + +Reviewed-By: Jan Cholasta +--- + freeipa.spec.in | 2 +- + ipaplatform/redhat/tasks.py | 44 ++++++++++++-------------------------------- + 2 files changed, 13 insertions(+), 33 deletions(-) + +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 01d42bc621c83541af7517d6d91eb37fd5b5c5cc..cd26d4ce66e320f8b8bf6aaa3e738b4c11f89aa9 100644 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -159,7 +159,7 @@ Requires: p11-kit + Requires: systemd-python + Requires: %{etc_systemd_dir} + Requires: gzip +-Requires: rpm-python ++Requires: rpm-libs + + Conflicts: %{alt_name}-server + Obsoletes: %{alt_name}-server < %{version} +diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py +index 2e894d776dcd5542e6c11cc0210add8ad9d90298..9be3ef664e6d15c31e53b7a8123de7b6bb2b81fe 100644 +--- a/ipaplatform/redhat/tasks.py ++++ b/ipaplatform/redhat/tasks.py +@@ -30,7 +30,8 @@ import socket + import sys + import urllib + import base64 +-import rpm ++from cffi import FFI ++from ctypes.util import find_library + from functools import total_ordering + + from subprocess import CalledProcessError +@@ -47,35 +48,14 @@ from ipaplatform.paths import paths + from ipaplatform.redhat.authconfig import RedHatAuthConfig + from ipaplatform.base.tasks import BaseTaskNamespace + ++_ffi = FFI() ++_ffi.cdef(""" ++int rpmvercmp (const char *a, const char *b); ++""") + +-# copied from rpmUtils/miscutils.py +-def stringToVersion(verstring): +- if verstring in [None, '']: +- return (None, None, None) +- i = verstring.find(':') +- if i != -1: +- try: +- epoch = str(long(verstring[:i])) +- except ValueError: +- # look, garbage in the epoch field, how fun, kill it +- epoch = '0' # this is our fallback, deal +- else: +- epoch = '0' +- j = verstring.find('-') +- if j != -1: +- if verstring[i + 1:j] == '': +- version = None +- else: +- version = verstring[i + 1:j] +- release = verstring[j + 1:] +- else: +- if verstring[i + 1:] == '': +- version = None +- else: +- version = verstring[i + 1:] +- release = None +- return (epoch, version, release) +- ++# use ctypes loader to get correct librpm.so library version according to ++# https://cffi.readthedocs.org/en/latest/overview.html#id8 ++_librpm = _ffi.dlopen(find_library("rpm")) + + log = log_mgr.get_logger(__name__) + +@@ -100,15 +80,15 @@ def selinux_enabled(): + class IPAVersion(object): + + def __init__(self, version): +- self.version_tuple = stringToVersion(version) ++ self.version = version + + def __eq__(self, other): + assert isinstance(other, IPAVersion) +- return rpm.labelCompare(self.version_tuple, other.version_tuple) == 0 ++ return _librpm.rpmvercmp(self.version, other.version) == 0 + + def __lt__(self, other): + assert isinstance(other, IPAVersion) +- return rpm.labelCompare(self.version_tuple, other.version_tuple) == -1 ++ return _librpm.rpmvercmp(self.version, other.version) < 0 + + + class RedHatTaskNamespace(BaseTaskNamespace): +-- +2.4.3 + diff --git a/SOURCES/0179-ipalib-assume-version-2.0-when-skip_version_check-is.patch b/SOURCES/0179-ipalib-assume-version-2.0-when-skip_version_check-is.patch new file mode 100644 index 0000000..1563374 --- /dev/null +++ b/SOURCES/0179-ipalib-assume-version-2.0-when-skip_version_check-is.patch @@ -0,0 +1,36 @@ +From 88c057bc798b2606bafbed5c0b76475b0640b5e8 Mon Sep 17 00:00:00 2001 +From: Jan Cholasta +Date: Tue, 12 Jan 2016 15:41:43 +0100 +Subject: [PATCH] ipalib: assume version 2.0 when skip_version_check is enabled + +https://fedorahosted.org/freeipa/ticket/5601 + +Reviewed-By: Martin Basti +--- + ipalib/frontend.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/ipalib/frontend.py b/ipalib/frontend.py +index 2ca3aaea82ea63702052eedbd7e4081f239cbaed..8adcee925a24fd546d7000e9239353da273e0bc9 100644 +--- a/ipalib/frontend.py ++++ b/ipalib/frontend.py +@@ -26,7 +26,6 @@ from distutils import version + + from ipapython.version import API_VERSION + from ipapython.ipa_log_manager import root_logger +-from ipalib.capabilities import VERSION_WITHOUT_CAPABILITIES + from base import NameSpace + from plugable import Plugin + from parameters import create_param, Param, Str, Flag, Password +@@ -425,7 +424,7 @@ class Command(HasParam): + if version_provided: + self.verify_client_version(unicode(options['version'])) + elif self.api.env.skip_version_check and not self.api.env.in_server: +- options['version'] = VERSION_WITHOUT_CAPABILITIES ++ options['version'] = u'2.0' + else: + options['version'] = API_VERSION + params = self.args_options_2_params(*args, **options) +-- +2.4.3 + diff --git a/SOURCES/0180-always-start-certmonger-during-IPA-server-configurat.patch b/SOURCES/0180-always-start-certmonger-during-IPA-server-configurat.patch new file mode 100644 index 0000000..b53e599 --- /dev/null +++ b/SOURCES/0180-always-start-certmonger-during-IPA-server-configurat.patch @@ -0,0 +1,87 @@ +From 80115a38d78db0c2a31dea06786af41eafb234f0 Mon Sep 17 00:00:00 2001 +From: Martin Babinsky +Date: Mon, 1 Feb 2016 12:59:04 +0100 +Subject: [PATCH] always start certmonger during IPA server configuration + upgrade + +This patch fixes a regression introduced by commit +bef0f4c5c38e7ff6415e8f8c96dc306ef7f0ce56. Instead of checking whether +there is CA installed in the topology, we should always start certmonger +service during upgrade regardless when CA was configured. + +https://fedorahosted.org/freeipa/ticket/5655 + +Reviewed-By: Jan Cholasta +Reviewed-By: Martin Basti +--- + ipaserver/install/server/upgrade.py | 33 +++++---------------------------- + 1 file changed, 5 insertions(+), 28 deletions(-) + +diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py +index 616fba5c1a5b3737481aecbb09ab5344641a3b04..1f1cfeb672809c0298c69c121ac38d6c7a482d11 100644 +--- a/ipaserver/install/server/upgrade.py ++++ b/ipaserver/install/server/upgrade.py +@@ -292,24 +292,6 @@ def setup_firefox_extension(fstore): + http.setup_firefox_extension(realm, domain) + + +-def is_ca_enabled(): +- """ +- check whether there is an active CA master +- :return: True if there is an active CA in topology, False otherwise +- """ +- ldap2 = api.Backend.ldap2 +- was_connected = ldap2.isconnected() +- +- if not was_connected: +- ldap2.connect() +- +- try: +- return api.Command.ca_is_enabled()['result'] +- finally: +- if not was_connected: +- ldap2.disconnect() +- +- + def ca_configure_profiles_acl(ca): + root_logger.info('[Authorizing RA Agent to modify profiles]') + +@@ -1420,6 +1402,10 @@ def upgrade_configuration(): + ) + upgrade_pki(ca, fstore) + ++ certmonger_service = services.knownservices.certmonger ++ if ca.is_configured() and not certmonger_service.is_running(): ++ certmonger_service.start() ++ + ca.configure_certmonger_renewal_guard() + + update_dbmodules(api.env.realm) +@@ -1435,8 +1421,7 @@ def upgrade_configuration(): + http.configure_selinux_for_httpd() + http.change_mod_nss_port_from_http() + +- if is_ca_enabled(): +- http.configure_certmonger_renewal_guard() ++ http.configure_certmonger_renewal_guard() + + ds.configure_dirsrv_ccache() + +@@ -1582,14 +1567,6 @@ def upgrade_check(options): + print unicode(e) + sys.exit(1) + +- try: +- ca_is_enabled = is_ca_enabled() +- except Exception as e: +- raise RuntimeError("Cannot connect to LDAP server: {0}".format(e)) +- +- if not services.knownservices.certmonger.is_running() and ca_is_enabled: +- raise RuntimeError('Certmonger is not running. Start certmonger and run upgrade again.') +- + if not options.skip_version_check: + # check IPA version and data version + try: +-- +2.5.0 + diff --git a/SOURCES/ipa-centos-branding.patch b/SOURCES/ipa-centos-branding.patch deleted file mode 100644 index 673cd2f..0000000 --- a/SOURCES/ipa-centos-branding.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 99efecaf87dc1fc9517efaff441a6a7ce46444eb Mon Sep 17 00:00:00 2001 -From: Jim Perrin -Date: Wed, 11 Mar 2015 10:37:03 -0500 -Subject: [PATCH] update for new ntp server method - ---- - ipaplatform/base/paths.py | 1 + - ipaserver/install/ntpinstance.py | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py -index af50262..5090062 100644 ---- a/ipaplatform/base/paths.py -+++ b/ipaplatform/base/paths.py -@@ -99,6 +99,7 @@ class BasePathNamespace(object): - PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/" - PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf" - ETC_REDHAT_RELEASE = "/etc/redhat-release" -+ ETC_CENTOS_RELEASE = "/etc/centos-release" - RESOLV_CONF = "/etc/resolv.conf" - SAMBA_KEYTAB = "/etc/samba/samba.keytab" - SMB_CONF = "/etc/samba/smb.conf" -diff --git a/ipaserver/install/ntpinstance.py b/ipaserver/install/ntpinstance.py -index c653525..4b0578b 100644 ---- a/ipaserver/install/ntpinstance.py -+++ b/ipaserver/install/ntpinstance.py -@@ -44,6 +44,8 @@ class NTPInstance(service.Service): - os = "" - if ipautil.file_exists(paths.ETC_FEDORA_RELEASE): - os = "fedora" -+ elif ipautil.file_exists(paths.ETC_CENTOS_RELEASE): -+ os = "centos" - elif ipautil.file_exists(paths.ETC_REDHAT_RELEASE): - os = "rhel" - --- -1.8.3.1 - diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec index 13775be..50d5e2f 100644 --- a/SPECS/ipa.spec +++ b/SPECS/ipa.spec @@ -35,7 +35,7 @@ Name: ipa Version: 4.2.0 -Release: 15%{?dist}.3 +Release: 15%{?dist}.6 Summary: The Identity, Policy and Audit system Group: System Environment/Base @@ -43,10 +43,10 @@ License: GPLv3+ URL: http://www.freeipa.org/ Source0: http://www.freeipa.org/downloads/src/freeipa-%{VERSION}.tar.gz # RHEL spec file only: START: Change branding to IPA and Identity-Management -#Source1: header-logo.png -#Source2: login-screen-background.jpg -#Source3: login-screen-logo.png -#Source4: product-name.png +Source1: header-logo.png +Source2: login-screen-background.jpg +Source3: login-screen-logo.png +Source4: product-name.png # RHEL spec file only: END: Change branding to IPA and Identity-Management BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -210,6 +210,27 @@ Patch0156: 0156-Add-profiles-and-default-CA-ACL-on-migration.patch Patch0157: 0157-disconnect-ldap2-backend-after-adding-default-CA-ACL.patch Patch0158: 0158-do-not-disconnect-when-using-existing-connection-to-.patch Patch0159: 0159-Fix-upgrade-of-forwardzones-when-zone-is-in-realmdom.patch +Patch0160: 0160-Fix-version-comparison.patch +Patch0161: 0161-DNS-fix-file-permissions.patch +Patch0162: 0162-Explicitly-call-chmod-on-newly-created-directories.patch +Patch0163: 0163-Fix-replace-mkdir-with-chmod.patch +Patch0164: 0164-DNSSEC-Improve-error-reporting-from-ipa-ods-exporter.patch +Patch0165: 0165-DNSSEC-Make-sure-that-current-state-in-OpenDNSSEC-ma.patch +Patch0166: 0166-DNSSEC-Make-sure-that-current-key-state-in-LDAP-matc.patch +Patch0167: 0167-DNSSEC-remove-obsolete-TODO-note.patch +Patch0168: 0168-DNSSEC-add-debug-mode-to-ldapkeydb.py.patch +Patch0169: 0169-DNSSEC-logging-improvements-in-ipa-ods-exporter.patch +Patch0170: 0170-DNSSEC-remove-keys-purged-by-OpenDNSSEC-from-master-.patch +Patch0171: 0171-DNSSEC-ipa-dnskeysyncd-Skip-zones-with-old-DNSSEC-me.patch +Patch0172: 0172-DNSSEC-ipa-ods-exporter-add-ldap-cleanup-command.patch +Patch0173: 0173-DNSSEC-ipa-dnskeysyncd-call-ods-signer-ldap-cleanup-.patch +Patch0174: 0174-DNSSEC-Log-debug-messages-at-log-level-DEBUG.patch +Patch0175: 0175-Allow-to-used-mixed-case-for-sysrestore.patch +Patch0176: 0176-prevent-crash-of-CA-less-server-upgrade-due-to-absen.patch +Patch0177: 0177-Upgrade-Fix-upgrade-of-NIS-Server-configuration.patch +Patch0178: 0178-use-FFI-call-to-rpmvercmp-function-for-version-compa.patch +Patch0179: 0179-ipalib-assume-version-2.0-when-skip_version_check-is.patch +Patch0180: 0180-always-start-certmonger-during-IPA-server-configurat.patch Patch1001: 1001-Hide-pkinit-functionality-from-production-version.patch Patch1002: 1002-Remove-pkinit-plugin.patch @@ -221,7 +242,6 @@ Patch1007: 1007-Do-not-build-tests.patch Patch1008: 1008-RCUE.patch Patch1009: 1009-Do-not-allow-installation-in-FIPS-mode.patch Patch1010: 1010-WebUI-add-API-browser-is-experimental-warning.patch -Patch1011: ipa-centos-branding.patch # RHEL spec file only: END %if ! %{ONLY_CLIENT} @@ -346,14 +366,17 @@ Requires(pre): certmonger >= 0.78 Requires(pre): 389-ds-base >= 1.3.4.0 Requires: fontawesome-fonts Requires: open-sans-fonts -Requires: openssl +# RHEL spec file only: START +Requires(pre): openssl >= 1:1.0.1e-42 +# RHEL spec file only: END +Requires: openssl >= 1:1.0.1e-42 Requires: softhsm >= 2.0.0rc1-1 Requires: p11-kit Requires: systemd-python Requires: %{etc_systemd_dir} Requires: gzip # RHEL spec file only: START -# Requires: redhat-access-plugin-ipa +Requires: redhat-access-plugin-ipa # RHEL spec file only: END Conflicts: %{alt_name}-server @@ -562,10 +585,10 @@ for p in %patches ; do done # Red Hat's Identity Management branding -#cp %SOURCE1 install/ui/images/header-logo.png -#cp %SOURCE2 install/ui/images/login-screen-background.jpg -#cp %SOURCE3 install/ui/images/login-screen-logo.png -#cp %SOURCE4 install/ui/images/product-name.png +cp %SOURCE1 install/ui/images/header-logo.png +cp %SOURCE2 install/ui/images/login-screen-background.jpg +cp %SOURCE3 install/ui/images/login-screen-logo.png +cp %SOURCE4 install/ui/images/product-name.png # RHEL spec file only: END %build @@ -1162,8 +1185,50 @@ fi # RHEL spec file only: DELETED: Do not build tests %changelog -* Tue Dec 08 2015 CentOS Sources - 4.2.0-15.el7.centos.3 -- Roll in CentOS Branding +* Tue Feb 2 2016 Jan Cholasta - 4.2.0-15.6 +- Resolves: #1298103 ipa-server-upgrade fails if certmonger is not running + - always start certmonger during IPA server configuration upgrade + +* Wed Jan 27 2016 Jan Cholasta - 4.2.0-15.5 +- Resolves: #1298097 IPA server upgrade fails from RHEL 7.0 to RHEL 7.2 using + "yum update ipa* sssd" + - Set minimal required version for openssl + +* Tue Jan 12 2016 Jan Cholasta - 4.2.0-15.4 +- Resolves: #1298097 IPA server upgrade fails from RHEL 7.0 to RHEL 7.2 using + "yum update ipa* sssd" + - Set minimal required version for openssl +- Resolves: #1298098 ipa-nis-manage does not update ldap with all NIS maps + - Upgrade: Fix upgrade of NIS Server configuration +- Resolves: #1298099 umask setting causes named-pkcs11 issue with directory + permissions on /var/lib/ipa/dnssec + - DNS: fix file permissions + - Explicitly call chmod on newly created directories + - Fix: replace mkdir with chmod +- Resolves: #1298100 Broken 7.2.0 to 7.2.z upgrade - flawed version comparison + - Fix version comparison + - use FFI call to rpmvercmp function for version comparison +- Resolves: #1298101 Sysrestore did not restore state if a key is specified in + mixed case + - Allow to used mixed case for sysrestore +- Resolves: #1298102 DNSSEC key purging is not handled properly + - DNSSEC: Improve error reporting from ipa-ods-exporter + - DNSSEC: Make sure that current state in OpenDNSSEC matches key state in + LDAP + - DNSSEC: Make sure that current key state in LDAP matches key state in BIND + - DNSSEC: remove obsolete TODO note + - DNSSEC: add debug mode to ldapkeydb.py + - DNSSEC: logging improvements in ipa-ods-exporter + - DNSSEC: remove keys purged by OpenDNSSEC from master HSM from LDAP + - DNSSEC: ipa-dnskeysyncd: Skip zones with old DNSSEC metadata in LDAP + - DNSSEC: ipa-ods-exporter: add ldap-cleanup command + - DNSSEC: ipa-dnskeysyncd: call ods-signer ldap-cleanup on zone removal + - DNSSEC: Log debug messages at log level DEBUG +- Resolves: #1298103 ipa-server-upgrade fails if certmonger is not running + - prevent crash of CA-less server upgrade due to absent certmonger +- Resolves: #1298104 The ipa -e skip_version_check=1 still issues + incompatibility error when called against RHEL 6 server + - ipalib: assume version 2.0 when skip_version_check is enabled * Wed Nov 25 2015 Jan Cholasta - 4.2.0-15.3 - Resolves: #1284052 IPA DNS Zone/DNS Forward Zone details missing after