diff --git a/target/dovecot/auth-passwdfile.inc b/target/dovecot/auth-passwdfile.inc index bba1af7e..d05c9abb 100644 --- a/target/dovecot/auth-passwdfile.inc +++ b/target/dovecot/auth-passwdfile.inc @@ -1,21 +1,19 @@ # Authentication for passwd-file users. Included from 10-auth.conf. # -# passwd-like file with specified location. -# +# Documentation +# PassDB: https://doc.dovecot.org/configuration_manual/authentication/password_databases_passdb/ +# UserDB: https://doc.dovecot.org/configuration_manual/authentication/user_databases_userdb/ +# +# !!! Attention !!! +# Do not add `scheme=SHA512-CRYPT` to the userdb args. This is not supported. passdb { driver = passwd-file - args = scheme=CRYPT username_format=%u /etc/dovecot/userdb + args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/userdb } userdb { driver = passwd-file args = username_format=%u /etc/dovecot/userdb - - # Default fields that can be overridden by passwd-file - #default_fields = quota_rule=*:storage=1G default_fields = uid=docker gid=docker home=/var/mail/%d/%u - - # Override fields from passwd-file - #override_fields = home=/home/virtual/%u } diff --git a/target/scripts/helper-functions.sh b/target/scripts/helper-functions.sh index 3333af73..832e9533 100755 --- a/target/scripts/helper-functions.sh +++ b/target/scripts/helper-functions.sh @@ -27,33 +27,33 @@ function dms_panic local SHUTDOWN_MESSAGE - case "${PANIC_TYPE}" in + case "${PANIC_TYPE:-}" in ( 'fail-init' ) # PANIC_INFO == SHUTDOWN_MESSAGE="Failed to start ${PANIC_INFO}!" - ;; + ;; ( 'no-env' ) # PANIC_INFO == SHUTDOWN_MESSAGE="Environment Variable: ${PANIC_INFO} is not set!" - ;; + ;; ( 'no-file' ) # PANIC_INFO == SHUTDOWN_MESSAGE="File ${PANIC_INFO} does not exist!" - ;; + ;; ( 'misconfigured' ) # PANIC_INFO == SHUTDOWN_MESSAGE="${PANIC_INFO} appears to be misconfigured, please verify." - ;; + ;; ( 'invalid-value' ) # PANIC_INFO == SHUTDOWN_MESSAGE="Invalid value for ${PANIC_INFO}!" - ;; + ;; ( * ) # `dms_panic` was called directly without a valid PANIC_TYPE SHUTDOWN_MESSAGE='Something broke :(' - ;; + ;; esac - if [[ -n ${PANIC_SCOPE} ]] + if [[ -n ${PANIC_SCOPE:-} ]] then _shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}" else diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index 98b6463c..c6e48ea9 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -332,6 +332,7 @@ function _setup_dovecot_local_user # creating users ; 'pass' is encrypted # comments and empty lines are ignored + local LOGIN PASS USER_ATTRIBUTES while IFS=$'|' read -r LOGIN PASS USER_ATTRIBUTES do # Setting variables for better readability @@ -342,24 +343,31 @@ function _setup_dovecot_local_user 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) - unset IFS + IFS=':' read -r -a USER_QUOTA < <(grep "${USER}@${DOMAIN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf) - [[ ${#USER_QUOTA[@]} -eq 2 ]] && USER_ATTRIBUTES="${USER_ATTRIBUTES} userdb_quota_rule=*:bytes=${USER_QUOTA[1]}" + if [[ ${#USER_QUOTA[@]} -eq 2 ]] + then + USER_ATTRIBUTES="${USER_ATTRIBUTES:+${USER_ATTRIBUTES} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}" + fi fi - # Let's go! - _notify 'inf' "user '${USER}' for domain '${DOMAIN}' with password '********', attr=${USER_ATTRIBUTES}" + if [[ -z ${USER_ATTRIBUTES} ]] + then + _notify 'inf' "Creating user '${USER}' for domain '${DOMAIN}'" + else + _notify 'inf' "Creating user '${USER}' for domain '${DOMAIN}' with attributes '${USER_ATTRIBUTES}'" + fi echo "${LOGIN} ${DOMAIN}/${USER}/" >> /etc/postfix/vmailbox - # User database for dovecot has the following format: + # Dovecot's userdb has the following format # user:password:uid:gid:(gecos):home:(shell):extra_fields - # Example : - # ${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}::userdb_mail=maildir:/var/mail/${DOMAIN}/${USER} - echo "${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}::${USER_ATTRIBUTES}" >> /etc/dovecot/userdb + echo \ + "${LOGIN}:${PASS}:5000:5000::/var/mail/${DOMAIN}/${USER}::${USER_ATTRIBUTES}" \ + >>/etc/dovecot/userdb + mkdir -p "/var/mail/${DOMAIN}/${USER}" - # Copy user provided sieve file, if present + # copy user provided sieve file, if present if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]] then cp "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" "/var/mail/${DOMAIN}/${USER}/.dovecot.sieve" @@ -367,6 +375,65 @@ function _setup_dovecot_local_user echo "${DOMAIN}" >> /tmp/vhost.tmp done < <(grep -v "^\s*$\|^\s*\#" /tmp/docker-mailserver/postfix-accounts.cf) + + # see https://github.com/docker-mailserver/docker-mailserver/pull/2248#issuecomment-953313852 + # for more details on this section + if [[ -f /tmp/docker-mailserver/postfix-virtual.cf ]] && [[ ${ENABLE_QUOTAS} -eq 1 ]] + then + # adding aliases to Dovecot's userdb + # ${REAL_FQUN} is a user's fully-qualified username + local ALIAS REAL_FQUN + while read -r ALIAS REAL_FQUN + do + # ignore comments + [[ ${ALIAS} == \#* ]] && continue + + # alias is assumed to not be a proper e-mail + # these aliases do not need to be added to Dovecot's userdb + [[ ! ${ALIAS} == *@* ]] && continue + + # clear possibly already filled arrays + # do not remove the following line of code + unset REAL_ACC USER_QUOTA + declare -a REAL_ACC USER_QUOTA + + local REAL_USERNAME REAL_DOMAINNAME + REAL_USERNAME=$(cut -d '@' -f 1 <<< "${REAL_FQUN}") + REAL_DOMAINNAME=$(cut -d '@' -f 2 <<< "${REAL_FQUN}") + + if ! grep -q "${REAL_FQUN}" /tmp/docker-mailserver/postfix-accounts.cf + then + _notify 'inf' "Alias '${ALIAS}' is non-local (or mapped to a non-existing account) and will not be added to Dovecot's userdb" + continue + fi + + _notify 'inf' "Adding alias '${ALIAS}' for user '${REAL_FQUN}' to Dovecot's userdb" + + # ${REAL_ACC[0]} => real account name (e-mail address) == ${REAL_FQUN} + # ${REAL_ACC[1]} => password hash + # ${REAL_ACC[2]} => optional user attributes + IFS='|' read -r -a REAL_ACC < <(grep "${REAL_FQUN}" /tmp/docker-mailserver/postfix-accounts.cf) + + 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 + IFS=':' read -r -a USER_QUOTA < <(grep "${REAL_FQUN}:" -i /tmp/docker-mailserver/dovecot-quotas.cf) + if [[ ${#USER_QUOTA[@]} -eq 2 ]] + then + REAL_ACC[2]="${REAL_ACC[2]:+${REAL_ACC[2]} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}" + fi + fi + + echo \ + "${ALIAS}:${REAL_ACC[1]}:5000:5000::/var/mail/${REAL_DOMAINNAME}/${REAL_USERNAME}::${REAL_ACC[2]:-}" \ + >> /etc/dovecot/userdb + done < /tmp/docker-mailserver/postfix-virtual.cf + fi else _notify 'inf' "'/tmp/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created." fi diff --git a/test/config/dovecot-lmtp/conf.d/auth-passwdfile.conf.ext b/test/config/dovecot-lmtp/conf.d/auth-passwdfile.conf.ext index c89d28c6..d05c9abb 100644 --- a/test/config/dovecot-lmtp/conf.d/auth-passwdfile.conf.ext +++ b/test/config/dovecot-lmtp/conf.d/auth-passwdfile.conf.ext @@ -1,20 +1,19 @@ # Authentication for passwd-file users. Included from 10-auth.conf. # -# passwd-like file with specified location. -# +# Documentation +# PassDB: https://doc.dovecot.org/configuration_manual/authentication/password_databases_passdb/ +# UserDB: https://doc.dovecot.org/configuration_manual/authentication/user_databases_userdb/ +# +# !!! Attention !!! +# Do not add `scheme=SHA512-CRYPT` to the userdb args. This is not supported. passdb { driver = passwd-file - args = scheme=CRYPT username_format=%u /etc/dovecot/users + args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/userdb } userdb { driver = passwd-file - args = username_format=%u /etc/dovecot/users - - # Default fields that can be overridden by passwd-file - #default_fields = quota_rule=*:storage=1G - - # Override fields from passwd-file - #override_fields = home=/home/virtual/%u + args = username_format=%u /etc/dovecot/userdb + default_fields = uid=docker gid=docker home=/var/mail/%d/%u } diff --git a/test/config/dovecot-lmtp/conf.d/auth-passwdfile.inc b/test/config/dovecot-lmtp/conf.d/auth-passwdfile.inc index bba1af7e..d05c9abb 100644 --- a/test/config/dovecot-lmtp/conf.d/auth-passwdfile.inc +++ b/test/config/dovecot-lmtp/conf.d/auth-passwdfile.inc @@ -1,21 +1,19 @@ # Authentication for passwd-file users. Included from 10-auth.conf. # -# passwd-like file with specified location. -# +# Documentation +# PassDB: https://doc.dovecot.org/configuration_manual/authentication/password_databases_passdb/ +# UserDB: https://doc.dovecot.org/configuration_manual/authentication/user_databases_userdb/ +# +# !!! Attention !!! +# Do not add `scheme=SHA512-CRYPT` to the userdb args. This is not supported. passdb { driver = passwd-file - args = scheme=CRYPT username_format=%u /etc/dovecot/userdb + args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/userdb } userdb { driver = passwd-file args = username_format=%u /etc/dovecot/userdb - - # Default fields that can be overridden by passwd-file - #default_fields = quota_rule=*:storage=1G default_fields = uid=docker gid=docker home=/var/mail/%d/%u - - # Override fields from passwd-file - #override_fields = home=/home/virtual/%u }