summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--roles/MX/files/etc/postfix/virtual/lists_maps.cf7
-rw-r--r--roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf14
-rw-r--r--roles/MX/tasks/main.yml3
-rw-r--r--roles/MX/templates/etc/postfix/main.cf.j29
-rw-r--r--roles/common-LDAP/files/etc/ldap/schema/fripost.ldif41
-rw-r--r--roles/common-LDAP/templates/etc/ldap/database.ldif.j218
6 files changed, 31 insertions, 61 deletions
diff --git a/roles/MX/files/etc/postfix/virtual/lists_maps.cf b/roles/MX/files/etc/postfix/virtual/lists_maps.cf
deleted file mode 100644
index da0e4a9..0000000
--- a/roles/MX/files/etc/postfix/virtual/lists_maps.cf
+++ /dev/null
@@ -1,7 +0,0 @@
-server_host = ldapi://%2Fprivate%2Fldapi/
-version = 3
-search_base = fvl=%u,fvd=%d,ou=virtual,o=mailHosting,dc=fripost,dc=org
-scope = base
-bind = none
-query_filter = (&(|(objectClass=FripostVirtualList)(objectClass=FripostVirtualListCommand))(fvl=%u)(fripostLocalAlias=%u#%d))
-result_attribute = fripostLocalAlias
diff --git a/roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf b/roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf
index 860c4e6..27c93d1 100644
--- a/roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf
+++ b/roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf
@@ -1,11 +1,11 @@
-# Despite the index on 'fripostLocalAlias' it's a bit more inefficient,
-# but more precise, than the alternative of using regexes here, and a
-# plain hash on the list managers' side.
server_host = ldapi://%2Fprivate%2Fldapi/
version = 3
-search_base = ou=virtual,o=mailHosting,dc=fripost,dc=org
-scope = sub
+search_base = fvl=%u,fvd=%d,ou=virtual,o=mailHosting,dc=fripost,dc=org
+scope = base
bind = none
-query_filter = (&(|(objectClass=FripostVirtualList)(objectClass=FripostVirtualListCommand))(fripostLocalAlias=%s))
-result_attribute = fripostLocalAlias
+query_filter = (&(|(objectClass=FripostVirtualList)(objectClass=FripostVirtualListCommand))(fvl=%u))
+result_attribute = fvl
+# We use these maps for both virtual mailboxes and transport (in the
+# former case the result is ignored, only the existence of a match
+# matters.)
result_format = smtp:[127.0.0.1]:2345
diff --git a/roles/MX/tasks/main.yml b/roles/MX/tasks/main.yml
index 1f5136a..de6924b 100644
--- a/roles/MX/tasks/main.yml
+++ b/roles/MX/tasks/main.yml
@@ -32,43 +32,42 @@
mode=0644
register: r
notify:
- Restart Postfix
- name: Create directory /etc/postfix-.../virtual
file: path=/etc/postfix-{{ postfix_instance[inst].name }}/virtual
state=directory
owner=root group=root
mode=0755
- name: Copy lookups tables
copy: src=etc/postfix/virtual/{{ item }}
dest=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/{{ item }}
owner=root group=root
mode=0644
with_items:
- mailbox_domains.cf
- reserved_maps.pcre
- alias_maps.cf
- - lists_maps.cf
- alias_catchall_maps.cf
- mailbox_maps.cf
- - reserved_transport_maps
- transport_lists_maps.cf
+ - reserved_transport_maps
- name: Compile the Reserved Transport Maps
postmap: cmd=postalias instance={{ postfix_instance[inst].name }}
src=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/reserved_transport_maps db=cdb
owner=root group=root
mode=0644
- name: Copy reserved-alias.pl
copy: src=usr/local/sbin/reserved-alias.pl
dest=/usr/local/sbin/reserved-alias.pl
owner=root group=root
mode=0755
- name: Start Postfix
service: name=postfix state=started
when: not r.changed
- meta: flush_handlers
diff --git a/roles/MX/templates/etc/postfix/main.cf.j2 b/roles/MX/templates/etc/postfix/main.cf.j2
index 6b32634..d301aaf 100644
--- a/roles/MX/templates/etc/postfix/main.cf.j2
+++ b/roles/MX/templates/etc/postfix/main.cf.j2
@@ -39,49 +39,54 @@ alias_maps =
alias_database =
local_recipient_maps =
message_size_limit = 67108864
recipient_delimiter = +
# Forward everything to our internal mailhub
{% if 'MTA-out' in group_names %}
relayhost = [127.0.0.1]:{{ MTA_out.port }}
{% else %}
relayhost = [{{ MTA_out.IPv4 }}]:{{ MTA_out.port }}
{% endif %}
relay_domains =
# Virtual transport
{% if 'LDA' in group_names %}
virtual_transport = smtp:[127.0.0.1]:{{ LDA.port }}
{% else %}
virtual_transport = smtp:[{{ LDA.IPv4 }}]:{{ LDA.port }}
{% endif %}
+transport_maps = ldap:$config_directory/virtual/transport_lists_maps.cf
virtual_mailbox_domains = ldap:$config_directory/virtual/mailbox_domains.cf
virtual_alias_maps = pcre:$config_directory/virtual/reserved_maps.pcre
ldap:$config_directory/virtual/alias_maps.cf
- ldap:$config_directory/virtual/lists_maps.cf
ldap:$config_directory/virtual/alias_catchall_maps.cf
virtual_mailbox_maps = ldap:$config_directory/virtual/mailbox_maps.cf
-mailbox_transport_maps = cdb:$config_directory/virtual/reserved_transport_maps
+ # it's a bit stupid to lookup for lists here
+ # and in transport, but we need to tell
+ # postfix to accept the recipient
+ # (virtual_mailbox_maps) *before* sending away
+ # to the list server (transport_maps)
ldap:$config_directory/virtual/transport_lists_maps.cf
+mailbox_transport_maps = cdb:$config_directory/virtual/reserved_transport_maps
# Don't rewrite remote headers
local_header_rewrite_clients =
# Pass the client information along to the content filter
smtp_send_xforward_command = yes
# Avoid splitting the envelope and scanning messages multiple times
smtp_destination_recipient_limit = 1000
# Tolerate occasional high latency
smtp_data_done_timeout = 1200s
# Tunnel everything through IPSec
smtp_tls_security_level = none
smtp_bind_address = 172.16.0.1
# TLS
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_CApath = /etc/ssl/certs/
smtpd_tls_session_cache_database= btree:$data_directory/smtpd_tls_session_cache
diff --git a/roles/common-LDAP/files/etc/ldap/schema/fripost.ldif b/roles/common-LDAP/files/etc/ldap/schema/fripost.ldif
index 2e5bb1f..514b6fa 100644
--- a/roles/common-LDAP/files/etc/ldap/schema/fripost.ldif
+++ b/roles/common-LDAP/files/etc/ldap/schema/fripost.ldif
@@ -56,135 +56,120 @@
# - nis.schema
dn: cn=fripost,cn=schema,cn=config
objectClass: olcSchemaConfig
#
# Attributes: 1.3.6.1.4.1.40011.1.1
#
olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.1 NAME 'fvd'
DESC 'A virtual mail domain'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
#
olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.2 NAME 'fvl'
DESC 'The local part of a virtual user, alias, list or list command'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
#
-# This is redundant since we always use DNs of the form
-# fvl=localpart,fvd=domainpart.tld,...
-# (But Postfix doesn't allow the use of '%u' and '%d' from the query in
-# its 'result_format'.)
-# It is a priori insecure to allow arbitrary values here since users
-# will modify this value themselves, however our Postfix will only
-# accept well-formed values, enforced by a custom filter:
-# query_filter = (&...(fripostLocalAlias=%u#%d))
-# result_attribute = fripostLocalAlias
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.3 NAME 'fripostLocalAlias'
- DESC 'A local alias, typically localpart#domainpart.tld'
- EQUALITY caseIgnoreIA5Match
- SUBSTR caseIgnoreIA5SubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
-#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.4 NAME 'fripostMaildrop'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.3 NAME 'fripostMaildrop'
DESC 'An email address the virtual alias should be mapped to'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
#
# We are creating a new attribute, optional in virtual domains and
# users, because the presence index should *not* apply to the
# mandatory attribute above.
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.5 NAME 'fripostOptionalMaildrop'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.4 NAME 'fripostOptionalMaildrop'
DESC 'An optional email address for catch-all aliases on domains and users'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.6 NAME 'fripostIsStatusActive'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.5 NAME 'fripostIsStatusActive'
DESC 'When present, a token locking the entry in an inactive state'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.7 NAME 'fripostPendingToken'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.6 NAME 'fripostPendingToken'
DESC 'Is the entry pending?'
EQUALITY caseExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.8 NAME 'fripostUserQuota'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.7 NAME 'fripostUserQuota'
DESC 'The quota on a user e.g., "50MB"'
EQUALITY caseExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.9 NAME 'fripostCanAddDomain'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.8 NAME 'fripostCanAddDomain'
DESC 'A user/domain that can add domains'
SUP distinguishedName )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.10 NAME 'fripostCanAddAlias'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.9 NAME 'fripostCanAddAlias'
DESC 'A user/domain that can add aliases under the parent domain'
SUP distinguishedName )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.11 NAME 'fripostCanAddList'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.10 NAME 'fripostCanAddList'
DESC 'A user/domain that can add lists under the parent domain'
SUP distinguishedName )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.12 NAME 'fripostOwner'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.11 NAME 'fripostOwner'
DESC 'A user that owns under parent domain'
SUP distinguishedName )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.13 NAME 'fripostPostmaster'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.12 NAME 'fripostPostmaster'
DESC 'A user that is a postmaster of the parent domain'
SUP distinguishedName )
#
-olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.14 NAME 'fripostListManager'
+olcAttributeTypes: ( 1.3.6.1.4.1.40011.1.2.1.13 NAME 'fripostListManager'
DESC 'The list manager'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )
#
#
# Objects: 1.3.6.1.4.1.40011.1.2
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.1 NAME 'FripostVirtual'
AUXILIARY
DESC 'Virtual mail hosting'
MAY ( fripostCanAddDomain ) )
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.2 NAME 'FripostVirtualDomain'
SUP top STRUCTURAL
DESC 'Virtual domain'
MUST ( fvd $ fripostIsStatusActive )
MAY ( fripostCanAddAlias $ fripostCanAddList $
fripostOwner $ fripostPostmaster $
fripostOptionalMaildrop $ description ) )
#
# | TODO: add limits here
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.3 NAME 'FripostVirtualUser'
SUP top STRUCTURAL
DESC 'Virtual user'
MUST ( fvl $ userPassword $ fripostIsStatusActive )
MAY ( fripostUserQuota $ fripostOptionalMaildrop $ description) )
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.4 NAME 'FripostVirtualAlias'
SUP top STRUCTURAL
DESC 'Virtual alias'
MUST ( fvl $ fripostMaildrop $ fripostIsStatusActive )
MAY ( fripostOwner $ description ) )
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.5 NAME 'FripostVirtualList'
SUP top STRUCTURAL
DESC 'Virtual list'
- MUST ( fvl $ fripostListManager $ fripostIsStatusActive $ fripostLocalAlias )
+ MUST ( fvl $ fripostListManager $ fripostIsStatusActive )
MAY ( fripostOwner $ description ) )
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.6 NAME 'FripostVirtualListCommand'
SUP top STRUCTURAL
DESC 'Virtual list command'
- MUST ( fvl $ fripostLocalAlias ) )
+ MUST ( fvl ) )
#
olcObjectClasses: ( 1.3.6.1.4.1.40011.1.2.7 NAME 'FripostPendingEntry'
SUP top AUXILIARY
DESC 'Virtual pending entry'
MAY ( fripostPendingToken ) )
diff --git a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2 b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
index 56cd110..3752f9f 100644
--- a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
+++ b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
@@ -41,109 +41,103 @@ olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
# * Restart slapd sudo service slapd start
#
#
# On single- and dual-core systems, change the maximum number of threads
# to 8. (The default, 16, is fine for 4- and 8-core systems.)
#
# dn: cn=config
# changetype: modify
# add: olcThreads
# olcThreads: 8
#
# References
# - https://wiki.zimbra.com/wiki/OpenLDAP_Performance_Tuning_5.0
# - http://www.openldap.org/doc/admin24/tuning.html
# - http://www.openldap.org/faq/data/cache/42.html
# - http://www.openldap.org/faq/data/cache/136.html
# - http://www.zytrax.com/books/ldap/apa/indeces.html
#
olcDbIndex: objectClass eq
# Let us make Postfix's life easier. TODO: only if MX, lists.f.o, MDA, etc.
-olcDbIndex: fripostIsStatusActive,fvd,fvl,fripostLocalAlias eq
+olcDbIndex: fripostIsStatusActive,fvd,fvl eq
olcDbIndex: fripostOptionalMaildrop pres
# SyncProv/SyncRepl specific indexing.
olcDbIndex: entryCSN,entryUUID eq
#
#
########################################################################
########################################################################
# Sync Replication
# TODO: replace the simple bind by Kerberos/GSSAPI
#
# References:
# - http://www.openldap.org/doc/admin24/replication.html#Syncrepl
# - http://www.zytrax.com/books/ldap/ch7/#ol-syncrepl-rap
#
{% if 'LDAP-provider' in group_names %}
olcLimits: dn.exact="cn=MX-replicate,ou=services,o=mailHosting,dc=fripost,dc=org"
time.soft=unlimited
time.hard=unlimited
size.soft=unlimited
size.hard=unlimited
{% elif 'MX' in group_names %}
olcSyncrepl: rid=000
provider=ldap://{{ LDAP_provider }}
type=refreshAndPersist
retry="5 5 300 +"
searchbase="ou=virtual,o=mailHosting,dc=fripost,dc=org"
- attrs=objectClass,fvd,fvl,fripostMaildrop,fripostOptionalMaildrop,fripostLocalAlias,fripostPostmaster,fripostOwner
+ attrs=objectClass,fvd,fvl,fripostMaildrop,fripostOptionalMaildrop,fripostPostmaster,fripostOwner
scope=sub
schemachecking=off
bindmethod=simple
binddn="cn=MX-replicate,ou=services,o=mailHosting,dc=fripost,dc=org"
credentials=mx
{% endif %}
#
#
########################################################################
########################################################################
# Access control
# /!\ WARN: All modification to the ACL should be reflected to the test
# /!\ suite as well!
#
# References:
# - http://www.openldap.org/doc/admin24/access-control.html
# - http://www.openldap.org/faq/data/cache/189.html
# - http://www.openldap.org/faq/data/cache/1140.html
# - http://www.openldap.org/faq/data/cache/1133.html
# - man 5 slapd.access
#
#
########################################################################
# Most common services: Postfix, Amavis, Dovecot
# (Most used ACLs are cheaper when written first.)
#
# Postfix have read access to the attribute it needs when eg, doing
# alias resolution.
olcAccess: to dn.children="ou=virtual,o=mailHosting,dc=fripost,dc=org"
- attrs=entry,objectClass,fvd,fvl,fripostMaildrop,fripostOptionalMaildrop,fripostLocalAlias
+ attrs=entry,objectClass,fvd,fvl,fripostMaildrop,fripostOptionalMaildrop
filter=(&(|(objectClass=FripostVirtualDomain)(objectClass=FripostVirtualUser)(objectClass=FripostVirtualAlias)(objectClass=FripostVirtualList)(objectClass=FripostVirtualListCommand))(!(objectClass=FripostPendingEntry))(!(fripostIsStatusActive=FALSE)))
by dn.exact="cn=MX-replicate,ou=services,o=mailHosting,dc=fripost,dc=org" =rsd
by realanonymous =rsd
by users =0 break
#
-# Postfix needs to look up lists' local aliases.
-olcAccess: to dn.exact="ou=virtual,o=mailHosting,dc=fripost,dc=org"
- attrs=entry
- by realanonymous =s
- by users =0 break
-#
# Search domain owners / postmasters (used by reserved-alias.pl).
olcAccess: to dn.children="ou=virtual,o=mailHosting,dc=fripost,dc=org"
attrs=entry,objectClass,fvd,fvl,fripostPostmaster,fripostOwner
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry))(!(fripostIsStatusActive=FALSE)))
by dn.exact="cn=MX-replicate,ou=services,o=mailHosting,dc=fripost,dc=org" =rsd
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" =rsd
by users =0 break
#
# The following is required for the content filter
{% if 'MDA' in group_names %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org$"
attrs=entry
filter=(&(objectClass=FripostVirtualDomain)(fripostIsStatusActive=TRUE))
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" =s
by users =0 break
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,@AmavisAccount
filter=(&(objectClass=FripostVirtualUser)(objectClass=AmavisAccount)(fripostIsStatusActive=TRUE))
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" =rsd
by users =0 break
@@ -445,46 +439,40 @@ olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripos
# 2. The domain owner can add/delete/change the ownership of the entry.
# 3. So can the domain postmasters.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualList)
attrs=fripostOwner
by dnattr=fripostOwner =rscd continue
by group/FripostVirtualDomain/fripostOwner.expand="$1" =wrscd
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" =wrscd
by * +0
#
# 1. The list owner read (but not edit) the transport-related attributes.
# 2. So can the domain ower.
# 3. So can the domain postmaster.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualList)
attrs=fripostListManager
by dnattr=fripostOwner =rscd
by group/FripostVirtualDomain/fripostOwner.expand="$1" =rscd
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" =rscd
#
-# Local aliases are for internal use only.
-olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org)$"
- filter=(objectClass=FripostVirtualList)
- attrs=fripostLocalAlias
- by * =0
-#
# 1. The list owners can edit their entry's attributes.
# 2. So can the domain owners.
# 3. So can the domain postmasters.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualList)
attrs=@FripostVirtualList
by dnattr=fripostOwner =wrscd
by group/FripostVirtualDomain/fripostOwner.expand="$1" =wrscd
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" =wrscd
#
# 1. The domain owner can create and delete lists, but only those with a 'pending' status
# 2. So can the domain postmaster.
# 3. The list owner can delete pending lists.
# 4. The entry creator can delete pending lists (needed to be able to rollback).
# 5. People with "canAddList" access can create lists, but only with a 'pending' status.
# 6. The list creation service can search and browse the entry.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,o=mailHosting,dc=fripost,dc=org)$"
filter=(&(objectClass=FripostVirtualList)(objectClass=FripostPendingEntry))
attrs=entry
by group/FripostVirtualDomain/fripostOwner.expand="$1" +w break