diff options
Diffstat (limited to 'ipaserver/install/plugins')
-rw-r--r-- | ipaserver/install/plugins/adtrust.py | 16 | ||||
-rw-r--r-- | ipaserver/install/plugins/dns.py | 41 | ||||
-rw-r--r-- | ipaserver/install/plugins/fix_replica_memberof.py | 4 | ||||
-rw-r--r-- | ipaserver/install/plugins/rename_managed.py | 159 | ||||
-rw-r--r-- | ipaserver/install/plugins/updateclient.py | 23 |
5 files changed, 130 insertions, 113 deletions
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py index c32d82e3a..555a28b8f 100644 --- a/ipaserver/install/plugins/adtrust.py +++ b/ipaserver/install/plugins/adtrust.py @@ -20,7 +20,7 @@ from ipaserver.install.plugins import MIDDLE from ipaserver.install.plugins.baseupdate import PostUpdate from ipalib import api, errors -from ipalib.dn import DN +from ipapython.dn import DN from ipapython.ipa_log_manager import * DEFAULT_ID_RANGE_SIZE = 200000 @@ -34,7 +34,7 @@ class update_default_range(PostUpdate): def execute(self, **options): ldap = self.obj.backend - dn = str(DN(api.env.container_ranges, api.env.basedn)) + dn = DN(api.env.container_ranges, api.env.basedn) search_filter = "objectclass=ipaDomainIDRange" try: (entries, truncated) = ldap.find_entries(search_filter, [], dn) @@ -44,7 +44,7 @@ class update_default_range(PostUpdate): root_logger.debug("default_range: ipaDomainIDRange entry found, skip plugin") return (False, False, []) - dn = str(DN(('cn', 'admins'), api.env.container_group, api.env.basedn)) + dn = DN(('cn', 'admins'), api.env.container_group, api.env.basedn) try: (dn, admins_entry) = ldap.get_entry(dn, ['gidnumber']) except errors.NotFound: @@ -65,12 +65,10 @@ class update_default_range(PostUpdate): ] updates = {} - dn = str(DN(('cn', '%s_id_range' % api.env.realm), - api.env.container_ranges, api.env.basedn)) + dn = DN(('cn', '%s_id_range' % api.env.realm), + api.env.container_ranges, api.env.basedn) - # make sure everything is str or otherwise python-ldap would complain - range_entry = map(str, range_entry) - updates[dn] = {'dn' : dn, 'default' : range_entry} + updates[dn] = {'dn': dn, 'default': range_entry} # Default range entry has a hard-coded range size to 200000 which is # a default range size in ipa-server-install. This could cause issues @@ -78,7 +76,7 @@ class update_default_range(PostUpdate): # bigger range (option --idmax). # We should make our best to check if this is the case and provide # user with an information how to fix it. - dn = str(DN(api.env.container_dna_posix_ids, api.env.basedn)) + dn = DN(api.env.container_dna_posix_ids, api.env.basedn) search_filter = "objectclass=dnaSharedConfig" attrs = ['dnaHostname', 'dnaRemainingValues'] try: diff --git a/ipaserver/install/plugins/dns.py b/ipaserver/install/plugins/dns.py index e11c331a4..d55596704 100644 --- a/ipaserver/install/plugins/dns.py +++ b/ipaserver/install/plugins/dns.py @@ -21,7 +21,7 @@ from ipaserver.install.plugins import MIDDLE from ipaserver.install.plugins.baseupdate import PostUpdate from ipaserver.install.plugins import baseupdate from ipalib import api, errors, util -from ipalib.dn import DN +from ipapython.dn import DN from ipalib.plugins.dns import dns_container_exists from ipapython.ipa_log_manager import * @@ -89,31 +89,29 @@ class update_dns_permissions(PostUpdate): entries otherwise. """ - _write_dns_perm_dn = DN('cn=Write DNS Configuration', - api.env.container_permission, - api.env.basedn) + _write_dns_perm_dn = DN(('cn', 'Write DNS Configuration'), + api.env.container_permission, api.env.basedn) _write_dns_perm_entry = ['objectClass:groupofnames', 'objectClass:top', 'cn:Write DNS Configuration', 'description:Write DNS Configuration', - 'member:cn=DNS Administrators,cn=privileges,cn=pbac,%s' \ - % api.env.basedn, - 'member:cn=DNS Servers,cn=privileges,cn=pbac,%s' \ - % api.env.basedn] - - _read_dns_perm_dn = DN('cn=Read DNS Entries', - api.env.container_permission, - api.env.basedn) + 'member:%s' % DN(('cn', 'DNS Administrators'), ('cn', 'privileges'), ('cn', 'pbac'), + api.env.basedn), + 'member:%s' % DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), + api.env.basedn)] + + _read_dns_perm_dn = DN(('cn', 'Read DNS Entries'), + api.env.container_permission, api.env.basedn) _read_dns_perm_entry = ['objectClass:top', 'objectClass:groupofnames', 'objectClass:ipapermission', 'cn:Read DNS Entries', 'description:Read DNS entries', 'ipapermissiontype:SYSTEM', - 'member:cn=DNS Administrators,cn=privileges,cn=pbac,%s' \ - % api.env.basedn, - 'member:cn=DNS Servers,cn=privileges,cn=pbac,%s' \ - % api.env.basedn,] + 'member:%s' % DN(('cn', 'DNS Administrators'), ('cn', 'privileges'), ('cn', 'pbac'), + api.env.basedn), + 'member:%s' % DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), + api.env.basedn),] _write_dns_aci_dn = DN(api.env.basedn) _write_dns_aci_entry = ['add:aci:\'(targetattr = "idnsforwardpolicy || idnsforwarders || idnsallowsyncptr || idnszonerefresh || idnspersistentsearch")(target = "ldap:///cn=dns,%(realm)s")(version 3.0;acl "permission:Write DNS Configuration";allow (write) groupdn = "ldap:///cn=Write DNS Configuration,cn=permissions,cn=pbac,%(realm)s";)\'' % dict(realm=api.env.basedn)] @@ -135,10 +133,7 @@ class update_dns_permissions(PostUpdate): (self._write_dns_aci_dn, 'updates', self._write_dns_aci_entry), (self._read_dns_aci_dn, 'updates', self._read_dns_aci_entry)): - dn = str(dn) - # make sure everything is str or otherwise python-ldap would complain - entry = map(str, entry) - dnsupdates[dn] = {'dn' : dn, container : entry} + dnsupdates[dn] = {'dn': dn, container: entry} return (False, True, [dnsupdates]) @@ -161,9 +156,9 @@ class update_dns_limits(PostUpdate): return (False, False, []) dns_principal = 'DNS/%s@%s' % (self.env.host, self.env.realm) - dns_service_dn = str(DN(('krbprincipalname', dns_principal), - self.env.container_service, - self.env.basedn)) + dns_service_dn = DN(('krbprincipalname', dns_principal), + self.env.container_service, + self.env.basedn) try: (dn, entry) = ldap.get_entry(dns_service_dn, self.limit_attributes) diff --git a/ipaserver/install/plugins/fix_replica_memberof.py b/ipaserver/install/plugins/fix_replica_memberof.py index 23bde0c9f..d4ab75348 100644 --- a/ipaserver/install/plugins/fix_replica_memberof.py +++ b/ipaserver/install/plugins/fix_replica_memberof.py @@ -44,7 +44,7 @@ class update_replica_exclude_attribute_list(PreUpdate): entries = repl.find_replication_agreements() self.log.debug("Found %d agreement(s)", len(entries)) for replica in entries: - self.log.debug(replica.description) + self.log.debug(replica.getValue('description')) attrlist = replica.getValue('nsDS5ReplicatedAttributeList') if attrlist is None: self.log.debug("Adding nsDS5ReplicatedAttributeList and nsDS5ReplicatedAttributeListTotal") @@ -68,7 +68,7 @@ class update_replica_exclude_attribute_list(PreUpdate): self.log.debug("Attribute list needs updating") current = replica.toDict() replica.setValue('nsDS5ReplicatedAttributeList', - replica.nsDS5ReplicatedAttributeList + ' %s' % ' '.join(missing)) + replica.getValue('nsDS5ReplicatedAttributeList') + ' %s' % ' '.join(missing)) try: repl.conn.updateEntry(replica.dn, current, replica.toDict()) self.log.debug("Updated") diff --git a/ipaserver/install/plugins/rename_managed.py b/ipaserver/install/plugins/rename_managed.py index a9eed0be3..99dac8148 100644 --- a/ipaserver/install/plugins/rename_managed.py +++ b/ipaserver/install/plugins/rename_managed.py @@ -24,6 +24,7 @@ from ipalib.frontend import Updater from ipaserver.install.plugins import baseupdate from ipalib import api, errors from ipapython import ipautil +from ipapython.dn import DN, EditableDN import ldap as _ldap def entry_to_update(entry): @@ -44,67 +45,99 @@ def entry_to_update(entry): return update -def generate_update(ldap, deletes=False): - """ - We need to separate the deletes that need to happen from the - new entries that need to be added. - """ - suffix = ipautil.realm_to_suffix(api.env.realm) - searchfilter = '(objectclass=*)' - definitions_managed_entries = [] - old_template_container = 'cn=etc,%s' % suffix - old_definition_container = 'cn=managed entries,cn=plugins,cn=config' - new = 'cn=Managed Entries,cn=etc,%s' % suffix - sub = ['cn=Definitions,', 'cn=Templates,'] - new_managed_entries = [] - old_templates = [] - template = None - restart = False - - # If the old entries don't exist the server has already been updated. - try: - (definitions_managed_entries, truncated) = ldap.find_entries( - searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False - ) - except errors.NotFound, e: - return (False, new_managed_entries) - - for entry in definitions_managed_entries: - new_definition = {} - definition_managed_entry_updates = {} - if deletes: - old_definition = {'dn': str(entry[0]), 'deleteentry': ['dn: %s' % str(entry[0])]} - old_template = str(entry[1]['managedtemplate'][0]) - definition_managed_entry_updates[old_definition['dn']] = old_definition - old_templates.append(old_template) - else: - entry[1]['managedtemplate'] = str(entry[1]['managedtemplate'][0].replace(old_template_container, sub[1] + new)) - new_definition['dn'] = str(entry[0].replace(old_definition_container, sub[0] + new)) - new_definition['default'] = entry_to_update(entry[1]) - definition_managed_entry_updates[new_definition['dn']] = new_definition - new_managed_entries.append(definition_managed_entry_updates) - for old_template in old_templates: # Only happens when deletes is True - try: - (dn, template) = ldap.get_entry(old_template, ['*'], normalize=False) - dn = str(dn) - new_template = {} - template_managed_entry_updates = {} - old_template = {'dn': dn, 'deleteentry': ['dn: %s' % dn]} - new_template['dn'] = str(dn.replace(old_template_container, sub[1] + new)) - new_template['default'] = entry_to_update(template) - template_managed_entry_updates[new_template['dn']] = new_template - template_managed_entry_updates[old_template['dn']] = old_template - new_managed_entries.append(template_managed_entry_updates) - except errors.NotFound, e: - pass +class GenerateUpdateMixin(object): + def generate_update(self, deletes=False): + """ + We need to separate the deletes that need to happen from the + new entries that need to be added. + """ + ldap = self.obj.backend - if len(new_managed_entries) > 0: - restart = True - new_managed_entries.sort(reverse=True) + suffix = ipautil.realm_to_suffix(api.env.realm) + searchfilter = '(objectclass=*)' + definitions_managed_entries = [] - return (restart, new_managed_entries) + old_template_container = DN(('cn', 'etc'), suffix) + new_template_container = DN(('cn', 'Templates'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix) -class update_managed_post_first(PreUpdate): + 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( + searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False + ) + except errors.NotFound, e: + return (False, update_list) + + for entry in definitions_managed_entries: + assert isinstance(entry.dn, DN) + if deletes: + old_dn = entry.data['managedtemplate'][0] + assert isinstance(old_dn, DN) + try: + (old_dn, entry) = ldap.get_entry(old_dn, ['*'], normalize=False) + except errors.NotFound, e: + pass + else: + # Compute the new dn by replacing the old container with the new container + new_dn = EditableDN(old_dn) + if new_dn.replace(old_template_container, new_template_container) != 1: + self.error("unable to replace '%s' with '%s' in '%s'", + old_template_container, new_template_container, old_dn) + continue + + new_dn = DN(new_dn) + + # The old attributes become defaults for the new entry + new_update = {'dn': new_dn, + 'default': entry_to_update(entry)} + + # Delete the old entry + old_update = {'dn': old_dn, 'deleteentry': None} + + # Add the delete and replacement updates to the list of all updates + update_list.append({old_dn: old_update, new_dn: new_update}) + + else: + # Update the template dn by replacing the old containter with the new container + old_dn = entry.data['managedtemplate'][0] + new_dn = EditableDN(old_dn) + if new_dn.replace(old_template_container, new_template_container) != 1: + self.error("unable to replace '%s' with '%s' in '%s'", + old_template_container, new_template_container, old_dn) + continue + new_dn = DN(new_dn) + entry.data['managedtemplate'] = new_dn + + # Edit the dn, then convert it back to an immutable DN + old_dn = entry.dn + new_dn = EditableDN(old_dn) + if new_dn.replace(old_definition_container, new_definition_container) != 1: + self.error("unable to replace '%s' with '%s' in '%s'", + old_definition_container, new_definition_container, old_dn) + continue + new_dn = DN(new_dn) + + # The old attributes become defaults for the new entry + new_update = {'dn': new_dn, + 'default': entry_to_update(entry.data)} + + # Add the replacement update to the collection of all updates + update_list.append({new_dn: new_update}) + + if len(update_list) > 0: + restart = True + update_list.sort(reverse=True) + + return (restart, update_list) + +class update_managed_post_first(PreUpdate, GenerateUpdateMixin): """ Update managed entries """ @@ -112,21 +145,21 @@ class update_managed_post_first(PreUpdate): def execute(self, **options): # Never need to restart with the pre-update changes - (ignore, new_managed_entries) = generate_update(self.obj.backend, False) + (ignore, update_list) = self.generate_update(False) - return (False, True, new_managed_entries) + return (False, True, update_list) api.register(update_managed_post_first) -class update_managed_post(PostUpdate): +class update_managed_post(PostUpdate, GenerateUpdateMixin): """ Update managed entries """ order=LAST def execute(self, **options): - (restart, new_managed_entries) = generate_update(self.obj.backend, True) + (restart, update_list) = self.generate_update(True) - return (restart, True, new_managed_entries) + return (restart, True, update_list) api.register(update_managed_post) diff --git a/ipaserver/install/plugins/updateclient.py b/ipaserver/install/plugins/updateclient.py index e23769471..dca2c75dd 100644 --- a/ipaserver/install/plugins/updateclient.py +++ b/ipaserver/install/plugins/updateclient.py @@ -25,6 +25,7 @@ from ipaserver.install.ldapupdate import LDAPUpdate from ipapython.ipautil import wait_for_open_socket from ipalib import api from ipalib import backend +from ipapython.dn import DN import ldap as _ldap class updateclient(backend.Executioner): @@ -44,7 +45,7 @@ class updateclient(backend.Executioner): updates is a dictionary keyed on dn. The value of an update is a dictionary with the following possible values: - - dn: str, duplicate of the key + - dn: DN, equal to the dn attribute - updates: list of updates against the dn - default: list of the default entry to be added if it doesn't exist @@ -103,7 +104,7 @@ class updateclient(backend.Executioner): autobind = False else: autobind = True - self.Backend.ldap2.connect(bind_dn='cn=Directory Manager', bind_pw=dm_password, autobind=autobind) + self.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password, autobind=autobind) def order(self, updatetype): """Return plugins of the given updatetype in sorted order. @@ -125,22 +126,12 @@ class updateclient(backend.Executioner): (restart, apply_now, res) = self.run(update.name, **kw) if restart: self.restart(dm_password, live_run) - dn_list = {} - for upd in res: - for dn in upd: - dn_explode = _ldap.explode_dn(dn.lower()) - l = len(dn_explode) - if dn_list.get(l): - if dn not in dn_list[l]: - dn_list[l].append(dn) - else: - dn_list[l] = [dn] - updates = {} - for entry in res: - updates.update(entry) if apply_now: - ld.update_from_dict(dn_list, updates) + updates = {} + for entry in res: + updates.update(entry) + ld.update_from_dict(updates) elif res: result.extend(res) |