Branch 'pykolab-0.5' - 4 commits - bin/kolab_smtp_access_policy.py configure.ac pykolab/auth

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Sun Jan 26 16:11:57 CET 2014


 bin/kolab_smtp_access_policy.py |   84 +++++++++++++++++++++++++++++++++-------
 configure.ac                    |    2 
 pykolab/auth/__init__.py        |    3 +
 pykolab/auth/ldap/__init__.py   |   16 ++++++-
 4 files changed, 88 insertions(+), 17 deletions(-)

New commits:
commit bc3c88ef753ed24f11fd66008e7ef4b594135edb
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jan 18 18:20:10 2014 +0100

    Bump release

diff --git a/configure.ac b/configure.ac
index 386cfc7..f01156e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_INIT([pykolab], 0.5.17)
-AC_SUBST([RELEASE], 3)
+AC_SUBST([RELEASE], 4)
 
 AC_CONFIG_SRCDIR(pykolab/constants.py.in)
 


commit 345209e57c8e3a7c23fe3420edac5eb3c8a77dd6
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Sep 20 13:53:36 2013 +0100

    Make sure the recipient checks are cached as well

diff --git a/bin/kolab_smtp_access_policy.py b/bin/kolab_smtp_access_policy.py
index 542345e..2553aea 100755
--- a/bin/kolab_smtp_access_policy.py
+++ b/bin/kolab_smtp_access_policy.py
@@ -48,7 +48,7 @@ except:
 from sqlalchemy.schema import Index
 from sqlalchemy.schema import UniqueConstraint
 
-sys.path = ['..'] + sys.path
+sys.path = ['..','.'] + sys.path
 
 import pykolab
 
@@ -66,13 +66,15 @@ log.remove_stdout_handler()
 
 conf = pykolab.getConf()
 
+mydomains = None
+
 #
 # Caching routines using SQLAlchemy.
 #
 # If creating the cache fails, we continue without any caching, significantly
 # increasing the load on LDAP.
 #
-cache_expire = 3600
+cache_expire = 86400
 try:
     metadata = MetaData()
 except:
@@ -740,7 +742,7 @@ class PolicyRequest(object):
                             "money.") % (self.sender, recipient)
                     )
 
-                return record[0].value
+                return records[0].value
 
         # TODO: Under some conditions, the recipient may not be fully qualified.
         # We'll cross that bridge when we get there, though.
@@ -748,6 +750,20 @@ class PolicyRequest(object):
             sasl_domain = recipient.split('@')[1]
         else:
             sasl_domain = conf.get('kolab', 'primary_domain')
+            recipient = "%s@%s" % (recipient,sasl_domain)
+
+        if not verify_domain(sasl_domain):
+            if not cache == False:
+                cache_update(
+                        function='verify_recipient',
+                        sender=self.sender,
+                        recipient=recipient,
+                        result=(int)(True),
+                        sasl_username=self.sasl_username,
+                        sasl_sender=self.sasl_sender
+                    )
+
+            return True
 
         if self.auth == None:
             self.auth = Auth(sasl_domain)
@@ -795,9 +811,19 @@ class PolicyRequest(object):
                             "object entries and the SMTP Access Policy can " + \
                             "therefore not restrict message flow")
                     )
+
+                cache_update(
+                        function='verify_recipient',
+                        sender=self.sender,
+                        recipient=normalize_address(recipient),
+                        result=(int)(True),
+                        sasl_username=self.sasl_username,
+                        sasl_sender=self.sasl_sender
+                    )
+
                 return True
             elif len(recipients) == 1:
