Skip to content

From Postfix and Dovecot

Read Coming from another server first. This page covers only what is particular to Postfix and Dovecot.

Find out where people sign in

Dovecot knows, so ask it:

doveconf -n passdb userdb

What it names decides which choice from part 1 fits.

ldap, against Active Directory

Choice A. Use the Active Directory settings as they are. If /etc/dovecot/dovecot-ldap.conf.ext has auth_bind = yes, Dovecot is already doing what Use Bind Authentication does, and its user_filter and pass_filter show what your site filters on. Carry any extra conditions from them into the login and mailbox filters.

ldap, against OpenLDAP or another LDAP server

Choice A if the LDAP server is staying, choice B if it is going. Start from Dovecot's own configuration in dovecot-ldap.conf.ext:

Dovecot inbuxa
uris or hosts Server URL
dn, dnpass Bind DN, Bind Secret
base Base DN
auth_bind = yes Use Bind Authentication on
pass_filter Login Filter, with %u replaced by ?
user_filter Mailbox Filter, with %u replaced by ?
pass_attrs userPassword=password Password Attribute userPassword, for choice B

If Postfix has its own LDAP lookups (virtual_mailbox_maps or virtual_alias_maps pointing at ldap: files), their query_filter shows which attribute holds aliases. That is the E-mail Alias Attribute.

sql, as with Postfix Admin

inbuxa can sign people in against the same database, as an SQL Directory, created under Settings › Security › Directories. Its Storage Backend is the connection to that database: PostgreSQL, MySQL or SQLite.

Each query returns one row, and the column names in the form say which column is which. The defaults are name for the address, secret, description and type. A type of group makes the row a group, and anything else a person. For Postfix Admin's schema on PostgreSQL:

Field Value
Login Query SELECT username AS name, regexp_replace(password, '^\{[A-Z0-9-]+\}(?=\$)', '') AS secret, name AS description, 'individual' AS type FROM mailbox WHERE username = $1 AND active
Recipient Query the same
E-mail Aliases Query SELECT address FROM alias WHERE goto = $1 AND address <> goto AND active
Member Of Query empty

The regexp_replace strips a Dovecot prefix such as {SHA512-CRYPT} from a crypt hash, and leaves {SSHA512}-style prefixes alone. On MySQL 8 and MariaDB 10.5 or later, REGEXP_REPLACE does the same, and the placeholder is ? instead of $1. Your column names may differ; take them from dovecot-sql.conf.ext, whose password_query is the one to copy.

An alias row in Postfix Admin can point at several addresses, or outside the domain. Those are mailing lists in inbuxa, not aliases, and the alias query above only picks up the single-destination ones.

Then take choice B: copy the mail, and switch the domain back to the internal directory.

passwd-file

There is no directory to point at, but the file is easy to load into one. Put it in an SQLite database, and use that as an SQL directory for choice B:

sqlite3 users.db 'CREATE TABLE users (name TEXT PRIMARY KEY, secret TEXT)'
cut -d: -f1,2 /etc/dovecot/users \
  | sed -E 's/:\{[A-Z0-9-]+\}(\$)/:\1/' \
  | sqlite3 -separator : users.db '.import /dev/stdin users'

The names in the file have to be full addresses. If they are bare usernames, add the domain as you load them.

Give the directory a Storage Backend of SQLite, at that file's path, and this as both the login and the recipient query:

SELECT name, secret, NULL AS description, 'individual' AS type
  FROM users WHERE name = $1

The file has to be where the server can read it. After the copy, set the domain back to the internal directory, and the file is no longer used.

Copying the mail

Dovecot signs an administrator in on someone's behalf with a master user. Add a passdb with master = yes, and set the separator:

auth_master_user_separator = *

Then imapsync signs in to Dovecot as [email protected]*admin with the master password:

imapsync \
  --host1 old.example.com --ssl1 \
  --user1 '[email protected]*admin' --password1 "$DOVECOT_MASTER_PASSWORD" \
  --host2 mail.example.net --ssl2 \
  --user2 '[email protected]%[email protected]' \
  --password2 "$MIGRATOR_PASSWORD" \
  --automap

doveadm user '*' lists every account, where the userdb can list them.

What else to carry across

  • Aliases: postconf virtual_alias_maps names the maps. Each line of a hash map is an alias or a list; see aliases.
  • Domains: postconf virtual_mailbox_domains. Each one needs adding to inbuxa before anything else.
  • Relay and transport maps, sender-dependent relays and smtpd_* restrictions have no file to copy. Set the equivalent up in the console, if you need it at all.
  • Sieve: Pigeonhole keeps each person's scripts under sieve_dir or ~/sieve, with the active one linked from ~/.dovecot.sieve. Scripts that use vnd.dovecot. extensions or extprograms won't compile.
  • Quotas: doveadm quota get -A lists them. Set them on the accounts before copying.
  • Roundcube contacts, if you ran it: each person exports their address book as vCard in Roundcube and imports it in the webmail.