start-mailserver.sh split (#1820)

* splitting start-mailserver.sh

* refactoring part 2

* refactored setup-stack.sh
* stzarted adjusting target/bin/*.sh to use new usage format

* corrected lowercase-uppercase test error

* better handling of .bashrc variable export

* linting tests and fix for default assignements

* last stylistic changes and rebase
This commit is contained in:
Georg Lauterbach 2021-02-23 20:03:01 +01:00 committed by GitHub
parent 2262d354db
commit c881facbd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 2214 additions and 2278 deletions

View file

@ -30,7 +30,7 @@ The development workflow is the following:
2. Run `git submodule update --init --recursive` 2. Run `git submodule update --init --recursive`
2. Write the code that is needed :D 2. Write the code that is needed :D
3. Add integration tests if necessary 3. Add integration tests if necessary
4. Get the linters with `make install_linters` 4. Get the linters with `make install_linters` and install `jq` with the package manager of your OS
5. Use `make clean all` to build image locally and run tests (note that tests work on Linux **only**) 5. Use `make clean all` to build image locally and run tests (note that tests work on Linux **only**)
6. Document your improvements if necessary (e.g. if you introduced new environment variables, write the description in [`ENVIRONMENT.md`](./ENVIRONMENT.md)) 6. Document your improvements if necessary (e.g. if you introduced new environment variables, write the description in [`ENVIRONMENT.md`](./ENVIRONMENT.md))
7. [Commit][commit] and [sign your commit][gpg], push and create a pull-request to merge into `master`. Please **use the pull-request template** to provide a minimum of contextual information and make sure to meet the requirements of the checklist. 7. [Commit][commit] and [sign your commit][gpg], push and create a pull-request to merge into `master`. Please **use the pull-request template** to provide a minimum of contextual information and make sure to meet the requirements of the checklist.

View file

@ -40,9 +40,10 @@ RUN \
apt-get -y --no-install-recommends install \ apt-get -y --no-install-recommends install \
# A - D # A - D
altermime amavisd-new apt-transport-https arj binutils bzip2 \ altermime amavisd-new apt-transport-https arj binutils bzip2 \
ca-certificates cabextract clamav clamav-daemon cpio curl \
dovecot-core dovecot-imapd dovecot-ldap dovecot-lmtpd \ dovecot-core dovecot-imapd dovecot-ldap dovecot-lmtpd \
dovecot-managesieved dovecot-pop3d dovecot-sieve dovecot-solr \ dovecot-managesieved dovecot-pop3d dovecot-sieve dovecot-solr \
dumb-init ca-certificates cabextract clamav clamav-daemon cpio curl \ dumb-init \
# E - O # E - O
ed fail2ban fetchmail file gamin gnupg gzip iproute2 iptables \ ed fail2ban fetchmail file gamin gnupg gzip iproute2 iptables \
locales logwatch lhasa libdate-manip-perl liblz4-tool \ locales logwatch lhasa libdate-manip-perl liblz4-tool \
@ -125,6 +126,7 @@ RUN \
COPY \ COPY \
./target/bin/* \ ./target/bin/* \
./target/scripts/*.sh \ ./target/scripts/*.sh \
./target/scripts/startup/*.sh \
./target/docker-configomat/configomat.sh \ ./target/docker-configomat/configomat.sh \
/usr/local/bin/ /usr/local/bin/

View file

@ -45,7 +45,7 @@ A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.)
**Recommended**: **Recommended**:
- 1 Core - 1 Core
- 1-2GB RAM - 2GB RAM
- Swap enabled for the container - Swap enabled for the container
**Minimum**: **Minimum**:
@ -128,7 +128,7 @@ docker-compose up -d mail
./setup.sh -Z config dkim ./setup.sh -Z config dkim
``` ```
If you're seeing error messages about unchecked error, please **verify that you're using the right version of `setup.sh`**. Refer to the [Get the tools](#get-the-tools) section and / or execute `./setup.sh help` and read teh `VERSION` section. If you're seeing error messages about unchecked error, please **verify that you're using the right version of `setup.sh`**. Refer to the [Get the tools](#get-the-tools) section and / or execute `./setup.sh help` and read the `VERSION` section.
In case you're using LDAP, the setup looks a bit different as you do not add user accounts directly. Postfix doesn't know your domain(s) and you need to provide it when configuring DKIM: In case you're using LDAP, the setup looks a bit different as you do not add user accounts directly. Postfix doesn't know your domain(s) and you need to provide it when configuring DKIM:

View file

@ -158,10 +158,6 @@ function _usage
Allows container access to the bind mount content that is private and Allows container access to the bind mount content that is private and
unshared with other containers on a SELinux-enabled host. unshared with other containers on a SELinux-enabled host.
\e[94mOthers\e[39m
-h \e[31m|\e[39m help
Shows this help dialogue.
\e[31m[\e[38;5;214mSUB\e[31m]\e[38;5;214mCOMMANDS\e[39m \e[31m[\e[38;5;214mSUB\e[31m]\e[38;5;214mCOMMANDS\e[39m
\e[94mCOMMAND\e[39m email \e[31m:=\e[39m \e[94mCOMMAND\e[39m email \e[31m:=\e[39m
${0} email add <EMAIL ADDRESS> [<PASSWORD>] ${0} email add <EMAIL ADDRESS> [<PASSWORD>]
@ -301,11 +297,6 @@ function _main
USE_CONTAINER=true USE_CONTAINER=true
;; ;;
h )
_usage
return
;;
p ) p )
case "${OPTARG}" in case "${OPTARG}" in
/* ) WISHED_CONFIG_PATH="${OPTARG}" ;; /* ) WISHED_CONFIG_PATH="${OPTARG}" ;;

View file

@ -5,13 +5,39 @@
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf} DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}
function __usage
{
printf "\e[35mADDALIAS\e[31m(\e[93m8\e[31m)
\e[38;5;214mNAME\e[39m
addalias - add an email alias for an existing user
\e[38;5;214mSYNOPSIS\e[39m
./setup.sh alias add <EMAIL ADDRESS> <RECIPIENT>
\e[38;5;214mOPTIONS\e[39m
\e[94mGeneric Program Information\e[39m
help Print the usage information.
\e[38;5;214mEXAMPLES\e[39m
\e[37m./setup.sh alias add alias-for-me@domain.tld admin@domain.tld\e[39m
Add the alias alias-for-me@doamin.tld for the existing user
admin@domain.tld.
\e[38;5;214mEXIT STATUS\e[39m
Exit status is 0 if command was successful. If wrong arguments are provided
or arguments contain errors, the script will exit early with exit status 1.
"
}
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
EMAIL="${1}" EMAIL="${1}"
RECIPIENT="${2}" RECIPIENT="${2}"
function usage { echo "Usage: addalias <alias@domain> <recipient@other>" ; } [[ -z ${EMAIL} ]] && { __usage ; errex 'No alias specified' ; }
[[ -z ${RECIPIENT} ]] && { __usage ; errex 'No recipient specified' ; }
[[ -z ${EMAIL} ]] && { usage ; errex "Error: No alias specified" ; }
[[ -z ${RECIPIENT} ]] && { usage ; errex "Error: No recipient specified" ; }
grep \ grep \
-qi "^$(escape "${EMAIL}")[a-zA-Z@.\ ]*$(escape "${RECIPIENT}")" \ -qi "^$(escape "${EMAIL}")[a-zA-Z@.\ ]*$(escape "${RECIPIENT}")" \

View file

@ -7,14 +7,40 @@
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf} DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}
function __usage
{
printf "\e[35mADDMAILUSER\e[31m(\e[93m8\e[31m)
\e[38;5;214mNAME\e[39m
addmailuser - add an email address (i.e. a user)
\e[38;5;214mSYNOPSIS\e[39m
./setup.sh email add <EMAIL ADDRESS> [<PASSWORD>]
\e[38;5;214mOPTIONS\e[39m
\e[94mGeneric Program Information\e[39m
help Print the usage information.
\e[38;5;214mEXAMPLES\e[39m
\e[37m./setup.sh email add test@domain.tld\e[39m
Add the email account test@domain.tld. You will be prompted
to input a password afterwards since no password was supplied.
\e[38;5;214mEXIT STATUS\e[39m
Exit status is 0 if command was successful. If wrong arguments are provided
or arguments contain errors, the script will exit early with exit status 1.
"
}
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
USER="${1}" USER="${1}"
shift shift
PASSWD="${*}" PASSWD="${*}"
function usage { echo "Usage: addmailuser <user@domain> [<password>]" ; } [[ -z ${USER} ]] && { __usage ; errex 'No username specified' ; }
[[ "${USER}" =~ .*\@.* ]] || { __usage ; errex 'Username must include the domain' ; }
[[ -z ${USER} ]] && { usage ; errex "no username specified" ; }
[[ "${USER}" =~ .*\@.* ]] || { usage ; errex "username must include the domain" ; }
# Protect config file with lock to avoid race conditions # Protect config file with lock to avoid race conditions
touch "${DATABASE}" touch "${DATABASE}"

View file

@ -5,22 +5,42 @@
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-relaymap.cf} DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-relaymap.cf}
function __usage
{
printf "\e[35mADDRELAYHOST\e[31m(\e[93m8\e[31m)
\e[38;5;214mNAME\e[39m
addrelayhost - add an relay host
\e[38;5;214mSYNOPSIS\e[39m
./setup.sh relay add-domain <DOMAIN> <HOST> [<PORT>]
\e[38;5;214mOPTIONS\e[39m
\e[94mGeneric Program Information\e[39m
help Print the usage information.
\e[38;5;214mEXIT STATUS\e[39m
Exit status is 0 if command was successful. If wrong arguments are provided
or arguments contain errors, the script will exit early with exit status 1.
"
}
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
DOMAIN="${1}" DOMAIN="${1}"
HOST="${2}" HOST="${2}"
PORT="${3}" PORT="${3}"
function usage { echo "Usage: addrelayhost <domain> <host> [<port>]" ; } [[ -z ${DOMAIN} ]] && { __usage ; errex 'No domain specified' ; }
[[ -z ${HOST} ]] && { __usage ; errex 'No relay host specified' ; }
[[ -z ${DOMAIN} ]] && { usage ; errex "no domain specified" ; }
[[ -z ${HOST} ]] && { usage ; errex "no relay host specified" ; }
[[ -z ${PORT} ]] && PORT=25 [[ -z ${PORT} ]] && PORT=25
if grep -qi "^@${DOMAIN}" "${DATABASE}" 2>/dev/null if grep -qi "^@${DOMAIN}" "${DATABASE}" 2>/dev/null
then then
# TODO check if fixed sed -i \
# sed -i "s ^@${DOMAIN}.* @${DOMAIN}\t\t[${HOST}]:${PORT}" "${DATABASE}" "s|^@${DOMAIN}.*|@${DOMAIN}\t\t[${HOST}]:${PORT}|" \
sed -i "s ^@""${DOMAIN}"".* ""@""${DOMAIN}""\t\t[""${HOST}""]:""${PORT}"" " "${DATABASE}" "${DATABASE}"
else else
echo -e "@${DOMAIN}\t\t[${HOST}]:${PORT}" >>"${DATABASE}" echo -e "@${DOMAIN}\t\t[${HOST}]:${PORT}" >>"${DATABASE}"
fi fi

View file

@ -5,25 +5,29 @@
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-sasl-password.cf} DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-sasl-password.cf}
function __usage { echo "Usage: addsaslpassword <domain> <username> <password>" ; }
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
DOMAIN="${1}" DOMAIN="${1}"
USER="${2}" USER="${2}"
PASSWD="${3}" PASSWD="${3}"
function usage { echo "Usage: addsaslpassword <domain> <username> <password>" ; } [[ -z ${DOMAIN} ]] && { __usage ; errex 'No domain specified' ; }
[[ -z ${USER} ]] && { __usage ; errex 'No username specified' ; }
[[ -z ${DOMAIN} ]] && { usage ; errex "no domain specified" ; }
[[ -z ${USER} ]] && { usage ; errex "no username specified" ; }
if [[ -z ${PASSWD} ]] if [[ -z ${PASSWD} ]]
then then
read -r -s -p "Enter Password: " PASSWD read -r -s -p "Enter Password: " PASSWD
echo echo
[[ -z ${PASSWD} ]] && errex "Password must not be empty" [[ -z ${PASSWD} ]] && errex 'Password must not be empty'
fi fi
if grep -qi "^@${DOMAIN}" "${DATABASE}" 2>/dev/null if grep -qi "^@${DOMAIN}" "${DATABASE}" 2>/dev/null
then then
sed -i "s ^@""${DOMAIN}"".* ""@""${DOMAIN}""\t\t""${USER}"":""${PASSWD}"" " "${DATABASE}" sed -i \
"s|^@${DOMAIN}.*|@${DOMAIN}\t\t${USER}:${PASSWD}|" \
"${DATABASE}"
else else
echo -e "@${DOMAIN}\t\t${USER}:${PASSWD}" >>"${DATABASE}" echo -e "@${DOMAIN}\t\t${USER}:${PASSWD}" >>"${DATABASE}"
fi fi

View file

@ -8,12 +8,16 @@ DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}
EMAIL="${1}" EMAIL="${1}"
RECIPIENT="${2}" RECIPIENT="${2}"
function usage { echo "Usage: delalias <alias@domain> <recipient@other>" ; } function __usage { echo "Usage: delalias <alias@domain> <recipient@other>" ; }
[[ -z ${EMAIL} ]] && { usage ; errex "Error: No alias specified" ; } [[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
[[ -z ${RECIPIENT} ]] && { usage ; errex "Error: No recipient specified" ; }
[[ -z ${EMAIL} ]] && { __usage ; errex "Error: No alias specified" ; }
[[ -z ${RECIPIENT} ]] && { __usage ; errex "Error: No recipient specified" ; }
[[ -s ${DATABASE} ]] || exit 0 [[ -s ${DATABASE} ]] || exit 0
sed -i -e "/^${EMAIL} *${RECIPIENT}$/d" \ sed -i \
-e "/^${EMAIL} *${RECIPIENT}$/d" \
-e "/^${EMAIL}/s/,${RECIPIENT}//g" \ -e "/^${EMAIL}/s/,${RECIPIENT}//g" \
-e "/^${EMAIL}/s/${RECIPIENT},//g" "${DATABASE}" -e "/^${EMAIL}/s/${RECIPIENT},//g" \
"${DATABASE}"

View file

@ -6,16 +6,18 @@
DATABASE=${DATABASE:-/tmp/docker-mailserver/dovecot-quotas.cf} DATABASE=${DATABASE:-/tmp/docker-mailserver/dovecot-quotas.cf}
USER_DATABASE=${USER_DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf} USER_DATABASE=${USER_DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}
function __usage { echo "Usage: delquota <username@domain>" ; }
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
USER="${1}" USER="${1}"
function usage { echo "Usage: delquota <username@domain>" ; } [[ -z ${USER} ]] && { __usage ; errex "No username specified" ; }
[[ "${USER}" =~ .*\@.* ]] || { __usage ; errex "Username must include the domain"; }
[[ -z ${USER} ]] && { usage ; errex "No username specified" ; }
[[ "${USER}" =~ .*\@.* ]] || { usage ; errex "username must include the domain"; }
if ! grep -qE "^${USER}\|" "${USER_DATABASE}" if ! grep -qE "^${USER}\|" "${USER_DATABASE}"
then then
usage __usage
errex "user ${USER} does not exist" errex "user ${USER} does not exist"
fi fi

View file

@ -8,4 +8,5 @@ DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}
[[ -f ${DATABASE} ]] || errex "Error: No postfix-virtual.cf file" [[ -f ${DATABASE} ]] || errex "Error: No postfix-virtual.cf file"
[[ -s ${DATABASE} ]] || errex "Error: Empty postfix-virtual.cf - no aliases have been added" [[ -s ${DATABASE} ]] || errex "Error: Empty postfix-virtual.cf - no aliases have been added"
( grep -v "^\s*$\|^\s*\#" "${DATABASE}" || true ) grep -v "^\s*$\|^\s*\#" "${DATABASE}"
exit 0

View file

@ -1,10 +1,5 @@
#! /bin/bash #! /bin/bash
# ? This is done to ignore the message "Make sure not to read and write
# ? the same file in the same pipeline", which is a result of ${DATABASE}
# ? being used below. (This disables the message file-wide.)
# shellcheck disable=SC2094
# shellcheck source=../scripts/helper-functions.sh # shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh . /usr/local/bin/helper-functions.sh
@ -13,8 +8,5 @@ DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}
[[ -f ${DATABASE} ]] || errex "Error: No postfix-virtual.cf file" [[ -f ${DATABASE} ]] || errex "Error: No postfix-virtual.cf file"
[[ -s ${DATABASE} ]] || errex "Error: Empty postfix-virtual.cf - no aliases have been added" [[ -s ${DATABASE} ]] || errex "Error: Empty postfix-virtual.cf - no aliases have been added"
# Lock database even though we are only reading { grep -v "^\s*$\|^\s*\#" "${DATABASE}" || true ; } | awk -F '|' '{ print $1; }'
( exit 0
flock -e 200
( grep -v "^\s*$\|^\s*\#" "${DATABASE}" || true ) | awk -F '|' '{ print $1; }'
) 200< "${DATABASE}"

View file

@ -48,11 +48,7 @@ function __usage
" "
} }
if [[ ${1:-} == 'help' ]] [[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
then
__usage
exit 0
fi
while [[ ${#} -gt 0 ]] while [[ ${#} -gt 0 ]]
do do

View file

@ -6,7 +6,7 @@ DMS_DEBUG="${DMS_DEBUG:=0}"
function errex function errex
{ {
echo "${@}" 1>&2 echo -e "Error :: ${*}\nAborting." >&2
exit 1 exit 1
} }
@ -149,13 +149,13 @@ function _populate_relayhost_map
sed -n '/^\s*[^#[:space:]]/ s/^[^@|]*@\([^|]\+\)|.*$/\1/p' /tmp/docker-mailserver/postfix-accounts.cf sed -n '/^\s*[^#[:space:]]/ s/^[^@|]*@\([^|]\+\)|.*$/\1/p' /tmp/docker-mailserver/postfix-accounts.cf
[ -f /tmp/docker-mailserver/postfix-virtual.cf ] && sed -n '/^\s*[^#[:space:]]/ s/^\s*[^@[:space:]]*@\(\S\+\)\s.*/\1/p' /tmp/docker-mailserver/postfix-virtual.cf [ -f /tmp/docker-mailserver/postfix-virtual.cf ] && sed -n '/^\s*[^#[:space:]]/ s/^\s*[^@[:space:]]*@\(\S\+\)\s.*/\1/p' /tmp/docker-mailserver/postfix-virtual.cf
} | while read -r domain } | while read -r DOMAIN
do do
# domain not already present *and* not ignored # DOMAIN not already present *and* not ignored
if ! grep -q -e "^@${domain}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${domain}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf if ! grep -q -e "^@${DOMAIN}\b" /etc/postfix/relayhost_map && ! grep -qs -e "^\s*@${DOMAIN}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf
then then
_notify 'inf' "Adding relay mapping for ${domain}" _notify 'inf' "Adding relay mapping for ${DOMAIN}"
echo "@${domain} [${RELAY_HOST}]:${RELAY_PORT}" >> /etc/postfix/relayhost_map echo "@${DOMAIN} [${RELAY_HOST}]:${RELAY_PORT}" >> /etc/postfix/relayhost_map
fi fi
done done
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
#! /bin/bash
function check
{
_notify 'tasklog' 'Checking configuration'
for FUNC in "${FUNCS_CHECK[@]}"
do
${FUNC} || _defunc
done
}
function _check_hostname
{
_notify 'task' 'Checking that hostname/domainname is provided or overridden'
if [[ -n ${OVERRIDE_HOSTNAME} ]]
then
export HOSTNAME=${OVERRIDE_HOSTNAME}
export DOMAINNAME="${HOSTNAME#*.}"
fi
_notify 'inf' "Domain has been set to ${DOMAINNAME}"
_notify 'inf' "Hostname has been set to ${HOSTNAME}"
if ! grep -q -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}"
then
_notify 'err' 'Setting hostname/domainname is required'
kill "$(< /var/run/supervisord.pid)"
return 1
fi
}