-                recipient = { 'dn': recipients[0] }
+                _recipient = { 'dn': recipients[0] }
             else:
                 log.debug(
                         _("Recipient address %r not found. Allowing since " + \
@@ -807,22 +833,31 @@ class PolicyRequest(object):
                         level=3
                     )
 
+                cache_update(
+                        function='verify_recipient',
+                        sender=self.sender,
+                        recipient=normalize_address(recipient),
+                        result=(int)(True),
+                        sasl_username=self.sasl_username,
+                        sasl_sender=self.sasl_sender
+                    )
+
                 return True
 
         elif isinstance(recipients, basestring):
-            recipient = {
+            _recipient = {
                     'dn': recipients
                 }
 
         # We have gotten an invalid recipient. We need to catch this case,
         # because testing can input invalid recipients, and so can faulty
         # applications, or misconfigured servers.
-        if not recipient['dn']:
+        if not _recipient['dn']:
             if not conf.allow_unauthenticated:
                 cache_update(
                         function='verify_recipient',
                         sender=self.sender,
-                        recipient=recipient,
+                        recipient=normalize_address(recipient),
                         result=(int)(False),
                         sasl_username=self.sasl_username,
                         sasl_sender=self.sasl_sender
@@ -833,7 +868,7 @@ class PolicyRequest(object):
                 cache_update(
                         function='verify_recipient',
                         sender=self.sender,
-                        recipient=recipient,
+                        recipient=normalize_address(recipient),
                         result=(int)(True),
                         sasl_username=self.sasl_username,
                         sasl_sender=self.sasl_sender
@@ -842,15 +877,24 @@ class PolicyRequest(object):
                 log.debug(_("Could not find this user, accepting"), level=8)
                 return True
 
-        if not recipient['dn'] == False:
+        if not _recipient['dn'] == False:
             recipient_policy = self.auth.get_entry_attribute(
                     sasl_domain,
-                    recipient,
+                    _recipient['dn'],
                     'kolabAllowSMTPSender'
                 )
 
         # If no such attribute has been specified, allow
         if recipient_policy == None:
+            cache_update(
+                    function='verify_recipient',
+                    sender=self.sender,
+                    recipient=normalize_address(recipient),
+                    result=(int)(True),
+                    sasl_username=self.sasl_username,
+                    sasl_sender=self.sasl_sender
+                )
+
             recipient_verified = True
 
         # Otherwise, parse the policy obtained with the subject of the policy
@@ -866,7 +910,7 @@ class PolicyRequest(object):
             cache_update(
                     function='verify_recipient',
                     sender=self.sender,
-                    recipient=recipient,
+                    recipient=normalize_address(recipient),
                     result=(int)(recipient_verified),
                     sasl_username=self.sasl_username,
                     sasl_sender=self.sasl_sender
@@ -895,10 +939,11 @@ class PolicyRequest(object):
                 )
 
             if not records == None and len(records) == len(self.recipients):
+                log.debug("Euh, what am I doing here?")
                 for record in records:
                     recipient_found = False
                     for recipient in self.recipients:
-                        if recipient == record['recipient']:
+                        if recipient == record.recipient:
                             recipient_found = True
 
                     if not recipient_found:
@@ -1103,6 +1148,7 @@ def cache_init():
 
     Session = sessionmaker(bind=engine)
     session = Session()
+    cache_cleanup()
 
     return cache
 
@@ -1118,8 +1164,8 @@ def cache_select(
     if not cache == True:
         return None
 
-    if not recipient == '':
-        recipients.append(recipient)
+    if not recipient == '' and recipients == []:
+        recipients = [recipient]
 
     return session.query(
             PolicyResult
@@ -1255,6 +1301,11 @@ def expand_mydomains():
         Return a list of my domains.
     """
 
+    global mydomains
+
+    if not mydomains == None:
+        return mydomains
+
     auth = Auth()
     auth.connect()
 
@@ -1325,6 +1376,11 @@ def verify_domain(domain):
         Verify whether the domain is internal (mine) or external.
     """
 
+    global mydomains
+
+    if not mydomains == None:
+        return domain in mydomains
+
     auth = Auth()
     auth.connect()
 
diff --git a/pykolab/auth/__init__.py b/pykolab/auth/__init__.py
index 1ae82e2..727a384 100644
--- a/pykolab/auth/__init__.py
+++ b/pykolab/auth/__init__.py
@@ -184,6 +184,9 @@ class Auth(pykolab.base.Base):
         if not domain == None and not self.domain == domain:
             self.connect(domain=domain)
 
+        if not self._auth or self._auth == None:
+            self.connect(domain=domain)
+
         result = self._auth.find_recipient(address)
 
         if isinstance(result, list) and len(result) == 1:


commit ca01db2cc0c6035a47ee8f311e5a0a58a9a66832
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Sep 18 15:34:31 2013 +0100

    Store a domain's root dn once it is found, so that subsequent actions against the same base sub-class instance do not need to search again and again

diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index 69af8c7..266a5d7 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -1637,6 +1637,12 @@ class LDAP(pykolab.base.Base):
         return _user_dn
 
     def _kolab_domain_root_dn(self, domain):
+        if not hasattr(self, 'domain_rootdns'):
+            self.domain_rootdns = {}
+
+        if self.domain_rootdns.has_key(domain):
+            return self.domain_rootdns[domain]
+
         self._bind()
 
         log.debug(_("Finding domain root dn for domain %s") % (domain), level=8)
@@ -1667,16 +1673,19 @@ class LDAP(pykolab.base.Base):
                     )
                 _domain_attrs = utils.normalize(_domain_attrs)
                 if _domain_attrs.has_key(domain_rootdn_attribute):
+                    self.domain_rootdns[domain] = _domain_attrs[domain_rootdn_attribute]
                     return _domain_attrs[domain_rootdn_attribute]
                 else:
                     if isinstance(_domain_attrs[domain_name_attribute], list):
                         domain = _domain_attrs[domain_name_attribute][0]
-
+                    else:
+                        domain = _domain_attrs[domain_name_attribute]
         else:
             if conf.has_option('ldap', 'base_dn'):
                 return conf.get('ldap', 'base_dn')
 
-        return utils.standard_root_dn(domain)
+        self.domain_rootdns[domain] = utils.standard_root_dn(domain)
+        return self.domain_rootdns[domain]
 
     def _kolab_filter(self):
         """


commit 449bff5693099c85751a7c50759e957683b249b2
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Aug 3 10:48:31 2013 +0100

    A standard root dn is the ,dc= version of the parent root domain, and not (potentially) an alias

diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index 46d9e44..69af8c7 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -1668,6 +1668,9 @@ class LDAP(pykolab.base.Base):
                 _domain_attrs = utils.normalize(_domain_attrs)
                 if _domain_attrs.has_key(domain_rootdn_attribute):
                     return _domain_attrs[domain_rootdn_attribute]
+                else:
+                    if isinstance(_domain_attrs[domain_name_attribute], list):
+                        domain = _domain_attrs[domain_name_attribute][0]
 
         else:
             if conf.has_option('ldap', 'base_dn'):




More information about the commits mailing list