Next / Previous / Contents / TCC Help System / NM Tech homepage

3.6.  generateAccounts(): Search LDAP for accounts

The purpose of this function is to query the LDAP server and generate a list of (uid, gecos) pairs for each user account.

homelist.py
# - - -   g e n e r a t e A c c o u n t s   - - -

def generateAccounts():
    """Query LDAP for all user accounts.

      [ LDAP_SERVER names TCC's LDAP server and that server is up ->
          return a list of (uid, gecos) tuples for each user
          account, in no particular order ]
    """

First, we bind to the LDAP server. Anonymous binding is sufficient to get the account information we want. See Section 3.3.3, “LDAP_SERVER.

homelist.py
    #-- 1 --
    # [ LDAP_SERVER names an accessible LDAP server ->
    #     anon  :=  an LDAP object representing an anonymous bind
    #               to LDAP_SERVER ]
    try:
        anon  =  ldap.initialize ( LDAP_SERVER )
        anon.bind ( "", "", ldap.AUTH_SIMPLE )
    except ldap.LDAP_Error, detail:
        print "*** Error, couldn't bind to the LDAP server."
        sys.exit(1)

Next, we use the LDAP module's search function to search first-level children of the node specified by ACCOUNTS_DN. The filterstr argument filters out entries that have no uid attribute. The attrlist argument requests that only the attributes named in the list are returned. See Section 3.3.4, “ACCOUNTS_DN, Section 3.3.1, “UID_ATTR, and Section 3.3.2, “GECOS_ATTR.

homelist.py
    #-- 2 --
    # [ anon is a bound LDAP object ->
    #     ldapResult  :=  a list of LDAP result tuples for
    #         a search of the immediate children of ACCOUNTS_DN that
    #         have a UID_ATTR attribute, containing the UID_ATTR and
    #         GECOS_ATTR attributes ]
    ldapResult  =  anon.search_s ( ACCOUNTS_DN, ldap.SCOPE_ONELEVEL,
        filterstr="(%s=*)" % UID_ATTR,
        attrlist=[UID_ATTR, GECOS_ATTR] )

The structure of ldapResult is described by this excerpt from LDAP programming with Python:

Each result tuple is of the form (dn, attrs), where dn is a string containing the DN (distinguished name) of the entry, and attrs is a dictionary containing the attributes associated with the entry. The keys of attrs are strings, and the associated values are lists of strings.

So to produce the return value, we pull out the second element of each tuple in ldapResult to get the attribute map, then form a tuple from the first element of the list for each attribute we want.

There's one more complication: some LDAP entries don't have a GECOS field. In that case we just skip that entry.

homelist.py
    #-- 3 --
    # [ ldapResult is an LDAP-search-format result list ->
    #     resultList  :=  list of (uid, gecos) tuples made from
    #                     ldapResult ]
    resultList  =  []
    for  dn, attrs in ldapResult:
        uid  =  attrs[UID_ATTR][0]
        try:
            gecos  =  attrs[GECOS_ATTR][0]
            resultList.append ( (uid, gecos) )
        except KeyError:
            pass

    #-- 4 --
    return resultList