Changeset 1259 for dassldapsync


Ignore:
Timestamp:
May 3, 2022, 7:53:07 PM (3 years ago)
Author:
joergs
Message:

adapted to SLES 15 and Python 3. Encoding problems with Python 2

Fixing sisabling deleting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • dassldapsync/dassldapsync.py

    r1257 r1259  
    44# core modules
    55import argparse
    6 import ConfigParser
     6from   configparser import ConfigParser
    77import logging
    88from   pprint import pprint
     
    2020import ldap.modlist
    2121from   ldap.syncrepl import SyncreplConsumer
    22 import ldapurl
     22from   ldapurl import LDAPUrl
    2323import ldif
    2424
     
    4646        self.pwd_max_days = 0
    4747
    48 class ConfigParserDefaults(ConfigParser.ConfigParser, object):
    49     def get(self, section, option, default=None):
    50         try:
    51             result = super(self.__class__, self).get(section, option)
    52         except ConfigParser.NoOptionError:
    53             if default is None:
    54                 raise
    55             else:
    56                 result = default
    57         return result
    58 
    59     def get_section(self, section):
    60         if section in self._sections:
    61             return self._sections[section]
    62 
    63     def get0(self, section, option, default=None):
    64         try:
    65             result = super(self.__class__, self).get(section, option)
    66         except ConfigParser.NoOptionError:
    67             result = default
    68         return result
    69 
    70     def getboolean(self, section, option, default=None):
    71         try:
    72             result = super(self.__class__, self).getboolean(section, option)
    73         except ConfigParser.NoOptionError:
    74             if default is None:
    75                 raise
    76             else:
    77                 result = default
    78         return result
    79 
    80     def get_ldap_url_obj(self, section):
    81         baseurl = 'ldap://{server}:389/{basedn}'.format(**(self.get_section(section)))
    82         attrs = None
    83         if self.get0(section, 'attributes') is not None:
    84             attrs = self.get(section, 'attributes').split(',')
    85         return ldapurl.LDAPUrl(
    86             baseurl,
    87             dn=self.get(section, 'baseDn', ''),
    88             who=self.get0(section, 'bindDn'),
    89             cred=self.get0(section, 'basePassword'),
    90             filterstr=self.get0(section, 'filter'),
    91             attrs=attrs
    92         )
    93 
    94 
    9548def readLDIFSource(path):
    9649    logger = logging.getLogger()
     
    10558    logger = logging.getLogger()
    10659    logger.info("reading LDAP objects from server {}".format(server))
    107     con = ldap.open(server, port=389)
     60    ldapurl = LDAPUrl(hostport="{}:389".format(self.server))
     61    con = ldap.initialize(ldapurl. initializeUrl())
    10862    if starttls:
    10963        con.start_tls_s()
     
    13185        self.classmap = {}
    13286
    133         self.junk_attrs = ["authzto", "memberof", "modifiersname", "modifytimestamp", "entryuuid",
    134                            "entrycsn", "contextcsn", "creatorsname", "createtimestamp",
    135                            "structuralobjectclass", "pwdaccountlockedtime", "pwdchangedtime", "pwdfailuretime" ]
     87        #self.junk_objectclasses = [ b"sambaidmapentry" ]
     88        #"sambasid",
     89        self.junk_objectclasses = []
     90        self.junk_attrs = ["authzto",
     91                           "creatorsname", "createtimestamp", "contextcsn",
     92                           "entrycsn", "entryuuid",
     93                           "memberof", "modifiersname", "modifytimestamp",
     94                           "pwdaccountlockedtime", "pwdchangedtime", "pwdfailuretime",
     95                           "structuralobjectclass"]
    13696
    13797        self.reset_result()
     
    149109        if self.con is None:
    150110            self.logger.info("connect to destination LDAP server {}".format(self.destserver))
    151             self.con = ldap.open(self.destserver, port=389)
     111            ldapurl = LDAPUrl(hostport="{}:389".format(self.destserver))
     112            self.con = ldap.initialize(ldapurl. initializeUrl())
    152113            if self.options.starttls:
    153114                self.con.start_tls_s()
     
    267228        max_age = datetime.timedelta(days=self.options.pwd_max_days)
    268229
     230        objectClasses = srcAttributes['objectClass']
     231        srcAttributes['objectClass'] = [oc for oc in objectClasses if oc.lower() not in self.junk_objectclasses]
     232
    269233        try:
    270234            destDn, destAttributes = self._get_dest_entry(srcDn, srcAttributes)
     
    294258                    self.logger.exception('modify failed')
    295259                    self.notify_modified(srcDn, False)
     260            else:
     261                self.notify_unchanged(srcDn)
    296262
    297263        except ldap.NO_SUCH_OBJECT:
    298264            if not self.options.updateonly:
    299265                try:
    300                     self.con.add_s(srcDn, ldap.modlist.addModlist(srcAttributes, self.junk_attrs))
     266                    entry = ldap.modlist.addModlist(srcAttributes, self.junk_attrs)
     267                    self.con.add_s(srcDn, entry)
    301268                    self.notify_created(srcDn)
    302269                except (ldap.OBJECT_CLASS_VIOLATION,
    303270                        ldap.NO_SUCH_OBJECT,
    304                         ldap.CONSTRAINT_VIOLATION):
     271                        ldap.CONSTRAINT_VIOLATION) as e:
     272                    #print(e)
    305273                    self.notify_created(srcDn, False)
    306274
     
    366334            ok = len(result[action]['ok'])
    367335            failed = len(result[action]['failed'])
    368             print "{} (ok: {}, failed: {}):".format(action, ok, failed)
     336            print("{} (ok: {}, failed: {}):".format(action, ok, failed))
    369337
    370338            if show_ok and ok > 0:
    371                 print "succeeded:"
    372                 print "\n".join(result[action]['ok'])
     339                print("succeeded:")
     340                print("\n".join(result[action]['ok']))
    373341
    374342            if show_failed and failed > 0:
    375                 print "failed:"
    376                 print "\n".join(result[action]['failed'])
     343                print("failed:")
     344                print("\n".join(result[action]['failed']))
    377345
    378346    def get_short_dn(self, dn):
    379347        return dn.lower().replace(',' + self.srcbasedn.lower(), '')
    380348
     349    def notify_unchanged(self, dn):
     350        logger.debug(u'{} unchanged'.format(self.get_short_dn(dn)))
     351
    381352    def notify_created(self, dn, ok=True):
    382353        if ok:
    383             logger.debug('{} created'.format(self.get_short_dn(dn)))
     354            logger.debug(u'{} created'.format(self.get_short_dn(dn)))
    384355            self.result['add']['ok'].append(dn)
    385356        else:
    386             self.logger.warning("failed to add {}".format(dn))
     357            self.logger.warning(u"failed to add {}".format(dn))
    387358            self.result['add']['failed'].append(dn)
    388359
    389360    def notify_modified(self, dn, ok=True):
    390361        if ok:
    391             logger.debug('{} modified'.format(self.get_short_dn(dn)))
     362            logger.debug(u'{} modified'.format(self.get_short_dn(dn)))
    392363            self.result['update']['ok'].append(dn)
    393364        else:
    394             self.logger.error("failed to modify {}".format(dn))
     365            self.logger.error(u"failed to modify {}".format(dn))
    395366            self.result['update']['failed'].append(dn)
    396367
    397368    def notify_deleted(self, dn, ok=True):
    398369        if ok:
    399             logger.debug('{} deleted'.format(self.get_short_dn(dn)))
     370            logger.debug(u'{} deleted'.format(self.get_short_dn(dn)))
    400371            self.result['delete']['ok'].append(dn)
    401372        else:
    402             self.logger.error("failed to delete {}".format(dn))
     373            self.logger.error(u"failed to delete {}".format(dn))
    403374            self.result['delete']['failed'].append(dn)
    404375
    405376    def notify_renamed(self, dn, newdn, uid, newuid, options):
    406         print "renamed", dn, newdn
     377        print(u"renamed {} -> {}".format(dn, newdn))
    407378        subprocess.check_call(
    408379            "%s %s %s %s %s" % (options.renamecommand, dn, newdn, uid, newuid),
     
    519490                    self.source_ldap_connection.simple_bind_s(
    520491                        self.source_ldap_url_obj.who, self.source_ldap_url_obj.cred)
    521                 except ldap.INVALID_CREDENTIALS, e:
    522                     print 'Login to LDAP server failed: ', str(e)
     492                except ldap.INVALID_CREDENTIALS as e:
     493                    print('Login to LDAP server failed: ', str(e))
    523494                    sys.exit(1)
    524495                except ldap.SERVER_DOWN:
    525                     print 'LDAP server is down, going to retry.'
     496                    print('LDAP server is down, going to retry.')
    526497                    time.sleep(5)
    527498                    continue
     
    539510            try:
    540511                while self.source_ldap_connection.syncrepl_poll(all=1, msgid=ldap_search):
    541                     print ".",
     512                    print(".", end="")
    542513            except KeyboardInterrupt:
    543514                # User asked to exit
    544                 print "aborted\n"
     515                print("aborted\n")
    545516                self.shutdown(None, None)
    546             except Exception, e:
     517            except Exception as e:
    547518                # Handle any exception
    548519                if self.watcher_running:
     
    566537        self.watcher_running = False
    567538
     539def get_ldap_url_obj(self, configsection):
     540    baseurl = 'ldap://{server}:389/{basedn}'.format(server=configsection.get('server'), basedn=configsection.get('basedn'))
     541    attrs = None
     542    if configsection.get('attributes') is not None:
     543        attrs = configsection.get('attributes').split(',')
     544    return LDAPUrl(
     545        baseurl,
     546        dn=configsection.get('baseDn'),
     547        who=configsection.get('bindDn'),
     548        cred=configsection.get('basePassword'),
     549        filterstr=configsection.get('filter'),
     550        attrs=attrs
     551    )
     552
    568553
    569554if __name__ == "__main__":
     
    578563    exclude = None
    579564
    580     config = ConfigParserDefaults()
     565    config = ConfigParser()
    581566    config.read(conffile)
    582567
     
    588573
    589574    basedn = config.get("source", "baseDn")
    590     filterstr = config.get0("source", "filter", None)
     575    filterstr = config.get("source", "filter", fallback=None)
    591576
    592577    if srcfile is None:
     
    600585    destadminpw = config.get("destination", "bindPassword")
    601586    destbasedn = config.get("destination", "baseDn")
    602     destdelete = config.getboolean("destination", "delete")
    603587    try:
    604588        rdn = config.get("destination", "rdn")
     
    613597        pass
    614598
    615     options.updateonly = not config.getboolean("destination", "create", False)
    616     options.starttls = config.getboolean("destination", "starttls", False)
    617     options.renameattr = config.get0("destination", "detectRename", None)
    618     options.renamecommand = config.get0("destination", "detectRename", None)
    619     options.pwd_max_days = int(config.get("source", "pwd_max_days", 0))
     599    options.updateonly = not config.getboolean("destination", "create", fallback=False)
     600    options.delete = config.getboolean("destination", "delete", fallback=False)   
     601    options.starttls = config.getboolean("destination", "starttls", fallback=False)
     602    options.renameattr = config.get("destination", "detectRename", fallback=None)
     603    options.renamecommand = config.get("destination", "detectRename", fallback=None)
     604    options.pwd_max_days = int(config.get("source", "pwd_max_days", fallback=0))
    620605    options.filter = filterstr
    621606
     
    628613        options.attrlist = None
    629614
    630     if config.get0('source', 'mode') == 'syncrepl':
     615    if config.get('source', 'mode', fallback=None) == 'syncrepl':
    631616        ldapsync = LdapSyncRepl(
    632617            destsrv, destadmindn, destadminpw, basedn, destbasedn,
    633618            options,
    634             source_ldap_url_obj=config.get_ldap_url_obj('source'))
     619            source_ldap_url_obj=get_ldap_url_obj(config['source']))
    635620        ldapsync.sync()
    636621    else:
Note: See TracChangeset for help on using the changeset viewer.