diff --git a/ldapuserdir/ldapuserdir.py b/ldapuserdir/ldapuserdir.py old mode 100644 new mode 100755 index 7bc85aa..9f4abda --- a/ldapuserdir/ldapuserdir.py +++ b/ldapuserdir/ldapuserdir.py @@ -12,7 +12,6 @@ with an LDAP based user directory service import ldap from ldap.controls import SimplePagedResultsControl -#import ldap.ldapobject import sys import re from glob import fnmatch @@ -66,10 +65,10 @@ class LdapUserDir(object): serverurl, user_dn, user_pw, - group_ou = 'ou=example.com', - user_ou = 'ou=example.com', - page_size = 500, - logger = None): + group_ou='ou=example.com', + user_ou='ou=example.com', + page_size=500, + logger=None): self.serverurl = serverurl self.group_ou = group_ou self.user_ou = user_ou @@ -77,12 +76,12 @@ class LdapUserDir(object): self.user_pw = user_pw self.page_size = page_size - if logger == None: + if logger is None: self.logger = logging.getLogger('LdapUserDir') self.logger.setLevel(logging.WARNING) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch = logging.StreamHandler() - + ch.setFormatter(formatter) ch.setLevel(logging.DEBUG) self.logger.addHandler(ch) @@ -90,22 +89,22 @@ class LdapUserDir(object): self.logger = logger self._ldap = ldap.initialize(self.serverurl, trace_level=0, - trace_file=sys.stderr) + trace_file=sys.stderr) self.logger.debug('binding to: %s\n' % serverurl) self.logger.debug('binding as user: %s\n' % user_dn) # Without this, paged results don't work (see the python-ldap FAQ for a # hint as to why) - self._ldap.set_option(ldap.OPT_REFERRALS,0) + self._ldap.set_option(ldap.OPT_REFERRALS, 0) try: self._ldap.bind_s(self.user_dn, self.user_pw) - except ldap.INVALID_CREDENTIALS, e: + except ldap.INVALID_CREDENTIALS: self.logger.error('Authentication failure for dn:"%s"\n' % self.user_dn) raise # need to clean that later - except ldap.LDAPError, e: + except ldap.LDAPError: raise @staticmethod @@ -132,7 +131,7 @@ class LdapUserDir(object): Returns ------- - str + str """ """transforms a DN to a CN """ @@ -143,9 +142,8 @@ class LdapUserDir(object): else: raise RuntimeError("failed to convert DN to CN (%s)" % dn) - def _search_s(self, base, scope, filterstr='(objectClass=*)', - attrlist=None, attrsonly=0): + attrlist=None, attrsonly=0): """Helper for search_s_reconn. Wraps ldap.search_ext to use paged results if desired (see self.page_size).""" if self.page_size == 0: @@ -185,7 +183,7 @@ desired (see self.page_size).""" return [r[:2] for r in results] def search_s_reconn(self, base, scope, filterstr='(objectClass=*)', - attrlist=None, attrsonly=0, recon_attempts = 2): + attrlist=None, attrsonly=0, recon_attempts=2): """wrapper of standard ldap.search_s synchronous search that tries to reconnect @@ -216,10 +214,10 @@ desired (see self.page_size).""" list of tuples list of tuples of the form (dn, attributes) """ - + attempts = 0 ok = False - while ok == False: + while not ok: try: ok = True attempts += 1 @@ -259,7 +257,7 @@ desired (see self.page_size).""" try: self._ldap.bind_s(self.user_dn, self.user_pw) - except ldap.INVALID_CREDENTIALS, e: + except ldap.INVALID_CREDENTIALS: self.logger.error('Authentication failure for dn:"%s"\n' % self.user_dn) except Exception, err: @@ -268,11 +266,7 @@ desired (see self.page_size).""" self.serverurl + ": %s" % (err,)) - - return repl - - #def search_s(self,base,scope,filterstr='(objectClass=*)',attrlist=None,attrsonly=0): def get_users(self, filter='*', ou=None, mssfu=False): """get the names of all users from the directory service @@ -290,7 +284,7 @@ desired (see self.page_size).""" dict dictionary of the matching users { dn1:list1, ... } """ - if ou == None: + if ou is None: ou = self.user_ou if mssfu: @@ -298,13 +292,10 @@ desired (see self.page_size).""" else: srch = '(&(objectClass=user)(!(objectClass=computer))(cn=%s))' - #try: r = self.search_s_reconn(ou, ldap.SCOPE_SUBTREE, - srch % filter) - #except ldap.LDAPError, e: - # print e - # return - return r + srch % filter) + + return r def get_users_by_mailaddr(self, filter='*', ou=None, mssfu=False): """get the names of all users from the directory service @@ -322,7 +313,7 @@ desired (see self.page_size).""" dict dictionary of the matching users { dn1:list1, ... } """ - if ou == None: + if ou is None: ou = self.user_ou if mssfu: @@ -330,15 +321,11 @@ desired (see self.page_size).""" else: srch = '(&(objectClass=user)(!(objectClass=computer))(mail=%s))' - #try: r = self.search_s_reconn(ou, ldap.SCOPE_SUBTREE, - srch % filter) - #except ldap.LDAPError, e: - # print e - # return - return r + srch % filter) + return r - def list_users_etcpwd(self, records, verbose = False): + def list_users_etcpwd(self, records, verbose=False): """Print '/etc/pwd' format like information about matching users Parameters ---------- @@ -346,8 +333,8 @@ desired (see self.page_size).""" verbose : bool, optional """ fields = ['cn', 'msSFU30UidNumber', 'msSFU30UidNumber', - 'msSFU30GidNumber', 'displayName', - 'msSFU30LoginShell', 'msSFU30HomeDirectory'] + 'msSFU30GidNumber', 'displayName', + 'msSFU30LoginShell', 'msSFU30HomeDirectory'] for dn, entry in records: if verbose: for k in fields + ['description', 'mail', 'mobile']: @@ -364,7 +351,6 @@ desired (see self.page_size).""" sys.stdout.write('N.A.:') sys.stdout.write('\n') - def systemuser2dn(self, uname): """Converts a user's system username to the dn of the ldap directory by performing a search on ldap @@ -385,13 +371,10 @@ desired (see self.page_size).""" if no such user exists """ - #try: srch = '(&(objectClass=user)(!(objectClass=computer))(msSFU30UidNumber=*)(msSFU30HomeDirectory=*)(cn=%s))' % uname self.logger.debug('systemuser2dn: %s' % srch) r = self.search_s_reconn(self.user_ou, ldap.SCOPE_SUBTREE, srch) - #except ldap.LDAPError, e: - # print e if len(r) == 0: raise LdapUserDirError("No such user") @@ -399,7 +382,7 @@ desired (see self.page_size).""" self.logger.debug('systemuser2dn: dn = %s' % r[0][0]) return r[0][0] - def get_groups_struct(self, gfilter='*', ou = None, mssfu=False): + def get_groups_struct(self, gfilter='*', ou=None, mssfu=False): """searches for groups that match filter returns the full ldap search result structure for the search @@ -418,7 +401,7 @@ desired (see self.page_size).""" dict list of the matching groups { (dn1:dict1), ... } """ - if ou == None: + if ou is None: group_ou = self.group_ou if mssfu: @@ -426,15 +409,13 @@ desired (see self.page_size).""" else: srch = '(&(objectClass=Group)(cn=%s))' % gfilter self.logger.debug('get_groups_struct: %s' % srch) - #try: + r = self.search_s_reconn(group_ou, ldap.SCOPE_SUBTREE, srch) - #except ldap.LDAPError, e: - # print e # The following filter is necessary, because AD yielded # some (None,String) fields when searching with # --group-ou='dc=d,dc=psi,dc=ch'. This led to errors. - r = [el for el in r if el[0] != None] + r = [el for el in r if el[0] is not None] return r def get_memberof(self, dn, recursive=True, mssfu=False): @@ -442,7 +423,7 @@ desired (see self.page_size).""" This routine relies on the LDAP directory keeping memberOf attributes in the individual entries. - + Note that a recursive search may not show all groups, if mssfu was selected, and a group in the hierarchy tree has no msSFU settings. @@ -465,10 +446,10 @@ desired (see self.page_size).""" srch = '(&)' if mssfu: - srch = '(|(msSFU30GidNumber=*)(msSFU30UidNumber=*))' + srch = '(|(msSFU30GidNumber=*)(msSFU30UidNumber=*))' r = self.search_s_reconn(dn, ldap.SCOPE_BASE, srch, - attrlist=['memberOf']) + attrlist=['memberOf']) if r == []: return [] @@ -495,8 +476,7 @@ desired (see self.page_size).""" return grplist - - def get_groups_for_user(self, user, gfilter = None, returndn = False, + def get_groups_for_user(self, user, gfilter=None, returndn=False, mssfu=False): """Get groups for a particular user from LDAP. @@ -506,7 +486,7 @@ desired (see self.page_size).""" Parameters ---------- user : str - system username or user DN + system username or user DN ou : str, optional The organisational unit to be used in the ldap search returndn : bool, optional @@ -538,11 +518,11 @@ desired (see self.page_size).""" if gfilter: reslist = fnmatch.filter(reslist, gfilter) - + return reslist - def list_groups(self, filter = '*', ou = None, mssfu=False, - returndn = False, verbose = False): + def list_groups(self, filter='*', ou=None, mssfu=False, + returndn=False, verbose=False): """Prints a list of groups from the LDAP directory to stdout Parameters @@ -566,7 +546,6 @@ desired (see self.page_size).""" sys.stderr.write("Error: no groups found (filter: %s)\n" % filter) return - if verbose: for dn, entry in r: if returndn: @@ -595,7 +574,6 @@ desired (see self.page_size).""" sys.stdout.write(",".join([self.dn_to_cn(dn) for dn in entry['member']]) + "\n") else: sys.stdout.write("\n") - def _mod_groupmembers(self, ldapmode, dngroup, usernames): """modifies (adds/deletes) members of an LDAP group entry @@ -629,10 +607,10 @@ desired (see self.page_size).""" mod_attrs = [(ldapmode, 'member', dnlist)] try: self._ldap.modify_s(dngroup, mod_attrs) - except ldap.ALREADY_EXISTS, e: + except ldap.ALREADY_EXISTS: self.logger.error('Entry already exists in group %s' % dngroup) raise - except ldap.LDAPError, e: + except ldap.LDAPError: self.logger.error('ERROR modifying LDAP: group: %s; user list: %s\n' % (dngroup, dnlist)) raise diff --git a/setup.py b/setup.py index f0eb7e8..fe206c4 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ # we use the distribute framework that has a backward compatible invocation # to the setuptools -from setuptools import setup, find_packages +from setuptools import setup # we get the package version from inside our package, since we then # can use it also from within the package @@ -11,22 +11,19 @@ from setuptools import setup, find_packages execfile('ldapuserdir/version.py') setup( - name = "ldapuserdir", - version = __version__, - description = "Client for interacting with a LDAP user/group directory service", - long_description = "Client for listing user and group information and" + name="ldapuserdir", + version=__version__, + description="Client for interacting with a LDAP user/group directory service", + long_description="Client for listing user and group information and" + " for managing group memberships", - author = "Derek Feichtinger", - author_email = "derek.feichtinger@psi.ch", - license = "GPL", - # url = - #packages = find_packages('sigateway'), - packages = ['ldapuserdir'], - scripts = ['bin/ldapuserdir-ctl'], + author="Derek Feichtinger", + author_email="derek.feichtinger@psi.ch", + license="GPL", + packages=['ldapuserdir'], + scripts=['bin/ldapuserdir-ctl'], # following format is (targetdir,[list of files]) - data_files = [('etc',['etc/ldapuserdir-ctl.cfg'])], + data_files=[('etc', ['etc/ldapuserdir-ctl.cfg'])], - install_requires = ['python-ldap'] + install_requires=['python-ldap'] ) -