docker-mailserver: [BUG] Mailbox contents not deleted

Bug Report

Context

Mailbox contents remain in maildata subdirectory after running sudo ./setup.sh email del test@example.com.

What is affected by this bug?

Deleting mailboxes.

When does this occur?

When deleting a mailbox with the setup.sh script.

How do we replicate the issue?

sudo ./setup.sh email del test@example.com
Password: 
sed: can't read /tmp/docker-mailserver/postfix-virtual.cf: No such file or directory
Do you want to delete the mailbox as well(all mails will be removed)?(y/n) y

Mailbox deleted.

Check contents of maildata subdirectory.

Behavior

Actual Behavior

The mailbox is no longer listed when running sudo ./setup.sh email list. But the test mailbox and its contents are still in the maildata subdirectory.

Expected Behavior

The mailbox contents should have been deleted.

Your Environment

Synology DS918+ with latest DSM and Docker version 18.09.8, build bfed4f5.

Environment Variables

---
version: "2"

# Define services
services:
  
  roundcubemail:
    image: roundcube/roundcubemail:latest
    container_name: roundcubemail
    restart: unless-stopped
    volumes:
      - /v/d/roundcube/www:/var/www/html
      - /v/d/roundcube/sqlite:/var/roundcube/db
    ports:
      - 127.0.0.1:8000:80
    environment:
      - ROUNDCUBEMAIL_DB_TYPE=sqlite
      - ROUNDCUBEMAIL_SKIN=elastic
      - ROUNDCUBEMAIL_DEFAULT_HOST=ssl://mail.example.com
      - ROUNDCUBEMAIL_SMTP_SERVER=ssl://mail.example.com
      - ROUNDCUBEMAIL_DEFAULT_PORT=993
      - ROUNDCUBEMAIL_SMTP_PORT=465
  
  solr:
    container_name: mailserver_solr
    image: lmmdock/dovecot-solr:latest
    volumes:
      - /v/d/solr-dovecot:/opt/solr/server/solr/dovecot
    restart: always
  
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    hostname: mail
    domainname: example.com
    container_name: mailserver
    ports:
      - "465:465"
      - "993:993"
    volumes:
      - /v/d/mailserver/maildata:/var/mail
      - /v/d/mailserver/mailstate:/var/mail-state
      - /v/d/mailserver/maillogs:/var/log/mail
      - /v/d/mailserver/config:/tmp/docker-mailserver/
      - /v/d/ssl/output:/tmp/ssl:ro
      - /v/d/mailserver/solr-dovecot/10-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro
    environment:
      - SSL_TYPE=manual
      - SSL_CERT_PATH=/tmp/ssl/fullchain.pem
      - SSL_KEY_PATH=/tmp/ssl/privkey.pem
      - POSTFIX_MESSAGE_SIZE_LIMIT=102400000
      - ENABLE_SPAMASSASSIN=0
      - ENABLE_CLAMAV=0
      - ENABLE_FAIL2BAN=0
      - ENABLE_POSTGREY=0
      - ENABLE_SASLAUTHD=0
      - ONE_DIR=1
      - DMS_DEBUG=0
    cap_add:
      - NET_ADMIN
      - SYS_PTRACE
    restart: always

Workaround?

Contents of mailbox are deleted when running sudo docker exec mailserver rm -R /var/mail/example.com/test/ afterwards.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 38 (25 by maintainers)

Commits related to this issue

Most upvoted comments

Oh, I just saw, that I mixed hostname/container name. I’ve edited my post.

I took mail from the posted docker-compose.yml above 😉

Which one? I can only see container_name: mailserver 😃

I think it’s not yet working.

DS918p:/volume1/docker/mailserver-edge$ sudo ./setup.sh email add test@example.com test
DS918p:/volume1/docker/mailserver-edge$ sudo ./setup.sh email del test@example.com
Do you want to delete the mailbox as well (removing all mails) ? [Y/n] y
Mailbox directory '/var/mail/example.com/test' did not exist.

