feat: Support ENV override on individual Postfix LDAP config files

Previously only `query_filter` had this support via an inconsistent `_${QUERY_KIND}` ENV suffix.

This has been shifted to the left under the new `POSTFIX_` prefix, so that it can easily leverage the ENV prefix with config templates, layering after the generic `POSTFIX_` template. Naming is now consistent with `${QUERY_KIND}` (upper-cased). This also enables using the common `LDAP_` prefix in the Postfix `.base` template.

As a part of the previous commit toggling based on presence of `query_filter`, this is now dropped from the Postfix `.base` template.
This commit is contained in:
polarathene 2023-10-05 12:31:59 +13:00
parent 8fe744ffd1
commit 1ec1853528
3 changed files with 20 additions and 41 deletions

View File

@ -1,4 +1,7 @@
bind_dn = ${BIND_DN}
bind_pw = ${BIND_PW}
server_host = ${SERVER_HOST}
search_base = ${SEARCH_BASE}
bind = yes bind = yes
query_filter = (&(mail=%s)(mailEnabled=TRUE))
result_attribute = mail result_attribute = mail
version = 3 version = 3

View File

@ -14,29 +14,6 @@ function _setup_ldap() {
# Generate Postfix LDAP configs: # Generate Postfix LDAP configs:
mkdir -p /etc/postfix/ldap mkdir -p /etc/postfix/ldap
for QUERY_KIND in 'users' 'groups' 'aliases' 'domains' 'senders'; do for QUERY_KIND in 'users' 'groups' 'aliases' 'domains' 'senders'; do
# NOTE: Presently, only `query_filter` is supported for individually targeting:
case "${QUERY_KIND}" in
( 'users' )
export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_USER}"
;;
( 'groups' )
export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_GROUP}"
;;
( 'aliases' )
export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_ALIAS}"
;;
( 'domains' )
export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_DOMAIN}"
;;
( 'senders' )
export LDAP_QUERY_FILTER="${LDAP_QUERY_FILTER_SENDERS}"
;;
esac
_create_config_postfix "${QUERY_KIND}" _create_config_postfix "${QUERY_KIND}"
done done
@ -67,15 +44,15 @@ function _create_config_dovecot() {
) > /etc/dovecot/dovecot-ldap.conf.ext ) > /etc/dovecot/dovecot-ldap.conf.ext
} }
# NOTE: Only relies on the `LDAP_` prefix, presently assigned a `POSTFIX_` prefix.
function _create_config_postfix() { function _create_config_postfix() {
local QUERY_KIND=${1} local QUERY_KIND=${1}
local LDAP_CONFIG_FILE="/etc/postfix/ldap/${QUERY_KIND}.cf" local LDAP_CONFIG_FILE="/etc/postfix/ldap/${QUERY_KIND}.cf"
_cleanse_config '=' <(cat 2>/dev/null \ _cleanse_config '=' <(cat 2>/dev/null \
/etc/dms/ldap/postfix.base \ <(_template_with_env 'LDAP_' /etc/dms/ldap/postfix.base) \
"/tmp/docker-mailserver/ldap-${QUERY_KIND}.cf" \ "/tmp/docker-mailserver/ldap-${QUERY_KIND}.cf" \
<(_template_with_env 'LDAP_' /etc/dms/ldap/postfix.tmpl) \ <(_template_with_env 'POSTFIX_' /etc/dms/ldap/postfix.tmpl) \
<(_template_with_env "POSTFIX_${QUERY_KIND^^}_" /etc/dms/ldap/postfix.tmpl) \
) > "${LDAP_CONFIG_FILE}" ) > "${LDAP_CONFIG_FILE}"
# Opt-out of generated config if `query_filter` was not configured: # Opt-out of generated config if `query_filter` was not configured:

View File

@ -39,25 +39,24 @@ function setup_file() {
# #
# LDAP filter queries explained. # LDAP filter queries explained.
# NOTE: All LDAP configs for Postfix (with the exception of `ldap/senders.cf`), return the `mail` attribute value of matched results. # NOTE: All LDAP configs use `result_attribute = mail` for Postfix to return the `mail` attribute value from query matched results.
# This is through the config key `result_attribute`, which the ENV substitution feature can only replace across all configs, not selectively like `query_filter`.
# NOTE: The queries below rely specifically upon attributes and classes defined by the schema `postfix-book.ldif`. These are not compatible with all LDAP setups. # NOTE: The queries below rely specifically upon attributes and classes defined by the schema `postfix-book.ldif`. These are not compatible with all LDAP setups.
# `mailAlias`` is supported by both classes provided from the schema `postfix-book.ldif`, but `mailEnabled` is only available to `PostfixBookMailAccount` class: # `mailAlias` is supported by both classes provided from the schema `postfix-book.ldif`, but `mailEnabled` is only available to `PostfixBookMailAccount` class:
local QUERY_ALIAS='(&(mailAlias=%s) (| (objectClass=PostfixBookMailForward) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ))' local QUERY_ALIASES='(&(mailAlias=%s) (| (objectClass=PostfixBookMailForward) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ))'
# Postfix does domain lookups with the domain of the recipient to check if DMS manages the mail domain. # Postfix does domain lookups with the domain of the recipient to check if DMS manages the mail domain.
# For this lookup `%s` only represents the domain, not a full email address. Hence the match pattern using a wildcard prefix `*@`. # For this lookup `%s` only represents the domain, not a full email address. Hence the match pattern using a wildcard prefix `*@`.
# For a breakdown, see QUERY_SENDERS comment. # For a breakdown, see the `QUERY_SENDERS` comment.
# NOTE: Although `result_attribute = mail` will return each accounts full email address, Postfix will only compare to domain-part. # NOTE: Although `result_attribute = mail` will return each accounts full email address, Postfix will only compare to domain-part.
local QUERY_DOMAIN='(| (& (|(mail=*@%s) (mailAlias=*@%s) (mailGroupMember=*@%s)) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ) (&(mailAlias=*@%s)(objectClass=PostfixBookMailForward)) )' local QUERY_DOMAINS='(| (& (|(mail=*@%s) (mailAlias=*@%s) (mailGroupMember=*@%s)) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ) (&(mailAlias=*@%s)(objectClass=PostfixBookMailForward)) )'
# Simple queries for a single attribute that additionally requires `mailEnabled=TRUE` from the `PostfixBookMailAccount` class: # Simple queries for a single attribute that additionally requires `mailEnabled=TRUE` from the `PostfixBookMailAccount` class:
# NOTE: `mail` attribute is not unique to `PostfixBookMailAccount`. The `mailEnabled` attribute is to further control valid mail accounts. # NOTE: `mail` attribute is not unique to `PostfixBookMailAccount`. The `mailEnabled` attribute is to further control valid mail accounts.
# TODO: For tests, since `mailEnabled` is not relevant (always configured as TRUE currently), # TODO: For tests, since `mailEnabled` is not relevant (always configured as TRUE currently),
# a simpler query like `mail=%s` or `mailGroupMember=%s` would be sufficient. The additional constraints could be covered in our docs instead. # a simpler query like `mail=%s` or `mailGroupMember=%s` would be sufficient. The additional constraints could be covered in our docs instead.
local QUERY_GROUP='(&(mailGroupMember=%s) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) )' local QUERY_GROUPS='(&(mailGroupMember=%s) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) )'
local QUERY_USER='(&(mail=%s) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) )' local QUERY_USERS='(&(mail=%s) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) )'
# Given the sender address `%s` from Postfix, query LDAP for accounts that meet the search filter, # Given the sender address `%s` from Postfix, query LDAP for accounts that meet the search filter,
# the `result_attribute` is `mail` + `uid` (`userID`) attributes for login names that are authorized to use that sender address. # the `result_attribute` is `mail` + `uid` (`userID`) attributes for login names that are authorized to use that sender address.
@ -93,7 +92,7 @@ function setup_file() {
--env ACCOUNT_PROVISIONER=LDAP --env ACCOUNT_PROVISIONER=LDAP
# Common LDAP ENV: # Common LDAP ENV:
# NOTE: `scripts/startup/setup.d/ldap.sh:_setup_ldap()` uses `_replace_by_env_in_file()` to configure settings (stripping `DOVECOT_` / `LDAP_` prefixes): # NOTE: `scripts/startup/setup.d/ldap.sh:_setup_ldap()` uses helper methods to generate / override LDAP configs (grouped by common ENV prefixes):
--env LDAP_SERVER_HOST="ldap://${FQDN_LDAP}" --env LDAP_SERVER_HOST="ldap://${FQDN_LDAP}"
--env LDAP_SEARCH_BASE='ou=users,dc=example,dc=test' --env LDAP_SEARCH_BASE='ou=users,dc=example,dc=test'
--env LDAP_START_TLS=no --env LDAP_START_TLS=no
@ -113,11 +112,11 @@ function setup_file() {
--env DOVECOT_TLS=no --env DOVECOT_TLS=no
# Postfix: # Postfix:
--env LDAP_QUERY_FILTER_ALIAS="${QUERY_ALIAS}" --env POSTFIX_ALIASES_QUERY_FILTER="${QUERY_ALIASES}"
--env LDAP_QUERY_FILTER_DOMAIN="${QUERY_DOMAIN}" --env POSTFIX_DOMAINS_QUERY_FILTER="${QUERY_DOMAINS}"
--env LDAP_QUERY_FILTER_GROUP="${QUERY_GROUP}" --env POSTFIX_GROUPS_QUERY_FILTER="${QUERY_GROUPS}"
--env LDAP_QUERY_FILTER_SENDERS="${QUERY_SENDERS}" --env POSTFIX_SENDERS_QUERY_FILTER="${QUERY_SENDERS}"
--env LDAP_QUERY_FILTER_USER="${QUERY_USER}" --env POSTFIX_USERS_QUERY_FILTER="${QUERY_USERS}"
) )
# Extra ENV needed to support specific test-cases: # Extra ENV needed to support specific test-cases: