summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorStanislav Laznicka <slaznick@redhat.com>2016-10-18 10:16:29 +0200
committerJan Cholasta <jcholast@redhat.com>2016-11-11 12:13:56 +0100
commit7279ef1d0f28dae9f3203362ca9e2245e56e111f (patch)
tree7a8fa7a7678d6443c5e9c3d9f92cfe45b68b6cca /ipaserver
parent83e72d704630b9cc5a1f713dfee30601950eb5e9 (diff)
downloadfreeipa-7279ef1d0f28dae9f3203362ca9e2245e56e111f.tar.gz
freeipa-7279ef1d0f28dae9f3203362ca9e2245e56e111f.tar.xz
freeipa-7279ef1d0f28dae9f3203362ca9e2245e56e111f.zip
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>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/dsinstance.py102
-rw-r--r--ipaserver/install/plugins/update_dna_shared_config.py125
-rw-r--r--ipaserver/install/server/install.py4
-rw-r--r--ipaserver/install/server/replicainstall.py8
-rw-r--r--ipaserver/install/server/upgrade.py1
5 files changed, 125 insertions, 115 deletions
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 49289d483..a7d1b6474 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -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)
- )
diff --git a/ipaserver/install/plugins/update_dna_shared_config.py b/ipaserver/install/plugins/update_dna_shared_config.py
new file mode 100644
index 000000000..21ed9c4a9
--- /dev/null
+++ b/ipaserver/install/plugins/update_dna_shared_config.py
@@ -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, ()
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 34d6793d1..b5826f3f9 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -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)
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index ba9b0f098..ca889fb4a 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -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)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index bea1276e5..5f6101589 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -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():