View file

@ -0,0 +1,154 @@
#! /bin/bash
function start_daemons
{
_notify 'tasklog' 'Starting daemons & mail server'
for FUNC in "${DAEMONS_START[@]}"
do
${FUNC} || _defunc
done
}
function _start_daemons_cron
{
_notify 'task' 'Starting cron'
supervisorctl start cron
}
function _start_daemons_rsyslog
{
_notify 'task' 'Starting rsyslog'
supervisorctl start rsyslog
}
function _start_daemons_saslauthd
{
_notify 'task' 'Starting saslauthd'
supervisorctl start "saslauthd_${SASLAUTHD_MECHANISMS}"
}
function _start_daemons_fail2ban
{
_notify 'task' 'Starting fail2ban'
touch /var/log/auth.log
# delete fail2ban.sock that probably was left here after container restart
if [[ -e /var/run/fail2ban/fail2ban.sock ]]
then
rm /var/run/fail2ban/fail2ban.sock
fi
supervisorctl start fail2ban
}
function _start_daemons_opendkim
{
_notify 'task' 'Starting opendkim'
supervisorctl start opendkim
}
function _start_daemons_opendmarc
{
_notify 'task' 'Starting opendmarc'
supervisorctl start opendmarc
}
function _start_daemons_postsrsd
{
_notify 'task' 'Starting postsrsd'
supervisorctl start postsrsd
}
function _start_daemons_postfix
{
_notify 'task' 'Starting postfix'
supervisorctl start postfix
}
function _start_daemons_dovecot
{
_notify 'task' 'Starting dovecot services'
if [[ ${ENABLE_POP3} -eq 1 ]]
then
_notify 'task' 'Starting pop3 services'
mv /etc/dovecot/protocols.d/pop3d.protocol.disab \
/etc/dovecot/protocols.d/pop3d.protocol
fi
if [[ -f /tmp/docker-mailserver/dovecot.cf ]]
then
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
fi
supervisorctl start dovecot
}
function _start_daemons_fetchmail
{
_notify 'task' 'Preparing fetchmail config'
/usr/local/bin/setup-fetchmail
if [[ ${FETCHMAIL_PARALLEL} -eq 1 ]]
then
mkdir /etc/fetchmailrc.d/
/usr/local/bin/fetchmailrc_split
local COUNTER=0
for RC in /etc/fetchmailrc.d/fetchmail-*.rc
do
COUNTER=$(( COUNTER + 1 ))
cat >"/etc/supervisor/conf.d/fetchmail-${COUNTER}.conf" << EOF
[program:fetchmail-${COUNTER}]
startsecs=0
autostart=false
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
user=fetchmail
command=/usr/bin/fetchmail -f ${RC} -v --nodetach --daemon %(ENV_FETCHMAIL_POLL)s -i /var/lib/fetchmail/.fetchmail-UIDL-cache --pidfile /var/run/fetchmail/%(program_name)s.pid
EOF
chmod 700 "${RC}"
chown fetchmail:root "${RC}"
done
supervisorctl reread
supervisorctl update
COUNTER=0
for _ in /etc/fetchmailrc.d/fetchmail-*.rc
do
COUNTER=$(( COUNTER + 1 ))
_notify 'task' "Starting fetchmail instance ${COUNTER}"
supervisorctl start "fetchmail-${COUNTER}"
done
else
_notify 'task' 'Starting fetchmail'
supervisorctl start fetchmail
fi
}
function _start_daemons_clamav
{
_notify 'task' 'Starting clamav'
supervisorctl start clamav
}
function _start_daemons_postgrey
{
_notify 'task' 'Starting postgrey'
rm -f /var/run/postgrey/postgrey.pid
supervisorctl start postgrey
}
function _start_daemons_amavis
{
_notify 'task' 'Starting amavis'
supervisorctl start amavis
}
function _start_changedetector
{
_notify 'task' 'Starting changedetector'
supervisorctl start changedetector
}

