mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2025-07-02 21:44:51 +02:00
change if style (#3361)
This commit is contained in:
parent
0e592aa911
commit
cf74127f78
58 changed files with 297 additions and 594 deletions
|
@ -19,8 +19,7 @@ function _create_accounts
|
|||
local DATABASE_ACCOUNTS='/tmp/docker-mailserver/postfix-accounts.cf'
|
||||
_create_masters
|
||||
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]; then
|
||||
_log 'trace' "Checking file line endings"
|
||||
sed -i 's|\r||g' "${DATABASE_ACCOUNTS}"
|
||||
|
||||
|
@ -47,19 +46,16 @@ function _create_accounts
|
|||
DOMAIN=$(echo "${LOGIN}" | cut -d @ -f2)
|
||||
|
||||
# test if user has a defined quota
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]; then
|
||||
declare -a USER_QUOTA
|
||||
IFS=':' read -r -a USER_QUOTA < <(grep "${USER}@${DOMAIN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf)
|
||||
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]
|
||||
then
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]; then
|
||||
USER_ATTRIBUTES="${USER_ATTRIBUTES:+${USER_ATTRIBUTES} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z ${USER_ATTRIBUTES} ]]
|
||||
then
|
||||
if [[ -z ${USER_ATTRIBUTES} ]]; then
|
||||
_log 'debug' "Creating user '${USER}' for domain '${DOMAIN}'"
|
||||
else
|
||||
_log 'debug' "Creating user '${USER}' for domain '${DOMAIN}' with attributes '${USER_ATTRIBUTES}'"
|
||||
|
@ -68,8 +64,7 @@ function _create_accounts
|
|||
local POSTFIX_VMAILBOX_LINE DOVECOT_USERDB_LINE
|
||||
|
||||
POSTFIX_VMAILBOX_LINE="${LOGIN} ${DOMAIN}/${USER}/"
|
||||
if grep -qF "${POSTFIX_VMAILBOX_LINE}" /etc/postfix/vmailbox
|
||||
then
|
||||
if grep -qF "${POSTFIX_VMAILBOX_LINE}" /etc/postfix/vmailbox; then
|
||||
_log 'warn' "User '${USER}@${DOMAIN}' will not be added to '/etc/postfix/vmailbox' twice"
|
||||
else
|
||||
echo "${POSTFIX_VMAILBOX_LINE}" >>/etc/postfix/vmailbox
|
||||
|
@ -78,8 +73,7 @@ function _create_accounts
|
|||
# Dovecot's userdb has the following format
|
||||
# user:password:uid:gid:(gecos):home:(shell):extra_fields
|
||||
DOVECOT_USERDB_LINE="${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}/home::${USER_ATTRIBUTES}"
|
||||
if grep -qF "${DOVECOT_USERDB_LINE}" "${DOVECOT_USERDB_FILE}"
|
||||
then
|
||||
if grep -qF "${DOVECOT_USERDB_LINE}" "${DOVECOT_USERDB_FILE}"; then
|
||||
_log 'warn' "Login '${LOGIN}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_USERDB_LINE}" >>"${DOVECOT_USERDB_FILE}"
|
||||
|
@ -88,8 +82,7 @@ function _create_accounts
|
|||
mkdir -p "/var/mail/${DOMAIN}/${USER}/home"
|
||||
|
||||
# copy user provided sieve file, if present
|
||||
if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]]
|
||||
then
|
||||
if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]]; then
|
||||
cp "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" "/var/mail/${DOMAIN}/${USER}/home/.dovecot.sieve"
|
||||
fi
|
||||
done < <(_get_valid_lines_from_file "${DATABASE_ACCOUNTS}")
|
||||
|
@ -109,8 +102,7 @@ function _create_dovecot_alias_dummy_accounts
|
|||
{
|
||||
local DATABASE_VIRTUAL='/tmp/docker-mailserver/postfix-virtual.cf'
|
||||
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && [[ ${ENABLE_QUOTAS} -eq 1 ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && [[ ${ENABLE_QUOTAS} -eq 1 ]]; then
|
||||
# adding aliases to Dovecot's userdb
|
||||
# ${REAL_FQUN} is a user's fully-qualified username
|
||||
local ALIAS REAL_FQUN DOVECOT_USERDB_LINE
|
||||
|
@ -129,8 +121,7 @@ function _create_dovecot_alias_dummy_accounts
|
|||
REAL_USERNAME=$(cut -d '@' -f 1 <<< "${REAL_FQUN}")
|
||||
REAL_DOMAINNAME=$(cut -d '@' -f 2 <<< "${REAL_FQUN}")
|
||||
|
||||
if ! grep -q "${REAL_FQUN}" "${DATABASE_ACCOUNTS}"
|
||||
then
|
||||
if ! grep -q "${REAL_FQUN}" "${DATABASE_ACCOUNTS}"; then
|
||||
_log 'debug' "Alias '${ALIAS}' is non-local (or mapped to a non-existing account) and will not be added to Dovecot's userdb"
|
||||
continue
|
||||
fi
|
||||
|
@ -142,24 +133,20 @@ function _create_dovecot_alias_dummy_accounts
|
|||
# ${REAL_ACC[2]} => optional user attributes
|
||||
IFS='|' read -r -a REAL_ACC < <(grep "${REAL_FQUN}" "${DATABASE_ACCOUNTS}")
|
||||
|
||||
if [[ -z ${REAL_ACC[1]} ]]
|
||||
then
|
||||
if [[ -z ${REAL_ACC[1]} ]]; then
|
||||
_dms_panic__misconfigured 'postfix-accounts.cf' 'alias configuration'
|
||||
fi
|
||||
|
||||
# test if user has a defined quota
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/dovecot-quotas.cf ]]; then
|
||||
IFS=':' read -r -a USER_QUOTA < <(grep "${REAL_FQUN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf)
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]
|
||||
then
|
||||
if [[ ${#USER_QUOTA[@]} -eq 2 ]]; then
|
||||
REAL_ACC[2]="${REAL_ACC[2]:+${REAL_ACC[2]} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
DOVECOT_USERDB_LINE="${ALIAS}:${REAL_ACC[1]}:5000:5000::/var/mail/${REAL_DOMAINNAME}/${REAL_USERNAME}::${REAL_ACC[2]:-}"
|
||||
if grep -qi "^${ALIAS}:" "${DOVECOT_USERDB_FILE}"
|
||||
then
|
||||
if grep -qi "^${ALIAS}:" "${DOVECOT_USERDB_FILE}"; then
|
||||
_log 'warn' "Alias '${ALIAS}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_USERDB_LINE}" >>"${DOVECOT_USERDB_FILE}"
|
||||
|
@ -175,8 +162,7 @@ function _create_masters
|
|||
: >"${DOVECOT_MASTERDB_FILE}"
|
||||
|
||||
local DATABASE_DOVECOT_MASTERS='/tmp/docker-mailserver/dovecot-masters.cf'
|
||||
if [[ -f ${DATABASE_DOVECOT_MASTERS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_DOVECOT_MASTERS} ]]; then
|
||||
_log 'trace' "Checking file line endings"
|
||||
sed -i 's|\r||g' "${DATABASE_DOVECOT_MASTERS}"
|
||||
|
||||
|
@ -203,8 +189,7 @@ function _create_masters
|
|||
# Dovecot's masterdb has the following format
|
||||
# user:password
|
||||
DOVECOT_MASTERDB_LINE="${LOGIN}:${PASS}"
|
||||
if grep -qF "${DOVECOT_MASTERDB_LINE}" "${DOVECOT_MASTERDB_FILE}"
|
||||
then
|
||||
if grep -qF "${DOVECOT_MASTERDB_LINE}" "${DOVECOT_MASTERDB_FILE}"; then
|
||||
_log 'warn' "Login '${LOGIN}' will not be added to '${DOVECOT_MASTERDB_FILE}' twice"
|
||||
else
|
||||
echo "${DOVECOT_MASTERDB_LINE}" >>"${DOVECOT_MASTERDB_FILE}"
|
||||
|
|
|
@ -12,11 +12,9 @@ function _handle_postfix_virtual_config
|
|||
|
||||
local DATABASE_VIRTUAL=/tmp/docker-mailserver/postfix-virtual.cf
|
||||
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]; then
|
||||
# fixing old virtual user file
|
||||
if grep -q ",$" "${DATABASE_VIRTUAL}"
|
||||
then
|
||||
if grep -q ",$" "${DATABASE_VIRTUAL}"; then
|
||||
sed -i -e "s|, |,|g" -e "s|,$||g" "${DATABASE_VIRTUAL}"
|
||||
fi
|
||||
|
||||
|
@ -30,14 +28,12 @@ function _handle_postfix_regexp_config
|
|||
{
|
||||
: >/etc/postfix/regexp
|
||||
|
||||
if [[ -f /tmp/docker-mailserver/postfix-regexp.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-regexp.cf ]]; then
|
||||
_log 'trace' "Adding regexp alias file postfix-regexp.cf"
|
||||
|
||||
cp -f /tmp/docker-mailserver/postfix-regexp.cf /etc/postfix/regexp
|
||||
|
||||
if ! grep 'virtual_alias_maps.*pcre:/etc/postfix/regexp' /etc/postfix/main.cf
|
||||
then
|
||||
if ! grep 'virtual_alias_maps.*pcre:/etc/postfix/regexp' /etc/postfix/main.cf; then
|
||||
sed -i -E \
|
||||
's|virtual_alias_maps(.*)|virtual_alias_maps\1 pcre:/etc/postfix/regexp|g' \
|
||||
/etc/postfix/main.cf
|
||||
|
|
|
@ -31,8 +31,7 @@ function _monitored_files_checksums
|
|||
|
||||
# Supported user provided configs:
|
||||
local DMS_DIR=/tmp/docker-mailserver
|
||||
if [[ -d ${DMS_DIR} ]]
|
||||
then
|
||||
if [[ -d ${DMS_DIR} ]]; then
|
||||
STAGING_FILES+=(
|
||||
"${DMS_DIR}/postfix-accounts.cf"
|
||||
"${DMS_DIR}/postfix-virtual.cf"
|
||||
|
@ -46,8 +45,7 @@ function _monitored_files_checksums
|
|||
fi
|
||||
|
||||
# SSL certs:
|
||||
if [[ ${SSL_TYPE:-} == 'manual' ]]
|
||||
then
|
||||
if [[ ${SSL_TYPE:-} == 'manual' ]]; then
|
||||
# When using "manual" as the SSL type,
|
||||
# the following variables may contain the certificate files
|
||||
STAGING_FILES+=(
|
||||
|
@ -56,8 +54,7 @@ function _monitored_files_checksums
|
|||
"${SSL_ALT_CERT_PATH:-}"
|
||||
"${SSL_ALT_KEY_PATH:-}"
|
||||
)
|
||||
elif [[ ${SSL_TYPE:-} == 'letsencrypt' ]]
|
||||
then
|
||||
elif [[ ${SSL_TYPE:-} == 'letsencrypt' ]]; then
|
||||
# React to any cert changes within the following LetsEncrypt locations:
|
||||
STAGING_FILES+=(
|
||||
/etc/letsencrypt/acme.json
|
||||
|
@ -74,8 +71,7 @@ function _monitored_files_checksums
|
|||
[[ -f "${FILE}" ]] && CHANGED_FILES+=("${FILE}")
|
||||
done
|
||||
|
||||
if [[ -n ${CHANGED_FILES:-} ]]
|
||||
then
|
||||
if [[ -n ${CHANGED_FILES:-} ]]; then
|
||||
sha512sum -- "${CHANGED_FILES[@]}"
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -63,8 +63,7 @@ function _db_operation
|
|||
[[ ${DATABASE} == "${DATABASE_VIRTUAL}" ]] && V_DELIMITER=','
|
||||
|
||||
# Perform requested operation:
|
||||
if _db_has_entry_with_key "${KEY}" "${DATABASE}"
|
||||
then
|
||||
if _db_has_entry_with_key "${KEY}" "${DATABASE}"; then
|
||||
# Find entry for key and return status code:
|
||||
case "${DB_ACTION}" in
|
||||
( 'append' )
|
||||
|
@ -79,8 +78,7 @@ function _db_operation
|
|||
;;
|
||||
|
||||
( 'remove' )
|
||||
if [[ -z ${VALUE} ]]
|
||||
then # Remove entry for KEY:
|
||||
if [[ -z ${VALUE} ]]; then # Remove entry for KEY:
|
||||
sedfile --strict -i "/^${KEY_LOOKUP}/d" "${DATABASE}"
|
||||
else # Remove target VALUE from entry:
|
||||
__db_list_already_contains_value || return 0
|
||||
|
|
|
@ -74,8 +74,7 @@ function _arg_expect_mail_account
|
|||
function _account_should_not_exist_yet
|
||||
{
|
||||
__account_already_exists && _exit_with_error "'${MAIL_ACCOUNT}' already exists"
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && grep -q "^${MAIL_ACCOUNT}" "${DATABASE_VIRTUAL}"
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]] && grep -q "^${MAIL_ACCOUNT}" "${DATABASE_VIRTUAL}"; then
|
||||
_exit_with_error "'${MAIL_ACCOUNT}' is already defined as an alias"
|
||||
fi
|
||||
}
|
||||
|
@ -95,8 +94,7 @@ function __account_already_exists
|
|||
# Also used by addsaslpassword
|
||||
function _password_request_if_missing
|
||||
{
|
||||
if [[ -z ${PASSWD} ]]
|
||||
then
|
||||
if [[ -z ${PASSWD} ]]; then
|
||||
read -r -s -p 'Enter Password: ' PASSWD
|
||||
echo
|
||||
[[ -z ${PASSWD} ]] && _exit_with_error 'Password must not be empty'
|
||||
|
|
|
@ -25,8 +25,7 @@ function _manage_virtual_aliases
|
|||
case "${ACTION}" in
|
||||
# Associate RECIPIENT to MAIL_ALIAS:
|
||||
( 'update' )
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]] && grep -q "^${MAIL_ALIAS}" "${DATABASE_ACCOUNTS}"
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]] && grep -q "^${MAIL_ALIAS}" "${DATABASE_ACCOUNTS}"; then
|
||||
_exit_with_error "'${MAIL_ALIAS}' is already defined as an account"
|
||||
fi
|
||||
_db_entry_add_or_append "${DATABASE_VIRTUAL}" "${MAIL_ALIAS}" "${RECIPIENT}"
|
||||
|
|
|
@ -27,8 +27,7 @@ function _obtain_hostname_and_domainname
|
|||
|
||||
# If the container is misconfigured.. `hostname -f` (which derives it's return value from `/etc/hosts` or DNS query),
|
||||
# will result in an error that returns an empty value. This warrants a panic.
|
||||
if [[ -z ${HOSTNAME} ]]
|
||||
then
|
||||
if [[ -z ${HOSTNAME} ]]; then
|
||||
_dms_panic__misconfigured 'obtain_hostname' '/etc/hosts'
|
||||
fi
|
||||
|
||||
|
@ -39,10 +38,8 @@ function _obtain_hostname_and_domainname
|
|||
# `hostname -d` was probably not the correct command for this intention either.
|
||||
# Needs further investigation for relevance, and if `/etc/hosts` is important for consumers
|
||||
# of this variable or if a more deterministic approach with `cut` should be relied on.
|
||||
if [[ $(_get_label_count "${HOSTNAME}") -gt 2 ]]
|
||||
then
|
||||
if [[ -n ${OVERRIDE_HOSTNAME:-} ]]
|
||||
then
|
||||
if [[ $(_get_label_count "${HOSTNAME}") -gt 2 ]]; then
|
||||
if [[ -n ${OVERRIDE_HOSTNAME:-} ]]; then
|
||||
# Emulates the intended behaviour of `hostname -d`:
|
||||
# Assign the HOSTNAME value minus everything up to and including the first `.`
|
||||
DOMAINNAME=${HOSTNAME#*.}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
function _exit_with_error
|
||||
{
|
||||
if [[ -n ${1+set} ]]
|
||||
then
|
||||
if [[ -n ${1+set} ]]; then
|
||||
_log 'error' "${1}"
|
||||
else
|
||||
_log 'error' "Call to '_exit_with_error' is missing a message to log"
|
||||
|
@ -58,8 +57,7 @@ function dms_panic
|
|||
;;
|
||||
esac
|
||||
|
||||
if [[ -n ${PANIC_SCOPE:-} ]]
|
||||
then
|
||||
if [[ -n ${PANIC_SCOPE:-} ]]; then
|
||||
_shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}"
|
||||
else
|
||||
_shutdown "${SHUTDOWN_MESSAGE}"
|
||||
|
|
|
@ -14,8 +14,7 @@ function _create_lock
|
|||
do
|
||||
# Handle stale lock files left behind on crashes
|
||||
# or premature/non-graceful exits of containers while they're making changes
|
||||
if [[ -n "$(find "${LOCK_FILE}" -mmin +1 2>/dev/null)" ]]
|
||||
then
|
||||
if [[ -n "$(find "${LOCK_FILE}" -mmin +1 2>/dev/null)" ]]; then
|
||||
_log 'warn' 'Lock file older than 1 minute - removing stale lock file'
|
||||
rm -f "${LOCK_FILE}"
|
||||
else
|
||||
|
@ -33,8 +32,7 @@ function _remove_lock
|
|||
{
|
||||
LOCK_FILE="${LOCK_FILE:-"/tmp/docker-mailserver/${SCRIPT_NAME}.lock"}"
|
||||
[[ -z "${LOCK_ID}" ]] && _exit_with_error "Cannot remove '${LOCK_FILE}' as there is no LOCK_ID set"
|
||||
if [[ -e "${LOCK_FILE}" ]] && grep -q "${LOCK_ID}" "${LOCK_FILE}" # Ensure we don't delete a lock that's not ours
|
||||
then
|
||||
if [[ -e "${LOCK_FILE}" ]] && grep -q "${LOCK_ID}" "${LOCK_FILE}"; then # Ensure we don't delete a lock that's not ours
|
||||
rm -f "${LOCK_FILE}"
|
||||
_log 'trace' "Removed lock '${LOCK_FILE}'"
|
||||
fi
|
||||
|
|
|
@ -44,14 +44,12 @@ RESET=$(echo -ne '\e[0m')
|
|||
# is missing. Both failures will return with exit code '1'.
|
||||
function _log
|
||||
{
|
||||
if [[ -z ${1+set} ]]
|
||||
then
|
||||
if [[ -z ${1+set} ]]; then
|
||||
_log 'error' "Call to '_log' is missing a valid log level"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z ${2+set} ]]
|
||||
then
|
||||
if [[ -z ${2+set} ]]; then
|
||||
_log 'error' "Call to '_log' is missing a message to log"
|
||||
return 1
|
||||
fi
|
||||
|
@ -100,8 +98,7 @@ function _log
|
|||
|
||||
MESSAGE+="${RESET}] ${2}"
|
||||
|
||||
if [[ ${1} =~ ^(warn|error)$ ]]
|
||||
then
|
||||
if [[ ${1} =~ ^(warn|error)$ ]]; then
|
||||
echo -e "${MESSAGE}" >&2
|
||||
else
|
||||
echo -e "${MESSAGE}"
|
||||
|
@ -120,11 +117,9 @@ function _log_with_date
|
|||
# use the default log level.
|
||||
function _get_log_level_or_default
|
||||
{
|
||||
if [[ -n ${LOG_LEVEL+set} ]]
|
||||
then
|
||||
if [[ -n ${LOG_LEVEL+set} ]]; then
|
||||
echo "${LOG_LEVEL}"
|
||||
elif [[ -e /etc/dms-settings ]] && grep -q -E "^LOG_LEVEL='[a-z]+'" /etc/dms-settings
|
||||
then
|
||||
elif [[ -e /etc/dms-settings ]] && grep -q -E "^LOG_LEVEL='[a-z]+'" /etc/dms-settings; then
|
||||
grep '^LOG_LEVEL=' /etc/dms-settings | cut -d "'" -f 2
|
||||
else
|
||||
echo 'info'
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
function _mask_ip_digit
|
||||
{
|
||||
if [[ ${1} -ge 8 ]]
|
||||
then
|
||||
if [[ ${1} -ge 8 ]]; then
|
||||
MASK=255
|
||||
elif [[ ${1} -le 0 ]]
|
||||
then
|
||||
elif [[ ${1} -le 0 ]]; then
|
||||
MASK=0
|
||||
else
|
||||
VALUES=(0 128 192 224 240 248 252 254 255)
|
||||
|
|
|
@ -33,8 +33,7 @@ function _create_vhost
|
|||
{
|
||||
: >"${DATABASE_VHOST}"
|
||||
|
||||
if [[ -f ${TMP_VHOST} ]]
|
||||
then
|
||||
if [[ -f ${TMP_VHOST} ]]; then
|
||||
sort < "${TMP_VHOST}" | uniq >>"${DATABASE_VHOST}"
|
||||
rm "${TMP_VHOST}"
|
||||
fi
|
||||
|
@ -48,8 +47,7 @@ function _vhost_collect_postfix_domains
|
|||
local DOMAIN UNAME
|
||||
|
||||
# getting domains FROM mail accounts
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_ACCOUNTS} ]]; then
|
||||
while IFS=$'|' read -r LOGIN _
|
||||
do
|
||||
DOMAIN=$(echo "${LOGIN}" | cut -d @ -f2)
|
||||
|
@ -58,8 +56,7 @@ function _vhost_collect_postfix_domains
|
|||
fi
|
||||
|
||||
# getting domains FROM mail aliases
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_VIRTUAL} ]]; then
|
||||
while read -r FROM _
|
||||
do
|
||||
UNAME=$(echo "${FROM}" | cut -d @ -f1)
|
||||
|
|
|
@ -77,8 +77,7 @@ function _relayhost_sasl
|
|||
chmod 0600 /etc/postfix/sasl_passwd
|
||||
|
||||
local DATABASE_SASL_PASSWD='/tmp/docker-mailserver/postfix-sasl-password.cf'
|
||||
if [[ -f ${DATABASE_SASL_PASSWD} ]]
|
||||
then
|
||||
if [[ -f ${DATABASE_SASL_PASSWD} ]]; then
|
||||
# Add domain-specific auth from config file:
|
||||
_get_valid_lines_from_file "${DATABASE_SASL_PASSWD}" >> /etc/postfix/sasl_passwd
|
||||
|
||||
|
@ -87,8 +86,7 @@ function _relayhost_sasl
|
|||
fi
|
||||
|
||||
# Add an authenticated relay host defined via ENV config:
|
||||
if [[ -n ${RELAY_USER} ]] && [[ -n ${RELAY_PASSWORD} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_USER} ]] && [[ -n ${RELAY_PASSWORD} ]]; then
|
||||
echo "$(_env_relay_host) ${RELAY_USER}:${RELAY_PASSWORD}" >> /etc/postfix/sasl_passwd
|
||||
fi
|
||||
|
||||
|
@ -122,8 +120,7 @@ function _populate_relayhost_map
|
|||
|
||||
# This config is mostly compatible with `/etc/postfix/relayhost_map`, but additionally supports
|
||||
# not providing a relay host for a sender domain to opt-out of RELAY_HOST? (2nd half of function)
|
||||
if [[ -f /tmp/docker-mailserver/postfix-relaymap.cf ]]
|
||||
then
|
||||
if [[ -f /tmp/docker-mailserver/postfix-relaymap.cf ]]; then
|
||||
_log 'trace' "Adding relay mappings from postfix-relaymap.cf"
|
||||
|
||||
# Match two values with some white-space between them (eg: `@example.test [relay.service.test]:465`):
|
||||
|
@ -161,8 +158,7 @@ function _populate_relayhost_map
|
|||
# DOMAIN_PART not already present in `/etc/postfix/relayhost_map`, and not listed as a relay opt-out domain in `postfix-relaymap.cf`
|
||||
# `^@${DOMAIN_PART}\b` - To check for existing entry, the `\b` avoids accidental partial matches on similar domain parts.
|
||||
# `^\s*@${DOMAIN_PART}\s*$` - Matches line with only a domain part (eg: @example.test) to avoid including a mapping for those domains to the RELAY_HOST.
|
||||
if ! grep -q -e "^@${DOMAIN_PART}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN_PART}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf
|
||||
then
|
||||
if ! grep -q -e "^@${DOMAIN_PART}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN_PART}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf; then
|
||||
_log 'trace' "Adding relay mapping for ${DOMAIN_PART}"
|
||||
echo "@${DOMAIN_PART} $(_env_relay_host)" >> /etc/postfix/relayhost_map
|
||||
fi
|
||||
|
@ -183,14 +179,12 @@ function _setup_relayhost
|
|||
{
|
||||
_log 'debug' 'Setting up Postfix Relay Hosts'
|
||||
|
||||
if [[ -n ${DEFAULT_RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${DEFAULT_RELAY_HOST} ]]; then
|
||||
_log 'trace' "Setting default relay host ${DEFAULT_RELAY_HOST} to /etc/postfix/main.cf"
|
||||
postconf "relayhost = ${DEFAULT_RELAY_HOST}"
|
||||
fi
|
||||
|
||||
if [[ -n ${RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_HOST} ]]; then
|
||||
_log 'trace' "Setting up relay hosts (default: ${RELAY_HOST})"
|
||||
|
||||
_relayhost_sasl
|
||||
|
@ -202,8 +196,7 @@ function _setup_relayhost
|
|||
|
||||
function _rebuild_relayhost
|
||||
{
|
||||
if [[ -n ${RELAY_HOST} ]]
|
||||
then
|
||||
if [[ -n ${RELAY_HOST} ]]; then
|
||||
_relayhost_sasl
|
||||
_populate_relayhost_map
|
||||
fi
|
||||
|
|
|
@ -8,8 +8,7 @@ function _setup_dhparam
|
|||
|
||||
_log 'debug' "Setting up ${DH_SERVICE} dhparam"
|
||||
|
||||
if [[ -f ${DH_CUSTOM} ]]
|
||||
then # use custom supplied dh params (assumes they're probably insecure)
|
||||
if [[ -f ${DH_CUSTOM} ]]; then # use custom supplied dh params (assumes they're probably insecure)
|
||||
_log 'trace' "${DH_SERVICE} will use custom provided DH paramters"
|
||||
_log 'warn' "Using self-generated dhparams is considered insecure - unless you know what you are doing, please remove '${DH_CUSTOM}'"
|
||||
|
||||
|
@ -39,8 +38,7 @@ function _setup_ssl
|
|||
local DOVECOT_CERT=${1}
|
||||
|
||||
# If a 2nd param is provided, a separate key and cert was received instead of a fullkeychain
|
||||
if [[ -n ${2} ]]
|
||||
then
|
||||
if [[ -n ${2} ]]; then
|
||||
local PRIVATE_KEY=$1
|
||||
local CERT_CHAIN=$2
|
||||
|
||||
|
@ -117,22 +115,18 @@ function _setup_ssl
|
|||
# NOTE: See the `SSL_TYPE=letsencrypt` case below for more details.
|
||||
function _traefik_support
|
||||
{
|
||||
if [[ -f /etc/letsencrypt/acme.json ]]
|
||||
then
|
||||
if [[ -f /etc/letsencrypt/acme.json ]]; then
|
||||
# Variable only intended for troubleshooting via debug output
|
||||
local EXTRACTED_DOMAIN
|
||||
|
||||
# Conditional handling depends on the success of `_extract_certs_from_acme`,
|
||||
# Failure tries the next fallback FQDN to try extract a certificate from.
|
||||
# Subshell not used in conditional to ensure extraction log output is still captured
|
||||
if [[ -n ${SSL_DOMAIN} ]] && _extract_certs_from_acme "${SSL_DOMAIN}"
|
||||
then
|
||||
if [[ -n ${SSL_DOMAIN} ]] && _extract_certs_from_acme "${SSL_DOMAIN}"; then
|
||||
EXTRACTED_DOMAIN=('SSL_DOMAIN' "${SSL_DOMAIN}")
|
||||
elif _extract_certs_from_acme "${HOSTNAME}"
|
||||
then
|
||||
elif _extract_certs_from_acme "${HOSTNAME}"; then
|
||||
EXTRACTED_DOMAIN=('HOSTNAME' "${HOSTNAME}")
|
||||
elif _extract_certs_from_acme "${DOMAINNAME}"
|
||||
then
|
||||
elif _extract_certs_from_acme "${DOMAINNAME}"; then
|
||||
EXTRACTED_DOMAIN=('DOMAINNAME' "${DOMAINNAME}")
|
||||
else
|
||||
_log 'warn' "letsencrypt (acme.json) failed to identify a certificate to extract"
|
||||
|
@ -220,8 +214,7 @@ function _setup_ssl
|
|||
local TMP_KEY_WITH_FULLCHAIN="${TMP_DMS_TLS_PATH}/${COMBINED_PEM_NAME}"
|
||||
local KEY_WITH_FULLCHAIN="${DMS_TLS_PATH}/${COMBINED_PEM_NAME}"
|
||||
|
||||
if [[ -f ${TMP_KEY_WITH_FULLCHAIN} ]]
|
||||
then
|
||||
if [[ -f ${TMP_KEY_WITH_FULLCHAIN} ]]; then
|
||||
cp "${TMP_KEY_WITH_FULLCHAIN}" "${KEY_WITH_FULLCHAIN}"
|
||||
chmod 600 "${KEY_WITH_FULLCHAIN}"
|
||||
|
||||
|
@ -241,8 +234,7 @@ function _setup_ssl
|
|||
local CERT_CHAIN="${DMS_TLS_PATH}/cert"
|
||||
|
||||
# Fail early:
|
||||
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]; then
|
||||
_dms_panic__no_env 'SSL_KEY_PATH or SSL_CERT_PATH' "${SCOPE_SSL_TYPE}"
|
||||
fi
|
||||
|
||||
|
@ -254,8 +246,7 @@ function _setup_ssl
|
|||
_dms_panic__no_file "(ALT) ${SSL_ALT_KEY_PATH} or ${SSL_ALT_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
||||
fi
|
||||
|
||||
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]; then
|
||||
cp "${SSL_KEY_PATH}" "${PRIVATE_KEY}"
|
||||
cp "${SSL_CERT_PATH}" "${CERT_CHAIN}"
|
||||
chmod 600 "${PRIVATE_KEY}"
|
||||
|
@ -264,8 +255,7 @@ function _setup_ssl
|
|||
_set_certificate "${PRIVATE_KEY}" "${CERT_CHAIN}"
|
||||
|
||||
# Support for a fallback certificate, useful for hybrid/dual ECDSA + RSA certs
|
||||
if [[ -n ${SSL_ALT_KEY_PATH} ]] && [[ -n ${SSL_ALT_CERT_PATH} ]]
|
||||
then
|
||||
if [[ -n ${SSL_ALT_KEY_PATH} ]] && [[ -n ${SSL_ALT_CERT_PATH} ]]; then
|
||||
_log 'trace' "Configuring fallback certificates using key ${SSL_ALT_KEY_PATH} and cert ${SSL_ALT_CERT_PATH}"
|
||||
|
||||
_set_alt_certificate "${SSL_ALT_KEY_PATH}" "${SSL_ALT_CERT_PATH}"
|
||||
|
@ -393,14 +383,11 @@ function _find_letsencrypt_domain
|
|||
{
|
||||
local LETSENCRYPT_DOMAIN
|
||||
|
||||
if [[ -n ${SSL_DOMAIN} ]] && [[ -e /etc/letsencrypt/live/$(_strip_wildcard_prefix "${SSL_DOMAIN}")/fullchain.pem ]]
|
||||
then
|
||||
if [[ -n ${SSL_DOMAIN} ]] && [[ -e /etc/letsencrypt/live/$(_strip_wildcard_prefix "${SSL_DOMAIN}")/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=$(_strip_wildcard_prefix "${SSL_DOMAIN}")
|
||||
elif [[ -e /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=${HOSTNAME}
|
||||
elif [[ -e /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem ]]; then
|
||||
LETSENCRYPT_DOMAIN=${DOMAINNAME}
|
||||
else
|
||||
_log 'error' "Cannot find a valid DOMAIN for '/etc/letsencrypt/live/<DOMAIN>/', tried: '${SSL_DOMAIN}', '${HOSTNAME}', '${DOMAINNAME}'"
|
||||
|
@ -416,16 +403,13 @@ function _find_letsencrypt_key
|
|||
local LETSENCRYPT_KEY
|
||||
|
||||
local LETSENCRYPT_DOMAIN=${1}
|
||||
if [[ -z ${LETSENCRYPT_DOMAIN} ]]
|
||||
then
|
||||
if [[ -z ${LETSENCRYPT_DOMAIN} ]]; then
|
||||
_dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_key'
|
||||
fi
|
||||
|
||||
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]
|
||||
then
|
||||
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]; then
|
||||
LETSENCRYPT_KEY='privkey'
|
||||
elif [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/key.pem ]]
|
||||
then
|
||||
elif [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/key.pem ]]; then
|
||||
LETSENCRYPT_KEY='key'
|
||||
else
|
||||
_log 'error' "Cannot find key file ('privkey.pem' or 'key.pem') in '/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/'"
|
||||
|
@ -438,8 +422,7 @@ function _find_letsencrypt_key
|
|||
function _extract_certs_from_acme
|
||||
{
|
||||
local CERT_DOMAIN=${1}
|
||||
if [[ -z ${CERT_DOMAIN} ]]
|
||||
then
|
||||
if [[ -z ${CERT_DOMAIN} ]]; then
|
||||
_log 'warn' "_extract_certs_from_acme | CERT_DOMAIN is empty"
|
||||
return 1
|
||||
fi
|
||||
|
@ -448,16 +431,14 @@ function _extract_certs_from_acme
|
|||
KEY=$(acme_extract.py /etc/letsencrypt/acme.json "${CERT_DOMAIN}" --key)
|
||||
CERT=$(acme_extract.py /etc/letsencrypt/acme.json "${CERT_DOMAIN}" --cert)
|
||||
|
||||
if [[ -z ${KEY} ]] || [[ -z ${CERT} ]]
|
||||
then
|
||||
if [[ -z ${KEY} ]] || [[ -z ${CERT} ]]; then
|
||||
_log 'warn' "_extract_certs_from_acme | Unable to find key and/or cert for '${CERT_DOMAIN}' in '/etc/letsencrypt/acme.json'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Currently we advise SSL_DOMAIN for wildcard support using a `*.example.com` value,
|
||||
# The filepath however should be `example.com`, avoiding the wildcard part:
|
||||
if [[ ${SSL_DOMAIN} == "${CERT_DOMAIN}" ]]
|
||||
then
|
||||
if [[ ${SSL_DOMAIN} == "${CERT_DOMAIN}" ]]; then
|
||||
CERT_DOMAIN=$(_strip_wildcard_prefix "${SSL_DOMAIN}")
|
||||
fi
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ function _get_valid_lines_from_file
|
|||
# and it will return its value stored in /etc/dms-settings
|
||||
function _get_dms_env_value
|
||||
{
|
||||
if [[ -f /etc/dms-settings ]]
|
||||
then
|
||||
if [[ -f /etc/dms-settings ]]; then
|
||||
grep "^${1}=" /etc/dms-settings | cut -d "'" -f 2
|
||||
else
|
||||
_log 'warn' "Call to '_get_dms_env_value' but '/etc/dms-settings' is not present"
|
||||
|
@ -34,8 +33,7 @@ function _get_dms_env_value
|
|||
function _chown_var_mail_if_necessary
|
||||
{
|
||||
# fix permissions, but skip this if 3 levels deep the user id is already set
|
||||
if find /var/mail -maxdepth 3 -a \( \! -user 5000 -o \! -group 5000 \) | read -r
|
||||
then
|
||||
if find /var/mail -maxdepth 3 -a \( \! -user 5000 -o \! -group 5000 \) | read -r; then
|
||||
_log 'trace' 'Fixing /var/mail permissions'
|
||||
chown -R 5000:5000 /var/mail || return 1
|
||||
fi
|
||||
|
@ -59,8 +57,7 @@ function _require_n_parameters_or_print_usage
|
|||
# https://github.com/docker-mailserver/docker-mailserver/issues/2985
|
||||
function _adjust_mtime_for_postfix_maincf
|
||||
{
|
||||
if [[ $(( $(date '+%s') - $(stat -c '%Y' '/etc/postfix/main.cf') )) -lt 2 ]]
|
||||
then
|
||||
if [[ $(( $(date '+%s') - $(stat -c '%Y' '/etc/postfix/main.cf') )) -lt 2 ]]; then
|
||||
touch -d '2 seconds ago' /etc/postfix/main.cf
|
||||
fi
|
||||
}
|
||||
|
@ -97,14 +94,11 @@ function _reload_postfix
|
|||
# 2. The second argument is a path to a file that does not exist
|
||||
function _replace_by_env_in_file
|
||||
{
|
||||
if [[ -z ${1+set} ]]
|
||||
then
|
||||
if [[ -z ${1+set} ]]; then
|
||||
_dms_panic__invalid_value 'first argument unset' 'utils.sh:_replace_by_env_in_file'
|
||||
elif [[ -z ${2+set} ]]
|
||||
then
|
||||
elif [[ -z ${2+set} ]]; then
|
||||
_dms_panic__invalid_value 'second argument unset' 'utils.sh:_replace_by_env_in_file'
|
||||
elif [[ ! -f ${2} ]]
|
||||
then
|
||||
elif [[ ! -f ${2} ]]; then
|
||||
_dms_panic__invalid_value "file '${2}' does not exist" 'utils.sh:_replace_by_env_in_file'
|
||||
fi
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue