Я использую exim и dovecot. Все пользователи виртуальные, т.е. они происходят из базы данных. Поиск адресов назначения для данного localpart@domain
может дать несколько строк, содержащих либо целевой почтовый ящик, либо целевой адрес электронной почты.
Следующий маршрутизатор отлично работает для правильной доставки всех писем:
pg_aliases:
driver = redirect
directory_transport = address_file
data = ${sg{\
${lookup pgsql { SELECT CASE WHEN substr(c_dest, 1, 1) = '/' THEN (c_dest||'@@'||c_domain) ELSE c_dest END FROM aliases WHERE c_local = '${quote_pgsql:$local_part}' AND c_domain = realDomain('${quote_pgsql:$domain}');}}}\
{/(.+)@@(.+)}\
{/var/spool/mail/\$2/\$1/Maildir/}}
Этот «код» старый и изначально написан не мной, но он работает, и я понимаю, почему: если адресатом является почтовый ящик (/mailboxname
) он преобразует его в путь, который вызовет directory_transport
быть вызванным. В противном случае пункт назначения - это адрес, который вызовет перенаправить драйвер, чтобы разобраться с этим.
Однако я бы хотел использовать dovecot-lda
для местной доставки сейчас.
Это означает, что мне нужно вызвать транспорт, который затем получит имя почтового ящика и домен из $address_data
и доставить ему:
dovecot_lda:
driver = pipe
command = /usr/libexec/dovecot/dovecot-lda -d ${extract{dest}{$address_data}}@${extract{domain}{$address_data}} -f $sender_address -a $original_local_part@$original_domain
...
Однако я не вижу способа заставить redirect
роутер называет этот транспорт. При использовании отдельного accept
роутер в дополнение к redirect
маршрутизатор, он будет доставить только в первый почтовый ящик назначения, поскольку он, похоже, не обрабатывает многострочные результаты в address_data
поиск роутера:
pg_dovecot:
driver = accept
transport = dovecot_lda
condition = ${lookup pgsql { SELECT substr(c_dest, 2) AS dest, c_domain AS domain FROM aliases WHERE c_local = '${quote_pgsql:$local_part}' AND c_domain = realDomain('${quote_pgsql:$domain}') AND substr(c_dest, 1, 1) = '/'; }}
address_data = ${lookup pgsql { SELECT substr(c_dest, 2) AS dest, c_domain AS domain FROM aliases WHERE c_local = '${quote_pgsql:$local_part}' AND c_domain = realDomain('${quote_pgsql:$domain}') AND substr(c_dest, 1, 1) = '/'; }}
Интересно, есть ли способ решить эту проблему.