View file

@ -0,0 +1,53 @@
#! /bin/bash
function fix
{
_notify 'tasklog' 'Post-configuration checks'
for FUNC in "${FUNCS_FIX[@]}"
do
${FUNC} || _defunc
done
_notify 'inf' 'Removing leftover PID files from a stop/start'
rm -rf /var/run/*.pid /var/run/*/*.pid
touch /dev/shm/supervisor.sock
}
function _fix_var_mail_permissions
{
_notify 'task' 'Checking /var/mail permissions'
# 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
_notify 'inf' 'Fixing /var/mail permissions'
chown -R 5000:5000 /var/mail
else
_notify 'inf' 'Permissions in /var/mail look OK'
fi
}
function _fix_var_amavis_permissions
{
local AMAVIS_STATE_DIR='/var/mail-state/lib-amavis'
[[ ${ONE_DIR} -eq 0 ]] && AMAVIS_STATE_DIR="/var/lib/amavis"
[[ ! -e ${AMAVIS_STATE_DIR} ]] && return 0
_notify 'inf' 'Checking and fixing Amavis permissions'
chown -hR amavis:amavis "${AMAVIS_STATE_DIR}"
return 0
}
function _fix_cleanup_clamav
{
_notify 'task' 'Cleaning up disabled Clamav'
rm -f /etc/logrotate.d/clamav-*
rm -f /etc/cron.d/clamav-freshclam
}
function _fix_cleanup_spamassassin
{
_notify 'task' 'Cleaning up disabled spamassassin'
rm -f /etc/cron.daily/spamassassin
}

