Imported Upstream version 4.3.1

This commit is contained in:
Mario Fetka
2021-08-10 02:37:58 +02:00
parent a791de49a2
commit 2f177da8f2
2056 changed files with 421730 additions and 1668138 deletions

Binary file not shown.

View File

@@ -17,23 +17,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipaplatform.paths import paths
from ipapython.dn import DN
from ipapython.ipa_log_manager import *
from ipapython import sysrestore
from ipaserver.install import installutils
from ipaserver.install import sysupgrade
from ipaserver.install.adtrustinstance import (
ADTRUSTInstance, map_Guests_to_nobody)
logger = logging.getLogger(__name__)
register = Registry()
DEFAULT_ID_RANGE_SIZE = 200000
@register()
class update_default_range(Updater):
"""
Create default ID range for upgraded servers.
@@ -45,12 +39,11 @@ class update_default_range(Updater):
dn = DN(self.api.env.container_ranges, self.api.env.basedn)
search_filter = "objectclass=ipaDomainIDRange"
try:
ldap.find_entries(search_filter, [], dn)
(entries, truncated) = ldap.find_entries(search_filter, [], dn)
except errors.NotFound:
pass
else:
logger.debug("default_range: ipaDomainIDRange entry found, skip "
"plugin")
root_logger.debug("default_range: ipaDomainIDRange entry found, skip plugin")
return False, []
dn = DN(('cn', 'admins'), self.api.env.container_group,
@@ -58,8 +51,8 @@ class update_default_range(Updater):
try:
admins_entry = ldap.get_entry(dn, ['gidnumber'])
except errors.NotFound:
logger.error("default_range: No local ID range and no admins "
"group found. Cannot create default ID range")
root_logger.error("default_range: No local ID range and no admins "
"group found. Cannot create default ID range")
return False, []
id_range_base_id = admins_entry['gidnumber'][0]
@@ -91,10 +84,10 @@ class update_default_range(Updater):
search_filter = "objectclass=dnaSharedConfig"
attrs = ['dnaHostname', 'dnaRemainingValues']
try:
(entries, _truncated) = ldap.find_entries(search_filter, attrs, dn)
(entries, truncated) = ldap.find_entries(search_filter, attrs, dn)
except errors.NotFound:
logger.warning("default_range: no dnaSharedConfig object found. "
"Cannot check default range size.")
root_logger.warning("default_range: no dnaSharedConfig object found. "
"Cannot check default range size.")
else:
masters = set()
remaining_values_sum = 0
@@ -106,9 +99,8 @@ class update_default_range(Updater):
try:
remaining_values = int(remaining_values)
except ValueError:
logger.warning("default_range: could not parse "
"remaining values from '%s'",
remaining_values)
root_logger.warning("default_range: could not parse "
"remaining values from '%s'", remaining_values)
continue
else:
remaining_values_sum += remaining_values
@@ -124,12 +116,11 @@ class update_default_range(Updater):
' RANGE_SIZE = (--idmax) - (--idstart) + 1'
]
logger.error("default_range: %s", "\n".join(msg))
root_logger.error("default_range: %s", "\n".join(msg))
return False, [update]
@register()
class update_default_trust_view(Updater):
"""
Create Default Trust View for upgraded servers.
@@ -152,7 +143,7 @@ class update_default_trust_view(Updater):
# First, see if trusts are enabled on the server
if not self.api.Command.adtrust_is_enabled()['result']:
logger.debug('AD Trusts are not enabled on this server')
self.log.debug('AD Trusts are not enabled on this server')
return False, []
# Second, make sure the Default Trust View does not exist yet
@@ -161,7 +152,7 @@ class update_default_trust_view(Updater):
except errors.NotFound:
pass
else:
logger.debug('Default Trust View already present on this server')
self.log.debug('Default Trust View already present on this server')
return False, []
# We have a server with AD trust support without Default Trust View.
@@ -175,7 +166,6 @@ class update_default_trust_view(Updater):
return False, [update]
@register()
class update_sigden_extdom_broken_config(Updater):
"""Fix configuration of sidgen and extdom plugins
@@ -206,7 +196,7 @@ class update_sigden_extdom_broken_config(Updater):
try:
entry = ldap.get_entry(dn, attrs_list=[basedn_attr])
except errors.NotFound:
logger.debug("configuration for %s not found, skipping", dn)
self.log.debug("configuration for %s not found, skipping", dn)
else:
configured_suffix = entry.single_value.get(basedn_attr)
if configured_suffix is None:
@@ -218,19 +208,19 @@ class update_sigden_extdom_broken_config(Updater):
elif configured_suffix == "$SUFFIX":
# configured value is wrong, fix it
entry.single_value[basedn_attr] = str(self.api.env.basedn)
logger.debug("updating attribute %s of %s to correct "
"value %s",
basedn_attr, dn, self.api.env.basedn)
self.log.debug("updating attribute %s of %s to correct "
"value %s", basedn_attr, dn,
self.api.env.basedn)
ldap.update_entry(entry)
modified = True
else:
logger.debug("configured basedn for %s is okay", dn)
self.log.debug("configured basedn for %s is okay", dn)
return modified
def execute(self, **options):
if sysupgrade.get_upgrade_state('sidgen', 'config_basedn_updated'):
logger.debug("Already done, skipping")
self.log.debug("Already done, skipping")
return False, ()
restart = False
@@ -242,7 +232,6 @@ class update_sigden_extdom_broken_config(Updater):
return restart, ()
@register()
class update_sids(Updater):
"""SIDs may be not created properly if bug with wrong configuration for
sidgen and extdom plugins is effective
@@ -256,7 +245,7 @@ class update_sids(Updater):
ldap = self.api.Backend.ldap2
if sysupgrade.get_upgrade_state('sidgen', 'update_sids') is not True:
logger.debug("SIDs do not need to be generated")
self.log.debug("SIDs do not need to be generated")
return False, ()
# check if IPA domain for AD trust has been created, and if we need to
@@ -270,8 +259,8 @@ class update_sids(Updater):
try:
entry = ldap.get_entry(domain_IPA_AD_dn, attrs_list=[attr_name])
except errors.NotFound:
logger.debug("IPA domain object %s is not configured",
domain_IPA_AD_dn)
self.log.debug("IPA domain object %s is not configured",
domain_IPA_AD_dn)
sysupgrade.set_upgrade_state('sidgen', 'update_sids', False)
return False, ()
else:
@@ -292,9 +281,9 @@ class update_sids(Updater):
try:
ldap.add_entry(task_entry)
except errors.DuplicateEntry:
logger.debug("sidgen task already created")
self.log.debug("sidgen task already created")
else:
logger.debug("sidgen task has been created")
self.log.debug("sidgen task has been created")
# we have to check all trusts domains which may been affected by the
# bug. Symptom is missing 'ipaNTSecurityIdentifier' attribute
@@ -313,11 +302,11 @@ class update_sids(Updater):
pass
else:
if truncated:
logger.warning("update_sids: Search results were truncated")
self.log.warning("update_sids: Search results were truncated")
for entry in trust_domain_entries:
domain = entry.single_value["cn"]
logger.error(
self.log.error(
"Your trust to %s is broken. Please re-create it by "
"running 'ipa trust-add' again.", domain)
@@ -325,78 +314,7 @@ class update_sids(Updater):
return False, ()
@register()
class update_tdo_gidnumber(Updater):
"""
Create a gidNumber attribute for Trusted Domain Objects.
The value is taken from the fallback group defined in cn=Default SMB Group.
"""
def execute(self, **options):
ldap = self.api.Backend.ldap2
# First, see if trusts are enabled on the server
if not self.api.Command.adtrust_is_enabled()['result']:
logger.debug('AD Trusts are not enabled on this server')
return False, []
# Read the gidnumber of the fallback group
dn = DN(('cn', ADTRUSTInstance.FALLBACK_GROUP_NAME),
self.api.env.container_group,
self.api.env.basedn)
try:
entry = ldap.get_entry(dn, ['gidnumber'])
gidNumber = entry.get('gidnumber')
except errors.NotFound:
logger.error("%s not found",
ADTRUSTInstance.FALLBACK_GROUP_NAME)
return False, ()
if not gidNumber:
logger.error("%s does not have a gidnumber",
ADTRUSTInstance.FALLBACK_GROUP_NAME)
return False, ()
# For each trusted domain object, add gidNumber
try:
tdos = ldap.get_entries(
DN(self.api.env.container_adtrusts, self.api.env.basedn),
scope=ldap.SCOPE_ONELEVEL,
filter="(objectclass=ipaNTTrustedDomain)",
attrs_list=['gidnumber'])
for tdo in tdos:
# if the trusted domain object does not contain gidnumber,
# add the default fallback group gidnumber
if not tdo.get('gidnumber'):
try:
tdo['gidnumber'] = gidNumber
ldap.update_entry(tdo)
logger.debug("Added gidnumber %s to %s",
gidNumber, tdo.dn)
except Exception:
logger.warning(
"Failed to add gidnumber to %s", tdo.dn)
except errors.NotFound:
logger.debug("No trusted domain object to update")
return False, ()
return False, ()
@register()
class update_mapping_Guests_to_nobody(Updater):
"""
Map BUILTIN\\Guests group to nobody
Samba 4.9 became more strict on availability of builtin Guests group
"""
def execute(self, **options):
# First, see if trusts are enabled on the server
if not self.api.Command.adtrust_is_enabled()['result']:
logger.debug('AD Trusts are not enabled on this server')
return False, []
map_Guests_to_nobody()
return False, []
api.register(update_default_range)
api.register(update_default_trust_view)
api.register(update_sids)
api.register(update_sigden_extdom_broken_config)

View File

@@ -17,20 +17,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
import logging
from ipaserver.install import cainstance
from ipaserver.install import installutils, certs, cainstance
from ipalib import errors
from ipalib import Updater
from ipalib.install import certmonger
from ipalib.plugable import Registry
from ipapython import certmonger
from ipaplatform.paths import paths
from ipapython.dn import DN
from ipapython import directivesetter
logger = logging.getLogger(__name__)
register = Registry()
@@ -41,15 +34,14 @@ class update_ca_renewal_master(Updater):
"""
def execute(self, **options):
ca = cainstance.CAInstance(self.api.env.realm)
ca = cainstance.CAInstance(self.api.env.realm, certs.NSS_DIR)
if not ca.is_configured():
logger.debug("CA is not configured on this host")
self.debug("CA is not configured on this host")
return False, []
ldap = self.api.Backend.ldap2
base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
self.api.env.basedn)
dn = DN(('cn', 'CA'), ('cn', self.api.env.host), base_dn)
filter = '(&(cn=CA)(ipaConfigString=caRenewalMaster))'
try:
entries = ldap.get_entries(base_dn=base_dn, filter=filter,
@@ -57,40 +49,21 @@ class update_ca_renewal_master(Updater):
except errors.NotFound:
pass
else:
logger.debug("found CA renewal master %s", entries[0].dn[1].value)
master = False
updates = []
for entry in entries:
if entry.dn == dn:
master = True
continue
updates.append({
'dn': entry.dn,
'updates': [
dict(action='remove', attr='ipaConfigString',
value='caRenewalMaster')
],
})
if master:
return False, updates
else:
return False, []
self.debug("found CA renewal master %s", entries[0].dn[1].value)
return False, []
criteria = {
'cert-file': paths.RA_AGENT_PEM,
'cert-database': paths.HTTPD_ALIAS_DIR,
'cert-nickname': 'ipaCert',
}
request_id = certmonger.get_request_id(criteria)
if request_id is not None:
logger.debug("found certmonger request for RA cert")
self.debug("found certmonger request for ipaCert")
ca_name = certmonger.get_request_value(request_id, 'ca-name')
if ca_name is None:
logger.warning(
"certmonger request for RA cert is missing ca_name, "
self.warning(
"certmonger request for ipaCert is missing ca_name, "
"assuming local CA is renewal slave")
return False, []
ca_name = ca_name.strip()
@@ -102,14 +75,14 @@ class update_ca_renewal_master(Updater):
elif ca_name == 'dogtag-ipa-ca-renew-agent':
return False, []
else:
logger.warning(
"certmonger request for RA cert has unknown ca_name '%s', "
self.warning(
"certmonger request for ipaCert has unknown ca_name '%s', "
"assuming local CA is renewal slave", ca_name)
return False, []
else:
logger.debug("certmonger request for RA cert not found")
self.debug("certmonger request for ipaCert not found")
config = directivesetter.get_directive(
config = installutils.get_directive(
paths.CA_CS_CFG_PATH, 'subsystem.select', '=')
if config == 'New':
@@ -117,11 +90,12 @@ class update_ca_renewal_master(Updater):
elif config == 'Clone':
return False, []
else:
logger.warning(
self.warning(
"CS.cfg has unknown subsystem.select value '%s', "
"assuming local CA is renewal slave", config)
return (False, False, [])
dn = DN(('cn', 'CA'), ('cn', self.api.env.host), base_dn)
update = {
'dn': dn,
'updates': [

View File

@@ -17,148 +17,20 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
import logging
import dns.exception
import ldap as _ldap
import re
import traceback
import time
from ldif import LDIFWriter
from ipalib import Registry, errors, util
from ipalib import api, errors, util
from ipalib import Updater
from ipapython.dn import DN
from ipapython import dnsutil
from ipaserver.install import sysupgrade
from ipaserver.install.bindinstance import ensure_dnsserver_container_exists
from ipaserver.plugins.dns import dns_container_exists
logger = logging.getLogger(__name__)
register = Registry()
from ipalib.plugins.dns import dns_container_exists
from ipapython.ipa_log_manager import *
class DNSUpdater(Updater):
backup_dir = u'/var/lib/ipa/backup/'
# override backup_filename in subclass, it will be mangled by strftime
backup_filename = None
def __init__(self, api):
super(DNSUpdater, self).__init__(api)
backup_path = u'%s%s' % (self.backup_dir, self.backup_filename)
self.backup_path = time.strftime(backup_path)
self._ldif_writer = None
self._saved_privileges = set() # store privileges only once
self.saved_zone_to_privilege = {}
def version_update_needed(self, target_version):
"""Test if IPA DNS version is smaller than target version."""
assert isinstance(target_version, int)
try:
return int(self.api.Command['dnsconfig_show'](
all=True)['result']['ipadnsversion'][0]) < target_version
except errors.NotFound:
# IPA DNS is not configured
return False
@property
def ldif_writer(self):
if not self._ldif_writer:
logger.info('Original zones will be saved in LDIF format in '
'%s file', self.backup_path)
self._ldif_writer = LDIFWriter(open(self.backup_path, 'w'))
return self._ldif_writer
def backup_zone(self, zone):
"""Backup zone object, its records, permissions, and privileges.
Mapping from zone to privilege (containing zone's permissions)
will be stored in saved_zone_to_privilege dict for further usage.
"""
dn = str(zone['dn'])
del zone['dn'] # dn shouldn't be as attribute in ldif
self.ldif_writer.unparse(dn, zone)
ldap = self.api.Backend.ldap2
if 'managedBy' in zone:
permission = ldap.get_entry(DN(zone['managedBy'][0]))
self.ldif_writer.unparse(str(permission.dn), dict(permission.raw))
for privilege_dn in permission.get('member', []):
# privileges can be shared by multiples zones
if privilege_dn not in self._saved_privileges:
self._saved_privileges.add(privilege_dn)
privilege = ldap.get_entry(privilege_dn)
self.ldif_writer.unparse(str(privilege.dn),
dict(privilege.raw))
# remember privileges referened by permission
if 'member' in permission:
self.saved_zone_to_privilege[
zone['idnsname'][0]
] = permission['member']
if 'idnszone' in zone['objectClass']:
# raw values are required to store into ldif
records = self.api.Command['dnsrecord_find'](zone['idnsname'][0],
all=True,
raw=True,
sizelimit=0)['result']
for record in records:
if record['idnsname'][0] == u'@':
# zone record was saved before
continue
dn = str(record['dn'])
del record['dn']
self.ldif_writer.unparse(dn, record)
@register()
class update_ipaconfigstring_dnsversion_to_ipadnsversion(Updater):
"""
IPA <= 4.3.1 used ipaConfigString "DNSVersion 1" on DNS container.
This was hard to deal with in API so from IPA 4.3.2 we are using
new ipaDNSVersion attribute with integer syntax.
Old ipaConfigString is left there for now so if someone accidentally
executes upgrade on an old replica again it will not re-upgrade the data.
"""
def execute(self, **options):
ldap = self.api.Backend.ldap2
dns_container_dn = DN(self.api.env.container_dns, self.api.env.basedn)
try:
container_entry = ldap.get_entry(dns_container_dn)
except errors.NotFound:
# DNS container not found, nothing to upgrade
return False, []
if 'ipadnscontainer' in [
o.lower() for o in container_entry['objectclass']
]:
# version data are already migrated
return False, []
logger.debug('Migrating DNS ipaConfigString to ipaDNSVersion')
container_entry['objectclass'].append('ipadnscontainer')
version = 0
for config_option in container_entry.get("ipaConfigString", []):
matched = re.match(r"^DNSVersion\s+(?P<version>\d+)$",
config_option, flags=re.I)
if matched:
version = int(matched.group("version"))
else:
logger.error(
'Failed to parse DNS version from ipaConfigString, '
'defaulting to version %s', version)
container_entry['ipadnsversion'] = version
ldap.update_entry(container_entry)
logger.debug('ipaDNSVersion = %s', version)
return False, []
@register()
class update_dnszones(Updater):
"""
Update all zones to meet requirements in the new FreeIPA versions
@@ -192,7 +64,7 @@ class update_dnszones(Updater):
try:
zones = self.api.Command.dnszone_find(all=True)['result']
except errors.NotFound:
logger.debug('No DNS zone to update found')
self.log.debug('No DNS zone to update found')
return False, []
for zone in zones:
@@ -218,8 +90,9 @@ class update_dnszones(Updater):
return False, []
api.register(update_dnszones)
@register()
class update_dns_limits(Updater):
"""
bind-dyndb-ldap persistent search queries LDAP for all DNS records.
@@ -245,13 +118,11 @@ class update_dns_limits(Updater):
entry = ldap.get_entry(dns_service_dn, self.limit_attributes)
except errors.NotFound:
# this host may not have DNS service set
logger.debug("DNS: service %s not found, no need to update limits",
dns_service_dn)
root_logger.debug("DNS: service %s not found, no need to update limits" % dns_service_dn)
return False, []
if all(entry.get(limit.lower(), [None])[0] == self.limit_value for limit in self.limit_attributes):
logger.debug("DNS: limits for service %s already set",
dns_service_dn)
root_logger.debug("DNS: limits for service %s already set" % dns_service_dn)
# service is already updated
return False, []
@@ -262,15 +133,15 @@ class update_dns_limits(Updater):
value=self.limit_value))
dnsupdate = {'dn': dns_service_dn, 'updates': limit_updates}
logger.debug("DNS: limits for service %s will be updated",
dns_service_dn)
root_logger.debug("DNS: limits for service %s will be updated" % dns_service_dn)
return False, [dnsupdate]
api.register(update_dns_limits)
@register()
class update_master_to_dnsforwardzones(DNSUpdater):
class update_master_to_dnsforwardzones(Updater):
"""
Update all zones to meet requirements in the new FreeIPA versions
@@ -278,21 +149,35 @@ class update_master_to_dnsforwardzones(DNSUpdater):
than none, will be tranformed to forward zones.
Original masters zone will be backed up to ldif file.
This should be applied only once,
and only if original version was lower than 4.0
This should be applied only once, and only if original version was lower than 4.0
"""
backup_filename = u'dns-master-to-forward-zones-%Y-%m-%d-%H-%M-%S.ldif'
backup_dir = u'/var/lib/ipa/backup/'
backup_filename = u'dns-forward-zones-backup-%Y-%m-%d-%H-%M-%S.ldif'
backup_path = u'%s%s' % (backup_dir, backup_filename)
def execute(self, **options):
ldap = self.api.Backend.ldap2
# check LDAP if forwardzones already uses new semantics
if not self.version_update_needed(target_version=1):
# forwardzones already uses new semantics,
# no upgrade is required
dns_container_dn = DN(self.api.env.container_dns, self.api.env.basedn)
try:
container_entry = ldap.get_entry(dns_container_dn)
except errors.NotFound:
# DNS container not found, nothing to upgrade
return False, []
logger.debug('Updating forward zones')
for config_option in container_entry.get("ipaConfigString", []):
matched = re.match("^DNSVersion\s+(?P<version>\d+)$",
config_option, flags=re.I)
if matched and int(matched.group("version")) >= 1:
# forwardzones already uses new semantics,
# no upgrade is required
return False, []
self.log.debug('Updating forward zones')
# update the DNSVersion, following upgrade can be executed only once
self.api.Command['dnsconfig_mod'](ipadnsversion=1)
container_entry.setdefault(
'ipaConfigString', []).append(u"DNSVersion 1")
ldap.update_entry(container_entry)
# Updater in IPA version from 4.0 to 4.1.2 doesn't work well, this
# should detect if update in past has been executed, and set proper
@@ -317,7 +202,7 @@ class update_master_to_dnsforwardzones(DNSUpdater):
pass
if not zones:
logger.debug('No DNS zone to update found')
self.log.debug('No DNS zone to update found')
return False, []
zones_to_transform = []
@@ -332,43 +217,100 @@ class update_master_to_dnsforwardzones(DNSUpdater):
zones_to_transform.append(zone)
if zones_to_transform:
logger.info('Zones with specified forwarders with policy '
'different than none will be transformed to forward '
'zones.')
# add time to filename
self.backup_path = time.strftime(self.backup_path)
# DNs of privileges which contain dns managed permissions
privileges_to_ldif = set() # store priviledges only once
zone_to_privileges = {} # zone: [privileges cn]
self.log.info('Zones with specified forwarders with policy different'
' than none will be transformed to forward zones.')
self.log.info('Original zones will be saved in LDIF format in '
'%s file' % self.backup_path)
try:
with open(self.backup_path, 'w') as f:
writer = LDIFWriter(f)
for zone in zones_to_transform:
# save backup to ldif
try:
dn = str(zone['dn'])
del zone['dn'] # dn shouldn't be as attribute in ldif
writer.unparse(dn, zone)
if 'managedBy' in zone:
entry = ldap.get_entry(DN(zone['managedBy'][0]))
for privilege_member_dn in entry.get('member', []):
privileges_to_ldif.add(privilege_member_dn)
writer.unparse(str(entry.dn), dict(entry.raw))
# privileges where permission is used
if entry.get('member'):
zone_to_privileges[zone['idnsname'][0]] = entry['member']
# raw values are required to store into ldif
records = self.api.Command['dnsrecord_find'](
zone['idnsname'][0],
all=True,
raw=True,
sizelimit=0)['result']
for record in records:
if record['idnsname'][0] == u'@':
# zone record was saved before
continue
dn = str(record['dn'])
del record['dn']
writer.unparse(dn, record)
except Exception as e:
self.log.error('Unable to backup zone %s' %
zone['idnsname'][0])
self.log.error(traceback.format_exc())
return False, []
for privilege_dn in privileges_to_ldif:
try:
entry = ldap.get_entry(privilege_dn)
writer.unparse(str(entry.dn), dict(entry.raw))
except Exception as e:
self.log.error('Unable to backup privilege %s' %
privilege_dn)
self.log.error(traceback.format_exc())
return False, []
f.close()
except Exception:
self.log.error('Unable to create backup file')
self.log.error(traceback.format_exc())
return False, []
# update
for zone in zones_to_transform:
try:
self.backup_zone(zone)
except Exception:
logger.error('Unable to create backup for zone, '
'terminating zone upgrade')
logger.error("%s", traceback.format_exc())
return False, []
# delete master zone
try:
self.api.Command['dnszone_del'](zone['idnsname'])
except Exception as e:
logger.error('Transform to forwardzone terminated: '
'removing zone %s failed (%s)',
zone['idnsname'][0], e)
logger.error("%s", traceback.format_exc())
self.log.error('Transform to forwardzone terminated: '
'removing zone %s failed (%s)' % (
zone['idnsname'][0], e)
)
self.log.error(traceback.format_exc())
continue
# create forward zone
try:
kw = {
'idnsforwarders': zone.get('idnsforwarders', []),
'idnsforwardpolicy': zone.get('idnsforwardpolicy',
[u'first'])[0],
'skip_overlap_check': True,
'idnsforwardpolicy': zone.get('idnsforwardpolicy', [u'first'])[0]
}
self.api.Command['dnsforwardzone_add'](zone['idnsname'][0], **kw)
except Exception:
logger.error('Transform to forwardzone terminated: '
'creating forwardzone %s failed',
zone['idnsname'][0])
logger.error("%s", traceback.format_exc())
except Exception as e:
self.log.error('Transform to forwardzone terminated: creating '
'forwardzone %s failed' %
zone['idnsname'][0])
self.log.error(traceback.format_exc())
continue
# create permission if original zone has one
@@ -376,178 +318,37 @@ class update_master_to_dnsforwardzones(DNSUpdater):
try:
perm_name = self.api.Command['dnsforwardzone_add_permission'](
zone['idnsname'][0])['value']
except Exception:
logger.error('Transform to forwardzone terminated: '
'Adding managed by permission to forward '
'zone %s failed', zone['idnsname'])
logger.error("%s", traceback.format_exc())
logger.info('Zone %s was transformed to forward zone '
' without managed permissions',
zone['idnsname'][0])
except Exception as e:
self.log.error('Transform to forwardzone terminated: '
'Adding managed by permission to forward zone'
' %s failed' % zone['idnsname'])
self.log.error(traceback.format_exc())
self.log.info('Zone %s was transformed to forward zone '
' without managed permissions',
zone['idnsname'][0])
continue
else:
if zone['idnsname'][0] in self.saved_zone_to_privilege:
if zone['idnsname'][0] in zone_to_privileges:
privileges = [
dn[0].value for dn in self.saved_zone_to_privilege[zone['idnsname'][0]]
dn[0].value for dn in zone_to_privileges[zone['idnsname'][0]]
]
try:
self.api.Command['permission_add_member'](perm_name,
privilege=privileges)
except Exception:
logger.error('Unable to restore privileges '
'for permission %s, for zone %s',
perm_name, zone['idnsname'])
logger.error("%s", traceback.format_exc())
logger.info('Zone %s was transformed to '
'forward zone without restored '
'privileges',
zone['idnsname'][0])
except Exception as e:
self.log.error('Unable to restore privileges for '
'permission %s, for zone %s'
% (perm_name, zone['idnsname']))
self.log.error(traceback.format_exc())
self.log.info('Zone %s was transformed to forward zone'
' without restored privileges',
zone['idnsname'][0])
continue
logger.debug('Zone %s was sucessfully transformed to forward '
'zone',
zone['idnsname'][0])
self.log.debug('Zone %s was sucessfully transformed to forward zone',
zone['idnsname'][0])
return False, []
@register()
class update_dnsforward_emptyzones(DNSUpdater):
"""
Migrate forward policies which conflict with automatic empty zones
(RFC 6303) to use forward policy = only.
BIND ignores conflicting forwarding configuration
when forwarding policy != only.
bind-dyndb-ldap 9.0+ will do the same so we have to adjust FreeIPA zones
accordingly.
"""
backup_filename = u'dns-forwarding-empty-zones-%Y-%m-%d-%H-%M-%S.ldif'
def update_zones(self):
try:
fwzones = self.api.Command.dnsforwardzone_find(all=True,
raw=True)['result']
except errors.NotFound:
# No forwardzones found, we are done
return
logged_once = False
for zone in fwzones:
if not (
dnsutil.related_to_auto_empty_zone(
dnsutil.DNSName(zone.get('idnsname')[0]))
and zone.get('idnsforwardpolicy', [u'first'])[0] != u'only'
and zone.get('idnsforwarders', []) != []
):
# this zone does not conflict with automatic empty zone
continue
if not logged_once:
logger.info('Forward policy for zones conflicting with '
'automatic empty zones will be changed to "only"')
logged_once = True
# backup
try:
self.backup_zone(zone)
except Exception:
logger.error('Unable to create backup for zone %s, '
'terminating zone upgrade',
zone['idnsname'][0])
logger.error("%s", traceback.format_exc())
continue
# change forward policy
try:
self.api.Command['dnsforwardzone_mod'](
zone['idnsname'][0],
idnsforwardpolicy=u'only'
)
except Exception as e:
logger.error('Forward policy update for zone %s failed '
'(%s)', zone['idnsname'][0], e)
logger.error("%s", traceback.format_exc())
continue
logger.debug('Zone %s was sucessfully modified to use forward '
'policy "only"', zone['idnsname'][0])
def update_global_ldap_forwarder(self):
config = self.api.Command['dnsconfig_show'](all=True,
raw=True)['result']
if (
config.get('idnsforwardpolicy', [u'first'])[0] == u'first'
and config.get('idnsforwarders', [])
):
logger.info('Global forward policy in LDAP for all servers will '
'be changed to "only" to avoid conflicts with '
'automatic empty zones')
self.backup_zone(config)
self.api.Command['dnsconfig_mod'](idnsforwardpolicy=u'only')
def execute(self, **options):
# check LDAP if DNS subtree already uses new semantics
if not self.version_update_needed(target_version=2):
# forwardzones already use new semantics, no upgrade is required
return False, []
logger.debug('Updating forwarding policies in LDAP '
'to avoid conflicts with automatic empty zones')
# update the DNSVersion, following upgrade can be executed only once
self.api.Command['dnsconfig_mod'](ipadnsversion=2)
self.update_zones()
try:
if dnsutil.has_empty_zone_addresses(self.api.env.host):
self.update_global_ldap_forwarder()
except dns.exception.DNSException as ex:
logger.error('Skipping update of global DNS forwarder in LDAP: '
'Unable to determine if local server is using an '
'IP address belonging to an automatic empty zone. '
'Consider changing forwarding policy to "only". '
'DNS exception: %s', ex)
return False, []
@register()
class update_dnsserver_configuration_into_ldap(DNSUpdater):
"""
DNS Locations feature requires to have DNS configuration stored in LDAP DB.
Create DNS server configuration in LDAP for each old server
"""
def execute(self, **options):
ldap = self.api.Backend.ldap2
if sysupgrade.get_upgrade_state('dns', 'server_config_to_ldap'):
logger.debug('upgrade is not needed')
return False, []
dns_container_dn = DN(self.api.env.container_dns, self.api.env.basedn)
try:
ldap.get_entry(dns_container_dn)
except errors.NotFound:
logger.debug('DNS container not found, nothing to upgrade')
sysupgrade.set_upgrade_state('dns', 'server_config_to_ldap', True)
return False, []
result = self.api.Command.server_show(self.api.env.host)['result']
if not 'DNS server' in result.get('enabled_role_servrole', []):
logger.debug('This server is not DNS server, nothing to upgrade')
sysupgrade.set_upgrade_state('dns', 'server_config_to_ldap', True)
return False, []
# create container first, if doesn't exist
ensure_dnsserver_container_exists(ldap, self.api)
try:
self.api.Command.dnsserver_add(self.api.env.host)
except errors.DuplicateEntry:
logger.debug("DNS server configuration already exists "
"in LDAP database")
else:
logger.debug("DNS server configuration has been sucessfully "
"created in LDAP database")
sysupgrade.set_upgrade_state('dns', 'server_config_to_ldap', True)
return False, []
api.register(update_master_to_dnsforwardzones)

View File

@@ -17,20 +17,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import os
import pwd
from ipapython import ipaldap
from ipaserver.install import replication
from ipalib import Registry
from ipalib import api
from ipalib import Updater
logger = logging.getLogger(__name__)
register = Registry()
EXCLUDE_TEMPLATE = '(objectclass=*) $ EXCLUDE %s'
@register()
class update_replica_attribute_lists(Updater):
"""
Run through all replication agreements and ensure that EXCLUDE list
@@ -39,8 +35,8 @@ class update_replica_attribute_lists(Updater):
"""
def execute(self, **options):
# We need an LDAPClient connection to the backend
logger.debug("Start replication agreement exclude list update task")
# We need an IPAdmin connection to the backend
self.log.debug("Start replication agreement exclude list update task")
conn = self.api.Backend.ldap2
repl = replication.ReplicationManager(self.api.env.realm,
@@ -50,11 +46,11 @@ class update_replica_attribute_lists(Updater):
# We need to update only IPA replica agreements, not winsync
ipa_replicas = repl.find_ipa_replication_agreements()
logger.debug("Found %d agreement(s)", len(ipa_replicas))
self.log.debug("Found %d agreement(s)", len(ipa_replicas))
for replica in ipa_replicas:
for desc in replica.get('description', []):
logger.debug('%s', desc)
self.log.debug(desc)
self._update_attr(repl, replica,
'nsDS5ReplicatedAttributeList',
@@ -65,7 +61,7 @@ class update_replica_attribute_lists(Updater):
self._update_attr(repl, replica,
'nsds5ReplicaStripAttrs', replication.STRIP_ATTRS)
logger.debug("Done updating agreements")
self.log.debug("Done updating agreements")
return False, [] # No restart, no updates
@@ -85,16 +81,16 @@ class update_replica_attribute_lists(Updater):
"""
attrlist = replica.single_value.get(attribute)
if attrlist is None:
logger.debug("Adding %s", attribute)
self.log.debug("Adding %s", attribute)
# Need to add it altogether
replica[attribute] = [template % " ".join(values)]
try:
repl.conn.update_entry(replica)
logger.debug("Updated")
self.log.debug("Updated")
except Exception as e:
logger.error("Error caught updating replica: %s", str(e))
self.log.error("Error caught updating replica: %s", str(e))
else:
attrlist_normalized = attrlist.lower().split()
@@ -102,17 +98,19 @@ class update_replica_attribute_lists(Updater):
if a.lower() not in attrlist_normalized]
if missing:
logger.debug("%s needs updating (missing: %s)", attribute,
', '.join(missing))
self.log.debug("%s needs updating (missing: %s)", attribute,
', '.join(missing))
replica[attribute] = [
'%s %s' % (attrlist, ' '.join(missing))]
try:
repl.conn.update_entry(replica)
logger.debug("Updated %s", attribute)
self.log.debug("Updated %s", attribute)
except Exception as e:
logger.error("Error caught updating %s: %s",
attribute, str(e))
self.log.error("Error caught updating %s: %s",
attribute, str(e))
else:
logger.debug("%s: No update necessary", attribute)
self.log.debug("%s: No update necessary" % attribute)
api.register(update_replica_attribute_lists)

View File

@@ -17,19 +17,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import six
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython import ipautil
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
if six.PY3:
unicode = str
@@ -60,8 +54,8 @@ class GenerateUpdateMixin(object):
If the input DN doesn't end with old_suffix, log, an raise ValueError.
"""
if not dn.endswith(old_suffix):
logger.error("unable to replace suffix '%s' with '%s' in '%s'",
old_suffix, new_suffix, dn)
self.error("unable to replace suffix '%s' with '%s' in '%s'",
old_suffix, new_suffix, dn)
raise ValueError('no replacement made')
return DN(*dn[:-len(old_suffix)]) + new_suffix
@@ -82,15 +76,16 @@ class GenerateUpdateMixin(object):
old_definition_container = DN(('cn', 'managed entries'), ('cn', 'plugins'), ('cn', 'config'), suffix)
new_definition_container = DN(('cn', 'Definitions'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
definitions_dn = DN(('cn', 'Definitions'))
update_list = []
restart = False
# If the old entries don't exist the server has already been updated.
try:
definitions_managed_entries, _truncated = ldap.find_entries(
definitions_managed_entries, truncated = ldap.find_entries(
searchfilter, ['*'], old_definition_container,
ldap.SCOPE_ONELEVEL)
except errors.NotFound:
except errors.NotFound as e:
return (False, update_list)
for entry in definitions_managed_entries:
@@ -100,7 +95,7 @@ class GenerateUpdateMixin(object):
assert isinstance(old_dn, DN)
try:
entry = ldap.get_entry(old_dn, ['*'])
except errors.NotFound:
except errors.NotFound as e:
pass
else:
# Compute the new dn by replacing the old container with the new container
@@ -156,8 +151,6 @@ class GenerateUpdateMixin(object):
return (restart, update_list)
@register()
class update_managed_post_first(Updater, GenerateUpdateMixin):
"""
Update managed entries
@@ -165,12 +158,12 @@ class update_managed_post_first(Updater, GenerateUpdateMixin):
def execute(self, **options):
# Never need to restart with the pre-update changes
_ignore, update_list = self.generate_update(False)
(ignore, update_list) = self.generate_update(False)
return False, update_list
api.register(update_managed_post_first)
@register()
class update_managed_post(Updater, GenerateUpdateMixin):
"""
Update managed entries
@@ -180,3 +173,5 @@ class update_managed_post(Updater, GenerateUpdateMixin):
(restart, update_list) = self.generate_update(True)
return restart, update_list
api.register(update_managed_post)

View File

@@ -2,24 +2,13 @@
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
#
from __future__ import absolute_import
import logging
from ipalib import errors
from ipalib import Registry
from ipalib import api
from ipalib import Updater
from ipapython.dn import DN
from ipaserver.install import cainstance
from ipaserver.install import certs, cainstance
from ipaserver.install import ldapupdate
from ipaplatform.paths import paths
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_ca_topology(Updater):
"""
Updates CA topology configuration entries
@@ -27,9 +16,9 @@ class update_ca_topology(Updater):
def execute(self, **options):
ca = cainstance.CAInstance(self.api.env.realm)
ca = cainstance.CAInstance(self.api.env.realm, certs.NSS_DIR)
if not ca.is_configured():
logger.debug("CA is not configured on this host")
self.log.debug("CA is not configured on this host")
return False, []
ld = ldapupdate.LDAPUpdate(ldapi=True, sub_dict={
@@ -39,24 +28,6 @@ class update_ca_topology(Updater):
ld.update([paths.CA_TOPOLOGY_ULDIF])
ldap = self.api.Backend.ldap2
ca_replica_dn = DN(
('cn', 'replica'),
('cn', 'o=ipaca'),
('cn', 'mapping tree'),
('cn', 'config'))
check_interval_attr = 'nsds5replicabinddngroupcheckinterval'
default_check_interval = ['60']
try:
ca_replica_entry = ldap.get_entry(ca_replica_dn)
except errors.NotFound:
pass
else:
if check_interval_attr not in ca_replica_entry:
ca_replica_entry[check_interval_attr] = default_check_interval
ldap.update_entry(ca_replica_entry)
return False, []
api.register(update_ca_topology)

View File

@@ -1,128 +0,0 @@
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#
import logging
import time
import ldap
from ipalib.plugable import Registry
from ipalib import errors
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_dna_shared_config(Updater):
def execute(self, **options):
method = options.get('method', "SASL/GSSAPI")
protocol = options.get('protocol', "LDAP")
dna_bind_method = "dnaRemoteBindMethod"
dna_conn_protocol = "dnaRemoteConnProtocol"
dna_plugin = DN(('cn', 'Distributed Numeric Assignment Plugin'),
('cn', 'plugins'),
('cn', 'config'))
dna_config_base = DN(('cn', 'posix IDs'), dna_plugin)
conn = self.api.Backend.ldap2
# Check the plugin is enabled else it is useless to update
# the shared entry
try:
entry = conn.get_entry(dna_plugin)
if entry.single_value.get('nsslapd-pluginenabled') == 'off':
return False, ()
except errors.NotFound:
logger.error("Could not find DNA plugin entry: %s",
dna_config_base)
return False, ()
try:
entry = conn.get_entry(dna_config_base)
except errors.NotFound:
logger.error("Could not find DNA config entry: %s",
dna_config_base)
return False, ()
sharedcfgdn = entry.single_value.get("dnaSharedCfgDN")
if sharedcfgdn is not None:
sharedcfgdn = DN(sharedcfgdn)
else:
logger.error(
"Could not find DNA shared config DN in entry: %s",
dna_config_base)
return False, ()
#
# Update the shared config entry related to that host
#
# If the shared config entry already exists (like upgrade)
# the update occurs immediately without sleep.
#
# If the shared config entry does not exist (fresh install)
# DS server waits for 30s after its startup to create it.
# Startup likely occurred few sec before this function is
# called so this loop will wait for 30s max.
#
# In case the server is not able to create the entry
# The loop gives a grace period of 60s before logging
# the failure to update the shared config entry and return
#
max_wait = 30
fqdn = self.api.env.host
for _i in range(0, max_wait + 1):
try:
entries = conn.get_entries(
sharedcfgdn, scope=ldap.SCOPE_ONELEVEL,
filter='dnaHostname=%s' % fqdn
)
break
except errors.NotFound:
logger.debug(
"Unable to find DNA shared config entry for "
"dnaHostname=%s (under %s) so far. Retry in 2 sec.",
fqdn, sharedcfgdn
)
time.sleep(2)
else:
logger.error(
"Could not get dnaHostname entries in %s seconds",
max_wait * 2
)
return False, ()
# If there are several entries, all of them will be updated
# just log a debug msg. This is likely the result of #5510
if len(entries) != 1:
logger.debug(
"%d entries dnaHostname=%s under %s. One expected",
len(entries), fqdn, sharedcfgdn
)
# time to set the bind method and the protocol in the
# shared config entries
for entry in entries:
update = False
if entry.single_value.get(dna_bind_method) != method:
entry[dna_bind_method] = method
update = True
if entry.single_value.get(dna_conn_protocol) != protocol:
entry[dna_conn_protocol] = protocol
update = True
if update:
try:
conn.update_entry(entry)
except Exception as e:
logger.error(
"Failed to set SASL/GSSAPI bind method/protocol "
"in entry %s: %s", entry, e
)
# no restart, no update
return False, ()

View File

@@ -1,84 +0,0 @@
# Authors:
# Florence Blanc-Renaud <flo@redhat.com>
#
# Copyright (C) 2017 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import Updater
from ipalib.install import certstore
from ipapython.dn import DN
from ipapython.certdb import get_ca_nickname
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_fix_duplicate_cacrt_in_ldap(Updater):
"""
When multiple entries exist for IPA CA cert in ldap, remove the duplicate
After this plugin, ds needs to be restarted. This ensures that
the attribute uniqueness plugin is working and prevents
other plugins from adding duplicates.
"""
def execute(self, **options):
# If CA is disabled, no need to check for duplicates of IPA CA
ca_enabled = self.api.Command.ca_is_enabled()['result']
if not ca_enabled:
return True, []
# Look for the IPA CA cert subject
ldap = self.api.Backend.ldap2
cacert_subject = certstore.get_ca_subject(
ldap,
self.api.env.container_ca,
self.api.env.basedn)
# Find if there are other certificates with the same subject
# They are duplicates resulting of BZ 1480102
base_dn = DN(('cn', 'certificates'), ('cn', 'ipa'), ('cn', 'etc'),
self.api.env.basedn)
try:
filter = ldap.make_filter({'ipaCertSubject': cacert_subject})
result, _truncated = ldap.find_entries(
base_dn=base_dn,
filter=filter,
attrs_list=[])
except errors.NotFound:
# No duplicate, we're good
logger.debug("No duplicates for IPA CA in LDAP")
return True, []
logger.debug("Found %d entrie(s) for IPA CA in LDAP", len(result))
cacert_dn = DN(('cn', get_ca_nickname(self.api.env.realm)), base_dn)
for entry in result:
if entry.dn == cacert_dn:
continue
# Remove the duplicate
try:
ldap.delete_entry(entry)
logger.debug("Removed the duplicate %s", entry.dn)
except Exception as e:
logger.warning("Failed to remove the duplicate %s: %s",
entry.dn, e)
return True, []

View File

@@ -17,18 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
from ipapython.ipa_log_manager import *
@register()
class update_idrange_type(Updater):
"""
Update all ID ranges that do not have ipaRangeType attribute filled.
@@ -40,8 +34,8 @@ class update_idrange_type(Updater):
base_dn = DN(self.api.env.container_ranges, self.api.env.basedn)
search_filter = ("(&(objectClass=ipaIDrange)(!(ipaRangeType=*)))")
logger.debug("update_idrange_type: search for ID ranges with no "
"type set")
root_logger.debug("update_idrange_type: search for ID ranges with no "
"type set")
while True:
# Run the search in loop to avoid issues when LDAP limits are hit
@@ -52,23 +46,24 @@ class update_idrange_type(Updater):
['objectclass'], base_dn, time_limit=0, size_limit=0)
except errors.NotFound:
logger.debug("update_idrange_type: no ID range without "
"type set found")
root_logger.debug("update_idrange_type: no ID range without "
"type set found")
return False, []
except errors.ExecutionError as e:
logger.error("update_idrange_type: cannot retrieve list "
"of ranges with no type set: %s", e)
root_logger.error("update_idrange_type: cannot retrieve list "
"of ranges with no type set: %s", e)
return False, []
if not entries:
# No entry was returned, rather break than continue cycling
logger.debug("update_idrange_type: no ID range was returned")
root_logger.debug("update_idrange_type: no ID range was "
"returned")
return False, []
logger.debug("update_idrange_type: found %d "
"idranges to update, truncated: %s",
len(entries), truncated)
root_logger.debug("update_idrange_type: found %d "
"idranges to update, truncated: %s",
len(entries), truncated)
error = False
@@ -85,36 +80,35 @@ class update_idrange_type(Updater):
entry['ipaRangeType'] = ['ipa-local']
else:
entry['ipaRangeType'] = ['unknown']
logger.error("update_idrange_type: could not detect "
"range type for entry: %s", str(entry.dn))
logger.error("update_idrange_type: ID range type set "
"to 'unknown' for entry: %s", str(entry.dn))
root_logger.error("update_idrange_type: could not detect "
"range type for entry: %s" % str(entry.dn))
root_logger.error("update_idrange_type: ID range type set "
"to 'unknown' for entry: %s" % str(entry.dn))
try:
ldap.update_entry(entry)
except (errors.EmptyModlist, errors.NotFound):
pass
except errors.ExecutionError as e:
logger.debug("update_idrange_type: cannot "
"update idrange type: %s", e)
root_logger.debug("update_idrange_type: cannot "
"update idrange type: %s", e)
error = True
if error:
# Exit loop to avoid infinite cycles
logger.error("update_idrange_type: error(s) "
"detected during idrange type update")
root_logger.error("update_idrange_type: error(s) "
"detected during idrange type update")
return False, []
elif not truncated:
# All affected entries updated, exit the loop
logger.debug("update_idrange_type: all affected idranges "
"were assigned types")
root_logger.debug("update_idrange_type: all affected idranges "
"were assigned types")
return False, []
return False, []
@register()
class update_idrange_baserid(Updater):
"""
Update ipa-ad-trust-posix ranges' base RID to 0. This applies to AD trust
@@ -128,29 +122,29 @@ class update_idrange_baserid(Updater):
search_filter = ("(&(objectClass=ipaTrustedADDomainRange)"
"(ipaRangeType=ipa-ad-trust-posix)"
"(!(ipaBaseRID=0)))")
logger.debug(
root_logger.debug(
"update_idrange_baserid: search for ipa-ad-trust-posix ID ranges "
"with ipaBaseRID != 0"
)
try:
(entries, _truncated) = ldap.find_entries(
(entries, truncated) = ldap.find_entries(
search_filter, ['ipabaserid'], base_dn,
paged_search=True, time_limit=0, size_limit=0)
except errors.NotFound:
logger.debug("update_idrange_baserid: no AD domain "
"range with posix attributes found")
root_logger.debug("update_idrange_baserid: no AD domain "
"range with posix attributes found")
return False, []
except errors.ExecutionError as e:
logger.error("update_idrange_baserid: cannot retrieve "
"list of affected ranges: %s", e)
root_logger.error("update_idrange_baserid: cannot retrieve "
"list of affected ranges: %s", e)
return False, []
logger.debug("update_idrange_baserid: found %d "
"idranges possible to update",
len(entries))
root_logger.debug("update_idrange_baserid: found %d "
"idranges possible to update",
len(entries))
error = False
@@ -158,22 +152,25 @@ class update_idrange_baserid(Updater):
for entry in entries:
entry['ipabaserid'] = 0
try:
logger.debug("Updating existing idrange: %s", entry.dn)
root_logger.debug("Updating existing idrange: %s" % (entry.dn))
ldap.update_entry(entry)
logger.info("Done")
root_logger.info("Done")
except (errors.EmptyModlist, errors.NotFound):
pass
except errors.ExecutionError as e:
logger.debug("update_idrange_type: cannot "
"update idrange: %s", e)
root_logger.debug("update_idrange_type: cannot "
"update idrange: %s", e)
error = True
if error:
logger.error("update_idrange_baserid: error(s) "
"detected during idrange baserid update")
root_logger.error("update_idrange_baserid: error(s) "
"detected during idrange baserid update")
else:
# All affected entries updated, exit the loop
logger.debug("update_idrange_baserid: all affected "
"idranges updated")
root_logger.debug("update_idrange_baserid: all affected "
"idranges updated")
return False, []
api.register(update_idrange_type)
api.register(update_idrange_baserid)

View File

@@ -1,38 +0,0 @@
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#
from ipalib import Registry
from ipalib import Updater
from ipalib import errors
from ipapython.dn import DN
register = Registry()
@register()
class update_ldap_server_list(Updater):
"""
Update defaultServerList, an option that helps Solaris
clients discover LDAP server replicas.
"""
def execute(self, **options):
ldap = self.api.Backend.ldap2
dn = DN(('cn', 'default'), ('ou', 'profile'), self.api.env.basedn)
try:
entry = ldap.get_entry(dn)
srvlist = entry.single_value.get('defaultServerList', '')
srvlist = srvlist.split()
if not self.api.env.host in srvlist:
srvlist.append(self.api.env.host)
attr = ' '.join(srvlist)
entry['defaultServerList'] = attr
ldap.update_entry(entry)
except errors.NotFound:
pass
except ldap.TYPE_OR_VALUE_EXISTS:
pass
# no restart, no updates
return False, ()

View File

@@ -83,24 +83,20 @@ No other keys are allowed in the template
The plugin also deletes permissions specified in OBSOLETE_PERMISSIONS.
"""
import logging
import six
from ipalib import api, errors
from ipapython.dn import DN
from ipalib.plugable import Registry
from ipalib.plugins import aci
from ipalib.plugins.permission import permission, permission_del
from ipalib.aci import ACI
from ipalib import Updater
from ipapython import ipautil
from ipaserver.plugins import aci
from ipaserver.plugins.permission import permission, permission_del
if six.PY3:
unicode = str
logger = logging.getLogger(__name__)
register = Registry()
OBSOLETE_PERMISSIONS = {
@@ -331,7 +327,7 @@ class update_managed_permissions(Updater):
for acistr in acistrs:
if ACI(acistr).isequal(anonymous_read_aci):
logger.debug('Removing anonymous ACI: %s', acistr)
self.log.debug('Removing anonymous ACI: %s', acistr)
acistrs.remove(acistr)
break
else:
@@ -360,18 +356,18 @@ class update_managed_permissions(Updater):
anonymous_read_aci = self.get_anonymous_read_aci(ldap)
if anonymous_read_aci:
logger.debug('Anonymous read ACI: %s', anonymous_read_aci)
self.log.debug('Anonymous read ACI: %s', anonymous_read_aci)
else:
logger.debug('Anonymous ACI not found')
self.log.debug('Anonymous ACI not found')
current_obj = () # initially distinct from any obj value, even None
for name, template, obj in self.get_templates():
if current_obj != obj:
if obj:
logger.debug('Updating managed permissions for %s',
obj.name)
self.log.debug('Updating managed permissions for %s',
obj.name)
else:
logger.debug('Updating non-object managed permissions')
self.log.debug('Updating non-object managed permissions')
current_obj = obj
self.update_permission(ldap,
@@ -384,15 +380,15 @@ class update_managed_permissions(Updater):
self.remove_anonymous_read_aci(ldap, anonymous_read_aci)
for obsolete_name in OBSOLETE_PERMISSIONS:
logger.debug('Deleting obsolete permission %s', obsolete_name)
self.log.debug('Deleting obsolete permission %s', obsolete_name)
try:
self.api.Command[permission_del](unicode(obsolete_name),
force=True,
version=u'2.101')
except errors.NotFound:
logger.debug('Obsolete permission not found')
self.log.debug('Obsolete permission not found')
else:
logger.debug('Obsolete permission deleted: %s', obsolete_name)
self.log.debug('Obsolete permission deleted: %s', obsolete_name)
return False, ()
@@ -433,58 +429,58 @@ class update_managed_permissions(Updater):
legacy_entry = ldap.get_entry(legacy_dn,
['ipapermissiontype', 'cn'])
except errors.NotFound:
logger.debug("Legacy permission %s not found", legacy_name)
self.log.debug("Legacy permission %s not found", legacy_name)
else:
if 'ipapermissiontype' not in legacy_entry:
if is_new:
_acientry, acistr = (
acientry, acistr = (
permission_plugin._get_aci_entry_and_string(
legacy_entry, notfound_ok=True))
try:
included, excluded = self.get_upgrade_attr_lists(
acistr, legacy_acistrs)
except IncompatibleACIModification:
logger.error(
self.log.error(
"Permission '%s' has been modified from its "
"default; not updating it to '%s'.",
legacy_name, name)
return
else:
logger.debug("Merging attributes from legacy "
"permission '%s'", legacy_name)
logger.debug("Included attrs: %s",
', '.join(sorted(included)))
logger.debug("Excluded attrs: %s",
', '.join(sorted(excluded)))
self.log.debug("Merging attributes from legacy "
"permission '%s'", legacy_name)
self.log.debug("Included attrs: %s",
', '.join(sorted(included)))
self.log.debug("Excluded attrs: %s",
', '.join(sorted(excluded)))
entry['ipapermincludedattr'] = list(included)
entry['ipapermexcludedattr'] = list(excluded)
remove_legacy = True
else:
logger.debug("Ignoring attributes in legacy "
"permission '%s' because '%s' exists",
legacy_name, name)
self.log.debug("Ignoring attributes in legacy "
"permission '%s' because '%s' exists",
legacy_name, name)
remove_legacy = True
else:
logger.debug("Ignoring V2 permission named '%s'",
legacy_name)
self.log.debug("Ignoring V2 permission named '%s'" %
legacy_name)
update_aci = True
logger.debug('Updating managed permission: %s', name)
self.log.debug('Updating managed permission: %s', name)
if is_new:
ldap.add_entry(entry)
else:
try:
ldap.update_entry(entry)
except errors.EmptyModlist:
logger.debug('No changes to permission: %s', name)
self.log.debug('No changes to permission: %s', name)
update_aci = False
if update_aci:
logger.debug('Updating ACI for managed permission: %s', name)
self.log.debug('Updating ACI for managed permission: %s', name)
permission_plugin.update_aci(entry)
if remove_legacy:
logger.debug("Removing legacy permission '%s'", legacy_name)
self.log.debug("Removing legacy permission '%s'", legacy_name)
self.api.Command[permission_del](unicode(legacy_name))
for name in template.get('replaces_system', ()):
@@ -493,14 +489,14 @@ class update_managed_permissions(Updater):
entry = ldap.get_entry(permission_plugin.get_dn(name),
['ipapermissiontype'])
except errors.NotFound:
logger.debug("Legacy permission '%s' not found", name)
self.log.debug("Legacy permission '%s' not found", name)
else:
flags = entry.get('ipapermissiontype', [])
if list(flags) == ['SYSTEM']:
logger.debug("Removing legacy permission '%s'", name)
self.log.debug("Removing legacy permission '%s'", name)
self.api.Command[permission_del](name, force=True)
else:
logger.debug("Ignoring V2 permission '%s'", name)
self.log.debug("Ignoring V2 permission '%s'", name)
def get_upgrade_attr_lists(self, current_acistring, default_acistrings):
"""Compute included and excluded attributes for a new permission
@@ -545,8 +541,8 @@ class update_managed_permissions(Updater):
current_aci = ACI(current_acistring)
current_attrs = _pop_targetattr(current_aci)
logger.debug("Current ACI for '%s': %s",
current_aci.name, current_acistring)
self.log.debug("Current ACI for '%s': %s",
current_aci.name, current_acistring)
attrs_in_all_defaults = None
attrs_in_any_defaults = set()
@@ -554,11 +550,11 @@ class update_managed_permissions(Updater):
for default_acistring in default_acistrings:
default_aci = ACI(default_acistring)
default_attrs = _pop_targetattr(default_aci)
logger.debug("Default ACI for '%s': %s",
default_aci.name, default_acistring)
self.log.debug("Default ACI for '%s': %s",
default_aci.name, default_acistring)
if current_aci != default_aci:
logger.debug('ACIs not compatible')
self.log.debug('ACIs not compatible')
continue
else:
all_incompatible = False
@@ -570,7 +566,7 @@ class update_managed_permissions(Updater):
attrs_in_any_defaults |= default_attrs
if all_incompatible:
logger.debug('All old default ACIs are incompatible')
self.log.debug('All old default ACIs are incompatible')
raise(IncompatibleACIModification())
included = current_attrs - attrs_in_any_defaults
@@ -663,8 +659,8 @@ class update_managed_permissions(Updater):
anonymous_read_aci.target['targetattr']['expression'])
read_blacklist &= attributes
if read_blacklist:
logger.debug('Excluded attributes for %s: %s',
name, ', '.join(read_blacklist))
self.log.debug('Excluded attributes for %s: %s',
name, ', '.join(read_blacklist))
entry['ipapermexcludedattr'] = list(read_blacklist)
# Sanity check
@@ -704,7 +700,7 @@ class update_read_replication_agreements_permission(Updater):
try:
perm_entry = ldap.get_entry(old_perm_dn)
except errors.NotFound:
logger.debug("Old permission not found")
self.log.debug("Old permission not found")
return False, ()
try:
@@ -713,9 +709,9 @@ class update_read_replication_agreements_permission(Updater):
# we can happily upgrade
pass
else:
logger.error("Permission '%s' cannot be upgraded. "
"Permission with target name '%s' already "
"exists", old_perm_dn, new_perm_dn)
self.log.error("Permission '{}' cannot be upgraded. "
"Permission with target name '{}' already "
"exists".format(old_perm_dn, new_perm_dn))
return False, ()
# values are case insensitive
@@ -733,14 +729,14 @@ class update_read_replication_agreements_permission(Updater):
perm_entry['ipapermlocation'] = []
perm_entry['ipapermtargetfilter'] = []
logger.debug("Removing MANAGED attributes from permission %s",
old_perm_dn)
self.log.debug("Removing MANAGED attributes from permission %s",
old_perm_dn)
try:
ldap.update_entry(perm_entry)
except errors.EmptyModlist:
pass
# do modrdn on permission
logger.debug("modrdn: %s -> %s", old_perm_dn, new_perm_dn)
self.log.debug("modrdn: %s -> %s", old_perm_dn, new_perm_dn)
ldap.move_entry(old_perm_dn, new_perm_dn)
return False, ()

View File

@@ -2,10 +2,6 @@
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
#
from __future__ import absolute_import
import logging
from ipalib.plugable import Registry
from ipalib import errors
from ipalib import Updater
@@ -14,8 +10,6 @@ from ipapython.dn import DN
from ipaserver.install import sysupgrade
from ipaserver.install.ldapupdate import LDAPUpdate
logger = logging.getLogger(__name__)
register = Registry()
@@ -38,7 +32,7 @@ class update_nis_configuration(Updater):
# maps, we do not want to restore them again
return
logger.debug("Recovering from missing NIS maps bug")
self.log.debug("Recovering from missing NIS maps bug")
suffix = "cn=NIS Server,cn=plugins,cn=config"
domain = self.api.env.domain
@@ -77,7 +71,7 @@ class update_nis_configuration(Updater):
ldap.get_entry(dn, attrs_list=['cn'])
except errors.NotFound:
# NIS is not configured on system, do not execute update
logger.debug("Skipping NIS update, NIS Server is not configured")
self.log.debug("Skipping NIS update, NIS Server is not configured")
# container does not exist, bug #5507 is not effective
sysupgrade.set_upgrade_state(
@@ -85,7 +79,7 @@ class update_nis_configuration(Updater):
else:
self.__recover_from_missing_maps(ldap)
logger.debug("Executing NIS Server update")
self.log.debug("Executing NIS Server update")
ld = LDAPUpdate(sub_dict={}, ldapi=True)
ld.update([paths.NIS_UPDATE_ULDIF])

View File

@@ -17,18 +17,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_pacs(Updater):
"""
Includes default nfs:None only if no nfs: PAC present in ipakrbauthzdata.
@@ -42,18 +35,20 @@ class update_pacs(Updater):
entry = ldap.get_entry(dn, ['ipakrbauthzdata'])
pacs = entry.get('ipakrbauthzdata', [])
except errors.NotFound:
logger.warning('Error retrieving: %s', str(dn))
self.log.warning('Error retrieving: %s' % str(dn))
return False, []
nfs_pac_set = any(pac.startswith('nfs:') for pac in pacs)
if not nfs_pac_set:
logger.debug('Adding nfs:NONE to default PAC types')
self.log.debug('Adding nfs:NONE to default PAC types')
updated_pacs = pacs + [u'nfs:NONE']
entry['ipakrbauthzdata'] = updated_pacs
ldap.update_entry(entry)
else:
logger.debug('PAC for nfs is already set, not adding nfs:NONE.')
self.log.debug('PAC for nfs is already set, not adding nfs:NONE.')
return False, []
api.register(update_pacs)

View File

@@ -2,28 +2,21 @@
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
#
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
from ipapython.ipa_log_manager import root_logger
from ipaserver.install import sysupgrade
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_passync_privilege_check(Updater):
def execute(self, **options):
update_done = sysupgrade.get_upgrade_state('winsync', 'passsync_privilege_updated')
if update_done:
logger.debug("PassSync privilege update pre-check not needed")
root_logger.debug("PassSync privilege update pre-check not needed")
return False, []
logger.debug("Check if there is existing PassSync privilege")
root_logger.debug("Check if there is existing PassSync privilege")
passsync_privilege_dn = DN(('cn','PassSync Service'),
self.api.env.container_privilege,
@@ -33,16 +26,16 @@ class update_passync_privilege_check(Updater):
try:
ldap.get_entry(passsync_privilege_dn, [''])
except errors.NotFound:
logger.debug("PassSync privilege not found, this is a new update")
root_logger.debug("PassSync privilege not found, this is a new update")
sysupgrade.set_upgrade_state('winsync', 'passsync_privilege_updated', False)
else:
logger.debug("PassSync privilege found, skip updating PassSync")
root_logger.debug("PassSync privilege found, skip updating PassSync")
sysupgrade.set_upgrade_state('winsync', 'passsync_privilege_updated', True)
return False, []
api.register(update_passync_privilege_check)
@register()
class update_passync_privilege_update(Updater):
"""
Add PassSync user as a member of PassSync privilege, if it exists
@@ -51,10 +44,10 @@ class update_passync_privilege_update(Updater):
def execute(self, **options):
update_done = sysupgrade.get_upgrade_state('winsync', 'passsync_privilege_updated')
if update_done:
logger.debug("PassSync privilege update not needed")
root_logger.debug("PassSync privilege update not needed")
return False, []
logger.debug("Add PassSync user as a member of PassSync privilege")
root_logger.debug("Add PassSync user as a member of PassSync privilege")
ldap = self.api.Backend.ldap2
passsync_dn = DN(('uid','passsync'), ('cn', 'sysaccounts'), ('cn', 'etc'),
self.api.env.basedn)
@@ -63,13 +56,13 @@ class update_passync_privilege_update(Updater):
self.api.env.basedn)
try:
ldap.get_entry(passsync_dn, [''])
entry = ldap.get_entry(passsync_dn, [''])
except errors.NotFound:
logger.debug("PassSync user not found, no update needed")
root_logger.debug("PassSync user not found, no update needed")
sysupgrade.set_upgrade_state('winsync', 'passsync_privilege_updated', True)
return False, []
else:
logger.debug("PassSync user found, do update")
root_logger.debug("PassSync user found, do update")
update = {'dn': passsync_privilege_dn,
'updates': [
@@ -79,3 +72,5 @@ class update_passync_privilege_update(Updater):
sysupgrade.set_upgrade_state('winsync', 'passsync_privilege_updated', True)
return False, [update]
api.register(update_passync_privilege_update)

View File

@@ -1,66 +0,0 @@
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#
from __future__ import absolute_import
import logging
import os
import tempfile
from ipalib import Registry
from ipalib import Updater
from ipalib.install import certmonger
from ipaplatform.paths import paths
from ipapython.certdb import NSSDatabase
from ipaserver.install import cainstance
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_ra_cert_store(Updater):
"""
Moves the ipaCert store from /etc/httpd/alias RA_AGENT_PEM, RA_AGENT_KEY
files
"""
def execute(self, **options):
ra_nick = 'ipaCert'
ca_enabled = self.api.Command.ca_is_enabled()['result']
if not ca_enabled:
return False, []
certdb = NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
if not certdb.has_nickname(ra_nick):
# Nothign to do
return False, []
elif os.path.exists(paths.RA_AGENT_PEM):
# even though the certificate file exists, we will overwrite it
# as it's probabably something wrong anyway
logger.warning(
"A certificate with the nickname 'ipaCert' exists in "
"the old '%s' NSS database as well as in the new "
"PEM file '%s'",
paths.HTTPD_ALIAS_DIR, paths.RA_AGENT_PEM)
_fd, p12file = tempfile.mkstemp(dir=certdb.secdir)
# no password is necessary as we will be saving it in clear anyway
certdb.export_pkcs12(ra_nick, p12file, pkcs12_passwd='')
# stop tracking the old cert and remove it
certmonger.stop_tracking(paths.HTTPD_ALIAS_DIR, nickname=ra_nick)
certdb.delete_cert(ra_nick)
if os.path.exists(paths.OLD_KRA_AGENT_PEM):
os.remove(paths.OLD_KRA_AGENT_PEM)
# get the private key and certificate from the file and start
# tracking it in certmonger
ca = cainstance.CAInstance()
ca.import_ra_cert(p12file)
os.remove(p12file)
return False, []

View File

@@ -2,18 +2,11 @@
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
#
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
from ipapython.ipa_log_manager import root_logger
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_referint(Updater):
"""
Update referential integrity configuration to new style
@@ -33,39 +26,39 @@ class update_referint(Updater):
def execute(self, **options):
logger.debug("Upgrading referential integrity plugin configuration")
root_logger.debug("Upgrading referential integrity plugin configuration")
ldap = self.api.Backend.ldap2
try:
entry = ldap.get_entry(self.referint_dn)
except errors.NotFound:
logger.error("Referential integrity configuration not found")
root_logger.error("Referential integrity configuration not found")
return False, []
referint_membership_attrs = []
logger.debug("Initial value: %s", repr(entry))
root_logger.debug("Initial value: %s", repr(entry))
# nsslapd-pluginArg0 -> referint-update-delay
update_delay = entry.get('nsslapd-pluginArg0')
if update_delay:
logger.debug("add: referint-update-delay: %s", update_delay)
root_logger.debug("add: referint-update-delay: %s", update_delay)
entry['referint-update-delay'] = update_delay
entry['nsslapd-pluginArg0'] = None
else:
logger.debug("Plugin already uses new style, skipping")
root_logger.debug("Plugin already uses new style, skipping")
return False, []
# nsslapd-pluginArg1 -> referint-logfile
logfile = entry.get('nsslapd-pluginArg1')
if logfile:
logger.debug("add: referint-logfile: %s", logfile)
root_logger.debug("add: referint-logfile: %s", logfile)
entry['referint-logfile'] = logfile
entry['nsslapd-pluginArg1'] = None
# nsslapd-pluginArg2 -> referint-logchanges
logchanges = entry.get('nsslapd-pluginArg2')
if logchanges:
logger.debug("add: referint-logchanges: %s", logchanges)
root_logger.debug("add: referint-logchanges: %s", logchanges)
entry['referint-logchanges'] = logchanges
entry['nsslapd-pluginArg2'] = None
@@ -82,11 +75,13 @@ class update_referint(Updater):
# mixing old and new style
entry['referint-membership-attr'] = referint_membership_attrs
logger.debug("Final value: %s", repr(entry))
root_logger.debug("Final value: %s", repr(entry))
try:
ldap.update_entry(entry)
except errors.EmptyModlist:
logger.debug("No modifications required")
root_logger.debug("No modifications required")
return False, []
return False, []
api.register(update_referint)

View File

@@ -17,18 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
from ipapython.ipa_log_manager import *
@register()
class update_service_principalalias(Updater):
"""
Update all services which do not have ipakrbprincipalalias attribute
@@ -42,8 +36,8 @@ class update_service_principalalias(Updater):
base_dn = DN(self.api.env.container_service, self.api.env.basedn)
search_filter = ("(&(objectclass=krbprincipal)(objectclass=ipaservice)"
"(!(objectclass=ipakrbprincipal)))")
logger.debug("update_service_principalalias: search for affected "
"services")
root_logger.debug("update_service_principalalias: search for affected "
"services")
while True:
# run the search in loop to avoid issues when LDAP limits are hit
@@ -53,21 +47,21 @@ class update_service_principalalias(Updater):
['objectclass', 'krbprincipalname'], base_dn,
time_limit=0, size_limit=0)
except errors.NotFound:
logger.debug("update_service_principalalias: no service "
"to update found")
root_logger.debug("update_service_principalalias: no service "
"to update found")
return False, []
except errors.ExecutionError as e:
logger.error("update_service_principalalias: cannot "
"retrieve list of affected services: %s", e)
root_logger.error("update_service_principalalias: cannot "
"retrieve list of affected services: %s", e)
return False, []
if not entries:
# no entry was returned, rather break than continue cycling
logger.debug("update_service_principalalias: no service "
"was returned")
root_logger.debug("update_service_principalalias: no service "
"was returned")
return False, []
logger.debug("update_service_principalalias: found %d "
"services to update, truncated: %s",
len(entries), truncated)
root_logger.debug("update_service_principalalias: found %d "
"services to update, truncated: %s",
len(entries), truncated)
error = False
for entry in entries:
@@ -79,18 +73,20 @@ class update_service_principalalias(Updater):
except (errors.EmptyModlist, errors.NotFound):
pass
except errors.ExecutionError as e:
logger.debug("update_service_principalalias: cannot "
"update service: %s", e)
root_logger.debug("update_service_principalalias: cannot "
"update service: %s", e)
error = True
if error:
# exit loop to avoid infinite cycles
logger.error("update_service_principalalias: error(s)"
"detected during service update")
root_logger.error("update_service_principalalias: error(s)"
"detected during service update")
return False, []
elif not truncated:
# all affected entries updated, exit the loop
logger.debug("update_service_principalalias: all affected"
" services updated")
root_logger.debug("update_service_principalalias: all affected"
" services updated")
return False, []
return False, []
api.register(update_service_principalalias)

View File

@@ -17,18 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib import Registry, errors
from ipalib import api, errors
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
from ipapython.ipa_log_manager import *
@register()
class update_uniqueness_plugins_to_new_syntax(Updater):
"""
Migrate uniqueness plugins to new style syntax
@@ -180,13 +174,13 @@ class update_uniqueness_plugins_to_new_syntax(Updater):
)
try:
entries, _truncated = ldap.find_entries(
entries, truncated = ldap.find_entries(
filter=old_style_plugin_search_filter,
base_dn=self.plugins_dn,
)
except errors.NotFound:
logger.debug("No uniqueness plugin entries with old style "
"configuration found")
root_logger.debug("No uniqueness plugin entries with old style "
"configuration found")
return False, []
update_list = []
@@ -201,14 +195,14 @@ class update_uniqueness_plugins_to_new_syntax(Updater):
for entry in entries:
# test for mixed configuration
if any(attr in entry for attr in new_attributes):
logger.critical("Mixed old and new style configuration "
"for plugin %s. Plugin will not work. "
"Skipping plugin migration, please fix it "
"manually",
entry.dn)
root_logger.critical("Mixed old and new style configuration "
"for plugin %s. Plugin will not work. "
"Skipping plugin migration, please fix it "
"manually",
entry.dn)
continue
logger.debug("Configuration of plugin %s will be migrated "
"to new style", entry.dn)
root_logger.debug("Configuration of plugin %s will be migrated "
"to new style", entry.dn)
try:
# detect which configuration was used
arg0 = entry.get('nsslapd-pluginarg0')
@@ -217,10 +211,12 @@ class update_uniqueness_plugins_to_new_syntax(Updater):
else:
update = self.__subtree_style(entry)
except ValueError as e:
logger.error("Unable to migrate configuration of "
"plugin %s (%s)",
entry.dn, e)
else:
update_list.append(update)
root_logger.error("Unable to migrate configuration of "
"plugin %s (%s)",
entry.dn, e)
update_list.append(update)
return False, update_list
api.register(update_uniqueness_plugins_to_new_syntax)

View File

@@ -17,40 +17,24 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ipalib.install import certstore
from ipaserver.install import certs, dsinstance
from ipaserver.install.installutils import realm_to_serverid
from ipalib import Registry, errors
from ipaserver.install import certs
from ipalib import api, errors, certstore
from ipalib import Updater
from ipapython import certdb
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
@register()
class update_upload_cacrt(Updater):
"""
Upload public CA certificate to LDAP
"""
def execute(self, **options):
serverid = realm_to_serverid(self.api.env.realm)
db = certs.CertDB(self.api.env.realm,
nssdir=dsinstance.config_dirname(serverid))
db = certs.CertDB(self.api.env.realm)
ca_cert = None
ca_enabled = self.api.Command.ca_is_enabled()['result']
if ca_enabled:
ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
ca_subject = certstore.get_ca_subject(
self.api.Backend.ldap2,
self.api.env.container_ca,
self.api.env.basedn)
else:
ca_nickname = None
server_certs = db.find_server_certs()
@@ -62,20 +46,12 @@ class update_upload_cacrt(Updater):
ldap = self.api.Backend.ldap2
for nickname, trust_flags in db.list_certs():
if trust_flags.has_key:
if 'u' in trust_flags:
continue
cert = db.get_cert_from_db(nickname)
subject = cert.subject
if ca_enabled and subject == ca_subject:
# When ca is enabled, we can have the IPA CA cert stored
# in the nss db with a different nickname (for instance
# when the server was installed with --subject to
# customize the CA cert subject), but it must always be
# stored in LDAP with the DN cn=$DOMAIN IPA CA
# This is why we check the subject instead of the nickname here
nickname = ca_nickname
trust_flags = certdb.IPA_CA_TRUST_FLAGS
trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
if nickname == ca_nickname and ca_enabled:
trust_flags = 'CT,C,C'
cert = db.get_cert_from_db(nickname, pem=False)
trust, ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
('cn','etc'), self.api.env.basedn)
@@ -84,8 +60,8 @@ class update_upload_cacrt(Updater):
try:
certstore.init_ca_entry(entry, cert, nickname, trust, eku)
except Exception as e:
logger.warning("Failed to create entry for %s: %s",
nickname, e)
self.log.warning("Failed to create entry for %s: %s",
nickname, e)
continue
if nickname == ca_nickname:
ca_cert = cert
@@ -97,11 +73,7 @@ class update_upload_cacrt(Updater):
try:
ldap.add_entry(entry)
except errors.DuplicateEntry:
if nickname == ca_nickname and ca_enabled:
try:
ldap.update_entry(entry)
except errors.EmptyModlist:
pass
pass
if ca_cert:
dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
@@ -115,19 +87,10 @@ class update_upload_cacrt(Updater):
entry.single_value['cACertificate;binary'] = ca_cert
ldap.add_entry(entry)
else:
force_write = False
try:
_cert_bin = entry['cACertificate;binary']
except ValueError:
# BZ 1644874
# sometimes the cert is badly stored, twice encoded
# force write to fix the value
logger.debug('Fixing the value of cACertificate;binary '
'in entry %s', entry.dn)
force_write = True
if force_write or b'' in entry['cACertificate;binary']:
if b'' in entry['cACertificate;binary']:
entry.single_value['cACertificate;binary'] = ca_cert
ldap.update_entry(entry)
return False, []
api.register(update_upload_cacrt)