Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm using exim and dovecot. All users are virtual, i.e. they come from a database. A lookup for the destination addresses for a given localpart@domain may yield multiple rows containing either the target mailbox or the target email address.

The following router works fine for delivering all emails properly:

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/}}

That "code" is old and initially not written by me, but it works and I see why: If the destination is a mailbox (/mailboxname) it converts it to a path which will cause the directory_transport to be invoked. Otherwise the destination is an address which will cause the redirect driver to deal with it.

However, I'd like to use use dovecot-lda for local delivery now.

This means I'll need to call a transport which will then take the mailboxname and domain from $address_data and deliver to it:

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
  ...

However, I don't see a way to make the redirect router call that transport. When using a separate accept router in addition to the redirect router it will only deliver to the first destination mailbox since it doesn't seem to handle multi-row results in the address_data lookup of the router:

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) = '/'; }}

I wonder if there's a way to solve this problem.

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.