summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-04-13 12:33:10 +0100
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-04-13 12:33:10 +0100
commit6bcf448d8ee1a9a542d7798c39a68d1be604c61f (patch)
treef8bc5bc3b9f49e2002a05f2050d0b193bdd8c696
parentbc0af8397060e65a265bc9ce22df17b1353bf436 (diff)
downloadpykolab-6bcf448d8ee1a9a542d7798c39a68d1be604c61f.tar.gz
Allow the Kolab SMTP Access Policy to consult groups as well
-rwxr-xr-xbin/kolab_smtp_access_policy.py33
-rw-r--r--pykolab/auth/__init__.py25
-rw-r--r--pykolab/auth/ldap/__init__.py109
3 files changed, 161 insertions, 6 deletions
diff --git a/bin/kolab_smtp_access_policy.py b/bin/kolab_smtp_access_policy.py
index 5ffb5b7..e2a9421 100755
--- a/bin/kolab_smtp_access_policy.py
+++ b/bin/kolab_smtp_access_policy.py
@@ -751,10 +751,23 @@ class PolicyRequest(object):
)
}
+ group = {
+ 'dn': auth.find_group(
+ search_attrs,
+ normalize_address(recipient),
+ domain=sasl_domain,
+ # TODO: Get the filter from the configuration.
+ additional_filter="(&(|(objectclass=" + \
+ "groupofuniquenames)(objectclass=" + \
+ "groupofurls))%(search_filter)s)"
+ )
+ }
+
+
# 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 user['dn']:
+ if not user['dn'] and not group['dn']:
if not conf.allow_unauthenticated:
cache_update(
function='verify_recipient',
@@ -779,11 +792,19 @@ class PolicyRequest(object):
log.debug(_("Could not find this user, accepting"), level=8)
return True
- recipient_policy = auth.get_user_attribute(
- sasl_domain,
- user,
- 'kolabAllowSMTPSender'
- )
+ if not user['dn'] == None:
+ recipient_policy = auth.get_user_attribute(
+ sasl_domain,
+ user,
+ 'kolabAllowSMTPSender'
+ )
+
+ if not group['dn'] == None:
+ recipient_policy = auth.get_group_attribute(
+ sasl_domain,
+ group,
+ 'kolabAllowSMTPSender'
+ )
# If no such attribute has been specified, allow
if recipient_policy == None:
diff --git a/pykolab/auth/__init__.py b/pykolab/auth/__init__.py
index 36e9600..04fd578 100644
--- a/pykolab/auth/__init__.py
+++ b/pykolab/auth/__init__.py
@@ -144,6 +144,23 @@ class Auth(object):
self._auth._disconnect()
+ def find_group(self, attr, value, domain=None, **kw):
+ self.connect(domain)
+
+ if self.secondary_domains.has_key(domain):
+ log.debug(
+ _("Using primary domain %s instead of secondary domain %s")
+ % (
+ self.secondary_domains[domain],
+ domain
+ ),
+ level=9
+ )
+
+ domain = self.secondary_domains[domain]
+
+ return self._auth._find_group(attr, value, domain=domain, **kw)
+
def find_user(self, attr, value, domain=None, **kw):
self.connect(domain)
@@ -242,6 +259,14 @@ class Auth(object):
return self._auth._domain_section(domain)
+ def get_group_attribute(self, domain, group, attribute):
+ self.connect(domain=domain)
+
+ if self.secondary_domains.has_key(domain):
+ domain = self.secondary_domains[domain]
+
+ return self._auth._get_group_attribute(group, attribute)
+
def get_user_attribute(self, domain, user, attribute):
self.connect(domain=domain)
diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index da16560..237cfbd 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -302,6 +302,65 @@ class LDAP(object):
return _user_dn
+ def _find_group(self, attr, value, domain=None, additional_filter=None, base_dn=None):
+ self._connect()
+ self._bind()
+
+ if domain == None:
+ domain = conf.get('kolab', 'primary_domain')
+
+ domain_root_dn = self._kolab_domain_root_dn(domain)
+
+ if conf.has_option(domain, 'group_base_dn'):
+ section = domain
+ else:
+ section = 'ldap'
+
+ if base_dn == None:
+ group_base_dn = conf.get_raw(
+ section,
+ 'group_base_dn'
+ ) % ({'base_dn': domain_root_dn})
+ else:
+ group_base_dn = base_dn
+
+ if type(attr) == str:
+ search_filter = "(%s=%s)" % (
+ attr,
+ value
+ )
+ elif type(attr) == list:
+ search_filter = "(|"
+ for _attr in attr:
+ search_filter = "%s(%s=%s)" % (search_filter, _attr, value)
+ search_filter = "%s)" % (search_filter)
+
+ if additional_filter:
+ search_filter = additional_filter % {
+ 'search_filter': search_filter
+ }
+
+ log.debug(
+ _("Attempting to find the group with search filter: %s") % (
+ search_filter
+ ),
+ level=8
+ )
+
+ _results = self.ldap.search_s(
+ group_base_dn,
+ scope=ldap.SCOPE_SUBTREE,
+ filterstr=search_filter,
+ attrlist=[ 'dn' ]
+ )
+
+ if len(_results) == 1:
+ (_group_dn, _group_attrs) = _results[0]
+ else:
+ return False
+
+ return _group_dn
+
def _find_user(self, attr, value, domain=None, additional_filter=None, base_dn=None):
self._connect()
self._bind()
@@ -771,6 +830,56 @@ class LDAP(object):
else:
return 'ldap'
+ def _get_group_attribute(self, group, attribute):
+ self._bind()
+
+ attribute = attribute.lower()
+
+ log.debug(
+ _("Getting attribute %s for group %s") % (attribute,user),
+ level=8
+ )
+
+ _result_type = None
+
+ _search = self.ldap.search_ext(
+ group['dn'],
+ ldap.SCOPE_BASE,
+ '(objectclass=*)',
+ [ 'dn', attribute ]
+ )
+
+ (
+ _result_type,
+ _result_data,
+ _result_msgid,
+ _result_controls
+ ) = self.ldap.result3(_search)
+
+ if len(_result_data) >= 1:
+ (group_dn, group_attrs) = _result_data[0]
+ else:
+ log.warning(_("Could not get attribute %s for group %s")
+ % (attribute,user['dn']))
+
+ return None
+
+ group_attrs = utils.normalize(group_attrs)
+
+ if not group_attrs.has_key(attribute):
+ log.debug(
+ _("Wanted attribute %s, which does not exist for group " + \
+ "%r") % (
+ attribute,
+ group_dn
+ ),
+ level=8
+ )
+
+ group_attrs[attribute] = None
+
+ return group_attrs[attribute]
+
def _get_user_attribute(self, user, attribute):
self._bind()