feat: Allow changing the Dovecot vmail UID/GID via ENV (#3550)
Some deployment scenarios are not compatible with `5000:5000` static vmail user with `/var/mail`. This feature allows adjusting the defaults to a UID / GID that is compatible. Signed-off-by: vincent <vincent@ducamps.win> Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
This commit is contained in:
parent
89cb6d85b9
commit
bd96c1161e
|
@ -33,6 +33,18 @@ Here you can adjust the [log-level for Supervisor](http://supervisord.org/loggin
|
||||||
|
|
||||||
The log-level will show everything in its class and above.
|
The log-level will show everything in its class and above.
|
||||||
|
|
||||||
|
##### DMS_VMAIL_UID
|
||||||
|
|
||||||
|
Default: 5000
|
||||||
|
|
||||||
|
The User ID assigned to the static vmail user for `/var/mail` (_Mail storage managed by Dovecot_).
|
||||||
|
|
||||||
|
##### DMS_VMAIL_GID
|
||||||
|
|
||||||
|
Default: 5000
|
||||||
|
|
||||||
|
The Group ID assigned to the static vmail group for `/var/mail` (_Mail storage managed by Dovecot_).
|
||||||
|
|
||||||
##### ONE_DIR
|
##### ONE_DIR
|
||||||
|
|
||||||
- 0 => state in default directories.
|
- 0 => state in default directories.
|
||||||
|
|
|
@ -34,6 +34,12 @@ SUPERVISOR_LOGLEVEL=
|
||||||
# 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
|
# 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
|
||||||
ONE_DIR=1
|
ONE_DIR=1
|
||||||
|
|
||||||
|
# Support for deployment where these defaults are not compatible (eg: some NAS appliances):
|
||||||
|
# /var/mail vmail User ID (default: 5000)
|
||||||
|
DMS_VMAIL_UID=
|
||||||
|
# /var/mail vmail Group ID (default: 5000)
|
||||||
|
DMS_VMAIL_GID=
|
||||||
|
|
||||||
# **empty** => use FILE
|
# **empty** => use FILE
|
||||||
# LDAP => use LDAP authentication
|
# LDAP => use LDAP authentication
|
||||||
# OIDC => use OIDC authentication (not yet implemented)
|
# OIDC => use OIDC authentication (not yet implemented)
|
||||||
|
|
|
@ -70,7 +70,7 @@ function _create_accounts() {
|
||||||
|
|
||||||
# Dovecot's userdb has the following format
|
# Dovecot's userdb has the following format
|
||||||
# user:password:uid:gid:(gecos):home:(shell):extra_fields
|
# user:password:uid:gid:(gecos):home:(shell):extra_fields
|
||||||
DOVECOT_USERDB_LINE="${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}/home::${USER_ATTRIBUTES}"
|
DOVECOT_USERDB_LINE="${LOGIN}:${PASS}:${DMS_VMAIL_UID}:${DMS_VMAIL_GID}::/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"
|
_log 'warn' "Login '${LOGIN}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||||
else
|
else
|
||||||
|
@ -141,7 +141,7 @@ function _create_dovecot_alias_dummy_accounts() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DOVECOT_USERDB_LINE="${ALIAS}:${REAL_ACC[1]}:5000:5000::/var/mail/${REAL_DOMAINNAME}/${REAL_USERNAME}::${REAL_ACC[2]:-}"
|
DOVECOT_USERDB_LINE="${ALIAS}:${REAL_ACC[1]}:${DMS_VMAIL_UID}:${DMS_VMAIL_GID}::/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"
|
_log 'warn' "Alias '${ALIAS}' will not be added to '${DOVECOT_USERDB_FILE}' twice"
|
||||||
else
|
else
|
||||||
|
|
|
@ -39,9 +39,9 @@ function _get_dms_env_value() {
|
||||||
# /var/mail folders (used during startup and change detection handling).
|
# /var/mail folders (used during startup and change detection handling).
|
||||||
function _chown_var_mail_if_necessary() {
|
function _chown_var_mail_if_necessary() {
|
||||||
# fix permissions, but skip this if 3 levels deep the user id is already set
|
# 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 "${DMS_VMAIL_UID}" -o \! -group "${DMS_VMAIL_GID}" \) | read -r; then
|
||||||
_log 'trace' 'Fixing /var/mail permissions'
|
_log 'trace' 'Fixing /var/mail permissions'
|
||||||
chown -R 5000:5000 /var/mail || return 1
|
chown -R "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" /var/mail || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ function _register_functions() {
|
||||||
|
|
||||||
# ? >> Setup
|
# ? >> Setup
|
||||||
|
|
||||||
|
_register_setup_function '_setup_vmail_id'
|
||||||
_register_setup_function '_setup_logs_general'
|
_register_setup_function '_setup_logs_general'
|
||||||
_register_setup_function '_setup_timezone'
|
_register_setup_function '_setup_timezone'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function _setup_vmail_id() {
|
||||||
|
if [[ "${DMS_VMAIL_UID}" != "5000" ]]; then
|
||||||
|
_log 'debug' "Setting 'docker' UID to ${DMS_VMAIL_UID}"
|
||||||
|
usermod --uid "${DMS_VMAIL_UID}" docker
|
||||||
|
fi
|
||||||
|
if [[ "${DMS_VMAIL_GID}" != "5000" ]]; then
|
||||||
|
_log 'debug' "Setting 'docker' GID to ${DMS_VMAIL_GID}"
|
||||||
|
groupmod --gid "${DMS_VMAIL_GID}" docker
|
||||||
|
fi
|
||||||
|
}
|
|
@ -46,6 +46,8 @@ function __environment_variables_general_setup() {
|
||||||
VARS[POSTMASTER_ADDRESS]="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
|
VARS[POSTMASTER_ADDRESS]="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
|
||||||
VARS[REPORT_RECIPIENT]="${REPORT_RECIPIENT:=${POSTMASTER_ADDRESS}}"
|
VARS[REPORT_RECIPIENT]="${REPORT_RECIPIENT:=${POSTMASTER_ADDRESS}}"
|
||||||
VARS[REPORT_SENDER]="${REPORT_SENDER:=mailserver-report@${HOSTNAME}}"
|
VARS[REPORT_SENDER]="${REPORT_SENDER:=mailserver-report@${HOSTNAME}}"
|
||||||
|
VARS[DMS_VMAIL_UID]="${DMS_VMAIL_UID:=5000}"
|
||||||
|
VARS[DMS_VMAIL_GID]="${DMS_VMAIL_GID:=5000}"
|
||||||
|
|
||||||
_log 'trace' 'Setting anti-spam & anti-virus environment variables'
|
_log 'trace' 'Setting anti-spam & anti-virus environment variables'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
load "${REPOSITORY_ROOT}/test/helper/common"
|
||||||
|
load "${REPOSITORY_ROOT}/test/helper/setup"
|
||||||
|
|
||||||
|
BATS_TEST_NAME_PREFIX='[ENV] (DMS_VMAIL_UID + DMS_VMAIL_GID) '
|
||||||
|
CONTAINER_NAME='dms-test_env-change-vmail-id'
|
||||||
|
|
||||||
|
function setup_file() {
|
||||||
|
_init_with_defaults
|
||||||
|
|
||||||
|
local CUSTOM_SETUP_ARGUMENTS=(
|
||||||
|
--env PERMIT_DOCKER=container
|
||||||
|
--env DMS_VMAIL_UID=9042
|
||||||
|
--env DMS_VMAIL_GID=9042
|
||||||
|
)
|
||||||
|
|
||||||
|
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||||
|
_wait_for_smtp_port_in_container
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
|
@test 'should successfully deliver mail' {
|
||||||
|
_send_email 'email-templates/existing-user1'
|
||||||
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
|
# Should be successfully sent (received) by Postfix:
|
||||||
|
_run_in_container grep 'to=<user1@localhost.localdomain>' /var/log/mail/mail.log
|
||||||
|
assert_success
|
||||||
|
assert_output --partial 'status=sent'
|
||||||
|
_should_output_number_of_lines 1
|
||||||
|
|
||||||
|
# Verify successful delivery via Dovecot to `/var/mail` account by searching for the subject:
|
||||||
|
_repeat_in_container_until_success_or_timeout 20 "${CONTAINER_NAME}" grep -R \
|
||||||
|
'Subject: Test Message existing-user1.txt' \
|
||||||
|
'/var/mail/localhost.localdomain/user1/new/'
|
||||||
|
assert_success
|
||||||
|
_should_output_number_of_lines 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: Migrate to test/helper/common.bash
|
||||||
|
# This test case is shared with tests.bats, but provides context on errors + some minor edits
|
||||||
|
# TODO: Could improve in future with keywords from https://github.com/docker-mailserver/docker-mailserver/pull/3550#issuecomment-1738509088
|
||||||
|
# Potentially via a helper that allows an optional fixed number of errors to be present if they were intentional
|
||||||
|
@test '/var/log/mail/mail.log is error free' {
|
||||||
|
# Postfix: https://serverfault.com/questions/934703/postfix-451-4-3-0-temporary-lookup-failure
|
||||||
|
_run_in_container grep 'non-null host address bits in' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Postfix delivery failure: https://github.com/docker-mailserver/docker-mailserver/issues/230
|
||||||
|
_run_in_container grep 'mail system configuration error' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Unknown error source: https://github.com/docker-mailserver/docker-mailserver/pull/85
|
||||||
|
_run_in_container grep -i ': error:' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Unknown error source: https://github.com/docker-mailserver/docker-mailserver/pull/320
|
||||||
|
_run_in_container grep -i 'not writable' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
_run_in_container grep -i 'permission denied' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Amavis: https://forum.howtoforge.com/threads/postfix-smtp-error-caused-by-clamav-cant-connect-to-a-unix-socket-var-run-clamav-clamd-ctl.81002/
|
||||||
|
_run_in_container grep -i '(!)connect' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Postfix: https://github.com/docker-mailserver/docker-mailserver/pull/2597
|
||||||
|
_run_in_container grep -i 'using backwards-compatible default setting' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
|
||||||
|
# Postgrey: https://github.com/docker-mailserver/docker-mailserver/pull/612#discussion_r117635774
|
||||||
|
_run_in_container grep -i 'connect to 127.0.0.1:10023: Connection refused' /var/log/mail/mail.log
|
||||||
|
assert_failure
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue