diff options
author | Rob Crittenden <rcritten@redhat.com> | 2009-01-29 16:26:07 -0500 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2009-02-03 15:27:14 -0500 |
commit | e30cd6ba42c256d2016db45146d616f329455e86 (patch) | |
tree | d4c5291095c80c92bc4803fe7f20fc2838124ffa /ipa-server/ipaserver/ldapupdate.py | |
parent | c4ed025001895bfc65c613cabbbfcb27c19cc29f (diff) | |
download | freeipa.git-e30cd6ba42c256d2016db45146d616f329455e86.tar.gz freeipa.git-e30cd6ba42c256d2016db45146d616f329455e86.tar.xz freeipa.git-e30cd6ba42c256d2016db45146d616f329455e86.zip |
Mass tree reorganization for IPAv2. To view previous history of files use:
% git log --follow -- <file>
renamed: ipa-server/autogen.sh -> autogen.sh
renamed: ipa-server/ipa-kpasswd/Makefile.am -> daemons/ipa-kpasswd/Makefile.am
renamed: ipa-server/ipa-kpasswd/README -> daemons/ipa-kpasswd/README
renamed: ipa-server/ipa-kpasswd/ipa_kpasswd.c -> daemons/ipa-kpasswd/ipa_kpasswd.c
renamed: ipa-server/ipa-kpasswd/ipa_kpasswd.init -> daemons/ipa-kpasswd/ipa_kpasswd.init
renamed: ipa-server/ipa-slapi-plugins/Makefile.am -> daemons/ipa-slapi-plugins/Makefile.am
renamed: ipa-server/ipa-slapi-plugins/README -> daemons/ipa-slapi-plugins/README
renamed: ipa-server/ipa-slapi-plugins/dna/Makefile.am -> daemons/ipa-slapi-plugins/dna/Makefile.am
renamed: ipa-server/ipa-slapi-plugins/dna/dna-conf.ldif -> daemons/ipa-slapi-plugins/dna/dna-conf.ldif
renamed: ipa-server/ipa-slapi-plugins/dna/dna.c -> daemons/ipa-slapi-plugins/dna/dna.c
renamed: ipa-server/ipa-slapi-plugins/ipa-memberof/Makefile.am -> daemons/ipa-slapi-plugins/ipa-memberof/Makefile.am
renamed: ipa-server/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c -> daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c
renamed: ipa-server/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h -> daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h
renamed: ipa-server/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c -> daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c
renamed: ipa-server/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif -> daemons/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif
renamed: ipa-server/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am -> daemons/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am
renamed: ipa-server/ipa-slapi-plugins/ipa-pwd-extop/README -> daemons/ipa-slapi-plugins/ipa-pwd-extop/README
renamed: ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c -> daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
renamed: ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif -> daemons/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/Makefile.am -> daemons/ipa-slapi-plugins/ipa-winsync/Makefile.am
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/README -> daemons/ipa-slapi-plugins/ipa-winsync/README
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif -> daemons/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-config.c -> daemons/ipa-slapi-plugins/ipa-winsync/ipa-winsync-config.c
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c -> daemons/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c
renamed: ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.h -> daemons/ipa-slapi-plugins/ipa-winsync/ipa-winsync.h
renamed: ipa-server/xmlrpc-server/ipa-rewrite.conf -> install/conf/ipa-rewrite.conf
renamed: ipa-server/xmlrpc-server/ipa.conf -> install/conf/ipa.conf
renamed: ipa-server/xmlrpc-server/ssbrowser.html -> install/html/ssbrowser.html
renamed: ipa-server/xmlrpc-server/unauthorized.html -> install/html/unauthorized.html
renamed: ipa-server/ipa-install/share/60ipaconfig.ldif -> install/share/60ipaconfig.ldif
renamed: ipa-server/ipa-install/share/60kerberos.ldif -> install/share/60kerberos.ldif
renamed: ipa-server/ipa-install/share/60radius.ldif -> install/share/60radius.ldif
renamed: ipa-server/ipa-install/share/60samba.ldif -> install/share/60samba.ldif
renamed: ipa-server/ipa-install/share/Makefile.am -> install/share/Makefile.am
renamed: ipa-server/ipa-install/share/bind.named.conf.template -> install/share/bind.named.conf.template
renamed: ipa-server/ipa-install/share/bind.zone.db.template -> install/share/bind.zone.db.template
renamed: ipa-server/ipa-install/share/bootstrap-template.ldif -> install/share/bootstrap-template.ldif
renamed: ipa-server/ipa-install/share/certmap.conf.template -> install/share/certmap.conf.template
renamed: ipa-server/ipa-install/share/default-aci.ldif -> install/share/default-aci.ldif
renamed: ipa-server/ipa-install/share/default-keytypes.ldif -> install/share/default-keytypes.ldif
renamed: ipa-server/ipa-install/share/dna-posix.ldif -> install/share/dna-posix.ldif
renamed: ipa-server/ipa-install/share/encrypted_attribute.ldif -> install/share/encrypted_attribute.ldif
renamed: ipa-server/ipa-install/share/fedora-ds.init.patch -> install/share/fedora-ds.init.patch
renamed: ipa-server/ipa-install/share/indices.ldif -> install/share/indices.ldif
renamed: ipa-server/ipa-install/share/kdc.conf.template -> install/share/kdc.conf.template
renamed: ipa-server/ipa-install/share/kerberos.ldif -> install/share/kerberos.ldif
renamed: ipa-server/ipa-install/share/krb.con.template -> install/share/krb.con.template
renamed: ipa-server/ipa-install/share/krb5.conf.template -> install/share/krb5.conf.template
renamed: ipa-server/ipa-install/share/krb5.ini.template -> install/share/krb5.ini.template
renamed: ipa-server/ipa-install/share/krbrealm.con.template -> install/share/krbrealm.con.template
renamed: ipa-server/ipa-install/share/master-entry.ldif -> install/share/master-entry.ldif
renamed: ipa-server/ipa-install/share/memberof-task.ldif -> install/share/memberof-task.ldif
renamed: ipa-server/ipa-install/share/ntp.conf.server.template -> install/share/ntp.conf.server.template
renamed: ipa-server/ipa-install/share/ntpd.sysconfig.template -> install/share/ntpd.sysconfig.template
renamed: ipa-server/ipa-install/share/preferences.html.template -> install/share/preferences.html.template
renamed: ipa-server/ipa-install/share/referint-conf.ldif -> install/share/referint-conf.ldif
renamed: ipa-server/ipa-install/share/schema_compat.uldif -> install/share/schema_compat.uldif
renamed: ipa-server/ipa-install/share/unique-attributes.ldif -> install/share/unique-attributes.ldif
renamed: ipa-server/ipa-install/Makefile.am -> install/tools/Makefile.am
renamed: ipa-server/ipa-install/README -> install/tools/README
renamed: ipa-server/ipa-compat-manage -> install/tools/ipa-compat-manage
renamed: ipa-server/ipa-fix-CVE-2008-3274 -> install/tools/ipa-fix-CVE-2008-3274
renamed: ipa-server/ipa-ldap-updater -> install/tools/ipa-ldap-updater
renamed: ipa-server/ipa-install/ipa-replica-install -> install/tools/ipa-replica-install
renamed: ipa-server/ipa-install/ipa-replica-manage -> install/tools/ipa-replica-manage
renamed: ipa-server/ipa-install/ipa-replica-prepare -> install/tools/ipa-replica-prepare
renamed: ipa-server/ipa-install/ipa-server-certinstall -> install/tools/ipa-server-certinstall
renamed: ipa-server/ipa-install/ipa-server-install -> install/tools/ipa-server-install
renamed: ipa-server/ipa-upgradeconfig -> install/tools/ipa-upgradeconfig
renamed: ipa-server/ipa-install/ipactl -> install/tools/ipactl
renamed: ipa-server/man/Makefile.am -> install/tools/man/Makefile.am
renamed: ipa-server/man/ipa-compat-manage.1 -> install/tools/man/ipa-compat-manage.1
renamed: ipa-server/man/ipa-ldap-updater.1 -> install/tools/man/ipa-ldap-updater.1
renamed: ipa-server/man/ipa-replica-install.1 -> install/tools/man/ipa-replica-install.1
renamed: ipa-server/man/ipa-replica-manage.1 -> install/tools/man/ipa-replica-manage.1
renamed: ipa-server/man/ipa-replica-prepare.1 -> install/tools/man/ipa-replica-prepare.1
renamed: ipa-server/man/ipa-server-certinstall.1 -> install/tools/man/ipa-server-certinstall.1
renamed: ipa-server/man/ipa-server-install.1 -> install/tools/man/ipa-server-install.1
renamed: ipa-server/man/ipa_kpasswd.8 -> install/tools/man/ipa_kpasswd.8
renamed: ipa-server/man/ipa_webgui.8 -> install/tools/man/ipa_webgui.8
renamed: ipa-server/man/ipactl.8 -> install/tools/man/ipactl.8
renamed: ipa-server/ipa-install/updates/Makefile.am -> install/updates/Makefile.am
renamed: ipa-server/ipa-install/updates/RFC2307bis.update -> install/updates/RFC2307bis.update
renamed: ipa-server/ipa-install/updates/RFC4876.update -> install/updates/RFC4876.update
renamed: ipa-server/ipa-install/updates/indices.update -> install/updates/indices.update
renamed: ipa-server/ipa-install/updates/nss_ldap.update -> install/updates/nss_ldap.update
renamed: ipa-server/ipa-install/updates/replication.update -> install/updates/replication.update
renamed: ipa-server/ipa-install/updates/winsync_index.update -> install/updates/winsync_index.update
renamed: ipa-server/ipaserver/Makefile.am -> ipaserver/install/Makefile.am
renamed: ipa-server/ipaserver/__init__.py -> ipaserver/install/__init__.py
renamed: ipa-server/ipaserver/bindinstance.py -> ipaserver/install/bindinstance.py
renamed: ipa-server/ipaserver/certs.py -> ipaserver/install/certs.py
renamed: ipa-server/ipaserver/dsinstance.py -> ipaserver/install/dsinstance.py
renamed: ipa-server/ipaserver/httpinstance.py -> ipaserver/install/httpinstance.py
renamed: ipa-server/ipaserver/installutils.py -> ipaserver/install/installutils.py
renamed: ipa-server/ipaserver/ipaldap.py -> ipaserver/install/ipaldap.py
renamed: ipa-server/ipaserver/krbinstance.py -> ipaserver/install/krbinstance.py
renamed: ipa-server/ipaserver/ldapupdate.py -> ipaserver/install/ldapupdate.py
renamed: ipa-server/ipaserver/ntpinstance.py -> ipaserver/install/ntpinstance.py
renamed: ipa-server/ipaserver/replication.py -> ipaserver/install/replication.py
renamed: ipa-server/ipaserver/service.py -> ipaserver/install/service.py
renamed: ipa-server/selinux/Makefile -> selinux/Makefile
renamed: ipa-server/selinux/ipa-server-selinux.spec.in -> selinux/ipa-server-selinux.spec.in
renamed: ipa-server/selinux/ipa_kpasswd/ipa_kpasswd.fc -> selinux/ipa_kpasswd/ipa_kpasswd.fc
renamed: ipa-server/selinux/ipa_kpasswd/ipa_kpasswd.te -> selinux/ipa_kpasswd/ipa_kpasswd.te
renamed: ipa-server/selinux/ipa_webgui/ipa_webgui.fc -> selinux/ipa_webgui/ipa_webgui.fc
renamed: ipa-server/selinux/ipa_webgui/ipa_webgui.te -> selinux/ipa_webgui/ipa_webgui.te
renamed: ipa-server/version.m4.in -> version.m4.in
Diffstat (limited to 'ipa-server/ipaserver/ldapupdate.py')
-rwxr-xr-x | ipa-server/ipaserver/ldapupdate.py | 593 |
1 files changed, 0 insertions, 593 deletions
diff --git a/ipa-server/ipaserver/ldapupdate.py b/ipa-server/ipaserver/ldapupdate.py deleted file mode 100755 index cdf23125..00000000 --- a/ipa-server/ipaserver/ldapupdate.py +++ /dev/null @@ -1,593 +0,0 @@ -# Authors: Rob Crittenden <rcritten@redhat.com> -# -# Copyright (C) 2008 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; version 2 only -# -# 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, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -# Documentation can be found at http://freeipa.org/page/LdapUpdate - -# TODO -# save undo files? - -UPDATES_DIR="/usr/share/ipa/updates/" - -import sys -from ipaserver import ipaldap, installutils -from ipa import entity, ipaerror, ipautil -import ldap -import logging -import krbV -import platform -import shlex -import time -import random -import os -import fnmatch - -class BadSyntax(Exception): - def __init__(self, value): - self.value = value - def __str__(self): - return repr(self.value) - -class LDAPUpdate: - def __init__(self, dm_password, sub_dict={}, live_run=True): - """dm_password = Directory Manager password - sub_dict = substitution dictionary - live_run = Apply the changes or just test - """ - self.sub_dict = sub_dict - self.live_run = live_run - self.dm_password = dm_password - self.conn = None - self.modified = False - - krbctx = krbV.default_context() - - fqdn = installutils.get_fqdn() - if fqdn is None: - raise RuntimeError("Unable to determine hostname") - - domain = ipautil.get_domain_name() - libarch = self.__identify_arch() - suffix = ipautil.realm_to_suffix(krbctx.default_realm) - - if not self.sub_dict.get("REALM"): - self.sub_dict["REALM"] = krbctx.default_realm - if not self.sub_dict.get("FQDN"): - self.sub_dict["FQDN"] = fqdn - if not self.sub_dict.get("DOMAIN"): - self.sub_dict["DOMAIN"] = domain - if not self.sub_dict.get("SUFFIX"): - self.sub_dict["SUFFIX"] = suffix - if not self.sub_dict.get("LIBARCH"): - self.sub_dict["LIBARCH"] = libarch - if not self.sub_dict.get("TIME"): - self.sub_dict["TIME"] = int(time.time()) - - # Try out the password - try: - conn = ipaldap.IPAdmin(fqdn) - conn.do_simple_bind(bindpw=self.dm_password) - conn.unbind() - except ldap.CONNECT_ERROR, e: - raise RuntimeError("Unable to connect to LDAP server %s" % fqdn) - except ldap.SERVER_DOWN, e: - raise RuntimeError("Unable to connect to LDAP server %s" % fqdn) - except ldap.INVALID_CREDENTIALS, e : - raise RuntimeError("The password provided is incorrect for LDAP server %s" % fqdn) - - def __detail_error(self, detail): - """IPA returns two errors back. One a generic one indicating the broad - problem and a detailed message back as well which should have come - from LDAP. This function will parse that into a human-readable - string. - """ - msg = "" - desc = detail[0].get('desc') - info = detail[0].get('info') - - if desc: - msg = desc - if info: - msg = msg + " " + info - - return msg - - def __identify_arch(self): - """On multi-arch systems some libraries may be in /lib64, /usr/lib64, - etc. Determine if a suffix is needed based on the current - architecture. - """ - bits = platform.architecture()[0] - - if bits == "64bit": - return "64" - else: - return "" - - def __template_str(self, s): - try: - return ipautil.template_str(s, self.sub_dict) - except KeyError, e: - raise BadSyntax("Unknown template keyword %s" % e) - - def __remove_quotes(self, line): - """Remove leading and trailng double or single quotes""" - if line.startswith('"'): - line = line[1:] - if line.endswith('"'): - line = line[:-1] - if line.startswith("'"): - line = line[1:] - if line.endswith("'"): - line = line[:-1] - - return line - - def __parse_values(self, line): - """Parse a comma-separated string into separate values and convert them - into a list. This should handle quoted-strings with embedded commas - """ - lexer = shlex.shlex(line) - lexer.wordchars = lexer.wordchars + ".()-" - l = [] - v = "" - for token in lexer: - if token != ',': - if v: - v = v + " " + token - else: - v = token - else: - l.append(self.__remove_quotes(v)) - v = "" - - l.append(self.__remove_quotes(v)) - - return l - - def read_file(self, filename): - if filename == '-': - fd = sys.stdin - else: - fd = open(filename) - text = fd.readlines() - if fd != sys.stdin: fd.close() - return text - - def __entry_to_entity(self, ent): - """Tne Entry class is a bare LDAP entry. The Entity class has a lot more - helper functions that we need, so convert to dict and then to Entity. - """ - entry = dict(ent.data) - entry['dn'] = ent.dn - for key,value in entry.iteritems(): - if isinstance(value,list) or isinstance(value,tuple): - if len(value) == 0: - entry[key] = '' - elif len(value) == 1: - entry[key] = value[0] - return entity.Entity(entry) - - def __combine_updates(self, dn_list, all_updates, update): - """Combine a new update with the list of total updates - - Updates are stored in 2 lists: - dn_list: contains a unique list of DNs in the updates - all_updates: the actual updates that need to be applied - - We want to apply the updates from the shortest to the longest - path so if new child and parent entries are in different updates - we can be sure the parent gets written first. This also lets - us apply any schema first since it is in the very short cn=schema. - """ - dn = update.get('dn') - dns = ldap.explode_dn(dn.lower()) - l = len(dns) - if dn_list.get(l): - if dn not in dn_list[l]: - dn_list[l].append(dn) - else: - dn_list[l] = [dn] - if not all_updates.get(dn): - all_updates[dn] = update - return all_updates - - e = all_updates[dn] - e['updates'] = e['updates'] + update['updates'] - - all_updates[dn] = e - - return all_updates - - def parse_update_file(self, data, all_updates, dn_list): - """Parse the update file into a dictonary of lists and apply the update - for each DN in the file.""" - valid_keywords = ["default", "add", "remove", "only"] - update = {} - d = "" - index = "" - dn = None - lcount = 0 - for line in data: - # Strip out \n and extra white space - lcount = lcount + 1 - - # skip comments and empty lines - line = line.rstrip() - if line.startswith('#') or line == '': continue - - if line.lower().startswith('dn:'): - if dn is not None: - all_updates = self.__combine_updates(dn_list, all_updates, update) - - update = {} - dn = line[3:].strip() - update['dn'] = self.__template_str(dn) - else: - if dn is None: - raise BadSyntax, "dn is not defined in the update" - - if line.startswith(' '): - v = d[len(d) - 1] - v = v + " " + line.strip() - d[len(d) - 1] = v - update[index] = d - continue - line = line.strip() - values = line.split(':', 2) - if len(values) != 3: - raise BadSyntax, "Bad formatting on line %d: %s" % (lcount,line) - - index = values[0].strip().lower() - - if index not in valid_keywords: - raise BadSyntax, "Unknown keyword %s" % index - - attr = values[1].strip() - value = values[2].strip() - value = self.__template_str(value) - - new_value = "" - if index == "default": - new_value = attr + ":" + value - else: - new_value = index + ":" + attr + ":" + value - index = "updates" - - d = update.get(index, []) - - d.append(new_value) - - update[index] = d - - if dn is not None: - all_updates = self.__combine_updates(dn_list, all_updates, update) - - return (all_updates, dn_list) - - def create_index_task(self, attribute): - """Create a task to update an index for an attribute""" - - r = random.SystemRandom() - - # Refresh the time to make uniqueness more probable. Add on some - # randomness for good measure. - self.sub_dict['TIME'] = int(time.time()) + r.randint(0,10000) - - cn = self.__template_str("indextask_$TIME") - dn = "cn=%s, cn=index, cn=tasks, cn=config" % cn - - e = ipaldap.Entry(dn) - - e.setValues('objectClass', ['top', 'extensibleObject']) - e.setValue('cn', cn) - e.setValue('nsInstance', 'userRoot') - e.setValues('nsIndexAttribute', attribute) - - logging.info("Creating task to index attribute: %s", attribute) - logging.debug("Task id: %s", dn) - - if self.live_run: - self.conn.addEntry(e.dn, e.toTupleList()) - - return dn - - def monitor_index_task(self, dn): - """Give a task DN monitor it and wait until it has completed (or failed) - """ - - if not self.live_run: - # If not doing this live there is nothing to monitor - return - - # Pause for a moment to give the task time to be created - time.sleep(1) - - attrlist = ['nstaskstatus', 'nstaskexitcode'] - entry = None - - while True: - try: - entry = self.conn.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)", attrlist) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - logging.error("Task not found: %s", dn) - return - except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e: - logging.error("Task lookup failure %s: %s", e, self.__detail_error(e.detail)) - return - - status = entry.getValue('nstaskstatus') - if status is None: - # task doesn't have a status yet - time.sleep(1) - continue - - if status.lower().find("finished") > -1: - logging.info("Indexing finished") - break - - logging.debug("Indexing in progress") - time.sleep(1) - - return - - def __create_default_entry(self, dn, default): - """Create the default entry from the values provided. - - The return type is entity.Entity - """ - entry = ipaldap.Entry(dn) - - if not default: - # This means that the entire entry needs to be created with add - return self.__entry_to_entity(entry) - - for line in default: - # We already do syntax-parsing so this is safe - (k, v) = line.split(':',1) - e = entry.getValues(k) - if e: - # multi-valued attribute - e = list(e) - e.append(v) - else: - e = v - entry.setValues(k, e) - - return self.__entry_to_entity(entry) - - def __get_entry(self, dn): - """Retrieve an object from LDAP. - - The return type is ipaldap.Entry - """ - searchfilter="objectclass=*" - sattrs = ["*"] - scope = ldap.SCOPE_BASE - - return self.conn.getList(dn, scope, searchfilter, sattrs) - - def __apply_updates(self, updates, entry): - """updates is a list of changes to apply - entry is the thing to apply them to - - returns the modified entry - """ - if not updates: - return entry - - only = {} - for u in updates: - # We already do syntax-parsing so this is safe - (utype, k, values) = u.split(':',2) - - values = self.__parse_values(values) - - e = entry.getValues(k) - if not isinstance(e, list): - if e is None: - e = [] - else: - e = [e] - - for v in values: - if utype == 'remove': - logging.debug("remove: '%s' from %s, current value %s", v, k, e) - try: - e.remove(v) - except ValueError: - logging.warn("remove: '%s' not in %s", v, k) - pass - entry.setValues(k, e) - logging.debug('remove: updated value %s', e) - elif utype == 'add': - logging.debug("add: '%s' to %s, current value %s", v, k, e) - # Remove it, ignoring errors so we can blindly add it later - try: - e.remove(v) - except ValueError: - pass - e.append(v) - logging.debug('add: updated value %s', e) - entry.setValues(k, e) - elif utype == 'only': - logging.debug("only: set %s to '%s', current value %s", k, v, e) - if only.get(k): - e.append(v) - else: - e = [v] - only[k] = True - entry.setValues(k, e) - logging.debug('only: updated value %s', e) - - self.print_entity(entry) - - return entry - - def print_entity(self, e, message=None): - """The entity object currently lacks a str() method""" - logging.debug("---------------------------------------------") - if message: - logging.debug("%s", message) - logging.debug("dn: " + e.dn) - attr = e.attrList() - for a in attr: - value = e.getValues(a) - if isinstance(value,str): - logging.debug(a + ": " + value) - else: - logging.debug(a + ": ") - for l in value: - logging.debug("\t" + l) - def is_schema_updated(self, s): - """Compare the schema in 's' with the current schema in the DS to - see if anything has changed. This should account for syntax - differences (like added parens that make no difference but are - detected as a change by generateModList()). - - This doesn't handle re-ordering of attributes. They are still - detected as changes, so foo $ bar != bar $ foo. - - return True if the schema has changed - return False if it has not - """ - s = ldap.schema.SubSchema(s) - s = s.ldap_entry() - - # Get a fresh copy and convert into a SubSchema - n = self.__get_entry("cn=schema")[0] - n = dict(n.data) - n = ldap.schema.SubSchema(n) - n = n.ldap_entry() - - if s == n: - return False - else: - return True - - def __update_record(self, update): - found = False - - new_entry = self.__create_default_entry(update.get('dn'), - update.get('default')) - - try: - e = self.__get_entry(new_entry.dn) - if len(e) > 1: - # we should only ever get back one entry - raise BadSyntax, "More than 1 entry returned on a dn search!? %s" % new_entry.dn - entry = self.__entry_to_entity(e[0]) - found = True - logging.info("Updating existing entry: %s", entry.dn) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - # Doesn't exist, start with the default entry - entry = new_entry - logging.info("New entry: %s", entry.dn) - except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR): - # Doesn't exist, start with the default entry - entry = new_entry - logging.info("New entry, using default value: %s", entry.dn) - - self.print_entity(entry) - - # Bring this entry up to date - entry = self.__apply_updates(update.get('updates'), entry) - - self.print_entity(entry, "Final value") - - if not found: - # New entries get their orig_data set to the entry itself. We want to - # empty that so that everything appears new when generating the - # modlist - # entry.orig_data = {} - try: - if self.live_run: - self.conn.addEntry(entry.dn, entry.toTupleList()) - except Exception, e: - logging.error("Add failure %s: %s", e, self.__detail_error(e.detail)) - else: - # Update LDAP - try: - updated = False - changes = self.conn.generateModList(entry.origDataDict(), entry.toDict()) - if (entry.dn == "cn=schema"): - updated = self.is_schema_updated(entry.toDict()) - else: - if len(changes) > 1: - updated = True - logging.debug("%s" % changes) - if self.live_run and updated: - self.conn.updateEntry(entry.dn, entry.origDataDict(), entry.toDict()) - logging.info("Done") - except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST), e: - logging.info("Entry already up-to-date") - updated = False - except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e: - logging.error("Update failed: %s: %s", e, self.__detail_error(e.detail)) - updated = False - - if ("cn=index" in entry.dn and - "cn=userRoot" in entry.dn): - taskid = self.create_index_task(entry.cn) - self.monitor_index_task(taskid) - - if updated: - self.modified = True - return - - def get_all_files(self, root, recursive=False): - """Get all update files""" - f = [] - for path, subdirs, files in os.walk(root): - for name in files: - if fnmatch.fnmatch(name, "*.update"): - f.append(os.path.join(path, name)) - if not recursive: - break - return f - - def update(self, files): - """Execute the update. files is a list of the update files to use. - - returns True if anything was changed, otherwise False - """ - - try: - self.conn = ipaldap.IPAdmin(self.sub_dict['FQDN']) - self.conn.do_simple_bind(bindpw=self.dm_password) - all_updates = {} - dn_list = {} - for f in files: - try: - logging.info("Parsing file %s" % f) - data = self.read_file(f) - except Exception, e: - print e - sys.exit(1) - - (all_updates, dn_list) = self.parse_update_file(data, all_updates, dn_list) - - sortedkeys = dn_list.keys() - sortedkeys.sort() - for k in sortedkeys: - for dn in dn_list[k]: - self.__update_record(all_updates[dn]) - finally: - if self.conn: self.conn.unbind() - - return self.modified |