commit a9fe479dd4b9fe0c00f1ba96c274599e96b9d695 Author: Christoph Date: Tue Feb 21 01:17:11 2017 +0100 Initial import diff --git a/install_update_dovecot.sh b/install_update_dovecot.sh new file mode 100755 index 0000000..015d7cc --- /dev/null +++ b/install_update_dovecot.sh @@ -0,0 +1,3246 @@ +#!/usr/bin/env bash + +## ------------------------------------------------------------------- +## - Install/Update Dovecot Server + + +## *************************************************** ## +## - rage.so36.net - ## +## - +# +### - Set update=false if that is a new installation +#_update=true +# +#_version=2.2.18 +#_pigeonhole=dovecot-2.2-pigeonhole-0.4.8 +# +#_src_base_dir=/usr/local/src/mailsystem +#_log_dir=${_src_base_dir}/log-dovecot-$_version +# +#postmaster_address="roots\@so36.net" +#hostname="rage.so36.net" +# +#ipv4="83.223.73.211" +#ipv6="2a01:30:1fff:fd00::211" +# +#imap_listener_adresses="127.0.0.1 $ipv4 $ipv6" +#imaps_listener_adresses="127.0.0.1 $ipv4 $ipv6" +# +#pop_listener_adresses="$ipv4 $ipv6" +#pops_listener_adresses="127.0.0.1 $ipv4 $ipv6" +# +#database=postgres +##database=mysql +# +#dbname=postfix +#dbuser=postfix +#dbpassword=9jKqFHNGrgFb +#dbhost=/var/run/postgresql +# +#default_pass_scheme=CRYPT +# +#cert_base_dir="/etc/postfix/ssl" +#server_cert=${cert_base_dir}/mailserver.crt +#server_key=${cert_base_dir}/mailserver.key +# +#imap_cert=${cert_base_dir}/imap.crt +#imap_key=${cert_base_dir}/imap.key +# +#pop_cert=${cert_base_dir}/pop.crt +#pop_key=${cert_base_dir}/pop.key +# +#spam_folder=Spam +# +#xmpp_listener=true +#xmpp_listener_address="127.0.0.1" +#xmpp_listener_port="4444" +# +#max_userip_connections=24 +##auth_mechanisms="plain login digest-md5 cram-md5" +#auth_mechanisms="plain login" +# +## quota warning sript +#from_address="so36.net " +#reply_to="support@so36.net" +#webmailer="https:\\webmail.so36.net" +#salutation="so36.NET" +## - +## - rage.so36.net - ## +## *************************************************** ## + +## *************************************************** ## +## - a.mx.oopen.de - ## +## - + +## - Set update=false if that is a new installation +#_update=true +# +#_version=2.2.18 +#_pigeonhole=dovecot-2.2-pigeonhole-0.4.8 +# +#_src_base_dir=/usr/local/src/mailsystem +#_log_dir=${_src_base_dir}/log-dovecot-$_version +# +#postmaster_address="admin\@oopen.de" +#hostname="a.mx.oopen.de" +# +#ipv4="83.223.85.164" +#ipv6="2a01:30:1fff:9::164" +# +#imap_listener_adresses="127.0.0.1 $ipv4 $ipv6" +#imaps_listener_adresses="$ipv4 $ipv6" +# +#pop_listener_adresses="$ipv4 $ipv6" +#pops_listener_adresses="$ipv4 $ipv6" +# +#database=postgres +##database=mysql +# +#dbname=postfix +#dbuser=postfix +#dbpassword=FKt4z55FxMZp +#dbhost=/var/run/postgresql +# +#default_pass_scheme=PLAIN +# +#cert_base_dir="/etc/postfix/ssl" +#server_cert=${cert_base_dir}/mailserver.crt +#server_key=${cert_base_dir}/mailserver.key +# +#imap_cert=${cert_base_dir}/imap.crt +#imap_key=${cert_base_dir}/imap.key +# +#pop_cert=${cert_base_dir}/pop.crt +#pop_key=${cert_base_dir}/pop.key +# +#spam_folder=Spam +# +#xmpp_listener=false +#xmpp_listener_address="127.0.0.1" +#xmpp_listener_port="4444" +# +#max_userip_connections=24 +##auth_mechanisms="plain login digest-md5 cram-md5" +#auth_mechanisms="plain login digest-md5 cram-md5 apop" +# +## quota warning sript +#from_address="o.open " +#reply_to="oo@oopen.de" +#webmailer="https:\\webmail.oopen.de" +#salutation="O.OPEN +# +#-- +#O.OPEN | Phone: +49 30 / 290 484 91 +#Erkelenzdamm 21 | Fax: +49 30 / 290 484 99 +#D-10999 Berlin | http://oopen.de" +## - +## - a.mx.oopen.de - ## +## *************************************************** ## + +## *************************************************** ## +## - c.mx.oopen.de - ## +## - + +## - Set update=false if that is a new installation +#_update=true +# +#_version=2.2.18 +#_pigeonhole=dovecot-2.2-pigeonhole-0.4.8 +# +#_src_base_dir=/usr/local/src/mailsystem +#_log_dir=${_src_base_dir}/log-dovecot-$_version +# +#postmaster_address="admin\@oopen.de" +#hostname="c.mx.oopen.de" +# +#ipv4="83.223.85.101" +#ipv6="2a01:30:1fff:3::101" +# +#imap_listener_adresses="127.0.0.1 $ipv4 $ipv6" +#imaps_listener_adresses="$ipv4 $ipv6" +# +#pop_listener_adresses="$ipv4 $ipv6" +#pops_listener_adresses="$ipv4 $ipv6" +# +##database=postgres +#database=mysql +# +#dbname=postfix +#dbuser=postfix +#dbpassword=AeB4kohyie5rahJ7 +#dbhost=/tmp/mysqld.sock +# +#default_pass_scheme=PLAIN +# +#cert_base_dir="/etc/postfix/ssl" +#server_cert=${cert_base_dir}/mail.initiativenserver.crt +#server_key=${cert_base_dir}/mail.initiativenserver.key +# +#imap_cert=${cert_base_dir}/mail.initiativenserver.crt +#imap_key=${cert_base_dir}/mail.initiativenserver.key +# +#pop_cert=${cert_base_dir}/mail.initiativenserver.crt +#pop_key=${cert_base_dir}/mail.initiativenserver.key +# +#spam_folder=Junk +# +#xmpp_listener=false +#xmpp_listener_address="127.0.0.1" +#xmpp_listener_port="4444" +# +#max_userip_connections=24 +##auth_mechanisms="plain login digest-md5 cram-md5" +#auth_mechanisms="plain login digest-md5 cram-md5 apop" +# +## quota warning sript +#from_address="Initiativenserver " +#reply_to="kontakt@initiativenserver.de" +#webmailer="https:\\webmail.initiativenserver.de" +#salutation="Aktionsbündnis gegen Gewalt, Rechtsextremismus und Fremdenfeindlichkeit +# +#-- +#Initiativenserver | phone: 0331 505824-28 +#Mittelstraße 38/39 | fax: 0331 505824-29 +#14467 Potsdam | email: kontakt@initiativenserver.de" +## - +## - c.mx.oopen.de - ## +## *************************************************** ## + +## *************************************************** ## +## - mx.warenform.de - ## +## - + +## - Set update=false if that is a new installation +#_update=true +# +#_version=2.2.13 +#_pigeonhole=dovecot-2.2-pigeonhole-0.4.3 +# +#_src_base_dir=/usr/local/src/mailsystem +#_log_dir=${_src_base_dir}/log-dovecot-$_version +# +#postmaster_address="admin\@warenform.net" +#hostname="mx.warenform.de" +# +#ipv4="83.223.85.151" +#ipv6="2a01:30:1fff:6::151" +# +#imap_listener_adresses="127.0.0.1 $ipv4 $ipv6" +#imaps_listener_adresses="$ipv4 $ipv6" +# +#pop_listener_adresses="$ipv4 $ipv6" +#pops_listener_adresses="$ipv4 $ipv6" +# +#database=postgres +##database=mysql +# +#dbname=postfix +#dbuser=postfix +#dbpassword=CbX8vg347Vvm +#dbhost=/var/run/postgresql +# +#default_pass_scheme=PLAIN +# +#cert_base_dir="/etc/postfix/ssl" +#server_cert=${cert_base_dir}/servercert.pem +#server_key=${cert_base_dir}/servercert.pem +# +#imap_cert=${cert_base_dir}/imap_warenform_de.crt +#imap_key=${cert_base_dir}/imap_warenform_de.key +# +#pop_cert=${cert_base_dir}/pop_warenform_de.crt +#pop_key=${cert_base_dir}/pop_warenform_de.key +# +#spam_folder=Spam +# +#xmpp_listener=false +#xmpp_listener_address="127.0.0.1" +#xmpp_listener_port="4444" +# +#max_userip_connections=24 +##auth_mechanisms="plain login digest-md5 cram-md5" +#auth_mechanisms="plain login digest-md5 cram-md5 apop" +# +## quota warning sript +#from_address="warenform gbr " +#reply_to="hilfe@kunden.warenform.net" +#webmailer="https:\\webmail.initiativenserver.de" +#salutation="Das WARENFORM-Team +# +#-- +#WARENFORM | Phone: +49 30 / 61 65 17 52 -0 +#Dresdner Str. 11 | Fax: +49 30 / 61 65 17 52 -66 +#D-10999 Berlin | http://www.warenform.net" +## - +## - mx.warenform.de - ## +## *************************************************** ## + + +curdir=`pwd` +rc_done="\033[71G[ \033[32mdone\033[m ]" +rc_failed="\033[71G[ \033[31m\033[1mfailed\033[m ]" +rc_skipped="\033[71G[ \033[33m\033[1mskipped\033[m ]" + + + +## *************************************************** ## +## - functions - ## +## - +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e "$*\\c" 1>&2 + else + echo -en "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo Fehler: $* + echo -e "\n\t\033[31m\033[1mSkript wird abgebrochen\033[m\033[m\n" + exit 1 +} +## - +## - Ende: functions - ## +## *************************************************** ## + +clear; + +echo "" +if $_update ;then + echo -e "\tUpdate Dovecot................: $_update" +else + echo -e "\tInstall Dovecot first time....: Yes" +fi +echo "" +echo -e "\tDovecot (new) version.........: $_version" +echo -e "\t(Sieve) pigeonhole version....: $_pigeonhole" +echo "" +echo -e "\tSFolder containing sources....: $_src_base_dir" +echo "" +echo -e "\tPostmaser adress..............: $postmaster_address" +echo -e "\tHostname......................: $hostname" +echo "" +echo -e "\tIPv4 address..................: $ipv4" +echo -e "\tIPv6 address..................: $ipv6" +echo "" +echo -e "\tIMAP listener addresses.......: $imap_listener_adresses" +echo -e "\tIMAPS listener addresses......: $imaps_listener_adresses" +echo "" +echo -e "\tPOP3 listener addresses.......: $pop_listener_adresses" +echo -e "\tPOP3S listener addresses......: $pops_listener_adresses" +echo "" +echo -e "\tDatenbank.....................: $database" +echo "" +echo -e "\tPostfix database host.........: $dbhost" +echo -e "\tPostfix database name.........: $dbname" +echo -e "\tPostfix database user.........: $dbuser" +echo -e "\tPostfix database password.....: $dbpassword" +echo "" +echo -e "\tDefault password scheme.......: $default_pass_scheme" +echo "" +echo -e "\tCertificat base directory.....: $cert_base_dir" +echo -e "\tServer certificate............: $server_cert" +echo -e "\tServer key....................: $server_key" +echo "" +echo -e "\tImap certificate..............: $imap_cert" +echo -e "\tImap key......................: $imap_key" +echo "" +echo -e "\tPop certificate...............: $pop_cert" +echo -e "\tPop key.......................: $pop_key" +echo "" + +echo -e "\tSpan folder...................: $spam_folder" +echo -e "\tMax user connections per ip...: $max_userip_connections" +echo "" +echo -e "\tAuth Listener (Jabber)........: $xmpp_listener" +if $xmpp_listener ; then + echo -e "\t Auth Listener Addresses....: $xmpp_listener_address" + echo -e "\t AUTH Listener PORT.........: $xmpp_listener_port" +fi +echo "" + +echononl "Sind die Angaben richtig [ja/nein]: " +read OK +while [ "X$OK" != "Xyes" -a "X$OK" != "XYes" -a "X$OK" != "Xja" -a "X$OK" != "XJa" \ + -a "X$OK" != "XNo" -a "X$OK" != "Xno" -a "X$OK" != "Xn" -a "X$OK" != "Xnein" -a "X$OK" != "XNein" ] +do + echononl "falsche Angabe! [ja/nein] :" + read OK +done + +[ $OK = "Yes" -o $OK = "yes" -o "$OK" = "ja" -o "$OK" = "Ja" ] || fatal Edit basename $0 and correct variables + +echo "" + +if $_update ;then + _new=false; +else + _new=true; +fi + +if [ "$database" = "mysql" ]; then + db_driver=mysql +else + db_driver=pgsql +fi + +if $_new ; then + if [ "$database" = "mysql" ]; then + + echo "" + echo "--" + echo "" + echo "Gib den Benutzernamen des/eines MySQL root user an.." + echo "" + _MYSQL_ROOT_USER=root + MYSQL_ROOT_USER= + while [ "X$MYSQL_ROOT_USER" = "X" ] + do + echononl "MySQL-User [${_MYSQL_ROOT_USER}]: " + read MYSQL_ROOT_USER + if [ "X$MYSQL_ROOT_USER" = "X" ]; then + MYSQL_ROOT_USER=$_MYSQL_ROOT_USER + fi + done + + + echo "" + echo "--" + echo "" + echo "Gib ein Passwort für den root user an.." + echo "" + _MYSQL_ROOT_PW_1="X" + _MYSQL_ROOT_PW_2="Y" + while [ "$_MYSQL_ROOT_PW_1" != "$_MYSQL_ROOT_PW_2" ] + do + echononl "Passworteingabe: " + read -s _MYSQL_ROOT_PW_1 + echo + if [ "X$_MYSQL_ROOT_PW_1" = "X" ]; then + echo -e "\n\t\033[33m\033[1mPassworteingabe erforderlich!\033[m\n" + continue + fi + echononl "Passwortwiederholung: " + read -s _MYSQL_ROOT_PW_2 + echo + if [ "X$_MYSQL_ROOT_PW_2" = "X" ]; then + echo -e "\n\t\033[33m\033[1mPasswortwiederholung erforderlich!\033[m\n" + continue + fi + if [ "$_MYSQL_ROOT_PW_1" != "$_MYSQL_ROOT_PW_2" ];then + echo -e "\n\t\033[33m\033[1mPassworteingaben sind nicht identisch!\033[m\n" + else + MYSQL_ROOT_PW=$_MYSQL_ROOT_PW_1 + fi + done + fi +fi + +export PGPASSWORD=$dbpassword +mkdir -p $_log_dir + + +## ----------------- +## --- Download + +cd ${_src_base_dir}/tarballs + +echo "Download sources.." + +## - Downloud Dovecot 2.2.x +## - +echononl "\tDownload dovecot-${_version}.tar.gz" +if [ ! -f "${_src_base_dir}/tarballs/dovecot-${_version}.tar.gz" ]; then + wget http://www.dovecot.org/releases/2.2/dovecot-${_version}.tar.gz > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Download failed" + fi +else + echo -e "$rc_skipped" +fi + + +## - Download Pigeonhole for Dovecot v2.2 +## - +echononl "\tDownload ${_pigeonhole}.tar.gz.." +if [ ! -f "${_src_base_dir}/tarballs/${_pigeonhole}.tar.gz" ]; then + wget http://pigeonhole.dovecot.org/releases/2.2/${_pigeonhole}.tar.gz > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Download failed" + fi +else + echo -e "$rc_skipped" +fi + + + +if $_new ; then + ## - Install reqired debian packages + ## - + echo "" + echo "Installing required debian packages.." + echononl "\tInstalling libpq5 libpq-dev .." + if ! dpkg -l libpq-dev | grep -e "^ii" | grep libpq-dev > /dev/null ; then + apt-get install libpq5 libpq-dev > ${_log_dir}/debian-install.log 2&>1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "installing debian package(s) failed" + fi + else + echo -e "$rc_skipped" + fi + echononl "\tInstalling libkrb5-dev .." + if ! dpkg -l libkrb5-dev | grep -e "^ii" | grep libkrb5-dev > /dev/null ; then + apt-get install libkrb5-dev >> ${_log_dir}/debian-install.log 2&>1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "installing debian package(s) failed" + fi + else + echo -e "$rc_skipped" + fi + + + ## ----------------- + ## - Create Users/groups needed for dovecot + + echo "" + echo "Create required users/groups.." + echononl "\tCreate group dovecot.." + if ! grep dovecot /etc/group > /dev/null ; then + addgroup --system --gid 91 dovecot > ${_log_dir}/system.log 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Create group failed + fi + else + echo -e "$rc_skipped" + fi + + echononl "\tCreate user dovecot.." + if ! grep dovecot /etc/passwd > /dev/null ; then + adduser --system --home /var/empty --no-create-home --shell /usr/sbin/nologin \ + --ingroup dovecot --uid 91 dovecot > ${_log_dir}/system.log 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Create user failed + fi + else + echo -e "$rc_skipped" + fi + + + echononl "\tCreate group dovenull.." + if ! grep dovenull /etc/group > /dev/null ; then + addgroup --system --gid 65533 dovenull > ${_log_dir}/system.log 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Create group failed + fi + else + echo -e "$rc_skipped" + fi + echononl "\tCreate user dovenull.." + if ! grep dovenull /etc/passwd > /dev/null ; then + adduser --system --home /var/empty --no-create-home --shell /usr/sbin/nologin \ + --ingroup dovenull --uid 65533 dovenull > ${_log_dir}/system.log 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Create user failed + fi + else + echo -e "$rc_skipped" + fi + +fi + + +## ----------------- +## --- Install Base System + +echo "" +echo "Installing Base System.." + +cd ${_src_base_dir} +echononl "\tUnpack dovecot-${_version}.tar.gz.." +tar -xzf tarballs/dovecot-${_version}.tar.gz > /dev/null +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Extracting dovecot failed +fi + +cd dovecot-${_version} + +echononl "\tConfigure Dovecot.." +./configure \ + --prefix=/usr/local/dovecot-${_version} \ + --with-${db_driver} \ + --with-gssapi=yes > ${_log_dir}/dovecot-${_version}-configure.log 2>&1 + + #--with-systemdsystemunitdir=/etc/systemd/system \ + +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Configuring dovecot failed +fi + +echononl "\tCompile Dovecot Sources.." +make > ${_log_dir}/dovecot-${_version}-make.log 2>&1 || exit 1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Compiling dovecot failed +fi +echononl "\tInstall Dovecot into Folder /usr/local/dovecot-${_version}" +make install > ${_log_dir}/dovecot-${_version}-install.log 2>&1 || exit 1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Installing dovecot failed +fi + + +## - Add /usr/local/dovecot/bin to PATH variable +## - +## - Edit /etc/profile and add bevor "export PATH" directive: +## - +## - checkdir="/usr/local/dovecot/bin" +## - if [ -d $checkdir ]; then +## - PATH=$PATH:$checkdir +## - fi +## - +echononl "\tAdd /usr/local/dovecot/bin to PATH variable.." +if ! grep "checkdir=\"/usr/local/dovecot/bin\"" /etc/profile > /dev/null ; then + perl -i -n -p -e "s#^(\s*)(export\ +PATH)#checkdir=\"/usr/local/dovecot/bin\"\nif [ -d \\\$checkdir ]; then\n PATH=\\\$PATH:\\\$checkdir\nfi\n\n\1\2#" /etc/profile +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Adjusting /etc/profile failed +fi +else + echo -e "$rc_skipped" +fi + +echononl "\tCopy Manpages if not exists.." +## - Manpages +## - +if ! grep /usr/local/dovecot/share/man /etc/manpath.config > /dev/null 2<&1 ; then + echo >> /etc/manpath.config + echo "MANDATORY_MANPATH /usr/local/dovecot/share/man /var/cache/man" >> /etc/manpath.config + echo "MANPATH_MAP /usr/local/dovecot/bin /usr/local/dovecot/share/man" >> /etc/manpath.config + echo "MANDB_MAP /usr/local/dovecot/share/man /var/cache/man" >> /etc/manpath.config + echo -e "$rc_done" +else + echo -e "$rc_skipped" +fi + + +## ----------------- +## --- Install Pigeonhole ManageSieve + +cd ${_src_base_dir} +echo "" +echononl "\tExtracting ${_pigeonhole}.tar.gz.." +gunzip < tarballs/${_pigeonhole}.tar.gz | tar -xf - +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Extracting ${_pigeonhole}.tar.gz failed +fi +cd ${_pigeonhole} + + +echononl "\tConfigure Pigeonhole ManageSieve.." +./configure \ + --prefix=/usr/local/dovecot-${_version} \ + --with-dovecot=/usr/local/dovecot-${_version}/lib/dovecot > ${_log_dir}/${_pigeonhole}-configure.log 2<&1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Configuring Pigeonhole ManageSieve failed +fi + +echononl "\tCompile Pigeonhole ManageSieve.." +make > ${_log_dir}/${_pigeonhole}-make.log 2<&1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Compiling Pigeonhole ManageSieve failed +fi + +echononl "\tInstall Pigeonhole ManageSieve.." +make install > ${_log_dir}/${_pigeonhole}-install.log 2<&1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Installing Pigeonhole ManageSieve failed +fi + + +## ----------------- +## --- Configure dovecot services + +_failed=false +echo "" +echo "Configure Dovecot.." + +## - Copy example config files to the config directory +## - +cp -r /usr/local/dovecot-${_version}/share/doc/dovecot/example-config/* \ + /usr/local/dovecot-${_version}/etc/dovecot/ + + +## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf +## - +## - protocols = imap pop3 sieve +## - listen = $ipv4 $ipv6 +## - base_dir = /var/run/dovecot/ +## - shutdown_clients = no +## - +## - dict { +## - expire = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext +## - } +## - +echononl "\tAdjust file dovecot.conf.." +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(listen\ ?=.*)#\1\#\# \2\n\1listen = $ipv4 $ipv6#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(protocols\ ?=.*)#\1\#\# \2\n\1protocols = imap pop3 sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(base_dir\ ?=.*)#\1\#\# \2\n\1base_dir = /var/run/dovecot/#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(shutdown_clients\ ?=.*)#\1\#\# \2\n\1shutdown_clients = no#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 expire = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true + + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" +fi + + + +if $_new ; then + + if [ "$db_driver" = "pgsql" ]; then + + count=`su - postgres -c "psql -q -A -t -l" | grep -c -e "^$dbname"` + if [ $count -eq 0 ];then + echononl "\tCreate database user ${dbuser}.." + echo "CREATE ROLE $dbuser WITH LOGIN NOCREATEDB NOCREATEROLE NOSUPERUSER ENCRYPTED PASSWORD '$dbpassword'" \ + | su - postgres -c "psql" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Creating database user $dbuser failed + fi + + echononl "\tCreate database ${dbname}.." + su - postgres -c "createdb -E utf8 -O ${dbuser} $dbname" + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Creating database $dbname failed + fi + fi + + ## - Create table expires in database ${dbname} + ## - + echononl "\tCreate table expires in database ${dbname}.." + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 + +create table expires ( + username varchar(100) not null, + mailbox varchar(255) not null, + expire_stamp integer not null, + primary key (username, mailbox) +); +EOF + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Creating table expires failed + fi + + echononl "\tCreate function merge_expires() / trigger mergeexpires.." + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +CREATE LANGUAGE plpgsql; + +create or replace function merge_expires() returns trigger as \$\$ +begin + update expires set expire_stamp = new.expire_stamp + where username = new.username and mailbox = new.mailbox; + if found then + return null; + else + return new; + end if; +end; +\$\$ language plpgsql; + +create trigger mergeexpires before insert on expires + for each row execute procedure merge_expires(); +EOF + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating function merge_expires() / trigger mergeexpires failed" + fi + + elif [ "$db_driver" = "mysql" ]; then + + if ! mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ + "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$dbname'" 2>/dev/null \ + | grep $_db_name > /dev/null 2>&1 ; then + + echononl "\tCreate database ${dbname}.." + mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ + "CREATE DATABASE IF NOT EXISTS $dbname CHARACTER SET utf8 COLLATE utf8_general_ci" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating database $dbname failed" + fi + + echononl "\tCreate database user ${dbuser}.." + mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ + "GRANT ALL ON ${dbname}.* TO '${dbuser}'@'localhost' IDENTIFIED BY '$dbpassword'" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating database user $dbuser failed" + fi + + echononl "\tFlushing database privileges.." + mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e "FLUSH PRIVILEGES" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Flushing database privileges failed" + fi + + fi + + + ## - Create table expires in database ${dbname} + ## - + echononl "\tCreate table expires in database ${dbname}.." + cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 + +create table expires ( + username varchar(100) not null, + mailbox varchar(255) not null, + expire_stamp integer not null, + primary key (username, mailbox) +); +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal Creating table expires failed + fi + fi +fi + + +if [ "$db_driver" = "pgsql" ]; then + + ## - create sql-dict.conf.ext file + ## - + echononl "\tCreate file sql-dict.conf.ext" + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + + +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + +## - if using postgres, you need also to create a trigger as follows: +## - +## - first create language plpgsql if not yet created: +## - +# CREATE LANGUAGE plpgsql; +# +# CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ +# BEGIN +# UPDATE expires SET expire_stamp = NEW.expire_stamp +# WHERE username = NEW.username AND mailbox = NEW.mailbox; +# IF FOUND THEN +# RETURN NULL; +# ELSE +# RETURN NEW; +# END IF; +# END; +# \$\$ LANGUAGE plpgsql; +# +# CREATE TRIGGER mergeexpires BEFORE INSERT ON expires +# FOR EACH ROW EXECUTE PROCEDURE merge_expires(); + + +map { +pattern = shared/expire/\$user/\$mailbox +table = expires +value_field = expire_stamp + +fields { + username = \$user + mailbox = \$mailbox +} +} +EOF + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating file sql-dict.conf.ext failed" + fi + +elif [ "$db_driver" = "mysql" ]; then + + ## - create sql-dict.conf.ext file + ## - + echononl "\tCreate file sql-dict.conf.ext" + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + + +map { +pattern = shared/expire/\$user/\$mailbox +table = expires +value_field = expire_stamp + +fields { + username = \$user + mailbox = \$mailbox +} +} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating file sql-dict.conf.ext failed" + fi +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf +## - +## - default_process_limit = 200 +## - default_client_limit = 2000 +## - +## - !! Bemerkung +## - Das Hochsetzen des default_client_limit Parameters auf einen Wert größer +## - als 1024 geht nur dann wenn auch die Anzahl der zulässigen "open files" +## - (default = 1024) geändert wird. Z.Bsp. in der Datei /etc/init.d/dovecot +## - durch Einfügen der zeile: +## - ulimit -n 32768 +## - +## - Linux VServer: +## - put the following lines into /etc/security/limits.conf +## - +## - @staff hard nofile 32768 +## - root hard nofile 32768 +## - +## - !! Mybe you have also create file /etc/vservers/*/ulimits/nofiles.hard +## - with the same contents: +## - +## - @staff hard nofile 32768 +## - @adm hard nofile 32768 +## - root hard nofile 32768 +## - +## - see also http://linux-vserver.org/Ulimit_Nofiles +## - +## - +## - +## - service auth { +## - +## - # Auth Listener (XMPP - Jabber) +## - inet_listener { +## - address = $xmpp_listener_address +## - port = $xmpp_listener_port +## - } +## - .. +## - unix_listener auth-userdb { +## - mode = 0666 +## - user = dovecot +## - group = dovecot +## - } +## - .. +## - unix_listener /var/spool/postfix/private/dovecot-auth { +## - mode = 0666 +## - user = postfix +## - group = postfix +## - } +## - .. +## - } +## - +## - service imap-login { +## - inet_listener imap { +## - address = $imap_listener_adresses +## - .. +## - } +## - inet_listener imaps { +## - address = $imaps_listener_adresses +## - .. +## - } +## - +## - process_min_avail = 16 +## - } +## - +## - service pop3-login { +## - inet_listener pop3 { +## - address = $pop_listener_adresses +## - .. +## - } +## - inet_listener pop3s { +## - address = $pops_listener_adresses +## - .. +## - } +## - } +## - +echononl "\tAdjusting file 10-master.conf.." +perl -i.ORIG -n -p -e "s#^([ ]*)(unix_listener\ +auth-userdb.*)#\1\2\n\1 mode = 0666\n\1 user = dovecot\n\1 group = dovecot#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(\#.*Postfix.*smtp-auth.*)#\1\2\n\1unix_listener /var/spool/postfix/private/dovecot-auth {\n\1 mode = 0666\n\1 user = postfix\n\1 group = postfix\n\1}#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(inet_listener\ +imap\ .*)#\1\2\n\1 address = $imap_listener_adresses#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(inet_listener\ +imaps.*)#\1\2\n\1 address = $imaps_listener_adresses#g#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(\#?process_min_avail\ ?=.*)#\1\#\# \2\n\1process_min_avail = 16#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(inet_listener\ +pop3\ .*)#\1\2\n\1 address = $pop_listener_adresses#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(inet_listener\ +pop3s.*)#\1\2\n\1 address = $pops_listener_adresses#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true + +if $xmpp_listener ; then + perl -i -n -p -e "s#^([ ]*)(service auth\s+\{.*)#\1\2\n\n \# Auth Listener (XMPP - Jabber)\n inet_listener {\n address = $xmpp_listener_address\n port = $xmpp_listener_port\n }\n#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +fi + +## - setting default prozcess/client limit +## - +perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_process_limit.*)#\1\2\ndefault_process_limit = 200#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_client_limit.*)#\1\2\ndefault_client_limit = 2000#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-ssl.conf +## - +## - ssl_cert = <$server_cert +## - ssl_key = <$server_key +## - +## - ssl_dh_parameters_length = 2048 +## - +## - ssl_protocols = !SSLv2 !SSLv3 +## - +## - ssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA +## - +## - ssl_prefer_server_ciphers = yes +## - +## - +## - there are another possibilities to handle certs, but this did'nt work +## - as i expected.. +## - #local_name imap.warenform.de { +## - # ssl_cert = <$imap_cert +## - # ssl_key = <$imap_key +## - #} +## - #local_name pop.warenform.de { +## - # ssl_cert = <$pop_cert +## - # ssl_key = <$pop_key +## - #} +## - +echononl "\tAdjusting file 10-ssl.conf.." +perl -i.ORIG -n -p -e "s#^([ ]*)(ssl_cert\ ?=.*)#\1\#\# \2\n\1ssl_cert = <$server_cert#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(ssl_key\ ?=.*)#\1\#\# \2\n\1ssl_key = <$server_key#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?(ssl_dh_parameters_length\ ?=.*)#\1\#\# \2\nssl_dh_parameters_length = 2048#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?(ssl_protocols\ ?=.*)#\1\#\# \2\nssl_protocols = !SSLv2 !SSLv3#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true + +perl -i -n -p -e "s#^([ ]*)\#?(ssl_cipher_list\ ?=.*)#\1\#\# \2\nssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true + +perl -i -n -p -e "s#^([ ]*)\#?(ssl_prefer_server_ciphers\ ?=.*)#\1\#\# \2\nssl_prefer_server_ciphers = yes#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file 10-ssl.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf +## - +## - mail_location = maildir:/var/vmail/%d/%n/Maildir +## - +## - mail_uid = vmail +## - mail_gid = vmail +## - +## - first_valid_uid = 5000 +## - last_valid_uid = 5000 +## - +## - first_valid_gid = 5000 +## - last_valid_gid = 5000 +## - +## - auth_socket_path = /var/run/dovecot/auth-userdb +## - mail_plugins = quota expire +## - +echononl "\tAdjusting file 10-mail.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(mail_location\ +=.*)#\1\#\# \2\n\1mail_location = maildir:/var/vmail/%d/%n/Maildir#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_uid.*)#\1\#\# \2\n\1mail_uid = vmail#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_gid.*)#\1\#\# \2\n\1mail_gid = vmail#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(first_valid_uid.*)#\1\#\# \2\n\1first_valid_uid = 5000#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(last_valid_uid.*)#\1\#\# \2\n\1last_valid_uid = 5000#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(first_valid_gid.*)#\1\#\# \2\n\1first_valid_gid = 5000#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(last_valid_gid.*)#\1\#\# \2\n\1last_valid_gid = 5000#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_socket_path\ +=.*)#\1\#\# \2\n\1auth_socket_path = /var/run/dovecot/auth-userdb#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota expire#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf +## - +## - comment out namespace section "namespace inbox". we will create namespaces later. +## - in detail, tha means comment out 3 lines: +## - namespace inbox { +## - .. +## - inbox = yes +## - .. +## - } +## - +perl -i -n -p -e "s#^([ ]*)(namespace\ +inbox\ +{\ *)#\1\#\#\ \2#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(inbox\ +=\ +yes\ *)#\1\#\#\ \2#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(}\ *)#\1\#\#\ \2#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf +## - +## - Add namespaces type private +## - +## - Add: +## - namespace inbox { +## - type = private +## - separator = / +## - prefix = +## - inbox = yes +## - } +## - +echononl "\tAdd namespaces type private to file 10-mail.conf" +cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf + +## - Namespaces +## - +namespace inbox { + # Namespace type: private, shared or public + type = private + + # 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 = + separator = / + + # Prefix required to access this namespace. This needs to be different for + # all namespaces. For example "Public/". + #prefix = + prefix = + + # Physical location of the mailbox. This is in same format as + # mail_location, which is also the default for it. + #location = + + # There can be only one INBOX, and this setting defines which namespace + # has it. + #inbox = no + inbox = yes + + # If namespace is hidden, it's not advertised to clients via NAMESPACE + # extension. You'll most likely also want to set list=no. This is mostly + # useful when converting from another server with different namespaces which + # you want to deprecate but still keep working. For example you can create + # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/". + #hidden = no + + # Show the mailboxes under this namespace with LIST command. This makes the + # namespace visible for clients that don't support NAMESPACE extension. + # "children" value lists child mailboxes, but hides the namespace prefix. + #list = yes + + # Namespace handles its own subscriptions. If set to "no", the parent + # namespace handles them (empty prefix should always have this as "yes") + #subscriptions = yes +} +EOF +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/15-mailboxes.conf +## - +## - Add definitions for mailbox Spam: +## - +## - mailbox Drafts { +## - auto = subscribe +## - special_use = \Drafts +## - } +## - +## - mailbox Trash { +## - auto = subscribe +## - special_use = \Trash +## - } +## - +## - mailbox Sent { +## - auto = subscribe +## - special_use = \Sent +## - } +## - +## - mailbox $spam_folder { +## - auto = subscribe +## - special_use = \Junk +## - } +## - +echononl "\tAdjusting file 15-mailboxes.conf" +if [ "$spam_folder" != "Junk" ]; then + perl -i.ORIG -n -p -e "s#^([ ]*)(mailbox\ +Junk\ +{.*)#\1mailbox $spam_folder {\n\1 auto = subscribe\n\1 special_use = \\\Junk\n\1}\n\1\2#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true +else + perl -i.ORIG -n -p -e "s#^([ ]*)(mailbox\ +$spam_folder\ +{.*)#\1\2\n\1 auto = subscribe#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true +fi +perl -i -n -p -e "s#^([ ]*)(mailbox\ +Drafts\ +{.*)#\1\2\n\1 auto = subscribe#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(mailbox\ +Trash\ +{.*)#\1\2\n\1 auto = subscribe#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)(mailbox\ +Sent\ +{.*)#\1\2\n\1 auto = subscribe#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-auth.conf +## - +## - disable_plaintext_auth = no +## - auth_mechanisms = $auth_mechanisms +## - !include auth-sql.conf.ext # comment all other includes +## - auth_username_translation = "%@" +## - +echononl "\tAdjusting file 10-auth.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(disable_plaintext_auth\ +=.*)#\1\#\# \2\n\1disable_plaintext_auth = no#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_mechanisms\ +=.*)#\1\#\# \2\n\1auth_mechanisms = $auth_mechanisms#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true +perl -i -n -p -e "s#^(\!include\ auth-.*)#\#\1#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true +perl -i -n -p -e "s#^\#(\!include\ auth-sql.*)#\1#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_username_translation\ +=.*)#\1\#\# \2\n\1auth_username_translation = \"%@\"#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf failed" +fi + + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/auth-sql.conf.ext +## - +## - passdb { +## - driver = sql +## - +## - +## - # path for sql configuration file, see example-config/dovecot-sql.conf.ext +## - args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext +## - } +## - +## - .. +## - +## - userdb { +## - driver = sql +## - args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext +## - } +## - +echononl "\tAdjusting file auth-sql.conf.ext" +perl -i.ORIG -n -p -e "s#^([ ]*)(args\ ?=.*)#\1\#\# \2\n\1args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/auth-sql.conf.ext + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/auth-sql.conf.ext failed" +fi + +## - create sql configuration file +## - +echononl "\tCreate sql configuration file sql-connect.conf.ext" +if [ "$db_driver" = "pgsql" ]; then + + cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext +driver = $db_driver +## - if using unix-socket (host=/var/run/postgresql) ensure that +## - coresponding entries in pg_hba.cof fits +## - for example +## - local all all md5 +## - +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +default_pass_scheme = $default_pass_scheme +password_query = SELECT username AS user, password \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true +user_query = SELECT '/var/vmail/' || maildir AS home, \\ + '5000' AS uid, '5000' AS gid \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true + #WHERE username = substring ('%u' from '#"[^-]+#"_*@%%' for '#') || '@%d' and active = true + +## - Query to get a list of all usernames. +## - +iterate_query = SELECT username AS user FROM mailbox +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" + fi + +elif [ "$db_driver" = "mysql" ]; then + + cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext +driver = $db_driver +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +default_pass_scheme = $default_pass_scheme +password_query = SELECT username AS user, password \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true +user_query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\ + '5000' AS uid, '5000' AS gid \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true + +## - Query to get a list of all usernames. +## - +iterate_query = SELECT username AS user FROM mailbox +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" + fi +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-logging.conf +## - +## - +## - if running inetd-script: +## - +## - log_path = /var/log/dovecot/dovecot.log +## - +## - or for example +## - +## - log_path = syslog +## - syslog_facility = local1 +## - auth_verbose = yes +## - auth_verbose_passwords = plain +## - +## - in conjunction with the the following entries in /etc/rsyslog.conf +## - +## - local1.* -/var/log/dovecot.log +## - local1.info -/var/log/dovecot.info +## - local1.warn -/var/log/dovecot.warn +## - local1.err -/var/log/dovecot.err +## - :msg,contains,"stored mail into mailbox"\ +## - -/var/log/dovecot.lmtp +## - +echononl "\tAdjusting file 10-logging.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(log_path\ ?=.*)#\1\#\# \2\n\1log_path = syslog#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(syslog_facility\ ?=.*)#\1\#\# \2\n\1syslog_facility = local1#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_verbose\ ?=.*)#\1\#\# \2\n\1auth_verbose = yes#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_verbose_passwords\ ?=.*)#\1\#\# \2\n\1auth_verbose_passwords = plain#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf failed" +fi + + +if $_new ; then + + mkdir -p /var/log/dovecot + + echo + echononl "\tCreate file /etc/rsyslog.d/dovecot.conf" + cat < /etc/rsyslog.d/dovecot.conf + +## - dovecot +## - +local1.info -/var/log/dovecot/dovecot.info +local1.warn -/var/log/dovecot/dovecot.warn +local1.err -/var/log/dovecot/dovecot.err +:msg,contains,"stored mail into mailbox" \\ + -/var/log/dovecot/dovecot.lmtp +local1.* -/var/log/dovecot/dovecot.log +& ~ + +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating file /etc/rsyslog.d/dovecot.conf failed" + fi + + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Restarting rsyslog failed" + fi + + + ## - logrotate for dovecot log-files + ## - + echononl "\tCreate file /etc/logrotate.d/dovecot" + cat < /etc/logrotate.d/dovecot + /var/log/dovecot/dovecot.log + /var/log/dovecot/dovecot.info + /var/log/dovecot/dovecot.warn + /var/log/dovecot/dovecot.err + /var/log/dovecot/dovecot.lmtp { + daily + start 0 + rotate 7 + missingok + notifempty + compress + delaycompress + create 640 root adm + copytruncate + #sharedscripts + #postrotate + #/etc/init.d/dovecot reload > /dev/null + #/bin/kill -usr1 'cat /var/run/dovecot/master.pid 2>/dev/null' 2>/dev/null || true + #endscript + } +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating file /etc/logrotate.d/dovecot failed" + fi + echo +fi + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/15-lda.conf +## - +## - postmaster_address = $postmaster_address +## - hostname = $hostname +## - sendmail_path = /usr/sbin/sendmail +## - lda_mailbox_autocreate = no +## - mail_plugins = $mail_plugins sieve +## - +echononl "\tAdjusting file 15-lda.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(postmaster_address\ +=.*)#\1\#\# \2\n\1postmaster_address = $postmaster_address#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(hostname\ +=.*)#\1\#\# \2\n\1hostname = $hostname#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(sendmail_path\ +=.*)#\1\#\# \2\n\1sendmail_path = /usr/sbin/sendmail#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(lda_mailbox_autocreate\ +=.*)#\1\#\# \2\n\1lda_mailbox_autocreate = no#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-lmtp +## - +## - lmtp_save_to_detail_mailbox = no +## - mail_plugins = $mail_plugins sieve +## - +echononl "\tAdjusting file 20-lmtp.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(lmtp_save_to_detail_mailbox\ +=.*)#\1\#\# \2\n\1lmtp_save_to_detail_mailbox = no#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-imap.conf +## - +## - ssl_cert = <$imap_cert +## - ssl_key = <$imap_key +## - mail_max_userip_connections = $max_userip_connections +## - mail_plugins = $mail_plugins imap_quota +## - imap_client_workarounds = delay-newmail +## - +echononl "\tAdjusting file 20-imap.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(protocol imap {)#\1\2\n\n\1 ssl_cert = <$imap_cert\n\1 ssl_key = <$imap_key\n#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_max_userip_connections\ +=.*)#\1\#\# \2\n\1mail_max_userip_connections = $max_userip_connections#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins imap_quota#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(imap_client_workarounds\ +=.*)#\1\#\# \2\n\1imap_client_workarounds = delay-newmail#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-pop3.conf +## - +## - ssl_cert = <$pop_cert +## - ssl_key = <$pop_key +## - mail_max_userip_connections = 10 +## - pop3_client_workarounds = outlook-no-nuls oe-ns-eoh +## - +echononl "\tAdjusting file 20-pop3.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(protocol pop3 {)#\1\2\n\n\1 ssl_cert = <$pop_cert\n\1 ssl_key = <$pop_key\n#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_max_userip_connections\ +=.*)#\1\#\# \2\n\1mail_max_userip_connections = 10#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(pop3_client_workarounds\ +=.*)#\1\#\# \2\n\1pop3_client_workarounds = outlook-no-nuls oe-ns-eoh#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-plugin.conf +## - +## - autocreate = $spam_folder +## - autocreate2 = Sent +## - autocreate3 = Trash +## - autocreate4 = Drafts + +## - autosubscribe = $spam_folder +## - autosubscribe2 = Sent +## - autosubscribe3 = Trash +## - autosubscribe4 = Drafts +## - +## - expire_dict = proxy::expire +## - +## - expire = Trash +## - expire2 = Trash.* +## - expire3 = $spam_folder +## - +echononl "\tAdjusting file 90-plugin.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)(\#?\ ?setting_name\ +=.*)#\1\2\n\n\1autocreate = $spam_folder\n\1autocreate2 = Sent\n\1autocreate3 = Trash\n\1autocreate4 = Drafts\n\n\1autosubscribe = $spam_folder\n\1autosubscribe2 = Sent\n\1autosubscribe3 = Trash\n\1autosubscribe4 = Drafts\n\n\1expire_dict = proxy::expire\n\n\1expire = Trash\n\1expire2 = Trash.*\n\1expire3 = $spam_folder\n#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-plugin.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-plugin.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-sieve.conf +## - +## - sieve = ~/.dovecot.sieve +## - #sieve_global_path = /usr/local/dovecot/etc/dovecot/sieve/default.sieve +## - sieve_before = /usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve +## - sieve_dir = ~/sieve +## - sieve_global = /usr/local/dovecot/etc/dovecot/sieve/global/ +## - recipient_delimiter = +## - +echononl "\tAdjusting file 90-sieve.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(sieve\ ?=.*)#\1\#\# \2\n\1sieve = ~/.dovecot.sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_before\ ?=.*)#\1\#\# \2\n\1sieve_before =/usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_dir\ ?=.*)#\1\#\# \2\n\1sieve_dir = ~/sieve#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_global\ ?=.*)#\1\#\# \2\n\1sieve_global = /usr/local/dovecot/etc/dovecot/sieve/global/#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(recipient_delimiter\ ?=.*)#\1\#\# \2\n\1recipient_delimiter =#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf" +fi + +mkdir -p /usr/local/dovecot-${_version}/etc/dovecot/sieve/global/ + +## - ceate global sieve script +## - +echononl "\tCeate global sieve script" +cat < /usr/local/dovecot-${_version}/etc/dovecot/sieve/move-spam.sieve +require ["fileinto"]; +# Move spam to spam folder +if header :contains "X-Spam-Flag" ["YES"] { + fileinto "$spam_folder"; + #discard; + stop; +} +EOF + +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Creating global sieve script failed" +fi + +## - NOTICE: if you pre-compile your (global) scripts, you will increase +## - performance +## - +echononl "\tPrecompile global sieve script" +cd /usr/local/dovecot-${_version}/etc/dovecot/sieve/ +/usr/local/dovecot-${_version}/bin/sievec \ + /usr/local/dovecot-${_version}/etc/dovecot/sieve/move-spam.sieve > /dev/null 2>&1 + +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Precompiling sieve script failed" +fi + + +## - you can also give dovecot's delivery service (lda / lmtp) the permissions to write +## - into the sieve directory. then dovecots delivery service will compile the script +## - by first using.. +## - +chown -R vmail:vmail /usr/local/dovecot-${_version}/etc/dovecot/sieve + + +if $_new ; then + + _create_init="" + echo + echo -n "Create init script /etc/init.d/dovecot ? [y/n]: " + read _create_init + if [ "y" = "$_create_init" -o "Y" = "$_create_init" -o "Yes" = "$_create_init" -o "yes" = "$_create_init" ];then + echononl "\tCreate init script for dovecot .." + ## - running dovecot service via init-script + ## - + cat < /etc/init.d/dovecot +#! /bin/sh +### BEGIN INIT INFO +# Provides: dovecot +# Required-Start: \$syslog \$postgresql +# Required-Stop: \$syslog \$postgresql +# Should-Start: \$local_fs \$time ntp +# Should-Stop: \$local_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Dovecot init script +# Description: Init script for dovecot services +### END INIT INFO + +# Author: Miquel van Smoorenburg . +# Modified for Debian GNU/Linux +# by Ian Murdock . +# + +# Do NOT "set -e" +ulimit -n 32768 + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/dovecot/sbin/dovecot:/usr/local/dovecot/bin +DESC="IMAP/POP3 mail server" +NAME=dovecot +DAEMON=/usr/local/dovecot/sbin/dovecot +DAEMON_ARGS="" +SCRIPTNAME=/etc/init.d/\$NAME +CONF=/usr/local/dovecot/etc/dovecot/\${NAME}.conf + +# Read configuration variable file if it is present +[ -r /etc/default/\$NAME ] && . /etc/default/\$NAME + +# Exit if the package is not installed +[ -x "\$DAEMON" ] || exit 0 + +# Exit if the configuration file doesn't exist +[ -f "\$CONF" ] || exit 0 + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# cong file readable? +if [ ! -r \${CONF} ]; then + [ "\$VERBOSE" != no ] && log_daemon_msg "\${CONF}: not readable" "\$NAME" \\ + && log_end_msg 1; + exit 1; +fi + + +# The init script should do nothing if dovecot or another imap/pop3 server +# is being run from inetd, and dovecot is configured to run as an imap or +# pop3 service +if [ -r /etc/inetd.conf ]; then + for p in \`sed -r "s/^ *(([^:]+|\[[^]]+]|\*):)?(pop3s?|imaps?)[ \t].*/\3/;t;d" \\ + /etc/inetd.conf\` + do + for q in \`sed -r "s/^[ \t]*protocols[ \t]*=[ \t]*(([^\"]*)|\"(.*)\")/\2\3/;t;d" \\ + \${CONF}\` + do + if [ \$p = \$q ]; then + exit 0 + fi + done + done +fi + +# determine the location of the PID file +# overide by setting base_dir in conf file or PIDBASE in /etc/defaults/\$NAME +PIDBASE=\${PIDBASE:-\`sed -r "s/^[ \t]*base_dir[ \t]*=[ \t]*([^ \t]*)/\1/;t;d" \${CONF}\`} +PIDFILE=\${PIDBASE:-/var/run/dovecot/}master.pid + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON --test > /dev/null \\ + || return 1 + start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON -- \\ + \$DAEMON_ARGS \\ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile \$PIDFILE --name \${DAEMON##*/} + RETVAL="\$?" + [ "\$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --pidfile \$PIDFILE --name \${DAEMON##*/} + [ "\$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f \$PIDFILE + return "\$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal USR1 --quiet --pidfile \$PIDFILE --name \$NAME + return 0 +} + + +case "\$1" in + start) + [ "\$VERBOSE" != no ] && log_daemon_msg "Starting \$DESC" "\$NAME" + do_start + case "\$?" in + 0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "\$VERBOSE" != no ] && log_daemon_msg "Stopping \$DESC" "\$NAME" + do_stop + case "\$?" in + 0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + reload|force-reload) + log_daemon_msg "Reloading \$DESC" "\$NAME" + do_reload + log_end_msg \$? + ;; + restart) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting \$DESC" "\$NAME" + do_stop + case "\$?" in + 0|1) + do_start + case "\$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: \$SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: \$SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +exit 0 +EOF + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating init script for dovecot failed" + fi + + chmod 755 /etc/init.d/dovecot + + else + echononl "\tCreate init script for dovecot .." + echo -e "$rc_skipped" + fi + + + ## - Make dovecot start at boot time + ## - + echononl "\tMake dovecot start at boottime.." + update-rc.d dovecot defaults > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Make dovecot start at boottime failed" + fi + + + ## - update postfix configuration to play with dovecot lda + ## - + + ## - /etc/postfix/master.cf + ## - + ## - add line + ## - dovecot unix - n n - - pipe + ## - flags=drhu user=vmail:vmail argv=/usr/local/dovecot/libexec/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} + if ! grep -e dovecot-lda /etc/postfix/master.cf > /dev/null ; then + cp /etc/postfix/master.cf /etc/postfix/master.cf.`date +%Y-%m-%d-%H%M` + echononl "\tConfigure /etc/postfix/master.cf to play with dovecot lda" + echo -e "\ndovecot unix - n n - - pipe\n flags=drhu user=vmail:vmail argv=/usr/local/dovecot/libexec/dovecot/dovecot-lda -f \${sender} -d \${user}@\${nexthop}" >> /etc/postfix/master.cf + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Configuring /etc/postfix/master.cf failed" + fi + fi + + + ## - /etc/postfix/main.cf + ## - + ## - add/uncomment: + ## - + ## - virtual_transport = dovecot + ## - dovecot_destination_recipient_limit = 1 + ## - + ## - in section restrictions, parameter smtpd_recipient_restrictions + ## - uncomment add + ## - + ## - permit_sasl_authenticated, + ## - + echononl "\tAdjust /etc/postfix/main.cf" + perl -i.`date +%Y-%m-%d-%H%M` -n -p -e "s#^(\s*)(virtual_transport\ *=.*)#\1\#\2\n\1virtual_transport = dovecot\ndovecot_destination_recipient_limit = 1#" \ + /etc/postfix/main.cf || _failed=true + perl -i-n -p -e "s#^(\s*)\#?(permit_sasl_authenticated)#\1\2#" /etc/postfix/main.cf || _failed=true + if ! $_failed ; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Adjusting /etc/postfix/main.cf failed" + fi + + + ## - add a cronjob to run expunge scripts, to delete old mails + ## - from users'mailbox. only cleanup spam and trash directories + ## - + echononl "\tCreate cronjob to run expunge scripts" + _crontab_tmp_file=/tmp/crontab_root.$$ + crontab -l > $_crontab_tmp_file 2> /dev/null + + if [[ ! -s $_crontab_tmp_file ]]; then + echo "PATH=/usr/local/dovecot/bin:$PATH" > $_crontab_tmp_file + fi + + if ! grep -e "/usr/local/dovecot/bin/doveadm\ *expunge" $_crontab_tmp_file > /dev/null ; then + echo "" >> $_crontab_tmp_file + echo "## - cleanup spam and trash directories of users'mailboxes" >> $_crontab_tmp_file + echo "## -" >> $_crontab_tmp_file + echo "13 3 * * * /usr/local/dovecot/bin/doveadm expunge -A mailbox Trash* savedbefore 1d; /usr/local/dovecot/bin/doveadm expunge -A mailbox ${spam_folder}* savedbefore 30d" >> $_crontab_tmp_file + crontab $_crontab_tmp_file + echo -e "$rc_done" + else + echo -e "$rc_skipped" + fi + rm -f $_crontab_tmp_file + +fi + +echo +echo -e "Change (from lda) to lmtp-service" + +## ----------------- +## --- Change (from lda) to lmtp-service + +## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf +## - +## - add "lmtp" to protocols +## - +echononl "\tAdd lmtp to protocols (dovecot.conf)" +perl -i -n -p -e "s#^([ ]*)(protocols\ +=\ +.*)#\1\2 lmtp#" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adding lmtp to protocols in file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf +## - +## - unix_listener /var/spool/postfix/private/dovecot-lmtp { +## - mode = 0600 +## - user = postfix +## - group = postfix +## - } +## - +echononl "\tAdding dovecot-lmtp listener to 10-master.conf" +perl -i -n -p -e "s#^([ ]*)(unix_listener\ +lmtp\ .*)#\1unix_listener /var/spool/postfix/private/dovecot-lmtp {\n user = postfix\n mode = 0660\n group = postfix#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" +fi + + +if $_new ; then + + ## - /etc/postfix/main.cf + ## - + ## - comment in: + ## - #virtual_transport = dovecot + ## - #dovecot_destination_recipient_limit = 1 + ## - + ## - add: + ## - virtual_transport = lmtp:unix:private/dovecot-lmtp + echononl "\tAdjust /etc/postfix/main.cf" + perl -i -n -p -e "s#^(\s*)(virtual_transport\ *=.*)#\1\#\2\n\1virtual_transport = lmtp:unix:private/dovecot-lmtp#" \ + /etc/postfix/main.cf || _failed=true + perl -i-n -p -e "s#^(\s*)(dovecot_destination_recipient_limit.*)#\1\#\2#" /etc/postfix/main.cf || _failed=true + if ! $_failed ; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Adjusting /etc/postfix/main.cf failed" + fi + +fi + + +## ----------------- +## --- Configure quota support for dovecot + +echo +echo -e "Configure quota support for dovecot" + + +## - take care quota plugins (quota,imap-quota) will +## - be loaded: +## - +## - there are two quota related plugins: +## - +## - * quota: implements the actual quota handling and includes also all the quota backends. +## - * imap_quota: for reporting quota information via imap. +## - +## - enable them in configuration files, e.g.: +## - +## - conf.d/10-mail.conf: +## - +## - # space separated list of plugins to load for all services. plugins specific to +## - # imap, lda, etc. are added to this list in their own .conf files. +## - mail_plugins = $mail_plugins quota +## - +## - conf.d/20-imap.conf: +## - +## - protocol imap { +## - # space separated list of plugins to load (default is global mail_plugins). +## - mail_plugins = $mail_plugins imap_quota +## - } +## - +## - we have done it befor, at the basic configuration +## - + +## - configure dict service +## - +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf +## - +## - add: +## - +## - service dict { +## - unix_listener dict { +## - mode = 0600 +## - user = vmail +## - } +## - } +## - +echononl "\tConfigure dict service (10-master.conf)" +perl -i -n -p -e "s#^([ ]*)(unix_listener\ +dict.*)#\1\2\n\1 mode = 0600\n\1 user = vmail#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf +## - +## - add: +## - +## - dict { +## - quota = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext +## - } +echononl "\tAdjust file dovecot.conf for (dict) quota service" +perl -i -n -p -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 quota = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" +fi + + +if $_new ; then + + if [ "$db_driver" = "pgsql" ]; then + + echononl "\tCreate table quota2 in database \"$dbname\".." + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +CREATE TABLE quota2 ( + username varchar(100) not null, + bytes bigint not null default 0, + messages integer not null default 0, + primary key (username) +); +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table quota2 in database \"$dbname\" failed" + fi + + echononl "\tCreate Trigger mergequota2.." + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +CREATE PROCEDURAL LANGUAGE plpgsql; + +CREATE FUNCTION merge_quota2() RETURNS trigger + LANGUAGE plpgsql + AS \$\$ + BEGIN + IF NEW.messages < 0 OR NEW.messages IS NULL THEN + -- ugly kludge: we came here from this function, really do try to insert + IF NEW.messages IS NULL THEN + NEW.messages = 0; + ELSE + NEW.messages = -NEW.messages; + END IF; + return NEW; + END IF; + + LOOP + UPDATE quota2 SET bytes = bytes + NEW.bytes, + messages = messages + NEW.messages + WHERE username = NEW.username; + IF found THEN + RETURN NULL; + END IF; + + BEGIN + IF NEW.messages = 0 THEN + INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); + ELSE + INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); + END IF; + return NULL; + EXCEPTION WHEN unique_violation THEN + -- someone just inserted the record, update it + END; + END LOOP; + END; + \$\$; +CREATE TRIGGER mergequota2 + BEFORE INSERT ON quota2 + FOR EACH ROW + EXECUTE PROCEDURE merge_quota2(); +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating function merge_quota2() / trigger merge_quota2 failed" + fi + + elif [ "$db_driver" = "mysql" ]; then + echononl "\tCreate table quota2 in database \"$dbname\".." + cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 +CREATE TABLE quota2 ( + username varchar(100) not null, + bytes bigint not null default 0, + messages integer not null default 0, + primary key (username) +); +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table quota2 in database \"$dbname\" failed" + fi + fi + +fi + +echononl "\tRenew file sql-dict.conf.ext" +if [ "$db_driver" = "pgsql" ]; then + + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +## - if using unix-socket (host=/var/run/postgresql) ensure that +## - coresponding entries in pg_hba.cof fits +## - for example +## - local all all md5 +## - +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +# CREATE TABLE quota2 ( +# username varchar(100) not null, +# bytes bigint not null default 0, +# messages integer not null default 0, +# primary key (username) +# ); +# +## - if using postgres, you need also to create a trigger as follows: +## - +## - first create language plpgsql if not yet created: +## - +# CREATE PROCEDURAL LANGUAGE plpgsql; +# +# CREATE FUNCTION merge_quota2() RETURNS trigger +# LANGUAGE plpgsql +# AS \$\$ +# BEGIN +# IF NEW.messages < 0 OR NEW.messages IS NULL THEN +# -- ugly kludge: we came here from this function, really do try to insert +# IF NEW.messages IS NULL THEN +# NEW.messages = 0; +# ELSE +# NEW.messages = -NEW.messages; +# END IF; +# return NEW; +# END IF; +# +# LOOP +# UPDATE quota2 SET bytes = bytes + NEW.bytes, +# messages = messages + NEW.messages +# WHERE username = NEW.username; +# IF found THEN +# RETURN NULL; +# END IF; +# +# BEGIN +# IF NEW.messages = 0 THEN +# INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); +# ELSE +# INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); +# END IF; +# return NULL; +# EXCEPTION WHEN unique_violation THEN +# -- someone just inserted the record, update it +# END; +# END LOOP; +# END; +# \$\$; +# +# +# ALTER FUNCTION public.merge_quota2() OWNER TO postfix; +# +# CREATE TRIGGER mergequota2 +# BEFORE INSERT ON quota2 +# FOR EACH ROW +# EXECUTE PROCEDURE merge_quota2(); + +map { + pattern = priv/quota/storage + table = quota2 + username_field = username + value_field = bytes +} +map { + pattern = priv/quota/messages + table = quota2 + username_field = username + value_field = messages +} + +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + +## - if using postgres, you need also to create a trigger as follows: +## - +## - first create language plpgsql if not yet created: +## - +# CREATE LANGUAGE plpgsql; +# +# CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ +# BEGIN +# UPDATE expires SET expire_stamp = NEW.expire_stamp +# WHERE username = NEW.username AND mailbox = NEW.mailbox; +# IF FOUND THEN +# RETURN NULL; +# ELSE +# RETURN NEW; +# END IF; +# END; +# \$\$ LANGUAGE plpgsql; +# +# CREATE TRIGGER mergeexpires BEFORE INSERT ON expires +# FOR EACH ROW EXECUTE PROCEDURE merge_expires(); + +map { + pattern = shared/expire/\$user/\$mailbox + table = expires + value_field = expire_stamp + + fields { + username = \$user + mailbox = \$mailbox + } +} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" + fi + + ## - you also have to update the userdb's query in file + ## - "/usr/local/dovecot/etc/dovecot/sql-connect.conf.ext" to + ## - support extra variable "quota_rule" + ## - + echononl "\tRenew file sql-connect.conf.ext" +cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext +driver = $db_driver +## - if using unix-socket (host=/var/run/postgresql) ensure that +## - coresponding entries in pg_hba.cof fits +## - for example +## - local all all md5 +## - +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +default_pass_scheme = $default_pass_scheme +password_query = SELECT username AS user, password \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true +user_query = SELECT '/var/vmail/' || maildir AS home, \\ + '5000' AS uid, '5000' AS gid, \\ + '*:bytes=' || quota AS quota_rule \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true + +## - Query to get a list of all usernames. +## - +iterate_query = SELECT username AS user FROM mailbox +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" + fi + +elif [ "$db_driver" = "mysql" ]; then + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +# CREATE TABLE quota2 ( +# username varchar(100) not null, +# bytes bigint not null default 0, +# messages integer not null default 0, +# primary key (username) +# ); + +map { + pattern = priv/quota/storage + table = quota2 + username_field = username + value_field = bytes +} +map { + pattern = priv/quota/messages + table = quota2 + username_field = username + value_field = messages +} + +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + +map { + pattern = shared/expire/\$user/\$mailbox + table = expires + value_field = expire_stamp + + fields { + username = \$user + mailbox = \$mailbox + } +} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" + fi + + ## - you also have to update the userdb's query in file + ## - "/usr/local/dovecot/etc/dovecot/sql-connect.conf.ext" to + ## - support extra variable "quota_rule" + ## - + echononl "\tRenew file sql-connect.conf.ext" +cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext +driver = $db_driver +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +default_pass_scheme = $default_pass_scheme +password_query = SELECT username AS user, password \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true +user_query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\ + '5000' AS uid, '5000' AS gid, \\ + CONCAT('*:bytes=',quota) AS quota_rule \\ + FROM mailbox \\ + WHERE username = '%u' AND active = true + +## - Query to get a list of all usernames. +## - +iterate_query = SELECT username AS user FROM mailbox +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" + fi +fi + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-quota.conf +## - +## - add to the end of file or in seperate plugin-blocks +## - as designed in that file: +## - plugin { +## - # sql backend: +## - quota = dict:user quota::proxy::quota +## - +## - quota_rule = *:storage=1g +## - quota_rule2 = trash:storage=+100m +## - +## - quota_warning = storage=95%% quota-warning 95 %u +## - quota_warning2 = storage=80%% quota-warning 80 %u +## - } +## - +## - service quota-warning { +## - executable = script /usr/local/bin/quota-warning.sh +## - user = dovecot +## - unix_listener quota-warning { +## - user = vmail +## - } +## - } +## - +echononl "\tAdjust file 90-quota.conf" +cp -a /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf.ORIG +cat <>/usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf + +## - +plugin { + # SQL backend: + quota = dict:User quota::proxy::quota + + quota_rule = *:storage=1G + quota_rule2 = Trash:storage=+200M + + quota_warning = storage=95%% quota-warning 95 %u + quota_warning2 = storage=80%% quota-warning 80 %u +} + +service quota-warning { + executable = script /usr/local/bin/quota-warning.sh + user = dovecot + unix_listener quota-warning { + user = vmail + } +} +EOF +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf failed" +fi + + +if $_new ; then + + echononl "\tCreate quota warning script.." + ## - create the user-warning script + ## - + cat </usr/local/bin/quota-warning.sh +#!/bin/sh + +# author: zhang huangbin +# purpose: send mail to notify user when his mailbox quota exceeds a +# specified limit. +# project: iredmail (http://www.iredmail.org/) + +LANG=en_US.UTF-8 + +percent=\$1 +user=\$2 + +cat << EOF | /usr/local/dovecot/libexec/dovecot/deliver -d \${user} -c /usr/local/dovecot/etc/dovecot/dovecot.conf +date: \`date +"%a, %e %b %Y %H:%M:%S %z"\` +from: $from_address +reply-to: $reply_to +to:\${user} +subject: mailbox quota warning: \${percent}% belegt. +content-type: text/plain; + charset=utf-8 + +Hallo! + +Deine Mailbox für das Postfach + \${user} +ist nun zu über \${percent}% voll. Damit Du weiterhin E-Mails +empfangen kannst, lösche bitte vorhandene E-Mails vom Server. + +Dies geht zum Beispiel via Webmailer: + $webmailer + +Viele Grüße + +$salutation +${_EOF:-EOF} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Create quota warning script /usr/local/bin/quota-warning.sh failed" + fi + + chmod 755 /usr/local/bin/quota-warning.sh + +fi + + +## ----------------- +## --- Configure ACL support for dovecot + +## - What to do: +## - +## - 1.) Add shared namespace +## - 2.) Add plugins to the several plugin lists +## - - "acl" to variable mail_plugins in 10-mail.conf +## - - "acl-imap" to variable mail_plugins in 20-imap.conf +## - +## - 3.a) Add acl to the plugin part in 90-acl.conf +## - +## - 3.b) To make shared mailboxes visible a database (dict) is needed. +## - This can also be a dict file. +## - Add acl_shared_dict to the plugin part of 90-acl.conf +## - +## - 4.) If using SQL backend, also a rule "acl =" in "dict" section +## - of file dovecont.conf needed +## - + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf +## - +## - Add namespaces type shared to 10-mail.conf +## - Take care to enable ACL plugin also, otherwise all users can access all the shared +## - mailboxes, assuming they have permissions on filesystem level to do so. +## - we will do that later.. +## - namespace { +## - type = shared +## - separator = / +## - prefix = shared/%%u/ +## - location = maildir:/var/vmail/%%d/%%n/Maildir:INDEX=~/Maildir/shared/%%u +## - subscriptions = no +## - list = children +## - } +## - +echononl "\tAdd namespaces type shared to 10-mail.conf" +cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf + +namespace { + #type = shared + #separator = / + type = shared + separator = / + + # Mailboxes are visible under "shared/user@domain/" + # %%n, %%d and %%u are expanded to the destination user. + #prefix = shared/%%u/ + 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 + location = maildir:/var/vmail/%%d/%%n/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 +} +EOF +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adding namespaces to /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-imap.conf +## - +## - mail_plugins = $mail_plugins imap_quota imap_acl +## - +echononl "\tAdd mail_plugin imap_acl to 20-imap.conf" +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins imap_quota imap_acl#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf +## - +## - mail_plugins = quota expire acl +## - +echononl "\tAdd mail_plugin acl to 10-mail.conf" +perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota expire acl#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" +fi + + +## - !! Notice !! +## - There a two possibilities, configuring acl backend: +## - - flat file +## - - SQL dictionary +## - +## - On rage.so36.net we actually uses SQL dictionary not a flat file + +## ----------------- +## - Using a flat file as dictionary backend +## - + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-acl.conf +## - +## - plugin { +## - # Without global ACLs: +## - acl = vfile +## - +## - # With global ACLs in /etc/dovecot/acls/ directory: +## - #acl = vfile:/etc/dovecot/acls +## - #acl = vfile:/etc/dovecot/acls:cache_secs=300 +## - } +## - +## - plugin { +## - #acl_shared_dict = file:/var/run/dovecot/shared-mailboxes.db +## - acl_shared_dict = file:/var/vmail/shared-mailboxes.db +## - } +## - +#perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(acl\ +=.*)#\1\#\# \2\n\n\1\# Without global ACLs:\n\1acl = vfile\n\n\1\# With global ACLs in /etc/dovecot/acls/ directory:\n\1\#acl = vfile:/etc/dovecot/acls\n\1\#acl = vfile:/etc/dovecot/acls:cache_secs=300#g" \ +# /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf +#perl -i -n -p -e "s#^([ ]*)\#?\ ?(acl_shared_dict\ +=.*)#\1\#\# \2\n\1acl_shared_dict = file:/var/vmail/shared-mailboxes.db#g" \ +# /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf + +## - +## - End: Using a flat file as dictionary backend +## ------------------------------------------------------------------------ + + +## ------------------------------------------------------------------------ +## - Using SQL dictionary +## - + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-acl.conf +## - +## - plugin { +## - ## acl = vfile:/etc/dovecot/global-acls:cache_secs=300 +## - +## - # Without global ACLs: +## - acl = vfile +## - .. +## - } +## - plugin { +## - acl_shared_dict = proxy::acl +## - } +## - +echononl "\tConfigure acl (90-acl.conf)" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(acl\ +=.*)#\1\#\# \2\n\n\1\# Without global ACLs:\n\1acl = vfile\n\n\1\# With global ACLs in /etc/dovecot/acls/ directory:\n\1\#acl = vfile:/etc/dovecot/acls\n\1\#acl = vfile:/etc/dovecot/acls:cache_secs=300#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(acl_shared_dict\ +=.*)#\1\#\# \2\n\1acl_shared_dict = proxy::acl#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf failed" +fi + +## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf +## - +## - dict { +## - acl = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext +## - ... +## - } +## - +echononl "\tAdjust file dovecot.conf for (dict) acl service" +perl -i -n -p -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 acl = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" +fi + +if $_new ; then + if [ "$db_driver" = "pgsql" ]; then + + ## - Create tables user_shares / anyone_shares + ## - + echononl "\tCreate table user_share" + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +CREATE TABLE user_shares ( + from_user varchar(100) not null, + to_user varchar(100) not null, + dummy char(1) DEFAULT '1', -- always '1' currently + primary key (from_user, to_user) +); +COMMENT ON TABLE user_shares IS 'User from_user shares folders to user to_user.'; +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table user_shares failed" + fi + + echononl "\tCreate table anyone_shares" + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +CREATE TABLE anyone_shares ( + from_user varchar(100) not null, + dummy char(1) DEFAULT '1', -- always '1' currently + primary key (from_user) +); +COMMENT ON TABLE anyone_shares IS 'User from_user shares folders to anyone.'; +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table anyone_shares failed" + fi + + elif [ "$db_driver" = "mysql" ]; then + + ## - Create table user_shares / anyone_shares + ## - + echononl "\tCreate table user_share" + cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 +CREATE TABLE user_shares ( + from_user varchar(100) not null, + to_user varchar(100) not null, + dummy char(1) DEFAULT '1', -- always '1' currently + primary key (from_user, to_user) +) COMMENT = 'User from_user shares folders to user to_user.'; +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table user_shares failed" + fi + + echononl "\tCreate table anyone_shares" + cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 +CREATE TABLE anyone_shares ( + from_user varchar(100) not null, + dummy char(1) DEFAULT '1', -- always '1' currently + primary key (from_user) +) COMMENT = 'User from_user shares folders to anyone.'; +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating table anyone_shares failed" + fi + fi +fi + + +if [ "$db_driver" = "pgsql" ]; then + + ## - adjust/renew file /usr/local/dovecot/etc/dovecot/sql-dict.conf.ext + ## - + echononl "\tRenew file sql-dict.conf.ext" + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +## - if using unix-socket (host=/var/run/postgresql) ensure that +## - coresponding entries in pg_hba.cof fits +## - for example +## - local all all md5 +## - +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +## - NOTE: +## - +## - All changes on database (CREATE TABLE / CREATE TRIGGER / what else..) +## - need to be done as the dbuser (here postfix) under whom dovecot +## - accesses the database. If not, you have to change the permissiond to allow +## - dovecot dbuser to access the createt table/trigger/... +## - + +# CREATE TABLE quota2 ( +# username varchar(100) not null, +# bytes bigint not null default 0, +# messages integer not null default 0, +# primary key (username) +# ); +# +## - if using postgres, you need also to create a trigger as follows: +## - +## - first create language plpgsql if not yet created: +## - +# CREATE PROCEDURAL LANGUAGE plpgsql; +# +# CREATE FUNCTION merge_quota2() RETURNS trigger +# LANGUAGE plpgsql +# AS \$\$ +# BEGIN +# IF NEW.messages < 0 OR NEW.messages IS NULL THEN +# -- ugly kludge: we came here from this function, really do try to insert +# IF NEW.messages IS NULL THEN +# NEW.messages = 0; +# ELSE +# NEW.messages = -NEW.messages; +# END IF; +# return NEW; +# END IF; +# +# LOOP +# UPDATE quota2 SET bytes = bytes + NEW.bytes, +# messages = messages + NEW.messages +# WHERE username = NEW.username; +# IF found THEN +# RETURN NULL; +# END IF; +# +# BEGIN +# IF NEW.messages = 0 THEN +# INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); +# ELSE +# INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); +# END IF; +# return NULL; +# EXCEPTION WHEN unique_violation THEN +# -- someone just inserted the record, update it +# END; +# END LOOP; +# END; +# \$\$; +# +# +# ALTER FUNCTION public.merge_quota2() OWNER TO postfix; +# +# CREATE TRIGGER mergequota2 +# BEFORE INSERT ON quota2 +# FOR EACH ROW +# EXECUTE PROCEDURE merge_quota2(); + +map { + pattern = priv/quota/storage + table = quota2 + username_field = username + value_field = bytes +} +map { + pattern = priv/quota/messages + table = quota2 + username_field = username + value_field = messages +} + +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + +## - if using postgres, you need also to create a trigger as follows: +## - +## - first create language plpgsql if not yet created: +## - +# CREATE LANGUAGE plpgsql; +# +# CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ +# BEGIN +# UPDATE expires SET expire_stamp = NEW.expire_stamp +# WHERE username = NEW.username AND mailbox = NEW.mailbox; +# IF FOUND THEN +# RETURN NULL; +# ELSE +# RETURN NEW; +# END IF; +# END; +# \$\$ LANGUAGE plpgsql; +# +# CREATE TRIGGER mergeexpires BEFORE INSERT ON expires +# FOR EACH ROW EXECUTE PROCEDURE merge_expires(); + + +map { + pattern = shared/expire/\$user/\$mailbox + table = expires + value_field = expire_stamp + + fields { + username = \$user + mailbox = \$mailbox + } +} + + +# CREATE TABLE user_shares ( +# from_user varchar(100) not null, +# to_user varchar(100) not null, +# dummy char(1) DEFAULT '1', -- always '1' currently +# primary key (from_user, to_user) +# ); +# COMMENT ON TABLE user_shares IS 'User from_user shares folders to user to_user.'; +# +# CREATE TABLE anyone_shares ( +# from_user varchar(100) not null, +# dummy char(1) DEFAULT '1', -- always '1' currently +# primary key (from_user) +# ); +# COMMENT ON TABLE anyone_shares IS 'User from_user shares folders to anyone.'; + +map { + pattern = shared/shared-boxes/user/\$to/\$from + table = user_shares + value_field = dummy + + fields { + from_user = \$from + to_user = \$to + } +} + +map { + pattern = shared/shared-boxes/anyone/\$from + table = anyone_shares + value_field = dummy + + fields { + from_user = \$from + } +} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" + fi + +elif [ "$db_driver" = "mysql" ]; then + + ## - adjust/renew file /usr/local/dovecot/etc/dovecot/sql-dict.conf.ext + ## - + echononl "\tRenew file sql-dict.conf.ext" + cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext +connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname + +# CREATE TABLE quota2 ( +# username varchar(100) not null, +# bytes bigint not null default 0, +# messages integer not null default 0, +# primary key (username) +# ); + +map { + pattern = priv/quota/storage + table = quota2 + username_field = username + value_field = bytes +} +map { + pattern = priv/quota/messages + table = quota2 + username_field = username + value_field = messages +} + +# CREATE TABLE expires ( +# username varchar(100) not null, +# mailbox varchar(255) not null, +# expire_stamp integer not null, +# primary key (username, mailbox) +# ); + + +map { + pattern = shared/expire/\$user/\$mailbox + table = expires + value_field = expire_stamp + + fields { + username = \$user + mailbox = \$mailbox + } +} + + +# CREATE TABLE user_shares ( +# from_user varchar(100) not null, +# to_user varchar(100) not null, +# dummy char(1) DEFAULT '1', -- always '1' currently +# primary key (from_user, to_user) +# ) COMMENT = 'User from_user shares folders to user to_user.'; +# +# CREATE TABLE anyone_shares ( +# from_user varchar(100) not null, +# dummy char(1) DEFAULT '1', -- always '1' currently +# primary key (from_user) +# ) COMMENT = 'User from_user shares folders to anyone.'; + +map { + pattern = shared/shared-boxes/user/\$to/\$from + table = user_shares + value_field = dummy + + fields { + from_user = \$from + to_user = \$to + } +} + +map { + pattern = shared/shared-boxes/anyone/\$from + table = anyone_shares + value_field = dummy + + fields { + from_user = \$from + } +} +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" + fi +fi + +## - +## - End: Using SQL dictionary +## ------------------------------------------------------------------------ + + +## ----------------- +## --- Configure managesieve support for dovecot + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-managesieve.conf +## - +## - service managesieve-login { +## - inet_listener sieve { +## - #address = 127.0.0.1 $ipv4 $ipv6 +## - address = 127.0.0.1 +## - port = 4190 +## - } +## - .. +## - } +## - +echononl "\tConfigure managesieve 20-managesieve.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(service managesieve-login\ +{.*)#\1service managesieve-login {#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(inet_listener\ +sieve\ +{.*)#\1inet_listener sieve {\n\1 \#address = 127.0.0.1 $ipv4 $ipv6\n\1 address = 127.0.0.1\n\1 port = 4190\n\1}\n\1\#\# \2#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*\#?\ ?vsz_limit.*)#\1\n}#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*)\#?\ ?(service managesieve\ +{.*)#\1service managesieve {#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true + +# since divecot 2.2.4: process_count changed to process_limit. +# +#perl -i -n -p -e "s#^([ ]*\#?\ ?process_count.*)#\1\n}#g" \ +# /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true +perl -i -n -p -e "s#^([ ]*\#?\ ?process_limit.*)#\1\n}#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true + +if ! $_failed ; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf failed" +fi + +_set_link="" +echo +echo "Set symlink " +echo -e -n " /usr/local/dovecot --> dovecot-${_version} /usr/local/dovecot? [y/n]: " +read _set_link +if [ "y" = "$_set_link" -o "Y" = "$_set_link" -o "Yes" = "$_set_link" -o "yes" = "$_set_link" ];then + echononl "\tCreate symlink.." + rm -f /usr/local/dovecot + ln -s dovecot-${_version} /usr/local/dovecot + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating Symlink /usr/local/dovecot --> dovecot-${_version} /usr/local/dovecot failed" + fi +fi + +_restart="" +echo +echo -e -n "Restart services (dovecot/postfix)? [y/n]: " +read _restart +if [ "y" = "$_restart" -o "Y" = "$_restart" -o "Yes" = "$_restart" -o "yes" = "$_restart" ];then + echononl "\tRestart dovecot.." + /etc/init.d/dovecot restart > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Restarting dovecot failed" + fi + echononl "\tRestart postfix.." + /etc/init.d/postfix restart > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Restarting postfix failed" + fi +fi + + +echo " + +Notice: +If you want to support more than 128 simultanously connections (the default), +you have to increase \"/proc/sys/fs/inotify/max_user_instances\". + +If you are running dovecot on a VServer Guest System, you have to do that on the +VServer Root System: + + # echo \"fs.inotify.max_user_instances = 1024\" >> /etc/sysctl.conf + # sysctl -p + +" +echo "" + +exit