Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ target/postsrsd/** text
*.local text
### Postfix
*.pcre text
### Config Templates feature
*.base text
*.tmpl text

#################################################
### Tests #####################################
Expand Down
10 changes: 2 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,8 @@ COPY target/rspamd/local.d/ /etc/rspamd/local.d/
# --- LDAP & SpamAssassin's Cron ----------------
# -----------------------------------------------

COPY target/dovecot/dovecot-ldap.conf.ext /etc/dovecot
COPY \
target/postfix/ldap-users.cf \
target/postfix/ldap-groups.cf \
target/postfix/ldap-aliases.cf \
target/postfix/ldap-domains.cf \
target/postfix/ldap-senders.cf \
/etc/postfix/
# LDAP config template support:
COPY --link target/features/ldap/ /etc/dms/ldap/

# hadolint ignore=SC2016
RUN <<EOF
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
base = ou=people,dc=example,dc=com
dn = ${BIND_DN}
dnpass = ${BIND_PW}
uris = ${SERVER_HOST}
base = ${SEARCH_BASE}
default_pass_scheme = SSHA
dn = cn=admin,dc=example,dc=com
dnpass = admin
uris = ldap://mail.example.com
tls = no
ldap_version = 3
pass_attrs = uniqueIdentifier=user,userPassword=password
pass_filter = (&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
user_attrs = mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail
user_filter = (&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
auth_bind = no
32 changes: 32 additions & 0 deletions target/features/ldap/dovecot.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Dovecot LDAP config docs: https://github.com/dovecot/core/blob/bbb600e46ca650a3a5ef812ea3a1e8c45a6ea0ba/doc/example-config/dovecot-ldap.conf.ext
hosts = ${HOSTS}
uris = ${URIS}
dn = ${DN}
dnpass = ${DNPASS}
sasl_bind = ${SASL_BIND}
sasl_mech = ${SASL_MECH}
sasl_realm = ${SASL_REALM}
sasl_authz_id = ${SASL_AUTHZ_ID}
tls = ${TLS}
tls_ca_cert_file = ${TLS_CA_CERT_FILE}
tls_ca_cert_dir = ${TLS_CA_CERT_DIR}
tls_cipher_suite = ${TLS_CIPHER_SUITE}
tls_cert_file = ${TLS_CERT_FILE}
tls_key_file = ${TLS_KEY_FILE}
tls_require_cert = ${TLS_REQUIRE_CERT}
ldaprc_path = ${LDAPRC_PATH}
debug_level = ${DEBUG_LEVEL}
auth_bind = ${AUTH_BIND}
auth_bind_userdn = ${AUTH_BIND_USERDN}
ldap_version = ${LDAP_VERSION}
base = ${BASE}
deref = ${DEREF}
scope = ${SCOPE}
user_attrs = ${USER_ATTRS}
user_filter = ${USER_FILTER}
pass_attrs = ${PASS_ATTRS}
pass_filter = ${PASS_FILTER}
iterate_attrs = ${ITERATE_ATTRS}
iterate_filter = ${ITERATE_FILTER}
default_pass_scheme = ${DEFAULT_PASS_SCHEME}
blocking = ${BLOCKING}
7 changes: 7 additions & 0 deletions target/features/ldap/postfix.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bind_dn = ${BIND_DN}
bind_pw = ${BIND_PW}
server_host = ${SERVER_HOST}
search_base = ${SEARCH_BASE}
bind = yes
result_attribute = mail
version = 3
35 changes: 35 additions & 0 deletions target/features/ldap/postfix.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Postfix LDAP table docs: http://www.postfix.org/ldap_table.5.html
server_host = ${SERVER_HOST}
server_port = ${SERVER_PORT}
timeout = ${TIMEOUT}
search_base = ${SEARCH_BASE}
query_filter = ${QUERY_FILTER}
result_format = ${RESULT_FORMAT}
domain = ${DOMAIN}
result_attribute = ${RESULT_ATTRIBUTE}
special_result_attribute = ${SPECIAL_RESULT_ATTRIBUTE}
terminal_result_attribute = ${TERMINAL_RESULT_ATTRIBUTE}
leaf_result_attribute = ${LEAF_RESULT_ATTRIBUTE}
scope = ${SCOPE}
bind = ${BIND}
bind_dn = ${BIND_DN}
bind_pw = ${BIND_PW}
recursion_limit = ${RECURSION_LIMIT}
expansion_limit = ${EXPANSION_LIMIT}
size_limit = ${SIZE_LIMIT}
dereference = ${DEREFERENCE}
chase_referrals = ${CHASE_REFERRALS}
version = ${VERSION}
debuglevel = ${DEBUGLEVEL}
sasl_mechs = ${SASL_MECHS}
sasl_realm = ${SASL_REALM}
sasl_authz_id = ${SASL_AUTHZ_ID}
sasl_minssf = ${SASL_MINSSF}
start_tls = ${START_TLS}
tls_ca_cert_dir = ${TLS_CA_CERT_DIR}
tls_ca_cert_file = ${TLS_CA_CERT_FILE}
tls_cert = ${TLS_CERT}
tls_key = ${TLS_KEY}
tls_require_cert = ${TLS_REQUIRE_CERT}
tls_random_file = ${TLS_RANDOM_FILE}
tls_cipher_suite = ${TLS_CIPHER_SUITE}
6 changes: 6 additions & 0 deletions target/features/ldap/saslauthd.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ldap_bind_dn: ${BIND_DN}
ldap_bind_pw: ${BIND_PW}
ldap_servers: ${SERVER_HOST}
ldap_search_base: ${SEARCH_BASE}
ldap_filter: (&(uniqueIdentifier=%u)(mailEnabled=TRUE))
ldap_referrals: yes
36 changes: 36 additions & 0 deletions target/features/ldap/saslauthd.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Parameter docs: https://github.com/cyrusimap/cyrus-sasl/blob/3959d45aa187d906d5fb3e8edf7e3661780967a5/saslauthd/LDAP_SASLAUTHD#L85-L242
ldap_auth_method: ${LDAP_AUTH_METHOD}
ldap_bind_dn: ${LDAP_BIND_DN}
ldap_bind_pw: ${LDAP_BIND_PW}
ldap_default_domain: ${LDAP_DEFAULT_DOMAIN}
ldap_default_realm: ${LDAP_DEFAULT_REALM}
ldap_deref: ${LDAP_DEREF}
ldap_filter: ${LDAP_FILTER}
ldap_group_attr: ${LDAP_GROUP_ATTR}
ldap_group_dn: ${LDAP_GROUP_DN}
ldap_group_filter: ${LDAP_GROUP_FILTER}
ldap_group_match_method: ${LDAP_GROUP_MATCH_METHOD}
ldap_group_search_base: ${LDAP_GROUP_SEARCH_BASE}
ldap_group_scope: ${LDAP_GROUP_SCOPE}
ldap_password: ${LDAP_PASSWORD}
ldap_password_attr: ${LDAP_PASSWORD_ATTR}
ldap_referrals: ${LDAP_REFERRALS}
ldap_restart: ${LDAP_RESTART}
ldap_id: ${LDAP_ID}
ldap_authz_id: ${LDAP_AUTHZ_ID}
ldap_mech: ${LDAP_MECH}
ldap_realm: ${LDAP_REALM}
ldap_scope: ${LDAP_SCOPE}
ldap_search_base: ${LDAP_SEARCH_BASE}
ldap_servers: ${LDAP_SERVERS}
ldap_start_tls: ${LDAP_START_TLS}
ldap_time_limit: ${LDAP_TIME_LIMIT}
ldap_timeout: ${LDAP_TIMEOUT}
ldap_tls_check_peer: ${LDAP_TLS_CHECK_PEER}
ldap_tls_cacert_file: ${LDAP_TLS_CACERT_FILE}
ldap_tls_cacert_dir: ${LDAP_TLS_CACERT_DIR}
ldap_tls_ciphers: ${LDAP_TLS_CIPHERS}
ldap_tls_cert: ${LDAP_TLS_CERT}
ldap_tls_key: ${LDAP_TLS_KEY}
ldap_use_sasl: ${LDAP_USE_SASL}
ldap_version: ${LDAP_VERSION}
9 changes: 0 additions & 9 deletions target/postfix/ldap-aliases.cf

This file was deleted.

9 changes: 0 additions & 9 deletions target/postfix/ldap-domains.cf

This file was deleted.

9 changes: 0 additions & 9 deletions target/postfix/ldap-groups.cf

This file was deleted.

9 changes: 0 additions & 9 deletions target/postfix/ldap-senders.cf

This file was deleted.

9 changes: 0 additions & 9 deletions target/postfix/ldap-users.cf

This file was deleted.

12 changes: 12 additions & 0 deletions target/scripts/build/packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ function _install_packages() {
"${DEBUG_PACKAGES[@]}"
}

function _install_feature_config_templates() {
_log 'debug' 'Installing support for feature - Config Templates'

# envsubst:
apt-get "${QUIET}" --no-install-recommends install gettext-base

# zenv:
# Download from GH releases to stdout, then extract the zenv file to make available via PATH:
curl -L "https://github.com/numToStr/zenv/releases/download/0.8.0/zenv-0.8.0-$(uname --machine)-unknown-linux-gnu.tar.gz" -o - | tar --gzip --extract --directory /usr/local/bin --file - zenv
}

function _install_dovecot() {
declare -a DOVECOT_PACKAGES

Expand Down Expand Up @@ -219,5 +230,6 @@ _install_rspamd
_install_fail2ban
_install_getmail
_install_utils
_install_feature_config_templates
_remove_data_after_package_installations
_post_installation_steps
2 changes: 1 addition & 1 deletion target/scripts/helpers/postfix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function _vhost_collect_postfix_domains() {
# NOTE: `setup-stack.sh:_setup_ldap` has related logic:
# - `main.cf:mydestination` setting removes `$mydestination` as an LDAP bugfix.
# - `main.cf:virtual_mailbox_domains` uses `/etc/postfix/vhost`, but may
# conditionally include a 2nd table (ldap:/etc/postfix/ldap-domains.cf).
# conditionally include a 2nd table (ldap:/etc/postfix/ldap/domains.cf).
function _vhost_ldap_support() {
[[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]] && echo "${DOMAINNAME}" >>"${TMP_VHOST}"
}
Expand Down
38 changes: 38 additions & 0 deletions target/scripts/helpers/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,41 @@ function _env_var_expect_integer() {
_log 'warn' "The value of '${ENV_VAR_NAME}' is not an integer ('${!ENV_VAR_NAME}'), but was expected to be"
return 1
}

# Replace `${VAR}` variables of the input file with their equivalent ENV values (excluding the common prefix)
#
# @param ${1} = Use a prefix for a group of environment variables
# @param ${2} = Filepath to ENV template
# @output = Template file content populated with available ENV
function _template_with_env() {
local ENV_PREFIX=${1:?ENV prefix is required}
local ENV_TEMPLATE=${2:?ENV template filepath is required}

if [[ ! -f ${ENV_TEMPLATE} ]]; then
_dms_panic__invalid_value "file '${ENV_TEMPLATE}' does not exist" 'utils.sh:_use_env_template'
fi

# Ensures that zenv only runs envsubst with ENV filtered from the provided prefix.
# Those ENV are loaded by zenv in the format of an `.env` file (with prefix dropped by sed)
# When an ENV is not available, envsubst will evaluate it as empty.
#
# NOTE: $PATH is retained to avoid needing absolute paths for binaries.
env --ignore-environment PATH="${PATH}" \
zenv --file <(env | grep "^${ENV_PREFIX}" | sed "s/^${ENV_PREFIX}//") \
envsubst < "${ENV_TEMPLATE}"
Comment thread
polarathene marked this conversation as resolved.
}

# Utility to cleanup a config file that may have unset or duplicate keys.
# - sed => Removes lines where keys have no value assigned.
# - tac + sort => Remove any duplicate keys (keeps the last instance found).
#
# @param ${1} = A delimiter between key and value columns
# @param ${2} = Input filepath to clean
# @output = The transformed file content
function _cleanse_config() {
local KV_DELIMITER=${1:?KV Delimiter is required}
Comment thread
georglauterbach marked this conversation as resolved.
local INPUT_FILE=${2?:Input file is required}

sed "/^[^${KV_DELIMITER}]*${KV_DELIMITER}\s*$/d" "${INPUT_FILE}" \
| tac | sort -u -t"${KV_DELIMITER}" -k1,1
}
Loading