I manually confirmed /var/mail/example.com/test exists. Also I was able to login to the test account using Roundcube and I made a draft message to test.

Also I expected pressing Enter in response to this question: Do you want to delete the mailbox as well (removing all mails) ? [Y/n] would go for the Y option since it’s capitalised. But it went with n instead and gave me this: Leaving the mailbox untouched. If you want to delete it at a later point use 'sudo docker exec mail rm -R /var/mail/example.com/test'.

Manually running sudo docker exec mail rm -R /var/mail/example.com/test was so far still the only way to actually remove the mailbox contents.

This:

#! /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
. /usr/local/bin/helper-functions.sh

DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}
ALIAS_DATABASE="/tmp/docker-mailserver/postfix-virtual.cf"
QUOTA_DATABASE="/tmp/docker-mailserver/dovecot-quotas.cf"

function usage
{
  echo "Usage: delmailuser [-y] <user@domain> <user2@anotherdomain> ..."
}

while getopts ":y" OPT
do
  case ${OPT} in
    y)
      MAILDEL="y"
      ;;
    \?)
      usage
      errex "Invalid option: -${OPTARG}"
      ;;
    *)
      usage
      errex "Invalid option: -${OPTARG}"
      ;;
  esac
done

shift $((OPTIND-1))

[[ -z ${*} ]] && { usage ; errex "No user specifed" ; }
[[ -s ${DATABASE} ]] || exit 0

(
  flock -e 200

  for USER in "${@}"
  do
    # very simple plausibility check
    [[ ${USER} != *'@'*'.'* ]] && errex "No valid address: ${USER}"

    declare -a MAILARR
    MAILARR[0]="${USER%@.*}"
    MAILARR[1]="${USER#.*@}"

    # ${USER} must not contain /s and other syntactic characters
    USER=$(escape "${USER}")

    if [[ -f ${DATABASE} ]]
    then
      if ! sed -i "/^""${USER}""|/d" "${DATABASE}"
      then
        errex "${USER} couldn't be deleted in ${DATABASE}. ${?}"
      fi
    fi

    if [[ -f ${ALIAS_DATABASE} ]]
    then
      # delete all aliases where the user is the only recipient( " ${USER$}" )
      # delete user only for all aliases that deliver to multiple recipients ( ",${USER}" "${USER,}" )
      if sed -i \
        -e "/ ""${USER}""$/d" -e "s/,""${USER}""//g" -e "s/""${USER}"",//g" \
        "${ALIAS_DATABASE}"
      then
        echo "${USER} and potential aliases deleted."
      else
        errex "Aliases for ${USER} couldn't be deleted in ${ALIAS_DATABASE}. ${?}"
      fi
    fi

    # remove quota directives
    if [[ -f ${QUOTA_DATABASE} ]]
    then
      if ! sed -i -e "/^${USER}:.*$/d" "${QUOTA_DATABASE}"
      then
        errex "Quota for ${USER} couldn't be deleted in ${QUOTA_DATABASE}. ${?}"
      fi
    fi

    if [[ ${MAILDEL} != "y" ]]
    then
      read -r -p "Do you want to delete the mailbox as well(all mails will be removed)?(y/n) " MAILDEL
    fi

    if [[ ${MAILDEL} != "y" ]]
    then
      echo "Leaving the mailbox untouched. If you want to delete it at a later point use 'sudo docker exec mail rm -R /var/mail/${MAILARR[1]}/${MAILARR[0]}'"
      exit 0
    fi

    if [[ -d "/var/mail/${MAILARR[1]}/${MAILARR[0]}" ]]
    then
      if rm -r -f "/var/mail/${MAILARR[1]}/${MAILARR[0]}"
      then
        echo "Mailbox deleted."
      else
        errex "Mailbox couldn't be deleted: ${?}"
      fi
    else
      errex "Mailbox directory '/var/mail/${MAILARR[1]}/${MAILARR[0]}' does not exist."
    fi
  done

) 200< "${DATABASE}"

is my refactoring. Seems a lot cleaner and more robust to me.