From c5a48f7c1477bbe6057aa247b86e7abce8953a14 Mon Sep 17 00:00:00 2001 From: GoliathLabs Date: Sun, 9 Apr 2023 21:19:18 +0200 Subject: [PATCH] Added: Initial support for shared mailboxes --- docs/content/config/environment.md | 17 +++++++++++++++ target/dovecot/10-mail.conf | 24 ++------------------- target/scripts/share-inbox.sh | 26 +++++++++++++++++++++++ target/scripts/start-mailserver.sh | 1 + target/scripts/startup/setup.d/dovecot.sh | 24 +++++++++++++++++++++ target/scripts/startup/variables-stack.sh | 4 ++++ 6 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 target/scripts/share-inbox.sh diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 9adfd5d9..a89f5907 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -876,6 +876,23 @@ The following variables overwrite the default values for ```/etc/dovecot/dovecot - Note: The left-hand value is the directory attribute, the right hand value is the dovecot variable. - More details on the [Dovecot Wiki](https://wiki.dovecot.org/AuthDatabase/LDAP/PasswordLookups) +##### DOVECOT_NAMESPACE_SEPARATOR + +- **empty** => separator of namespaces is backend-dependent +- typical namespace separator is slash `/` + +##### DOVECOT_ENABLE_INBOX_SHARING + +- **0** => inbox sharing is disabled +- 1 => inbox sharing is enabled + +In order to enable inbox sharing, you also need to specify a namespace separator using the `DOVECOT_NAMESPACE_SEPARATOR` variable. +Then, you may want to tweak [sharing settings](https://wiki.dovecot.org/SharedMailboxes/Shared) in the config file - `/etc/dovecot/11-shared.conf` in the container. +Finally, you will want to define how will Dovecot keep track of which mailboxes are shared to a particular user by [defining a dictionary](https://wiki.dovecot.org/Dictionary). + +You can share a mailbox by calling a script `/usr/local/bin/share-inbox.sh` in the container e.g. using `docker-compose exec`. +That script will sync [mailbox's ACLs](https://doc.dovecot.org/settings/plugin/acl/) together with the dictionary. + #### Postgrey ##### ENABLE_POSTGREY diff --git a/target/dovecot/10-mail.conf b/target/dovecot/10-mail.conf index f91fd1b2..ac2e4cb7 100644 --- a/target/dovecot/10-mail.conf +++ b/target/dovecot/10-mail.conf @@ -47,7 +47,7 @@ namespace inbox { # Hierarchy separator to use. You should use the same separator for all # namespaces or some clients get confused. '/' is usually a good one. # The default however depends on the underlying mail storage format. - #separator = + #@DOVECOT_NAMESPACE_SEPARATOR_CLAUSE@ # Prefix required to access this namespace. This needs to be different for # all namespaces. For example "Public/". @@ -78,28 +78,8 @@ namespace inbox { #subscriptions = yes } -# Example shared namespace configuration -#namespace { - #type = shared - #separator = / +# See 11-shared.conf for shared inbox configuration - # Mailboxes are visible under "shared/user@domain/" - # %%n, %%d and %%u are expanded to the destination user. - #prefix = shared/%%u/ - - # Mail location for other users' mailboxes. Note that %variables and ~/ - # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the - # destination user's data. - #location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u - - # Use the default namespace for saving subscriptions. - #subscriptions = no - - # List the shared/ namespace only if there are visible shared mailboxes. - #list = children -#} -# Should shared INBOX be visible as "shared/user" or "shared/user/INBOX"? -#mail_shared_explicit_inbox = no # System user and group used to access mails. If you use multiple, userdb # can override these by returning uid or gid fields. You can use either numbers diff --git a/target/scripts/share-inbox.sh b/target/scripts/share-inbox.sh new file mode 100644 index 00000000..5eb8ffd5 --- /dev/null +++ b/target/scripts/share-inbox.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# $1: The source account name +# $2: The account name of who receives access +# $3, $4 and so on: list of permissions - one of: lookup read write write-seen write-deleted insert post expunge +# Call me like this: share_inbox.sh office bob lookup read + +DOMAIN=$(hostname -d) +if [[ "${ENABLE_SHARED_INBOX}" = 0 ]] +then + echo "You have to enable inbox sharing by means of 'ENABLE_SHARED_INBOX' before actually sharing anything." >&2 + exit 1 +fi + +if ! grep -q '\.' <<< "${DOMAIN}" +then + echo "Couldn't detect the target domain - 'hostname -d' returned '${DOMAIN}', which seems to be garbage. Configure the container, so it is aware of its domain" >&2 + exit 1 +fi + +SHARING=$1 +shift +SHARED_TO=$1 +shift + +doveadm acl add -u "${SHARING}@${DOMAIN}" 'Inbox' "user=${SHARED_TO}@${DOMAIN}" "$@" diff --git a/target/scripts/start-mailserver.sh b/target/scripts/start-mailserver.sh index cbe38da9..ef1013f7 100755 --- a/target/scripts/start-mailserver.sh +++ b/target/scripts/start-mailserver.sh @@ -95,6 +95,7 @@ function _register_functions() { _register_setup_function '_setup_docker_permit' _register_setup_function '_setup_mailname' _register_setup_function '_setup_dovecot_hostname' + _register_setup_function '_setup_dovecot_namespaces' _register_setup_function '_setup_postfix_early' diff --git a/target/scripts/startup/setup.d/dovecot.sh b/target/scripts/startup/setup.d/dovecot.sh index 8e7dcfe7..73e9d6f1 100644 --- a/target/scripts/startup/setup.d/dovecot.sh +++ b/target/scripts/startup/setup.d/dovecot.sh @@ -197,3 +197,27 @@ function _setup_dovecot_hostname() { _log 'debug' 'Applying hostname to Dovecot' sedfile -i "s|^#hostname =.*$|hostname = '${HOSTNAME}'|g" /etc/dovecot/conf.d/15-lda.conf } + +function _setup_dovecot_namespaces +{ + _log 'info' "Setting up dovecot namespaces" + uncomment_shared_config_contents=no + if [[ ${DOVECOT_ENABLE_INBOX_SHARING} = 0 ]] + then + _log 'info' "Shared inboxes are disabled - the '${DOVECOT_SHARED_INBOX_CONFIG}' config file is left commented out" + else + uncomment_shared_config_contents=yes + fi + if [[ -z ${DOVECOT_NAMESPACE_SEPARATOR} ]] + then + [[ "${DOVECOT_ENABLE_INBOX_SHARING}" = 1 ]] && _log 'warn' 'Namespace separator has to be defined in order for shared inboxes to work.' + uncomment_shared_config_contents=no + DOVECOT_NAMESPACE_SEPARATOR_CLAUSE="# ${DOVECOT_NAMESPACE_SEPARATOR_CLAUSE}" + else + DOVECOT_NAMESPACE_SEPARATOR_CLAUSE="${DOVECOT_NAMESPACE_SEPARATOR_CLAUSE}" + fi + + [[ "${uncomment_shared_config_contents}" = yes ]] && sed -i -e "s/^#<#//" "/etc/dovecot/conf.d/${VARS[DOVECOT_SHARED_INBOX_CONFIG]}" + sed -i "s|#@DOVECOT_NAMESPACE_SEPARATOR_CLAUSE@|${DOVECOT_NAMESPACE_SEPARATOR_CLAUSE}|" /etc/dovecot/conf.d/10-mail.conf + sed -i "s|@DOVECOT_NAMESPACE_SEPARATOR_CLAUSE@|${DOVECOT_NAMESPACE_SEPARATOR_CLAUSE}|" "/etc/dovecot/conf.d/${DOVECOT_SHARED_INBOX_CONFIG}" +} \ No newline at end of file diff --git a/target/scripts/startup/variables-stack.sh b/target/scripts/startup/variables-stack.sh index a3be72b8..9ac16653 100644 --- a/target/scripts/startup/variables-stack.sh +++ b/target/scripts/startup/variables-stack.sh @@ -123,6 +123,10 @@ function __environment_variables_general_setup() { VARS[DOVECOT_INET_PROTOCOLS]="${DOVECOT_INET_PROTOCOLS:=all}" VARS[DOVECOT_MAILBOX_FORMAT]="${DOVECOT_MAILBOX_FORMAT:=maildir}" VARS[DOVECOT_TLS]="${DOVECOT_TLS:=no}" + VARS[DOVECOT_ENABLE_INBOX_SHARING]="${DOVECOT_ENABLE_INBOX_SHARING:=0}" + VARS[DOVECOT_NAMESPACE_SEPARATOR_CLAUSE]="separator = ${DOVECOT_NAMESPACE_SEPARATOR}" + VARS[DOVECOT_SHARED_INBOX_CONFIG]="11-shared.conf" + VARS[POSTFIX_DAGENT]="${POSTFIX_DAGENT:=}" VARS[POSTFIX_INET_PROTOCOLS]="${POSTFIX_INET_PROTOCOLS:=all}"