summaryrefslogtreecommitdiffstats
path: root/roles/common-LDAP/templates/etc/ldap
diff options
context:
space:
mode:
Diffstat (limited to 'roles/common-LDAP/templates/etc/ldap')
-rw-r--r--roles/common-LDAP/templates/etc/ldap/database.ldif.j2163
1 files changed, 114 insertions, 49 deletions
diff --git a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2 b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
index 8310818..a0ac705 100644
--- a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
+++ b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
@@ -1,157 +1,159 @@
# Fripost's LDAP database definition
# Copyright (c) 2013-2014 Guilhem Moulin <guilhem@fripost.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
dn: cn=config
objectClass: olcGlobal
cn: config
-olcArgsFile: /var/run/slapd/slapd.args
-olcPidFile: /var/run/slapd/slapd.pid
+olcArgsFile: /run/slapd/slapd.args
+olcPidFile: /run/slapd/slapd.pid
olcLogLevel: none
olcToolThreads: 1
{% if ansible_processor_vcpus > 4 %}
olcThreads: {{ 2 * ansible_processor_vcpus }}
{% else %}
olcThreads: 8
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcTLSCertificateFile: /etc/ldap/ssl/ldap.fripost.org.pem
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.fripost.org.key
# If we are being offered a client cert, it has to be trusted (in which
# case we map the X.509 subject to a DN in our namespace), or we
# terminate the connection. Not providing a certificate is fine for
# TLS-protected simple binds, though.
olcTLSVerifyClient: try
-olcTLSCACertificateFile: /etc/ldap/ssl/clients.pem
+olcTLSCACertificateFile: /etc/ldap/ssl/syncrepl.pem
olcAuthzRegexp: "^(cn=[^,]+,ou=syncRepl),ou=LDAP,ou=SSLcerts,o=Fripost$"
- "$1,dc=fripost,dc=org"
+ "dn.exact:$1,dc=fripost,dc=org"
olcSaslSecProps: minssf=128,noanonymous,noplain,nodict
olcTLSCipherSuite: PFS:%LATEST_RECORD_VERSION:!CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:!VERS-SSL3.0:!VERS-TLS1.0:!VERS-TLS1.1
+olcTLSDHParamFile: /etc/ssl/dhparams.pem
{% endif %}
olcLocalSSF: 128
# /!\ This is not portable! But we only use glibc's crypt(3), which
# supports (salted, streched) SHA512
olcPasswordHash: {CRYPT}
olcPasswordCryptSaltFormat: $6$%s
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMonitorConfig
olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
olcAccess: to dn.subtree="cn=monitor"
by dn.exact="username=munin,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" read
by * =0
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=fripost,dc=org
-{% if 'LDAP-provider' not in group_names and 'MX' in group_names %}
+{% if 'LDAP_provider' not in group_names and 'MX' in group_names %}
olcReadOnly: TRUE
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcLastMod: TRUE
olcDbCheckpoint: 512 15
{% else %}
olcLastMod: FALSE
{% endif %}
# The root user has all rights on the whole database (when SASL-binding
# on a UNIX socket).
olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
# Ensure that all DIT access is made according to the LDAPv3 protocol,
# and must use 1/ authentication, and 2/ SASL or TLS. (Local clients
# should use ldapi:// and SASL/EXERNAL, while remote clients should use
# TLS.)
olcRequires: none LDAPv3 authc strong
olcSecurity: simple_bind=128 ssf=128 update_ssf=128
#
#
########################################################################
# Performance considerations
#
# To reindex an existing database, you have to
# * Stop slapd sudo service slapd stop
# * Reindex sudo -u openldap slapindex -b 'dc=fripost,dc=org'
# * Restart slapd sudo service slapd start
#
olcDbIndex: objectClass eq
# Let us make Postfix's life easier.
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcDbIndex: fvd,fvl eq,sub
olcDbIndex: fripostIsStatusActive eq
{% elif 'MX' in group_names or 'MDA' in group_names %}
olcDbIndex: fripostIsStatusActive,fvd,fvl eq
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcDbIndex: fripostOptionalMaildrop,fripostMaildrop eq,sub
olcDbIndex: fripostCanAddDomain,fripostCanAddAlias,fripostCanAddList,fripostOwner,fripostPostmaster,fripostListManager eq
{% elif 'MX' in group_names %}
olcDbIndex: fripostOptionalMaildrop pres
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
+olcDbIndex: member,cn eq
{% endif %}
-{% if ('LDAP-provider' not in group_names and 'MX' in group_names) or
- ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if ('LDAP_provider' not in group_names and 'MX' in group_names) or
+ ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
# SyncProv/SyncRepl specific indexing.
olcDbIndex: entryCSN,entryUUID eq
{% endif%}
#
#
# 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
#
#
########################################################################
# Sync Replication
#
# 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 %}
+{% if 'LDAP_provider' in group_names %}
olcLimits: dn.onelevel="ou=syncRepl,dc=fripost,dc=org"
time.soft=unlimited
time.hard=unlimited
size.soft=unlimited
size.hard=unlimited
{% endif %}
-{% if 'MX' in group_names and 'LDAP-provider' not in group_names %}
+{% if 'MX' in group_names and 'LDAP_provider' not in group_names %}
# Test it:
# LDAPSASL_MECH=external LDAPTLS_CACERT=/etc/ldap/ssl/ldap.fripost.org.pem LDAPTLS_CERT=/etc/ldap/ssl/mx.pem LDAPTLS_KEY=/etc/ldap/ssl/mx.key sudo -u openldap ldapwhoami -H ldaps://ldap.fripost.org/
# LDAPSASL_MECH=external LDAPTLS_CACERT=/etc/ldap/ssl/ldap.fripost.org.pem LDAPTLS_CERT=/etc/ldap/ssl/mx.pem LDAPTLS_KEY=/etc/ldap/ssl/mx.key sudo -u openldap ldapsearch -H ldaps://ldap.fripost.org/ -b ou=virtual,dc=fripost,dc=org
olcSyncrepl: rid=000
provider=ldaps://ldap.fripost.org
type=refreshAndPersist
retry="10 30 300 +"
searchbase="ou=virtual,dc=fripost,dc=org"
attrs=objectClass,fvd,fvl,fripostIsStatusActive,fripostMaildrop,fripostOptionalMaildrop,fripostPostmaster,fripostOwner,fripostUseContentFilter,fripostListManager
scope=sub
sizelimit=unlimited
schemachecking=off
bindmethod=sasl
saslmech=external
tls_cert=/etc/ldap/ssl/mx.pem
tls_key=/etc/ldap/ssl/mx.key
tls_cacert=/etc/ldap/ssl/ldap.fripost.org.pem
tls_reqcert=hard
{% endif %}
#
@@ -196,300 +198,363 @@ olcAddContentAcl: TRUE
# local ldapi:// socket (when using auth_binds, Dovecot delegates
# authentication to the LDAP server).
# * Authenticated users are allowed to change (ie replace) their
# password through TLS-protected connections, but read access is not
# granted.
# * Domain postmasters are allowed to change (ie replace) their users'
# password through TLS-protected connections, but read access is not
# granted.
# * The same goes for general admins.
# * The same goes for local admins.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualUser)
attrs=userPassword
by realanonymous tls_ssf=128 =xd
by realanonymous sockurl.regex="^ldapi://" =xd
by realself tls_ssf=128 =w
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" tls_ssf=128 =w
by dn.onelevel="ou=admins,dc=fripost,dc=org" tls_ssf=128 =w
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =w
#
-# TODO: are there other services which need to be able to simple bind?
+# * Services can authenticate
+{% if 'LDAP_provider' in group_names -%}
+olcAccess: to dn.onelevel="ou=services,dc=fripost,dc=org"
+ filter=(objectClass=simpleSecurityObject)
+ attrs=userPassword
+ by realanonymous tls_ssf=128 =xd
+{% endif -%}
#
# * Catch-all: no one else may access the passwords (including for
# simple bind).
olcAccess: to dn.subtree="dc=fripost,dc=org"
attrs=userPassword
by * =0
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Base
#
# * Only SyncRepl replicates may access operational attributes in the
# subtree, when using a TLS-protected connection.
-{% if 'LDAP-provider' in group_names -%}
+{% if 'LDAP_provider' in group_names -%}
olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
- attrs=entryDN,entryCSN,entryUUID,structuralObjectClass,hasSubordinates,subschemaSubentry
+ attrs=entryCSN,structuralObjectClass,hasSubordinates,subschemaSubentry
by dn.onelevel="ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
by * =0
#
# * They may also read entries (ie, the attributes they have access to
# as per the ACL below) in that subtree, when using a TLS-protected
# connection. Listing entries (their DN) is required to replicate
# deletions properly.
olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass
by dn.onelevel="ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
olcAccess: to dn.children="ou=virtual,dc=fripost,dc=org"
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
{% endif -%}
#
# * Postfix may use the base as a searchBase on the MX:es, when
# connecting a local ldapi:// socket from the 'private' directory in
# one of the non-default instance's chroot.
-# * So may Dovecot on the MDA (needed for the iterate filter), when
-# SASL-binding using the EXTERNAL mechanism and connecting to a local
-# ldapi:// socket.
+# * So may _dovecot-auth-proxy on the MDA (needed for the iterate
+# logic), when SASL-binding using the EXTERNAL mechanism and
+# connecting to a local ldapi:// socket.
+# * So may Nextcloud on the LDAP provider
olcAccess: to dn.exact="ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass
filter=(objectClass=FripostVirtual)
{% if 'MDA' in group_names -%}
- by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
+ by dn.exact="username=_dovecot-auth-proxy,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =sd
{% endif -%}
+ {% if 'MSA' in group_names -%}
+ by dn.exact="username=_postfix-sender-login,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
+ {% endif -%}
+ {% if 'LDAP_provider' in group_names -%}
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =sd
+ {% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Domain entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
-# * So has Dovecot on the MDA (for the iterate filter), when
-# SASL-binding using the EXTERNAL mechanism and connecting to a local
-# ldapi:// socket.
-# * Amavis may use the entry as searchBase (required to look for the
-# per-user preferences) but doesn't have read access to the entry.
# * The 'nobody' UNIX user has read access on the MX:es, when using
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket. This is required for the 'reserved-alias.pl'
# script.
+# * Amavis may use the entry as searchBase (required to look for the
+# per-user preferences) but doesn't have read access to the entry.
+# * So has _dovecot-auth-proxy on the MDA (for the iterate logic), when
+# SASL-binding using the EXTERNAL mechanism and connecting to a local
+# ldapi:// socket.
+# * So has _postfix-sender-login on the submission service to verify
+# envelope sender ownership
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvd
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names -%}
- {% if groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
- {% endif -%}
+ {% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ {% endif -%}
{% if 'MDA' in group_names -%}
- by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
- {% if 'MX' in group_names -%}
- by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ {% if 'IMAP' in group_names -%}
+ by dn.exact="username=_dovecot-auth-proxy,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ {% endif -%}
+ {% if 'MSA' in group_names -%}
+ by dn.exact="username=_postfix-sender-login,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual domain is
# active, and read the destination address for catch-alls, when using
# a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostOptionalMaildrop
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# * The 'nobody' UNIX user can list the domain owners and postmasters on
# the MX:es, when SASL-binding using the EXTERNAL mechanism and
# connecting to a local ldapi:// socket. This is required for the
# 'reserved-alias.pl' script.
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostOwner,fripostPostmaster
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names %}
by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias domain entries
#
# * The SyncRepl MX replicates have read access to the entry itself and
# the destination domain it aliases to, when using a TLS-protected
# connection.
# * So has Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,fripostMaildrop
filter=(&(objectClass=FripostVirtualAliasDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# User entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
-# * So has Dovecot on the MDA (for the iterate filter), when
+# * So has _dovecot-auth-proxy on the MDA (for the iterate logic), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * So has Amavis on the MDA, when SASL-binding using the EXTERNAL
# mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl
filter=(objectClass=FripostVirtualUser)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
+ {% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ {% endif -%}
{% if 'MDA' in group_names -%}
- by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
+ {% if 'IMAP' in group_names -%}
+ by dn.exact="username=_dovecot-auth-proxy,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ {% endif -%}
+ {% if 'MSA' in group_names -%}
+ by dn.exact="username=_postfix-sender-login,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ {% endif -%}
by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual user is
# active, when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostUseContentFilter
filter=(objectClass=FripostVirtualUser)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
{% if 'MDA' in group_names %}
#
# * Amavis can look for per-user configuration options, when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# TODO: only allow it to read the configuration options users are allowed
# to set and modify.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=@AmavisAccount
filter=(&(objectClass=FripostVirtualUser)(objectClass=AmavisAccount)(fripostIsStatusActive=TRUE)(fripostUseContentFilter=TRUE))
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
#
# * Dovecot can look for user quotas, when SASL-binding using the
# EXTERNAL mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostUserQuota
filter=(objectClass=FripostVirtualUser)
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias entries
#
# * The SyncRepl MX replicates can read the entry itelf, whether it
# is active, and the address(es) it aliases to, when using a
# TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostMaildrop,fripostIsStatusActive
filter=(objectClass=FripostVirtualAlias)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# List entries
#
# * The SyncRepl replicates can read the entry itelf and the list manager, when
# using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostListManager
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# * The SyncRepl MX replicates can check whether a virtual list is
# active when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+#
+# * The MSA's _postfix-sender-login user can read entry ownership to
+# dermine the SASL login name(s) owning a given sender address
+{% if 'MSA' in group_names %}
+olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
+ attrs=fripostOwner,fripostPostmaster
+ filter=(|(objectClass=FripostVirtualAliasDomain)(objectClass=FripostVirtualDomain))
+ by dn.exact="username=_postfix-sender-login,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ by users =0 break
+olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
+ attrs=entry,objectClass,fvl,fripostOwner
+ filter=(|(objectClass=FripostVirtualAlias)(objectClass=FripostVirtualList)(objectClass=FripostVirtualUser))
+ by dn.exact="username=_postfix-sender-login,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ by users =0 break
+{% endif %}
+{% if 'LDAP_provider' in group_names %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+#
+# Export Fripost members to Nextcloud
+olcAccess: to dn.exact="fvd=fripost.org,ou=virtual,dc=fripost,dc=org"
+ attrs=entry,objectClass,fvd
+ filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by users =0 break
+olcAccess: to dn.regex="^fvl=[^,]+,fvd=fripost.org,ou=virtual,dc=fripost,dc=org$"
+ attrs=entry,entryDN,entryUUID,objectClass,fvl,fripostIsStatusActive
+ filter=(&(objectClass=FripostVirtualUser)(!(objectClass=FripostPendingEntry))(fripostIsStatusActive=TRUE))
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by users =0 break
+olcAccess: to dn.exact="ou=groups,dc=fripost,dc=org"
+ attrs=entry,objectClass
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by users =0 break
+olcAccess: to dn.exact="cn=medlemmar,ou=groups,dc=fripost,dc=org"
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by users =0 break
+olcAccess: to dn.exact="cn=styrelse,ou=groups,dc=fripost,dc=org"
+ by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by users =0 break
+#
# TODO: allow users to edit their entry, etc
#
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Catch-all
#
# * Catch all the breaks above.
# * Deny any access to everyone else.
olcAccess: to dn.subtree="dc=fripost,dc=org"
by dn.children="ou=virtual,dc=fripost,dc=org" +0
by * =0
# vim: set filetype=ldif :