1. Zhang Huangbin
  2. iredapd

Commits

Zhang Huangbin  committed 64db595

Bypass user alias addresses (shadowAddress) if user is allowed to send to mail list. Thanks Henri Veldsink for his feedback and testing.

  • Participants
  • Parent commits 8ede84b
  • Branches default

Comments (0)

Files changed (2)

File ChangeLog

View file
  • Ignore whitespace
 iRedAPD-1.3.4:
+    * Bypass user alias addresses (shadowAddress) if user is allowed to send
+      to mail list. Thanks Henri Veldsink for his feedback and testing.
     * Allow to use same logging hander in plugins, print plugin debug message.
     * Queary user aliases as allowed sender.
     * Print error message if plugin module doesn't exist.

File src/plugins/ldap_maillist_access_policy.py

View file
  • Ignore whitespace
 
     logger.debug('(%s) Get allowed senders...' % (PLUGIN_NAME))
 
-    basedn = ldapBaseDn
-    searchScope = 2     # Use SCOPE_BASE to improve performance.
+    recipient_domain = recipient.split('@', 1)[-1]
 
-    # Set search base dn, scope, filter and attribute list based on access policy.
+    # Set base dn as domain dn.
+    domaindn = 'domainName=' + recipient_domain + ',' + ldapBaseDn
+
+    # Default search scope. 2==ldap.SCOPE_SUBTREE
+    searchScope = 2
+
+    # Set search filter, attributes based on policy.
+    # Override base dn, scope if necessary.
     if policy == 'membersonly':
-        # Filter used to get domain members.
+        basedn = domaindn
+        # Filter: get mail list members.
         searchFilter = "(&(|(objectclass=mailUser)(objectClass=mailExternalUser))(accountStatus=active)(memberOfGroup=%s))" % (recipient, )
-        searchAttr = ['mail', 'shadowAddress',]
+
+        # Get both mail and shadowAddress.
+        searchAttrs = ['mail', 'shadowAddress',]
+
     elif policy == 'allowedonly' or policy == 'moderatorsonly':
+        # Get mail list moderators.
         basedn = listDn
-        searchScope = 0     # Use SCOPE_BASE to improve performance.
-        # Filter used to get domain moderators.
+        searchScope = 0     # Use ldap.SCOPE_BASE to improve performance.
         searchFilter = "(&(objectclass=mailList)(mail=%s))" % (recipient, )
-        searchAttr = ['listAllowedUser']
+        searchAttrs = ['listAllowedUser']
+
     else:
-        # Policy: membersAndModeratorsOnly.
+        basedn = domaindn
+        # Policy: policy==membersAndModeratorsOnly or not set.
         # Filter used to get both members and moderators.
         searchFilter = "(|(&(|(objectClass=mailUser)(objectClass=mailExternalUser))(memberOfGroup=%s))(&(objectclass=mailList)(mail=%s)))" % (recipient, recipient, )
-        searchAttr = ['mail', 'shadowAddress', 'listAllowedUser',]
+        searchAttrs = ['mail', 'shadowAddress', 'listAllowedUser',]
 
     logger.debug('(%s) base dn: %s' % (PLUGIN_NAME, basedn))
     logger.debug('(%s) search scope: %s' % (PLUGIN_NAME, searchScope))
     logger.debug('(%s) search filter: %s' % (PLUGIN_NAME, searchFilter))
-    logger.debug('(%s) search attributes: %s' % (PLUGIN_NAME, ', '.join(searchAttr)))
+    logger.debug('(%s) search attributes: %s' % (PLUGIN_NAME, ', '.join(searchAttrs)))
 
     try:
-        result = ldapConn.search_s(basedn, searchScope, searchFilter, searchAttr)
+        result = ldapConn.search_s(basedn, searchScope, searchFilter, searchAttrs)
         userList = []
         for obj in result:
-            for k in searchAttr:
+            for k in searchAttrs:
                 if k in obj[1].keys():
                     # Example of result data:
                     # [('dn', {'listAllowedUser': ['user@domain.ltd']})]
                     userList += obj[1][k]
                 else:
                     pass
+
+        # Exclude mail list itself.
+        if recipient in userList:
+            userList.remove(recipient)
+
         logger.debug('(%s) search result: %s' % (PLUGIN_NAME, str(userList)))
+
+        # Query once more to get 'shadowAddress'.
+        if len(userList) > 0 and (policy == 'allowedonly' or policy == 'moderatorsonly'):
+            logger.debug('(%s) Addition query to get user aliases...' % (PLUGIN_NAME))
+
+            basedn = 'ou=Users,' + domaindn
+            searchFilter = '(&(objectClass=mailUser)(|'
+            for i in userList:
+                searchFilter += '(mail=%s)' % i
+            searchFilter += '))'
+
+            searchAttrs = ['shadowAddress',]
+
+            logger.debug('(%s) base dn: %s' % (PLUGIN_NAME, basedn))
+            logger.debug('(%s) search scope: 2 (ldap.SCOPE_SUBTREE)' % (PLUGIN_NAME))
+            logger.debug('(%s) search filter: %s' % (PLUGIN_NAME, searchFilter))
+            logger.debug('(%s) search attributes: %s' % (PLUGIN_NAME, ', '.join(searchAttrs)))
+
+            try:
+                resultOfShadowAddresses = ldapConn.search_s(
+                    'ou=Users,'+domaindn,
+                    2,  # ldap.SCOPE_SUBTREE
+                    searchFilter,
+                    ['mail', 'shadowAddress',],
+                )
+
+                for obj in resultOfShadowAddresses:
+                    for k in searchAttrs:
+                        if k in obj[1].keys():
+                            # Example of result data:
+                            # [('dn', {'listAllowedUser': ['user@domain.ltd']})]
+                            userList += obj[1][k]
+                        else:
+                            pass
+
+                logger.debug('(%s) final result: %s' % (PLUGIN_NAME, str(userList)))
+
+            except Exception, e:
+                logger.debug(str(e))
+
         return userList
     except Exception, e:
         logger.debug('(%s) Error: %s' % (PLUGIN_NAME, str(e)))