diff options
| author | Stanislav Laznicka <slaznick@redhat.com> | 2016-10-18 10:16:29 +0200 |
|---|---|---|
| committer | Jan Cholasta <jcholast@redhat.com> | 2016-11-11 12:13:56 +0100 |
| commit | 7279ef1d0f28dae9f3203362ca9e2245e56e111f (patch) | |
| tree | 7a8fa7a7678d6443c5e9c3d9f92cfe45b68b6cca /ipaserver/install/plugins | |
| parent | 83e72d704630b9cc5a1f713dfee30601950eb5e9 (diff) | |
| download | freeipa-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/install/plugins')
| -rw-r--r-- | ipaserver/install/plugins/update_dna_shared_config.py | 125 |
1 files changed, 125 insertions, 0 deletions
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, () |