View file

@ -0,0 +1,64 @@
#! /bin/bash
function start_misc
{
_notify 'inf' 'Starting miscellaneous tasks'
for FUNC in "${FUNCS_MISC[@]}"
do
${FUNC} || _defunc
done
}
# consolidate all states into a single directory
# (/var/mail-state) to allow persistence using docker volumes
function _misc_save_states
{
local STATEDIR FILE FILES
STATEDIR='/var/mail-state'
if [[ ${ONE_DIR} -eq 1 ]] && [[ -d ${STATEDIR} ]]
then
_notify 'inf' "Consolidating all state onto ${STATEDIR}"
FILES=(
spool/postfix
lib/postfix
lib/amavis
lib/clamav
lib/spamassassin
lib/fail2ban
lib/postgrey
lib/dovecot
)
for FILE in "${FILES[@]}"
do
DEST="${STATEDIR}/${FILE//\//-}"
FILE="/var/${FILE}"
if [[ -d ${DEST} ]]
then
_notify 'inf' "Destination ${DEST} exists, linking ${FILE} to it"
rm -rf "${FILE}"
ln -s "${DEST}" "${FILE}"
elif [[ -d ${FILE} ]]
then
_notify 'inf' "Moving contents of ${FILE} to ${DEST}:" "$(ls "${FILE}")"
mv "${FILE}" "${DEST}"
ln -s "${DEST}" "${FILE}"
else
_notify 'inf' "Linking ${FILE} to ${DEST}"
mkdir -p "${DEST}"
ln -s "${DEST}" "${FILE}"
fi
done
_notify 'inf' 'Fixing /var/mail-state/* permissions'
chown -R clamav /var/mail-state/lib-clamav
chown -R postfix /var/mail-state/lib-postfix
chown -R postgrey /var/mail-state/lib-postgrey
chown -R debian-spamd /var/mail-state/lib-spamassassin
chown -R postfix /var/mail-state/spool-postfix
fi
}

File diff suppressed because it is too large Load diff

View file

@ -615,7 +615,7 @@ EOF
@test "checking accounts: user_without_domain creation should be rejected since user@domain format is required" { @test "checking accounts: user_without_domain creation should be rejected since user@domain format is required" {
run docker exec mail /bin/sh -c "addmailuser user_without_domain mypassword" run docker exec mail /bin/sh -c "addmailuser user_without_domain mypassword"
assert_failure assert_failure
assert_output --partial "username must include the domain" assert_output --partial "Username must include the domain"
} }
@test "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" { @test "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {