mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Moved update of DNA plugin among update plugins
To make the code more general, moved the update_dna_shared_config among other update plugins. Bugfix: DNA shared config connection protocol was compared to a method string which would result in a try to always update it even if there was no need to. https://fedorahosted.org/389/ticket/48373 causes that two shared DNA config entries are created instead of one. https://fedorahosted.org/freeipa/ticket/6392 Reviewed-By: Martin Babinsky <mbabinsk@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
committed by
Jan Cholasta
parent
83e72d7046
commit
7279ef1d0f
@@ -14,4 +14,11 @@ dnaFilter: (|(objectClass=posixAccount)(objectClass=posixGroup)(objectClass=ipaI
|
||||
dnaScope: $SUFFIX
|
||||
dnaThreshold: 500
|
||||
dnaSharedCfgDN: cn=posix-ids,cn=dna,cn=ipa,cn=etc,$SUFFIX
|
||||
dnaExcludeScope: cn=provisioning,$SUFFIX
|
||||
|
||||
# Enable the DNA plugin
|
||||
dn: cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
|
||||
changetype: modify
|
||||
replace: nsslapd-pluginEnabled
|
||||
nsslapd-pluginEnabled: on
|
||||
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
# Enable the DNA plugin
|
||||
dn: cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
|
||||
only:nsslapd-pluginEnabled: on
|
||||
|
||||
# Change the magic value to -1
|
||||
dn: cn=Posix IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
|
||||
only:dnaMagicRegen: -1
|
||||
add: dnaExcludeScope: cn=provisioning,$SUFFIX
|
||||
|
||||
# Config winsync plugin according to DNA
|
||||
dn: cn=ipa-winsync,cn=plugins,cn=config
|
||||
remove:ipaWinSyncUserAttr: uidNumber 999
|
||||
remove:ipaWinSyncUserAttr: gidNumber 999
|
||||
|
||||
@@ -28,3 +28,4 @@ plugin: update_idrange_baserid
|
||||
plugin: update_passync_privilege_update
|
||||
plugin: update_dnsserver_configuration_into_ldap
|
||||
plugin: update_ldap_server_list
|
||||
plugin: update_dna_shared_config
|
||||
|
||||
@@ -1282,105 +1282,3 @@ class DsInstance(service.Service):
|
||||
|
||||
# check for open secure port 636 from now on
|
||||
self.open_ports.append(636)
|
||||
|
||||
def update_dna_shared_config(self, method="SASL/GSSAPI", 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.admin_conn
|
||||
|
||||
# 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
|
||||
except errors.NotFound:
|
||||
root_logger.error("Could not find DNA plugin entry: %s" %
|
||||
dna_config_base)
|
||||
return
|
||||
|
||||
try:
|
||||
entry = conn.get_entry(dna_config_base)
|
||||
except errors.NotFound:
|
||||
root_logger.error("Could not find DNA config entry: %s" %
|
||||
dna_config_base)
|
||||
return
|
||||
|
||||
sharedcfgdn = entry.single_value.get("dnaSharedCfgDN")
|
||||
if sharedcfgdn is not None:
|
||||
sharedcfgdn = DN(sharedcfgdn)
|
||||
else:
|
||||
root_logger.error(
|
||||
"Could not find DNA shared config DN in entry: %s" %
|
||||
dna_config_base)
|
||||
return
|
||||
|
||||
#
|
||||
# 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
|
||||
for _i in range(0, max_wait + 1):
|
||||
try:
|
||||
entries = conn.get_entries(
|
||||
sharedcfgdn, scope=ldap.SCOPE_ONELEVEL,
|
||||
filter='dnaHostname=%s' % self.fqdn
|
||||
)
|
||||
break
|
||||
except errors.NotFound:
|
||||
root_logger.debug(
|
||||
"Unable to find DNA shared config entry for "
|
||||
"dnaHostname=%s (under %s) so far. Retry in 2 sec." %
|
||||
(self.fqdn, sharedcfgdn)
|
||||
)
|
||||
time.sleep(2)
|
||||
else:
|
||||
root_logger.error(
|
||||
"Could not get dnaHostname entries in {} seconds".format(
|
||||
max_wait * 2)
|
||||
)
|
||||
return
|
||||
|
||||
# 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:
|
||||
root_logger.debug(
|
||||
"%d entries dnaHostname=%s under %s. One expected" %
|
||||
(len(entries), self.fqdn, sharedcfgdn)
|
||||
)
|
||||
|
||||
# time to set the bind method and the protocol in the
|
||||
# shared config entries
|
||||
for entry in entries:
|
||||
mod = []
|
||||
if entry.single_value.get(dna_bind_method) != method:
|
||||
mod.append((ldap.MOD_REPLACE, dna_bind_method, method))
|
||||
|
||||
if entry.single_value.get(dna_conn_protocol) != method:
|
||||
mod.append((ldap.MOD_REPLACE, dna_conn_protocol, protocol))
|
||||
|
||||
if mod:
|
||||
try:
|
||||
conn.modify_s(entry.dn, mod)
|
||||
except Exception as e:
|
||||
root_logger.error(
|
||||
"Failed to set SASL/GSSAPI bind method/protocol "
|
||||
"in entry {}: {}".format(entry, e)
|
||||
)
|
||||
|
||||
125
ipaserver/install/plugins/update_dna_shared_config.py
Normal file
125
ipaserver/install/plugins/update_dna_shared_config.py
Normal file
@@ -0,0 +1,125 @@
|
||||
#
|
||||
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import time
|
||||
import ldap
|
||||
|
||||
from ipalib.plugable import Registry
|
||||
from ipalib import errors
|
||||
from ipalib import Updater
|
||||
from ipapython.dn import DN
|
||||
|
||||
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:
|
||||
self.log.error("Could not find DNA plugin entry: %s" %
|
||||
dna_config_base)
|
||||
return False, ()
|
||||
|
||||
try:
|
||||
entry = conn.get_entry(dna_config_base)
|
||||
except errors.NotFound:
|
||||
self.log.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:
|
||||
self.log.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:
|
||||
self.log.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:
|
||||
self.log.error(
|
||||
"Could not get dnaHostname entries in {} seconds".format(
|
||||
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:
|
||||
self.log.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:
|
||||
self.log.error(
|
||||
"Failed to set SASL/GSSAPI bind method/protocol "
|
||||
"in entry {}: {}".format(entry, e)
|
||||
)
|
||||
# no restart, no update
|
||||
return False, ()
|
||||
@@ -869,10 +869,6 @@ def install(installer):
|
||||
service.print_msg("Restarting the web server")
|
||||
http.restart()
|
||||
|
||||
# update DNA shared config entry is done as far as possible
|
||||
# from restart to avoid waiting for its creation
|
||||
ds.update_dna_shared_config()
|
||||
|
||||
# Set the admin user kerberos password
|
||||
ds.change_admin_password(admin_password)
|
||||
|
||||
|
||||
@@ -897,10 +897,6 @@ def install(installer):
|
||||
print("Configuration of client side components failed!")
|
||||
raise RuntimeError("Failed to configure the client")
|
||||
|
||||
# update DNA shared config entry is done as far as possible
|
||||
# from restart to avoid waiting for its creation
|
||||
ds.update_dna_shared_config()
|
||||
|
||||
# Everything installed properly, activate ipa service.
|
||||
services.knownservices.ipa.enable()
|
||||
|
||||
@@ -1527,10 +1523,6 @@ def promote(installer):
|
||||
config.dirman_password,
|
||||
kra_cert_bundle=ca_data)
|
||||
|
||||
# update DNA shared config entry is done as far as possible
|
||||
# from restart to avoid waiting for its creation
|
||||
ds.update_dna_shared_config()
|
||||
|
||||
custodia.import_dm_password(config.master_host_name)
|
||||
|
||||
promote_sssd(config.host_name)
|
||||
|
||||
@@ -1615,7 +1615,6 @@ def upgrade_configuration():
|
||||
ds.principal = "ldap/%s@%s" % (ds.fqdn, ds.realm)
|
||||
|
||||
ds_enable_sidgen_extdom_plugins(ds)
|
||||
ds.update_dna_shared_config()
|
||||
|
||||
# Now 389-ds is available, run the remaining http tasks
|
||||
if not http.is_kdcproxy_configured():
|
||||
|
||||
Reference in New Issue
Block a user