diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2013-12-18 14:34:10 +0100 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2015-06-07 02:51:31 +0200 |
commit | e98d17cca0011ead0bb89c7674a2209760dce59f (patch) | |
tree | 77be1b1e3ab980906e2d29ad0b665488edfea49c /roles | |
parent | b51df24e3b1b64c17a3aac652b142e2082c77a26 (diff) |
Remove the 'fripostLocalAlias' attribute.
Instead, we pretend that lists are valid users (via a match in the
mailbox_transport_maps) but choose a different transport (with the same
request in transport_maps).
The advantage is that we get rid of the ugly hack for list transport…
A minor drawback is that we now have two LDAP lookups instead of one for
non local addresses (ie, everything but reserved addresses). Hopefully
the requests are cached; but even if they aren't, querying a local LDAP
server is supposed to be cheap.
Diffstat (limited to 'roles')
-rw-r--r-- | roles/MX/files/etc/postfix/virtual/lists_maps.cf | 7 | ||||
-rw-r--r-- | roles/MX/files/etc/postfix/virtual/transport_lists_maps.cf | 14 | ||||
-rw-r--r-- | roles/MX/tasks/main.yml | 3 | ||||
-rw-r--r-- | roles/MX/templates/etc/postfix/main.cf.j2 | 9 | ||||
-rw-r--r-- | roles/common-LDAP/files/etc/ldap/schema/fripost.ldif | 41 | ||||
-rw-r--r-- | roles/common-LDAP/templates/etc/ldap/database.ldif.j2 | 18 |
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 |