diff --git a/dovecot-conf.patch b/dovecot-conf.patch new file mode 100644 index 0000000..5f699c7 --- /dev/null +++ b/dovecot-conf.patch @@ -0,0 +1,628 @@ +diff -r -u dovecot-0.99.11.orig/configure.in dovecot-0.99.11/configure.in +--- dovecot-0.99.11.orig/configure.in 2004-09-04 05:20:19.000000000 -0400 ++++ dovecot-0.99.11/configure.in 2004-11-19 16:36:37.000000000 -0500 +@@ -21,6 +21,20 @@ + # check posix headers + AC_CHECK_HEADERS(sys/time.h) + ++AC_ARG_WITH(logindir, ++[ --with-logindir=DIR LOGIN directory (LOCALSTATEDIR/run/dovecot)], ++ logindir="$withval", ++ logindir=\${localstatedir}/run/dovecot/login ++) ++AC_SUBST(logindir) ++ ++AC_ARG_WITH(docdir, ++[ --with-docdir=DIR directory for documentation (DATADIR/doc/dovecot)], ++ docdir="$withval", ++ docdir=\${datadir}/doc/dovecot ++) ++AC_SUBST(docdir) ++ + AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Enable IPv6 support (default)], + if test x$enableval = xno; then +@@ -180,6 +194,8 @@ + ) + AC_SUBST(ssldir) + ++AM_CONDITIONAL(BUILD_SSL, test "$want_gnutls" = "yes" -o "$want_openssl" = "yes" ) ++ + AC_ARG_WITH(pop3d, + [ --with-pop3d Build POP3 server (default)], + if test x$withval = xno; then +@@ -1121,6 +1137,13 @@ + AC_MSG_RESULT($i_cv_type_in6_addr) + fi + ++if test $i_cv_type_in6_addr = yes; then ++ listenaddr='[[::]]' ++else ++ listenaddr='*' ++fi ++AC_SUBST(listenaddr) ++ + dnl ** + dnl ** storage classes + dnl ** +@@ -1148,7 +1171,9 @@ + + AC_OUTPUT( + Makefile ++dovecot.conf + doc/Makefile ++doc/mkcert.sh + src/Makefile + src/lib/Makefile + src/lib-charset/Makefile +diff -r -u dovecot-0.99.11.orig/doc/Makefile.am dovecot-0.99.11/doc/Makefile.am +--- dovecot-0.99.11.orig/doc/Makefile.am 2004-05-25 14:21:10.000000000 -0400 ++++ dovecot-0.99.11/doc/Makefile.am 2004-11-19 12:21:31.000000000 -0500 +@@ -1,4 +1,4 @@ +-docdir = $(datadir)/doc/dovecot ++exampledir=$(docdir)/examples + + doc_DATA = \ + auth.txt \ +@@ -10,10 +10,13 @@ + nfs.txt \ + securecoding.txt + +-EXTRA_DIST = \ ++example_DATA = \ + mkcert.sh \ + dovecot-openssl.cnf \ + dovecot-ldap.conf \ + dovecot-mysql.conf \ +- dovecot-pgsql.conf \ ++ dovecot-pgsql.conf ++ ++EXTRA_DIST = \ ++ $(example_DATA) \ + $(doc_DATA) +diff -r -u dovecot-0.99.11.orig/Makefile.am dovecot-0.99.11/Makefile.am +--- dovecot-0.99.11.orig/Makefile.am 2003-05-05 12:46:57.000000000 -0400 ++++ dovecot-0.99.11/Makefile.am 2004-11-22 16:08:01.000000000 -0500 +@@ -1,7 +1,18 @@ + SUBDIRS = src doc + + confdir = $(sysconfdir) +-conf_DATA = dovecot-example.conf ++conf_DATA = dovecot.conf ++ ++doc_DATA = \ ++ AUTHORS \ ++ COPYING \ ++ COPYING.LGPL \ ++ ChangeLog \ ++ INSTALL \ ++ NEWS \ ++ README \ ++ TODO ++ + + EXTRA_DIST = \ + config.rpath \ +diff -N -u dovecot-0.99.11.orig/doc/mkcert.sh.in dovecot-0.99.11/doc/mkcert.sh.in +--- dovecot-0.99.11.orig/doc/mkcert.sh.in 1969-12-31 19:00:00.000000000 -0500 ++++ dovecot-0.99.11/doc/mkcert.sh.in 2004-11-19 13:47:38.000000000 -0500 +@@ -0,0 +1,34 @@ ++#!/bin/sh ++ ++# Generates a self-signed certificate. ++# Edit dovecot-openssl.cnf before running this. ++ ++OPENSSL=${OPENSSL-openssl} ++SSLDIR=${SSLDIR-@ssldir@} ++OPENSSLCONFIG=${OPENSSLCONFIG-dovecot-openssl.cnf} ++ ++CERTFILE=$SSLDIR/certs/@PACKAGE@.pem ++KEYFILE=$SSLDIR/private/@PACKAGE@.pem ++ ++if [ ! -d $SSLDIR/certs ]; then ++ echo "$SSLDIR/certs directory doesn't exist" ++fi ++ ++if [ ! -d $SSLDIR/private ]; then ++ echo "$SSLDIR/private directory doesn't exist" ++fi ++ ++if [ -f $CERTFILE ]; then ++ echo "$CERTFILE already exists, won't overwrite" ++ exit 1 ++fi ++ ++if [ -f $KEYFILE ]; then ++ echo "$KEYFILE already exists, won't overwrite" ++ exit 1 ++fi ++ ++$OPENSSL req -new -x509 -nodes -config $OPENSSLCONFIG -out $CERTFILE -keyout $KEYFILE -days 365 || exit 2 ++chmod 0600 $KEYFILE ++echo ++$OPENSSL x509 -subject -fingerprint -noout -in $CERTFILE || exit 2 +diff -N -u dovecot-0.99.11.orig/dovecot.conf.in dovecot-0.99.11/dovecot.conf.in +--- dovecot-0.99.11.orig/dovecot.conf.in 1969-12-31 19:00:00.000000000 -0500 ++++ dovecot-0.99.11/dovecot.conf.in 2004-11-19 16:42:03.000000000 -0500 +@@ -0,0 +1,481 @@ ++## Dovecot 1.0 configuration file ++ ++# Base directory where to store runtime data. ++#base_dir = @localstatedir@/run/dovecot/ ++ ++# Protocols we want to be serving: ++# imap imaps pop3 pop3s ++#protocols = imap imaps ++ ++# IP or host address where to listen in for connections. It's not currently ++# possible to specify multiple addresses. "*" listens in all IPv4 interfaces. ++# "[::]" listens in all IPv6 interfaces, but may also listen in all IPv4 ++# interfaces depending on the operating system. You can specify ports with ++# "host:port". ++imap_listen = @listenaddr@ ++pop3_listen = @listenaddr@ ++ ++# IP or host address where to listen in for SSL connections. Defaults ++# to above non-SSL equilevants if not specified. ++#imaps_listen = @listenaddr@ ++#pop3s_listen = @listenaddr@ ++ ++# Disable SSL/TLS support. ++@BUILD_SSL_TRUE@ssl_disable = no ++ ++# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before ++# dropping root privileges, so keep the key file unreadable by anyone but ++# root. Included doc/mkcert.sh can be used to easily generate self-signed ++# certificate, just make sure to update the domains in dovecot-openssl.cnf ++@BUILD_SSL_TRUE@ssl_cert_file = @ssldir@/certs/@PACKAGE@.pem ++@BUILD_SSL_TRUE@ssl_key_file = @ssldir@/private/@PACKAGE@.pem ++ ++# SSL parameter file. Master process generates this file for login processes. ++# It contains Diffie Hellman and RSA parameters. ++@BUILD_SSL_TRUE@ssl_parameters_file = @localstatedir@/run/dovecot/ssl-parameters.dat ++ ++# How often to regenerate the SSL parameters file. Generation is quite CPU ++# intensive operation. The value is in hours, 0 disables regeneration ++# entirely. ++@BUILD_SSL_TRUE@ssl_parameters_regenerate = 24 ++ ++# Disable LOGIN command and all other plaintext authentications unless ++# SSL/TLS is used (LOGINDISABLED capability). Note that 127.*.*.* and ++# IPv6 ::1 addresses are considered secure, this setting has no effect if ++# you connect from those addresses. ++#disable_plaintext_auth = yes ++ ++# Use this logfile instead of syslog(). /dev/stderr can be used if you want to ++# use stderr for logging (ONLY /dev/stderr - otherwise it is closed). ++#log_path = ++ ++# For informational messages, use this logfile instead of the default ++#info_log_path = ++ ++# Prefix for each line written to log file. % codes are in strftime(3) ++# format. ++#log_timestamp = "%b %d %H:%M:%S " ++ ++## ++## Login processes ++## ++ ++# Directory where authentication process places authentication UNIX sockets ++# which login needs to be able to connect to. The sockets are created when ++# running as root, so you don't have to worry about permissions. Note that ++# everything in this directory is deleted when Dovecot is started. ++#login_dir = @logindir@ ++ ++# chroot login process to the login_dir. Only reason not to do this is if you ++# wish to run the whole Dovecot without roots. ++#login_chroot = yes ++ ++ ++## ++## IMAP login process ++## ++ ++login = imap ++ ++# Executable location. ++#login_executable = @libexecdir@/dovecot/imap-login ++ ++# User to use for the login process. Create a completely new user for this, ++# and don't use it anywhere else. The user must also belong to a group where ++# only it has access, it's used to control access for authentication process. ++#login_user = dovecot ++ ++# Set max. process size in megabytes. If you don't use ++# login_process_per_connection you might need to grow this. ++#login_process_size = 32 ++ ++# Should each login be processed in it's own process (yes), or should one ++# login process be allowed to process multiple connections (no)? Yes is more ++# secure, espcially with SSL/TLS enabled. No is faster since there's no need ++# to create processes all the time. ++#login_process_per_connection = yes ++ ++# Number of login processes to create. If login_process_per_user is ++# yes, this is the number of extra processes waiting for users to log in. ++#login_processes_count = 3 ++ ++# Maximum number of extra login processes to create. The extra process count ++# usually stays at login_processes_count, but when multiple users start logging ++# in at the same time more extra processes are created. To prevent fork-bombing ++# we check only once in a second if new processes should be created - if all ++# of them are used at the time, we double their amount until limit set by this ++# setting is reached. This setting is used only if login_process_per_use is yes. ++#login_max_processes_count = 128 ++ ++# Maximum number of connections allowed in login state. When this limit is ++# reached, the oldest connections are dropped. If login_process_per_user ++# is no, this is a per-process value, so the absolute maximum number of users ++# logging in actually login_processes_count * max_logging_users. ++#login_max_logging_users = 256 ++ ++## ++## POP3 login process ++## ++ ++# Settings default to same as above, so you don't have to set anything ++# unless you want to override them. ++ ++login = pop3 ++ ++# Exception to above rule being the executable location. ++#login_executable = @libexecdir@/dovecot/pop3-login ++ ++## ++## Mail processes ++## ++ ++# Maximum number of running mail processes. When this limit is reached, ++# new users aren't allowed to log in. ++#max_mail_processes = 1024 ++ ++# Show more verbose process titles (in ps). Currently shows user name and ++# IP address. Useful for seeing who are actually using the IMAP processes ++# (eg. shared mailboxes or if same uid is used for multiple accounts). ++#verbose_proctitle = no ++ ++# Show protocol level SSL errors. ++@BUILD_SSL_TRUE@verbose_ssl = no ++ ++# Valid UID range for users, defaults to 500 and above. This is mostly ++# to make sure that users can't log in as daemons or other system users. ++# Note that denying root logins is hardcoded to dovecot binary and can't ++# be done even if first_valid_uid is set to 0. ++#first_valid_uid = 500 ++#last_valid_uid = 0 ++ ++# Valid GID range for users, defaults to non-root/wheel. Users having ++# non-valid GID as primary group ID aren't allowed to log in. If user ++# belongs to supplementary groups with non-valid GIDs, those groups are ++# not set. ++#first_valid_gid = 1 ++#last_valid_gid = 0 ++ ++# Grant access to these extra groups for mail processes. Typical use would be ++# to give "mail" group write access to /var/mail to be able to create dotlocks. ++#mail_extra_groups = ++ ++# ':' separated list of directories under which chrooting is allowed for mail ++# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too). ++# This setting doesn't affect login_chroot or auth_chroot variables. ++# WARNING: Never add directories here which local users can modify, that ++# may lead to root exploit. Usually this should be done only if you don't ++# allow shell access for users. See doc/configuration.txt for more information. ++#valid_chroot_dirs = ++ ++# Default chroot directory for mail processes. This can be overridden by ++# giving /./ in user's home directory (eg. /home/./user chroots into /home). ++#mail_chroot = ++ ++# Default MAIL environment to use when it's not set. By leaving this empty ++# dovecot tries to do some automatic detection as described in ++# doc/mail-storages.txt. There's a few special variables you can use: ++# ++# %u - username ++# %n - user part in user@domain, same as %u if there's no domain ++# %d - domain part in user@domain, empty if user there's no domain ++# %h - home directory ++# ++# You can also limit a width of string by giving the number of max. characters ++# after the '%' character. For example %1u gives the first character of ++# username. Some examples: ++# ++# default_mail_env = maildir:/var/mail/%1u/%u/Maildir ++# default_mail_env = mbox:~/mail/:INBOX=/var/mail/%u ++# default_mail_env = mbox:/var/mail/%d/%n/:INDEX=/var/indexes/%d/%n ++# ++#default_mail_env = ++ ++# Space-separated list of fields to cache for all mails. Currently these ++# fields are allowed followed by a list of commands they speed up: ++# ++# Envelope - FETCH ENVELOPE and SEARCH FROM, TO, CC, BCC, SUBJECT, ++# SENTBEFORE, SENTON, SENTSINCE, HEADER MESSAGE-ID, ++# HEADER IN-REPLY-TO ++# Body - FETCH BODY ++# Bodystructure - FETCH BODY, BODYSTRUCTURE ++# MessagePart - FETCH BODY[1.2.3] (ie. body parts), RFC822.SIZE, ++# SEARCH SMALLER, LARGER, also speeds up BODY/BODYSTRUCTURE ++# generation. This is always set with mbox mailboxes, and ++# also default with Maildir. ++# ++# Different IMAP clients work in different ways, that's why Dovecot by default ++# only caches MessagePart which speeds up most operations. Whenever client ++# does something where caching could be used, the field is automatically marked ++# to be cached later. For example after FETCH BODY the BODY will be cached ++# for all new messages. Normally you should leave this alone, unless you know ++# what most of your IMAP clients are. Caching more fields than needed makes ++# the index files larger and generate useless I/O. ++# ++# With maildir there's one extra optimization - if nothing is cached, indexing ++# the maildir becomes much faster since it's not opening any of the mail files. ++# This could be useful if your IMAP clients access only new mails. ++ ++#mail_cache_fields = MessagePart ++ ++# Space-separated list of fields that Dovecot should never set to be cached. ++# Useful if you want to save disk space at the cost of more I/O when the fields ++# needed. ++#mail_never_cache_fields = ++ ++# Workarounds for various client bugs: ++# oe6-fetch-no-newmail: ++# Never send EXISTS/RECENT when replying to FETCH command. Outlook Express ++# seems to think they are FETCH replies and gives user "Message no longer ++# in server" error. Note that OE6 still breaks even with this workaround ++# if synchronization is set to "Headers Only". ++# outlook-idle: ++# Outlook and Outlook Express never abort IDLE command, so if no mail ++# arrives in half a hour, Dovecot closes the connection. This is still ++# fine, except Outlook doesn't connect back so you don't see if new mail ++# arrives. ++# outlook-pop3-no-nuls: ++# Outlook and Outlook Express hang if mails contain NUL characters. ++# This setting replaces them with 0x80 character. ++#client_workarounds = ++ ++# Dovecot can notify client of new mail in selected mailbox soon after it's ++# received. This setting specifies the minimum interval in seconds between ++# new mail notifications to client - internally they may be checked more or ++# less often. Setting this to 0 disables the checking. ++# NOTE: Evolution client breaks with this option when it's trying to APPEND. ++#mailbox_check_interval = 0 ++ ++# Like mailbox_check_interval, but used for IDLE command. ++#mailbox_idle_check_interval = 30 ++ ++# Allow full filesystem access to clients. There's no access checks other than ++# what the operating system does for the active UID/GID. It works with both ++# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/ ++# or ~user/. ++#mail_full_filesystem_access = no ++ ++# Maximum allowed length for custom flag name. It's only forced when trying ++# to create new flags. ++#mail_max_flag_length = 50 ++ ++# Save mails with CR+LF instead of plain LF. This makes sending those mails ++# take less CPU, especially with sendfile() syscall with Linux and FreeBSD. ++# But it also creates a bit more disk I/O which may just make it slower. ++#mail_save_crlf = no ++ ++# Use mmap() instead of read() to read mail files. read() seems to be a bit ++# faster with my Linux/x86 and it's better with NFS, so that's the default. ++#mail_read_mmaped = no ++ ++# By default LIST command returns all entries in maildir beginning with dot. ++# Enabling this option makes Dovecot return only entries which are directories. ++# This is done by stat()ing each entry, so it causes more disk I/O. ++# (For systems setting struct dirent->d_type, this check is free and it's ++# done always regardless of this setting) ++#maildir_stat_dirs = no ++ ++# Copy mail to another folders using hard links. This is much faster than ++# actually copying the file. This is problematic only if something modifies ++# the mail in one folder but doesn't want it modified in the others. I don't ++# know any MUA which would modify mail files directly. IMAP protocol also ++# requires that the mails don't change, so it would be problematic in any case. ++# If you care about performance, enable it. ++#maildir_copy_with_hardlinks = no ++ ++# Check if mails' content has been changed by external programs. This slows ++# down things as extra stat() needs to be called for each file. If changes are ++# noticed, the message is treated as a new message, since IMAP protocol ++# specifies that existing messages are immutable. ++#maildir_check_content_changes = no ++ ++# Which locking methods to use for locking mbox. There's three available: ++# dotlock: Create .lock file. This is the oldest and most NFS-safe ++# solution. If you want to use /var/mail/ like directory, the users ++# will need write access to that directory. ++# fcntl : Use this if possible. Works with NFS too if lockd is used. ++# flock : May not exist in all systems. Doesn't work with NFS. ++# ++# You can use both fcntl and flock too; if you do the order they're declared ++# with is important to avoid deadlocks if other MTAs/MUAs are using both fcntl ++# and flock. Some operating systems don't allow using both of them ++# simultaneously, eg. BSDs. If dotlock is used, it's always created first. ++#mbox_locks = dotlock fcntl ++ ++# Should we create dotlock file even when we want only a read-lock? Setting ++# this to yes hurts the performance when the mailbox is accessed simultaneously ++# by multiple processes, but it's needed for reliable reading if no other ++# locking methods are available. ++#mbox_read_dotlock = no ++ ++# Maximum time in seconds to wait for lock (all of them) before aborting. ++#mbox_lock_timeout = 300 ++ ++# If dotlock exists but the mailbox isn't modified in any way, override the ++# lock file after this many seconds. ++#mbox_dotlock_change_timeout = 30 ++ ++# umask to use for mail files and directories ++#umask = 0077 ++ ++# Drop all privileges before exec()ing the mail process. This is mostly ++# meant for debugging, otherwise you don't get core dumps. Note that setting ++# this to yes means that log file is opened as the logged in user, which ++# might not work. It could also be a small security risk if you use single UID ++# for multiple users, as the users could ptrace() each others processes then. ++#mail_drop_priv_before_exec = no ++ ++## ++## IMAP process ++## ++ ++# Executable location ++#imap_executable = @libexecdir@/dovecot/imap ++ ++# Set max. process size in megabytes. Most of the memory goes to mmap()ing ++# files, so it shouldn't harm much even if this limit is set pretty high. ++#imap_process_size = 256 ++ ++# Support for dynamically loadable modules. ++#imap_use_modules = no ++#imap_modules = @moduledir@/imap ++ ++## ++## POP3 process ++## ++ ++# Executable location ++#pop3_executable = @libexecdir@/dovecot/pop3 ++ ++# Set max. process size in megabytes. Most of the memory goes to mmap()ing ++# files, so it shouldn't harm much even if this limit is set pretty high. ++#pop3_process_size = 256 ++ ++# Support for dynamically loadable modules. ++#pop3_use_modules = no ++#pop3_modules = @moduledir@/pop3 ++ ++## ++## Authentication processes ++## ++ ++# An Authentication process is a child process used by Dovecot that ++# handles the authentication steps. The steps cover an authentication ++# mechanism (auth_mechanisms, how the client authenticates in the IMAP or ++# POP3 protocol), which password database should be queried (auth_passdb), ++# and which user database should be queried (auth_userdb, to obtain ++# UID, GID, and location of the user's mailbox/home directory). ++# ++# You can have multiple processes, though a typical configuration will ++# have only one. Each time "auth = xx" is seen, a new process ++# definition is started. The point of multiple processes is to be able ++# to set stricter permissions. (See auth_user below.) ++# ++# Just remember that only one Authentication process is asked for the ++# password, so you can't have different passwords accessible through ++# different process definitions (unless they have different ++# auth_mechanisms, and you're ok with having different password for ++# each mechanisms). ++ ++# Authentication process name. ++auth = default ++ ++# Specifies how the client authenticates in the IMAP protocol. ++# Space separated list of permitted authentication mechanisms: ++# anonymous plain digest-md5 cram-md5 ++# ++# anonymous - No authentication required. ++# plain - The password is sent as plain text. All IMAP/POP3 clients ++# support this, and the password can be encrypted by Dovecot to match ++# any of the encryption schemes used in password databases. ++# digest-md5 and cram-md5 - both encrypt the password so it is more ++# secure in transit, but are not well supported by clients, and ++# require that the password database use a matching encryption ++# scheme (or be in plaintext). ++# ++# See auth.txt for more details. ++# ++# If you are using SSL there is less benefit to digest-md5 and ++# cram-md5 as the communication is already encrypted. ++auth_mechanisms = plain ++ ++# Space separated list of realms for SASL authentication mechanisms that need ++# them. You can leave it empty if you don't want to support multiple realms. ++# Many clients simply use the first one listed here, so keep the default realm ++# first. ++#auth_realms = ++ ++# Default realm/domain to use if none was specified. This is used for both ++# SASL realms and appending @domain to username in plaintext logins. ++#auth_default_realm = ++ ++# Where user database is kept: ++# passwd: /etc/passwd or similiar, using getpwnam() ++# passwd-file : passwd-like file with specified location ++# static uid= gid= home=: static settings ++# vpopmail: vpopmail library ++# ldap : LDAP, see doc/dovecot-ldap.conf ++# pgsql : a PostgreSQL database, see doc/dovecot-pgsql.conf ++auth_userdb = passwd ++ ++# Where password database is kept: ++# passwd: /etc/passwd or similiar, using getpwnam() ++# shadow: /etc/shadow or similiar, using getspnam() ++# pam [ | *]: PAM authentication ++# passwd-file : passwd-like file with specified location ++# vpopmail: vpopmail authentication ++# ldap : LDAP, see doc/dovecot-ldap.conf ++# pgsql : a PostgreSQL database, see doc/dovecot-pgsql.conf ++auth_passdb = pgsql @sysconfdir@/dovecot-pgsql.conf ++ ++#auth_executable = @libexecdir@/dovecot/dovecot-auth ++ ++# Set max. process size in megabytes. ++#auth_process_size = 256 ++ ++# User to use for the process. This user needs access to only user and ++# password databases, nothing else. Only shadow and pam authentication ++# requires roots, so use something else if possible. Note that passwd ++# authentication with BSDs internally accesses shadow files, which also ++# requires roots. ++auth_user = root ++ ++# Directory where to chroot the process. Most authentication backends don't ++# work if this is set, and there's no point chrooting if auth_user is root. ++#auth_chroot = ++ ++# Number of authentication processes to create ++#auth_count = 1 ++ ++# List of allowed characters in username. If the user-given username contains ++# a character not listed in here, the login automatically fails. This is just ++# an extra check to make sure user can't exploit any potential quote escaping ++# vulnerabilities with SQL/LDAP databases. If you want to allow all characters, ++# set this value to empty. ++#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ ++ ++# Username to use for users logging in with ANONYMOUS SASL mechanism ++#auth_anonymous_username = anonymous ++ ++# More verbose logging. Useful for figuring out why authentication isn't ++# working. ++#auth_verbose = no ++ ++# Even more verbose logging for debugging purposes. Shows for example SQL ++# queries. ++#auth_debug = no ++ ++# digest-md5 authentication process. It requires special MD5 passwords which ++# /etc/shadow and PAM doesn't support, so we never need roots to handle it. ++# Note that the passwd-file is opened before chrooting and dropping root ++# privileges, so it may be 0600-root owned file. ++ ++#auth = digest_md5 ++#auth_mechanisms = digest-md5 ++#auth_realms = ++#auth_userdb = passwd-file /etc/passwd.imap ++#auth_passdb = passwd-file /etc/passwd.imap ++#auth_user = imapauth ++#auth_chroot = ++ ++# if you plan to use only passwd-file, you don't need the two auth processes, ++# simply set "auth_methods = plain digest-md5" diff --git a/dovecot.spec b/dovecot.spec index 414337d..d0d6575 100644 --- a/dovecot.spec +++ b/dovecot.spec @@ -1,13 +1,17 @@ Summary: Dovecot Secure imap server Name: dovecot Version: 0.99.11 -Release: 2.FC4.1 +Release: 6.devel License: LGPL Group: System Environment/Daemons Source: %{name}-%{version}.tar.gz Source1: dovecot.init Source2: dovecot.pam -Patch100: dovecot-0.99.10.4-conf.patch +Source3: maildir-migration.txt +Source4: migrate-folders +Source5: migrate-users +Source6: perfect_maildir.pl +Patch100: dovecot-conf.patch # Patches 500+ from upstream fixes URL: http://dovecot.procontrol.fi/ @@ -19,8 +23,12 @@ BuildRequires: openldap-devel BuildRequires: pam-devel BuildRequires: pkgconfig BuildRequires: zlib-devel +BuildRequires: gettext-devel Prereq: openssl, /sbin/chkconfig, /usr/sbin/useradd +%define docdir %{_docdir}/%{name}-%{version} +%define ssldir /usr/share/ssl + %description Dovecot is an IMAP server for Linux/UNIX-like systems, written with security primarily in mind. It also contains a small POP3 server. It supports mail @@ -35,21 +43,25 @@ in either of maildir or mbox formats. %build rm -f ./configure aclocal -autoconf -%configure \ - --with-pgsql \ - --with-mysql \ - --with-ssl=openssl \ - --with-ssldir=/usr/share/ssl \ +automake -a -f +autoconf -f +%configure \ + --with-docdir=%{docdir} \ + --with-logindir=/var/run/dovecot-login \ + --with-mbox-locks=fcntl \ + --with-pgsql \ + --with-mysql \ + --with-ssl=openssl \ + --with-ssldir=%{ssldir} \ --with-ldap make %install rm -rf $RPM_BUILD_ROOT -%makeinstall +make DESTDIR=$RPM_BUILD_ROOT install + rm -rf $RPM_BUILD_ROOT/%{_datadir}/%{name} -install -m 644 dovecot-example.conf $RPM_BUILD_ROOT/%{_sysconfdir}/dovecot.conf mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d install -m 755 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d/dovecot @@ -57,17 +69,19 @@ mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/dovecot # generate ghost .pem file -mkdir -p $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private} -touch $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private}/dovecot.pem -chmod 600 $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private}/dovecot.pem +mkdir -p $RPM_BUILD_ROOT/%{ssldir}/{certs,private} +touch $RPM_BUILD_ROOT/%{ssldir}/{certs,private}/dovecot.pem +chmod 600 $RPM_BUILD_ROOT/%{ssldir}/{certs,private}/dovecot.pem mkdir -p $RPM_BUILD_ROOT/var/run/dovecot chmod 700 $RPM_BUILD_ROOT/var/run/dovecot mkdir -p $RPM_BUILD_ROOT/var/run/dovecot-login -# the dovecot make install installs docs. blah. -rm -rf $RPM_BUILD_ROOT/%{_docdir}/%{name} -rm -f $RPM_BUILD_ROOT/etc/dovecot-example.conf +install -m755 -d $RPM_BUILD_ROOT%{docdir}/UW-to-Dovecot-Migration +for f in maildir-migration.txt migrate-folders migrate-users perfect_maildir.pl +do + install -m644 $RPM_SOURCE_DIR/$f $RPM_BUILD_ROOT%{docdir}/UW-to-Dovecot-Migration +done %pre /usr/sbin/useradd -c "dovecot" -u 97 -s /sbin/nologin -r -d /usr/libexec/dovecot dovecot 2>/dev/null || : @@ -75,8 +89,8 @@ rm -f $RPM_BUILD_ROOT/etc/dovecot-example.conf %post /sbin/chkconfig --add dovecot # create a ssl cert -if [ ! -f %{_datadir}/ssl/certs/dovecot.pem ]; then -pushd %{_datadir}/ssl &>/dev/null +if [ ! -f %{ssldir}/certs/dovecot.pem ]; then +pushd %{ssldir} &>/dev/null umask 077 cat << EOF | openssl req -new -x509 -days 365 -nodes -out certs/dovecot.pem -keyout private/dovecot.pem &>/dev/null -- @@ -107,12 +121,12 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) -%doc doc/*.txt doc/dovecot-openssl.cnf doc/mkcert.sh INSTALL AUTHORS ChangeLog COPYING TODO README NEWS COPYING.LGPL +%doc %{docdir} %config(noreplace) %{_sysconfdir}/dovecot.conf %config %{_sysconfdir}/rc.d/init.d/dovecot %config %{_sysconfdir}/pam.d/dovecot -%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{_datadir}/ssl/certs/dovecot.pem -%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{_datadir}/ssl/private/dovecot.pem +%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/certs/dovecot.pem +%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/private/dovecot.pem %dir %{_libexecdir}/%{name} %{_libexecdir}/%{name}/* %{_sbindir}/dovecot diff --git a/maildir-migration.txt b/maildir-migration.txt new file mode 100644 index 0000000..b8f0f56 --- /dev/null +++ b/maildir-migration.txt @@ -0,0 +1,315 @@ +Replacing UW-IMAP with Dovecot on Red Hat Enterprise Linux 3. + +G.R.Keech + +2004-11-09 + +Version 1.0 + + +Summary + +The IMAP server in Red Hat Enterprise Linux version 3 (RHEL3) is the +University of Washington (UW) implemenation. UW IMAP uses the mbox +mail storage format which has been found to have significant +scalability and performance issues. This paper describes how to +replace UW IMAP with the Dovecot IMAP server which uses the maildir +mail storage format and, consequently, is significantly faster. + + +Maildir vs Mbox + +Format issues. The mbox format holds email with one file corresponding +to an entire mail folder. Maildir, on the other hand, stores messages +one directory per folder, with each message being a single file. The +mbox format doesn't scale well when many users have large mail folders +which are polled frequently. When the sum of sizes of all the +frequently polled mail greatly exceed the system's RAM, then mail +boxes cannot be effectively cached in RAM. This leads to a situation +where mbox files are being continually re-read with each poll by each +mail client, leading to excessive IO activity and poor performance. + +Example. Here is a real example of poor performance using UW IMAP. +The site characteristics were as follows: + +* about 116 active mail accounts with users using a mix of both +Outlook express and Outlook; + +* Mail clients poll for new mail every five minutes; + +* 1GB system RAM in mail server; + +* Mail server using Postfix on RHEL3 (kernel 2.4.21-20.EL); + +* System has single 3.0GHz P4 processor and SATA disk; + +* 112 inboxes totalling 3.3GB (average about 30MB each); + +* 8.5GB of filed email in imap folders. + +Performance with mbox. When in use the load average on the mail server +was normally between four and six with spikes above 15 not uncommon +and spikes above 20 occasionally. Most of this load was associated +with instances of uw-imap in disk wait state. The user experience in +checking mail was very poor, despite this being a reasonably small +site. When users checked for new mail they frequently encountered +server timeouts. For users with large inboxes, it was not uncommon +for it to take between 60 and 90 seconds just to check for new mail. + +Performance with maildir. Once the imap service was changed to +Dovecot, with all the other variables remaining unchanged, the +situation improved dramatically. Load average is very rarely above +0.5 and is usually under 0.2 during working hours. The user +experience was improved significantly. Users no longer +experience timeouts, and the time taken to check for new mail +is usually only two or three seconds and always less than 10 seconds. + + +Setting up Dovecot + +Dovecot. The Dovecot IMAP server will replace UW IMAP in RHEL4. The +Dovecot project is at http://dovecot.procontrol.fi/. It was built for +RHEL3 based on the package from the Beta of RHEL4. The RHEL3 version +used in this migration can be found at +http://people.redhat.com/rkeech/#dovecot. + +Operation. Dovecot, unlike uw-imap, runs as a conventional +daemon-based service, ie it is not run from xinetd. When running +A typical process hierarchy when Dovecot is running looks as follows: + +dovecot --+--- dovecot-auth + +--- imap + +--- imap-login + +One instance of the "imap" process will exist for each mail client +connection. These imap processes execute with the user context of +whichever mail account user is connecting. The main "dovecot" process +runs as root, as does "dovecot-auth". The imap-login processes run +as user "dovecot". + +Configuration. Dovecot is configured with /etc/dovecot.conf. The relevant +configuration setting that had to be changed in this case were as follows: + + protocols = imap + default_mail_env = maildir:/data/mail2/%u/ + +User home. In this particular migration, mail account users did not +need shell access and did not need home directories for anything but +mail folder storage. Accordingly it was possible to change the users' +home directories to be the same as the mail spool area. This can be +achieved with (for this example) + + usermod -d /data/mail2/ + +User shell. Mail accounts can function without a user shell. However +if a mail auto-responder (ie "vacation") is used then a shell is necessary. +Under RHEL3 a restricted shell is possible and reduces the security +concerns associated with providing shell access to mail users. For +a restricted version of bash make a sybolic link called "/bin/rbash" +pointing to "/bin/bash", and make /bin/rbash the users' shell. + +Postfix delivery. The location of mail delivery by Postfix is set +according to the "mail_spool_directory" parameter. When using uw-imap +this was set to "/var/spool/mail". A trailing slash on the +mail_spool_directory value directs Postfix to use maildir format. The +change to Postfix configuration in this case was done with: + + postconf -e "mail_spool_directory = /data/mail2/" + +Directory structure. For mail delivery to work with maildir a number +of sub-directories must exist in the user's personal mail spool +directory. If user "fred" has mail delivered to /data/mail2/fred/ +then that directory should have subdirectories "cur" "new" and "tmp" +in it. The "new" directory is where incoming mail messages are put. +Other folders structured in subdirectories, eg an imap folder called +"Sent" for user "fred" would be /data/mail2/fred/.Sent, and there would +be a line "Sent" in the file /data/mail2/fred/.subscriptions. + +Account creation. In the case where the mail spool area is also the +home directory, then for new accounts to accept maildir mail delivery, +the following directories should be created: + + /etc/skel/cur + /etc/skel/tmp + /etc/skel/new + +thus when an account is created, the necessary subdirectories are +automatically created in the new user's home for a maildir-style +inbox. + + +Migrating Mbox folders to Maildirs + +Conversion. The tools to convert existing mbox-style mailboxes +and folders to maildir format are not provided with Dovecot or RHEL3. +A tool called perfect_maildir was found on the Net which performs +the conversion for a single folder only. A script was written to +provide for bulk conversion of folders for all users. + +Perfect_maildir. The tool lives at http://perfectmaildir.home-dn.net. +Versions prior to 0.3 should not be used. Perfect_maildir is a Perl +script. + +Migration plan. The migration to maildir was performed within the +following bounds: + +* existing inboxes were in /var/spool/mail + +* existing mail folders were under /home// + +* new inboxes and mailfolders were combined under /data/mail2// + + +Migration scripts. The scripts prepared to handle the bulk conversion are +"migration-users" and "migrate-folders". migrate-users creates the +necessary new user mail directories under the new base directory, which +in this case was /data/mail2/. In a situation where mail accounts +needed to be setup, without the need to migrate folders then migrate-users +would be sufficient, ie the second script would not be used. +migrate-folders does the main work of the migration by calling perfect_maildir +once for each mbox mailfolder including the users' inbox. migrate-users +must be run before migrate-folders. + + +Pre-migration. Before migrating, some things to check are: + + Will the file system have enough inodes now that the number of files + is much larger? "df -i" will help. Run tune2fs as required to + increase the allowance for inodes. + + Will there be a very large number of mail accounts? The maximum + number of subdirectories per directory is 32k. If the number of + accounts does or might exceed this, then change the Dovecot + default_mail_env to suit. See the Dovecot documentation for more + information. + + Where do you want dovecot to send its log messages? By default it + uses syslog and sends to the mail facility. This can be changed to + log to a its own log file if it is not convenient to log to maillog. + +Migration steps. The actual mail file migration was performed as below +using the scripts from http://people.rehdat.com/rkeech/#maildirmigration +Note, the migration steps described here leave the original mbox inboxes +and mail folders intact. Should the migration fail, then the capacity +to continue using mbox format is retained. + +1. Ensure that no new accounts are created until the migration is +complete. Normal email operation can proceed until step X. Do not +change Postfix's mail_spool_directory until step Y. + +2. Create a working directory /root/migrate/. + +3. Create a list of users whose mailboxes are to be migrated +/root/migrate/userlist-master. The file has one user per line. + +4. Create a list of mbox folders (excluding inboxes) to be migrated +/root/migrate/folderlist-master The file has one mbox per line and +excludes the path to the user's home, eg + + +----------------- + |fred/Drafts + |fred/private + |fred/Sent + |fred/office + |fred/projectx + |mary/Sent + |mary/private + + +Check that the folderlist does not contain any folders with characters +likely to be problematic when handled by scripts, ie folders whose names +include quotation marks, comas, pound signs, "&" symbols etc. Any such +folders should have their names changed. The name change in the +folderlist file should reflect the name change on disk. Folder names +with spaces, hyphens, percent signs, and periods are known to be OK. + +5. Proceed with a test migration with a small subset of users by +creating /root/migrate/userlist and /root/migrate/folderlist based on +subsets of userlist-master and folderlist-master. The test migration +should be done with accounts that have representative mail in both +inbox and imap folders. + +6. Ensure that the new mail base directory is clear. In this example +it means that /data/mail2/ is emtpy. + +7. Run migrate-users which should read /root/migrate/userlist and +create the new user mail directories under /data/mail2/. Check that +a directory for each user is created under /data/mail2/. + +8. Start dovecot on an alternative port so as not to intefere with the +normal uw-imap. This is done by editing /etc/dovecot.conf with + + imap_listen = 1.2.3.4:1043 + +Obviously change address 1.2.3.4 to correspond to the local server. +Run + + service dovecot start + +Dovecot should start cleanly. + +It is assumed that the "protocols" and "default_mail_env" settings +are already set in /etc/dovecot.conf as described in "Configuration" +above. + +9. Run migrate-folders which should reate /root/migrate/folderlist and +populate all the necessary maildirs under each user directory. +This will invoke perfect_maildir.pl as required for each mbox file. +If the mail folders are large the this step could take some time. + +10. Test that the files created under /data/mail2/ are visible as +folders via Dovecot by configuring an imap mail client.to point +to port 1043 on the mail server using on of the test migrated accounts. +The imap mail client program should correctly sign on to the +new imap server and the migrated folders should be visible to +the user. The mail client should test that: + +a. new folders can be created and deleted. + +b. that existing mail from migrated folders is visible and that +it sorts correctly by date + +c. test that existing mail can be moved between folders. + +d. the mail client should see both an inbox and all other folders +which were in the folderlist. + +If step 10 passes (ie folders are visible as expected) then proceed with +full migration per the following steps. Do not proceed further unless +proper and expected mail folder operation is seen in the imap test of +step 10. + +11. Prepare new folderlist and userlist files from the respective +master files in the mitrate directory. + +12. Remove the test mail folders prepared steps 7 and 9 from the +new base directory (/data/mail2/* in this example). + +13. Declare mail as unavailable. + +14. Stop incoming mail (service postfix stop) and prevent further +use of imap (chkconfig imap off). + +15. Run migrate-users and migrate-folders again. + +16. Check a test user on the alternate port like step 10. +If all is OK, then + +17. Re-configure dovecot to operate on the normal imap port +by commenting out the imap_listen directive in dovecot.conf. +Re-start dovecot. + +18. Check that mail can be read on the normal imap port. + +19. Change email delivery into the new folders: + + postconf -e "mail_spool_directory = /data/mail2/" + +20 Re-start mail + + service postfix start + +21. Check and double check. + +22. Go home. + diff --git a/migrate-folders b/migrate-folders new file mode 100755 index 0000000..ede6213 --- /dev/null +++ b/migrate-folders @@ -0,0 +1,195 @@ +#!/bin/bash + +# author: G.R.Keech +# name: migrate-folders +# date: 2004-10-20 + +# This script assists in the conversion of mail boxes +# in mbox format to maildir format. +# See also migrate-users. + +# Applicability. +# +# This script is intended for the common case on Red Hat systems +# where mail users have mail folders in their home directories +# under /home, and have inboxes in /var/spool/mail/ +#================================================================== +# Change the value of the elements in this section as required. + +#This is a list of folders, one per line. This does not +#include the inboxes. This might be prepared starting with +#the output of "find /home -type d". +FOLDERLIST=/root/migrate/folderlist +# folder is the existing mbox folder being migrated. +# It is a path under /home. +# eg if oldfolder is fred/personal, then folder is personal, +# user is fred. + +#Specify the location of the new location for mail folders. +#This cannot be the same as the old location because it will +#create directory names that contend with existing file names. +NEWBASE=/var/spool/mail2 + +#The script to convert invidual mail folders to maildir format. +#http://perfectmaildir.home-dn.net/ +FOLDERCONVERT=/usr/local/bin/perfect_maildir.pl + +#This is a list of users to have their mail folders created. +#One user per line. +#Suggest create with cut -d: -f1 /etc/passwd > ~/migrate/u1 +#then remove inappropriate entries by hand. +USERLIST=/root/migrate/userlist + +# Detailed migration information is sent to this file +MIGRATELOG=/tmp/foldermigrationlog-$(date -I) +#================================================================= +echo +echo "Have you created the users' mail directories yet? (y/n)" +echo +read ans +if [ "$ans" != "y" ] +then + echo Good Bye. + echo use the migrate-users script first. + exit 0 +fi +echo +echo This will copy existing mbox-style mail folders listed +echo in the file $FOLDERLIST. Maildir-style folders will +echo be created under $NEWBASE +echo +echo "Do you want to continue? (y/n)" +read ans +if [ "$ans" != "y" ] +then + echo Good Bye. + exit 0 +fi +echo +echo Note: Detailed folder migration information will be sent to $MIGRATELOG +echo +echo Press enter to start +read ans + +if [ ! -x ${FOLDERCONVERT} ] +then + echo Error: file ${FOLDERCONVERT} is not available to execute. + exit 1 +fi + +if [ ! -d ${NEWBASE} ] +then + echo Error: directory $NEWBASE does not exist + exit 1 +fi + +if [ ! -f "${USERLIST}" ] +then + echo Error: user list file \"$USERLIST\" does not exist. + exit 1 +fi + + +#----------------------------------------------------------------- +echo +echo Testing that the base of the folderlist entries corresponds to usernames +while read oldfolder +do + user="$(dirname "$oldfolder")" + if grep ^${user}: /etc/passwd &> /dev/null + then + echo -n . + else + echo User \"$user\": is bogus. + echo The string \"$user\" from the file \"$FOLDERLIST\" needs to + echo correspond exactly to a username. Edit the file accordingly. + exit 1 + fi +done < $FOLDERLIST +echo +echo PASS +echo +nusers=$(wc -l $USERLIST | awk '{ print $1 }' ) +n=1 +#----------------------------------------------------------------- +# Iterate through user list and migrate folders. +while read user +do + #----------------------------------------------------------------- + # Step 1: Check stuff + if grep ^${user}: /etc/passwd &> /dev/null + then + echo -n "$n / $nusers : User \"$user\" is OK: " + n=$(( $n + 1 )) + echo "User \"$user\"" >> $MIGRATELOG + + inbox=/var/spool/mail/${user} + + if [ \( ! -f "${inbox}" \) -o \( ! -s "${inbox}" \) ] + then + echo User \"${user}\" has no inbox to convert. + else + #----------------------------------------------------------------- + # Step 2: Migrate user inboxes from /var/spool/mail/. + newdir="${NEWBASE}/${user}/" + $FOLDERCONVERT "$newdir" < "${inbox}" >> $MIGRATELOG 2>&1 + chown -R ${user}:mail "${newdir}" + find "$newdir" -type f -exec chmod 600 {} \; + echo -n " inbox " + fi + #----------------------------------------------------------------- + # Step 3: Migrate other mail folders from user home directories. + while read oldfolder + do + folder=$(basename "${oldfolder}") + fuser="$(dirname "$oldfolder")" + + if [ "$user" = "$fuser" ] + then + if [ ! -f "/home/${oldfolder}" ] + then + echo Error folder \"${folder}\" does not exist. + break + fi + + if [ ! -d ${NEWBASE}/${fuser} ] + then + echo Error ${NEWBASE}/${fuser} does not exist. + break + fi + + newdir="${NEWBASE}/${fuser}/.$folder" + mkdir -p "$newdir"/cur + mkdir -p "$newdir"/new + mkdir -p "$newdir"/tmp + chmod -R 770 "${newdir}" + $FOLDERCONVERT "$newdir" < "/home/$oldfolder" >> $MIGRATELOG 2>&1 + chown -R ${user}:mail "${newdir}" + #chmod 600 "$newdir/cur/*" + find "$newdir" -type f -exec chmod 600 {} \; + + echo "$folder" >> ${NEWBASE}/${fuser}/.subscriptions + chmod 600 ${NEWBASE}/${fuser}/.subscriptions + chown ${fuser}:mail ${NEWBASE}/${fuser}/.subscriptions + + echo -n . + fi + done < $FOLDERLIST + echo + + else + echo User "$user: is bogus." + fi + +done < $USERLIST + +echo +echo +echo To make the new base mail directory active, change the +echo mail_spool_directory setting for postfix using +echo postconf -e \"mail_spool_directory = ${NEWBASE}/\" +echo and change Dovecots default_mail_env setting in +echo /etc/dovecot.conf to +echo default_mail_env = maildir:${NEWBASE}/%u +echo + diff --git a/migrate-users b/migrate-users new file mode 100755 index 0000000..d5d48d4 --- /dev/null +++ b/migrate-users @@ -0,0 +1,77 @@ +#!/bin/bash +# file: migrate-users +# author: Richard Keech + +# This script assists in the conversion of mail boxes +# in mbox format to maildir format. +# See also migrage-folders. + +#This is a list of users to have their mail folders created. +#One user per line. +#Suggest create with cut -d: -f1 /etc/passwd > ~/migrate/u1 +#then remove inappropriate entries by hand. +USERLIST=/root/migrate/userlist + +#Specify the location of the new location for mail folders. +#This cannot be the same as the old location because it will +#create directory names that contend with existing file names. +NEWBASE=/var/spool/mail2/ + +echo this will create user mail folders in $NEWBASE from +echo the list of users in $USERLIST. +echo +echo "Do you want to continue? (y/n)" +read ans +if [ "$ans" != "y" ] +then + echo Good Bye. + exit 0 +fi + +if [ ! -f "$USERLIST" ] +then + echo Error: user list file \"$USERLIST\" does not exist. + exit 1 +fi + +if [ ! -d "$NEWBASE" ] +then + echo Error: new base directory \"$NEWBASE\" does not exist. + exit 1 +fi + +while read user +do + if grep ^${user}: /etc/passwd &> /dev/null + then + echo User \"$user\" is OK. + else + echo User \"$user\": is bogus. + exit 1 + fi + + mkdir ${NEWBASE}/$user + newdir="${NEWBASE}/${user}/" + mkdir -p "$newdir"/cur + mkdir -p "$newdir"/new + mkdir -p "$newdir"/tmp + chmod -R 770 "${newdir}" + chown -R ${user}:mail "$newdir" +done < $USERLIST + +echo +echo New mail directories have been created under $NEWBASE +echo +echo If required, prepare a list of existing mbox folders +echo as /root/migrate/folderlist and run migrate-folders. +echo +echo To make the new base mail directory active, change the +echo mail_spool_directory setting for postfix using +echo postconf -e \"mail_spool_directory = ${NEWBASE}/\" +echo and change Dovecots default_mail_env setting in +echo /etc/dovecot.conf to +echo default_mail_env = maildir:${NEWBASE}/%u +echo +echo If you want to migrate existing mail folders then defer +echo the dovecot and postfix changes until the folder migration +echo is complete. diff --git a/perfect_maildir.pl b/perfect_maildir.pl new file mode 100755 index 0000000..4667d65 --- /dev/null +++ b/perfect_maildir.pl @@ -0,0 +1,147 @@ +#!/usr/bin/perl -w + +# "Simple but Perfect" mbox to Maildir converter v0.3 +# Copyright (C) 2001-2003 Philip Mak +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +use strict; +use Date::Parse qw( str2time ); + +#### Settings +# This will be used to set the file time (needed for courier-imap and some others) +# $datestyle = "date": extract date from the "Date: " header +# $datestyle = "from": extract date from the "From " mbox header +my $datestyle = "from"; + +# Use maildir++ format (append the message size to the filename) +my $maildirplus = 0; +#### + + +# Get the hostname +my $hostname = `hostname`; +chomp ($hostname); + +# check for valid arguments +my ($maildir) = @ARGV; +if (!$maildir) { + print STDERR "Usage: perfect_maildir ~/Maildir < mbox\n"; + exit 1; +} elsif (! -d $maildir) { + print STDERR "Cannot open $maildir\n"; + exit 1; +} + +# check for writable maildir +unless (-w "$maildir/cur") { + print STDERR "Cannot write to $maildir/cur\n"; + exit 1; +} +unless (-w "$maildir/new") { + print STDERR "Cannot write to $maildir/new\n"; + exit 1; +} + +my $num = 0; +my $time = time; +my $date; +my $delivered_time; + +repeat: + +# read header +my $headers = ''; +my $flags = ''; +my $subject = ''; +while (my $line = ) { + # detect end of headers + last if $line eq "\n"; + + if ($datestyle eq "from") { + # Get date from the "From " line (this should appears here for the first message only) + $date = $1 if $line =~ /^From [^ ^\t]+[ \t]+(.{24})/; + } elsif ($datestyle eq "date") { + # Get date from the "Date: " header + $date = $1 if $line =~ /^Date: (.*)$/; + } + # strip "From" line from header + $headers .= $line unless $line =~ /^From ./; + + # detect flags + $flags .= $1 if $line =~ /^Status: ([A-Z]+)/; + $flags .= $1 if $line =~ /^X-Status: ([A-Z]+)/; + $subject = $1 if $line =~ /^Subject: (.*)$/; +} + +$num++; + +if ($datestyle =~ /(from|date)/) { + $delivered_time = str2time("$date"); +} else { + $delivered_time = $time; +} + +# open output file +my $file; +if ($flags =~ /O/) { + $file = sprintf( "%s%05d%s", "$maildir/cur/$delivered_time.", $num, ".$hostname" ); + my $extra = ''; + $extra .= 'F' if $flags =~ /F/; # flagged + $extra .= 'R' if $flags =~ /A/; # replied + $extra .= 'S' if (($flags =~ /R/) || ($flags =~ /O/)); # seen + $extra .= 'T' if $flags =~ /D/; # trashed + $file .= ":2,$extra" if $extra; +} else { + $file = sprintf( "%s%05d%s", "$maildir/new/$delivered_time.", $num, ".$hostname" ); +} + +# filter out the "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA" message or the message doesn't exists +if (($num == 1 and $subject eq "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA") || (!$headers)) { + $file = '/dev/null'; + $num--; +} + +open(FILE, ">$file"); +print FILE "$headers\n"; +while (my $line = ) { + if ($datestyle eq "from") { + # Get date from the "From " line (this should appears here for the first message only) + $date = $1 if $line =~ /^From [^ ^\t]+[ \t]+(.{24})/; + } + # End of current message + last if ($line =~ /^From ./); + + # unescape "From" + $line =~ s/^>From (.)/From $1/; + + print FILE $line; +} +close(FILE); + +utime( $time, $delivered_time, $file ) if ($datestyle =~ /(from|date)/); + +if ($maildirplus) { + my $size = -s $file; + my $mdplusfile = $file; + $mdplusfile =~ s/\.$hostname/.$hostname,S=$size/; + rename $file,$mdplusfile; +} + +goto repeat unless eof(STDIN); + +my $elapsed = time - $time; +print "Inserted $num messages into maildir $maildir in $elapsed seconds\n";