#!/usr/bin/python """ Tool to force update memberOf attributes of users on OpenLDAP directory using memberOf overlay """ import getpass import logging from mylib.ldap import LdapClient from mylib.ldap import LdapServer from mylib.pbar import Pbar from mylib.scripts.helpers import get_opts_parser from mylib.scripts.helpers import init_logging default_host = 'ldapi:///' default_filter = '(objectClass=posixGroup)' default_attr = 'uniqueMember' parser = get_opts_parser( desc="Update memberOf attributes", just_try=True, progress=True) # options ldap_opts = parser.add_argument_group('LDAP options') ldap_opts.add_argument( '-H', '--host', action="store", type=str, dest="host", help="LDAP server URI (default: %s)" % default_host, default=default_host ) ldap_opts.add_argument( '-D', '--dn', action="store", type=str, dest="dn", help="LDAP bind DN", default=None ) ldap_opts.add_argument( '-P', '--password', action="store", type=str, dest="pwd", help="LDAP bind password", default=None ) ldap_opts.add_argument( '-f', '--filter', action="store", type=str, dest="filter", help="LDAP groups filter (default: %s)" % default_filter, default=default_filter ) ldap_opts.add_argument( '-b', '--base', action="store", type=str, dest="base", help="LDAP group base DN", default=None ) ldap_opts.add_argument( '--v2', action="store_true", dest="ldapv2", help="Utiliser le protocole LDAP v2.", default=None ) ldap_opts.add_argument( '-a', '--attr', action="store", type=str, dest="attr", help="Group members attribute (default: %s)" % default_attr, default=default_attr ) options = parser.parse_args() if options.base is None: parser.error('You must specify base DN using --base parameter') init_logging(options, "Update memberOf") if options.dn and not options.pwd: options.pwd = getpass.getpass() class MyLdapClient(LdapClient): """ Implement a custom LdapClient to handle group objects """ # pylint: disable=super-init-not-called def __init__(self, scripts_options): self.options = scripts_options logging.info("Connect to LDAP server %s", self.options.host) self.cnx = LdapServer( self.options.host, dn=self.options.dn, pwd=self.options.pwd, v2=self.options.ldapv2) self.cnx.connect() def get_groups(self): """ Retreive groups form LDAP server """ return self.get_objects( 'group', self.options.filter, self.options.base, [self.options.attr] ) def touch_group_members(self, obj): """ Touch group members attribute """ current = self.get_attr(obj, self.options.attr, all_values=True) if not current: return True logging.debug('Update - remove values of %s', obj['dn']) changes = self.get_changes(obj, {options.attr: []}) logging.debug('Changes:\n%s', self.format_changes(changes)) if self.update_object(obj, changes): obj[options.attr] = [] logging.debug('Update - restore values of %s', obj['dn']) changes = self.get_changes(obj, {options.attr: current}) logging.debug('Changes:\n%s', self.format_changes(changes)) return myldap.update_object(obj, changes) return False # Start LDAP connection myldap = MyLdapClient(options) groups = myldap.get_groups() logging.info('%s groups found', len(groups)) pbar = Pbar('Update memberOf', len(groups), enabled=options.progress) for dn, group in groups.items(): myldap.touch_group_members(group) pbar.increment() pbar.finish()