#!/usr/bin/env bash ## =================================================================== ## - Install/Update Dovecot Server ## =================================================================== ## ----------------------------------------------------------------- ## ---------------------------------------------------------------- ## --- ## --- For configurations see file conf/install_update_dovecot.conf ## --- ## --- Dont make changes here! ## --- ## ----------------------------------------------------------------- ## ----------------------------------------------------------------- # ------------- # - Settings # ------------- _src_base_dir="$(realpath $(dirname $0))" conf_file="${_src_base_dir}/conf/install_update_dovecot.conf" curdir=`pwd` log_file="$(mktemp)" backup_date="$(date +%Y-%m-%d-%H%M)" 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 an Variable # ------------- 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 -e "\t[ \033[31m\033[1mFatal\033[m ]: \033[37m\033[1m$*\033[m" echo "" echo -e "\t\033[31m\033[1m Skript wird abgebrochen\033[m\033[m\n" rm -f $log_file exit 1 } error(){ echo "" echo -e "\t[ \033[31m\033[1mError\033[m ]: $*" echo "" } warn(){ echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" } # - Support systemd ? # - if [[ "X$(which systemd)" = "X" ]]; then SYSTEMD_EXISTS=false else SYSTEMD_EXISTS=true fi echo echononl "\tInclude Configuration file.." if [[ ! -f $conf_file ]]; then echo -e "$rc_failed" fatal "Missing configuration file '$conf_file'" else source $conf_file echo -e "$rc_done" fi if [[ -z "$systemd_support" ]] ; then if $SYSTEMD_EXISTS ; then systemd_support=true else systemd_support=false fi fi _log_dir=${_src_base_dir}/log-dovecot-$_version # ------------- # - List Script Configurations # ------------- 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 "\tSystemd support...............: $systemd_support" 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 "" if ! $_update ;then warn "Take care, your PostgreSQL configuration (pg_hba.conf) contains the following line:\n\n\t pg_hba.conf:\n\t \033[1mlocal all postfix trust\033[m" fi 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 $conf_file)' and correct variables" # ------------- # - Begin Install/Update # ------------- 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 echo "Doing some backups.." echononl "\tBackup existing installation log directory.." if [[ -d "${_log_dir}" ]]; then mv "${_log_dir}" "${_log_dir}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Cannot Backup (move) directory '${_log_dir}'" fi else echo -e "$rc_skipped" fi echononl "\tBackup existing installation directory.." if [[ -d "/usr/local/dovecot-${_version}" ]]; then mv "/usr/local/dovecot-${_version}" "/usr/local/dovecot-${_version}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Cannot Backup (move) directory '${_log_dir}'" fi else echo -e "$rc_skipped" fi echononl "\tBackup existing source directory.." if [[ -d "${_src_base_dir}/dovecot-${_version}" ]]; then mv "${_src_base_dir}/dovecot-${_version}" "${_src_base_dir}/dovecot-${_version}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Cannot Backup (move) directory '${_src_base_dir}/dovecot-${_version}'" fi else echo -e "$rc_skipped" fi mkdir -p $_log_dir ## ----------------- ## --- Download cd ${_src_base_dir} echo "" 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 if [ ! -f "${_src_base_dir}/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 if [ ! -f "${_src_base_dir}/${_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 tar -xzf 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} config_params=" --prefix=/usr/local/dovecot-${_version} \ --with-${db_driver} \ --with-gssapi=yes --with-rundir=/var/run/dovecot" if $systemd_support ; then config_params="$config_params \ --with-systemdsystemunitdir=/etc/systemd/system/" fi 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 \ LDFLAGS="-s" \ ./configure $config_params > ${_log_dir}/dovecot-${_version}-configure.log 2>&1 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 - gunzip < ${_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 ## - ## - default_vsz_limit = 512M ## - ## - !! 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 ## - .. ## - } ## - } ## - _failed=false 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 perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_vsz_limit.*)#\1\2\ndefault_vsz_limit = 512M#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 ## - #} ## - _failed=false 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 ## - _failed=false 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 ## - .. ## - } ## - _failed=false _found=false _tmp_file="$(mktemp)" > $_tmp_file while IFS='' read -r _line || [[ -n $_line ]] ; do if echo "$_line" | grep -i -E "^\s*namespace\s+inbox\s+" > /dev/null 2>&1 ; then echo "found!" echo "## $_line" >> $_tmp_file _found=true continue fi if $_found && echo "$_line" | grep -i -E "^\s*}" > /dev/null 2>&1 ; then echo "## $_line" >> $_tmp_file _found=false continue fi if $_found ; then echo "## $_line" >> $_tmp_file else echo "$_line" >> $_tmp_file fi done < "/usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf" if [[ "$?" != "0" ]] ; then _failed=true fi mv /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf.ORIG if [[ "$?" != "0" ]] ; then _failed=true fi mv $_tmp_file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf if [[ "$?" != "0" ]] ; then _failed=true fi #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 ## - } ## - _failed=false 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 = "%@" ## - _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 = ## - _failed=false 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 > $log_file 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat $log_file)" 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.." if $systemd_support ; then systemctl enable dovecot > /dev/null 2>&1 else update-rc.d dovecot defaults > /dev/null 2>&1 fi 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 -a "/etc/postfix/master.cf" "/etc/postfix/master.cf.$backup_date" 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: ## - ## - smtpd_sasl_type = dovecot ## - smtpd_sasl_path = private/dovecot-auth ## - ## - virtual_transport = dovecot ## - dovecot_destination_recipient_limit = 1 ## - ## - in section restrictions, parameter smtpd_recipient_restrictions ## - uncomment add ## - ## - permit_sasl_authenticated, ## - _failed=false echononl "\tAdjust /etc/postfix/main.cf" perl -i.$backup_date -n -p -e "s#^(\s*)(smtpd_sasl_auth_enable\ *=.*)#smtpd_sasl_auth_enable = no#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_type\ *=.*)#smtpd_sasl_type = dovecot#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_path\ *=.*)#smtpd_sasl_path = private/dovecot-auth#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(virtual_transport\ *=.*)#virtual_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 ## - _failed=false 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 ## - ## - change: ## - smtpd_sasl_auth_enable = yes ## - smtpd_sasl_type = dovecot ## - smtpd_sasl_path = private/dovecot-auth ## - virtual_transport = lmtp:unix:private/dovecot-lmtp _failed=false echononl "\tAdjust /etc/postfix/main.cf" perl -i -n -p -e "s#^(\s*)(smtpd_sasl_auth_enable\ *=.*)#smtpd_sasl_auth_enable = yes#" \ /etc/postfix/main.cf || _failed=true #perl -i -n -p -e "s#^(\s*)(smtpd_sasl_type\ *=.*)#\1\#\2\n\1smtpd_sasl_type = dovecot#" \ perl -i -n -p -e "s#^(\s*)(smtpd_sasl_type\ *=.*)#smtpd_sasl_type = dovecot#" \ /etc/postfix/main.cf || _failed=true #perl -i -n -p -e "s#^(\s*)(smtpd_sasl_path\ *=.*)#\1\#\2\n\1smtpd_sasl_path = private/dovecot-auth#" \ # /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_path\ *=.*)#smtpd_sasl_path = private/dovecot-auth#" \ /etc/postfix/main.cf || _failed=true #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*)(virtual_transport\ *=.*)#virtual_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 ## - } ## - } ## - _failed=false 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 ## - } _failed=false 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 ## - _failed=false 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 ## - _failed=false 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 ## - } ## - _failed=false 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 ## - ... ## - } ## - _failed=false 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 ## - } ## - .. ## - } ## - _failed=false 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.." if $systemd_support ; then systemctl start dovecot else /etc/init.d/dovecot restart > /dev/null 2>&1 fi if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Restarting dovecot failed" fi echononl "\tRestart postfix.." if $SYSTEMD_EXISTS ; then systemctl restart postfix else /etc/init.d/postfix restart > /dev/null 2>&1 fi 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 "" rm -f "$log_file" exit