updateMemberOf/updateMemberOf
Benjamin Renard ebedffb14c
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Clone cleaning and configure CI to run tests
2022-12-17 00:33:34 +01:00

143 lines
3.7 KiB
Python
Executable file

#!/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(u"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()