I have been playing with TMDA for just a little while on a secondary
account, and have found it to be very very useful.  Thank you all for
this software.

Attached is a quick patch I created for searching LDAP as part of TMDA.
This is still very very small and just a simple search using LDAP and
if any results are returned it accepts it.  I used an LDAP uri to hold the
the information in a single line.

examples:

from-ldap 
"ldap://localhost:389/dc=example,dc=com?mail,cn?sub?(|%(keys)s)?bindname=uid=me%2Cou=People%2Cdc=example%2Cdc=com,X-BINDPW=itisme"
 accept

from-ldap "ldap://localhost:389/cn=me,ou=abook,dc=example,dc=com??sub?(|%(keys)s)?"  
accept

currently the %(keys)s  substitution is very limited but can and will be
fixed.  :)

I currently have an OID arch and thinking a small schema could be used to
store all of the users rules in LDAP.

-Jeremy


Index: TMDA/FilterParser.py
===================================================================
RCS file: /cvsroot/tmda/tmda/TMDA/FilterParser.py,v
retrieving revision 1.59
diff -u -r1.59 FilterParser.py
--- TMDA/FilterParser.py        11 Jul 2003 23:02:59 -0000      1.59
+++ TMDA/FilterParser.py        19 Aug 2003 01:09:37 -0000
@@ -222,7 +222,7 @@
     bol_comment = re.compile(r'\s*#')
 
     most_sources = re.compile(r"""
-    ( (?:to|from)-(?:file|cdb|dbm|ezmlm|mailman|mysql|sql)
+    ( (?:to|from)-(?:file|cdb|dbm|ezmlm|mailman|mysql|sql|ldap)
     | size | pipe
     | (?:to|from) (?!-) )
     """, re.VERBOSE | re.IGNORECASE)
@@ -268,6 +268,8 @@
         'to-cdb'       : ('optional',),
         'from-dbm'     : ('optional',),
         'to-dbm'       : ('optional',),
+        'from-ldap'    : ('optional',),
+        'to-ldap'      : ('optional',),
         'from-ezmlm'   : ('optional',),
         'to-ezmlm'     : ('optional',),
         'from-mailman' : ('attr', 'optional' ),
@@ -720,6 +722,25 @@
                                   source)
 
 
+    def __search_ldap(self, uri, keys, actions, source):
+        import ldap
+        import ldapurl
+        found_match = 0
+        LDAPurl = ldapurl.LDAPUrl(uri)
+        conn = ldap.initialize(LDAPurl.initializeUrl())
+        x = ")(mail=".join([ key.lower() for key in keys if key])
+        x = {"keys":"(mail=" + x + ")"}
+        filter = LDAPurl.filterstr % (x)
+        conn.simple_bind_s(LDAPurl.who,LDAPurl.cred)
+        r = conn.search_s(LDAPurl.dn, LDAPurl.scope, 
+                          filterstr=filter, 
+                          attrlist=LDAPurl.attrs, attrsonly=1)
+        if r:
+            found_match = 1
+        return found_match
+
+
+        
     def __search_cdb(self, pathname, keys, actions, source):
         """
         Search DJB's constant databases; see <http:/cr.yp.to/cdb.html>.
@@ -947,6 +968,19 @@
                     found_match = self.__search_cdb(match, keys,
                                                     actions, source)
                 except cdb.error, e:
+                    if not args.has_key('optional'):
+                        raise MatchError(lineno, str(e))
+                if found_match:
+                    break
+            # LDAP Databsse 
+            if source in ('from-ldap', 'to-ldap'):
+                import ldap
+                import ldapurl
+                keys += self.__extract_domains(keys)
+                try:
+                    found_match = self.__search_ldap(match, keys,
+                                                     actions, source)
+                except (ldap.LDAPError,), e:
                     if not args.has_key('optional'):
                         raise MatchError(lineno, str(e))
                 if found_match:

Reply via email to