Dynamic tags in email address

Felix Gustavsson blackvoid+dovecot at fantas.in
Sat Oct 25 20:38:16 UTC 2014


On 2014-10-25 21:27, Robert Schetterer wrote:
> Am 25.10.2014 um 20:12 schrieb Felix Gustavsson:
>> I'm trying to get dynamic tagging (user+sometag at example.com) to work on
>> a mail server I'm setting up, however it only works as long as it's sent
>> to the main user and not to aliases.
>>
>> virtual-alias-maps query: SELECT get_email_alias_dyn('%s')
>> virtual-mailbox-domains query: SELECT 1 FROM domain WHERE name='%s'
>> virtual-mailbox-maps query: SELECT 1 FROM user_alias INNER JOIN domain
>> ON user_alias.domainID = domain.id WHERE user_alias.primary = 1 AND
>> CONCAT(user_alias.name, '@', domain.name)='%s'
>>
>> "get_email_alias_dyn()" is a stored function which returns the
>> destination email, so alias+tag at example.com returns user at example.com,
>> alias at example.com returns user at example.com and so on.
>>
>> It works perfectly fine when the mail does not contain any tags
>> (alias at example.com or user at example.com) or if it's the primary email
>> which contains tags (user+sometag at example.com), but when it's tags on an
>> alias the mail is bounced due to "user unknown".
>>
>> I tried modifying the dovecot service in master.cf so the addresses can
>> be filtered with Sieve (http://wiki2.dovecot.org/LDA/Postfix), but that
>> did not solve the issue either, so I have not idea where it goes wrong
>> or how to solve it.
> seems complex
>
> have you read
>
> http://wiki2.dovecot.org/Pigeonhole/Sieve/Examples
Didn't know that feature existed. I have now changed so it uses 
recipient_delimiter and I've changed the virtual-alias-maps query to 
fetch the primary email only instead of handling everything after the 
plus sign, however it still does not work.

So I decided to log which queries are sent to the mysql database and it 
looks like it tries to get the home path of the alias and not the 
primary email. So when dovecot runs the user_query, %u is replaced with 
alias at example.com and not user at example.com which is weird, because the 
virtual-alias-maps query returns the primary email (user at example.com), 
so there should be no reason for alias at example.com to be used to get the 
mailbox.

Here is the results from postmap when trying to maps:
# postmap -q alias at example.com 
mysql:/etc/postfix/mysql-virtual-alias-maps.cf
user at example.com
# postmap -q user at example.com 
mysql:/etc/postfix/mysql-virtual-alias-maps.cf
user at example.com
# postmap -q example.com 
mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
1
# postmap -q user at example.com 
mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
1
# postmap -q alias at example.com 
mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
(no result)
> Plus Addressed mail filtering
>
> Using the subaddress extension, it is possible to match against the
> 'detail' part of an e-mail address, e.g. a '+tag' suffix to the local
> part of the address. This is for example useful when you don't want just
> any +tag to create a directory, but you want to use tagged addresses
> such as with amavisd-new. This example would place email addressed to
> user+spam at example.com into user's Spam folder.
>
> require ["fileinto", "envelope", "subaddress"];
> if envelope :detail "to" "spam"{
>    fileinto "Spam";
> }
>
> The following more advanced example uses the subaddress extension to
> handle recipient addresses structured as sales+<name>@company.com in a
> special way. The <name> part is extracted from the address using
> variables extension, transformed into a format with the first letter in
> upper case and subsequently used to create the folder name where the
> message is stored. The folder name is structured as users/<name>. If the
> +<name> detail is omitted from the recipient address, the message is
> filed in the sales folder.
>
> require ["variables", "envelope", "fileinto", "subaddress"];
>
> if envelope :is :user "to" "sales" {
>    if envelope :matches :detail "to" "*" {
>      /* Save name in ${name} in all lowercase except for the first letter.
>       * Joe, joe, jOe thus all become 'Joe'.
>       */
>      set :lower :upperfirst "name" "${1}";
>    }
>
>    if string :is "${name}" "" {
>      /* Default case if no detail is specified */
>      fileinto "sales";
>    } else {
>      /* For sales+joe@ this will become users/Joe */
>      fileinto "users/${name}";
>    }
> }
>
> To work with Postfix, this requires that the envelope "to" still
> contains the full address, so pass it with the -a flag.
>
> dovecot unix    -       n       n       -       -      pipe
>    flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/dovecot-lda
>    -f ${sender} -d ${user}@${nexthop} -a ${recipient}
>
> or
>
> mailbox_command = /usr/lib/dovecot/dovecot-lda -a "$RECIPIENT"
>
>
> also there is
>
> 15-lda.conf
>
> # Delimiter character between local-part and detail in email address.
> #recipient_delimiter = +
>
> 90-sieve.conf
>
>
>   # The separator that is expected between the :user and :detail
>    # address parts introduced by the subaddress extension. This may
>    # also be a sequence of characters (e.g. '--'). The current
>    # implementation looks for the separator from the left of the
>    # localpart and uses the first one encountered. The :user part is
>    # left of the separator and the :detail part is right. This setting
>    # is also used by Dovecot's LMTP service.
>    #recipient_delimiter = +
>
>
> dont know if this helps
>
>
>> I have included the logs from when I sent to alias+tag at example.com below:
>>
>> Oct 25 19:54:20 xx postfix/smtpd[10987]: connect from
>> mail-wg0-f50.google.com[74.125.82.50]
>> Oct 25 19:54:21 xx postfix/smtpd[10987]: 10585DFA63:
>> client=mail-wg0-f50.google.com[74.125.82.50]
>> Oct 25 19:54:21 xx postfix/cleanup[10995]: 10585DFA63:
>> message-id=<CAGPeO-YcJwbRJb-Gfga+G_vKqj9cm80rMZf9LAfENRCFfxLVAg at mail.gmail.com>
>>
>> Oct 25 19:54:25 xx postfix/qmgr[9945]: 10585DFA63: from=<xx at gmail.com>,
>> size=1743, nrcpt=1 (queue active)
>> Oct 25 19:54:25 xx postfix/smtpd[10987]: disconnect from
>> mail-wg0-f50.google.com[74.125.82.50]
>> Oct 25 19:54:25 xx dovecot: auth-worker(11000): mysql(127.0.0.1):
>> Connected to database mailcp
>> Oct 25 19:54:25 xx postfix/pipe[10998]: 10585DFA63: to=<xx+test at xx.com>,
>> relay=dovecot, delay=5.4, delays=5.4/0/0/0.03, dsn=5.1.1, status=bounced
>> (user unknown)
>> Oct 25 19:54:25 xx postfix/cleanup[10995]: D39B2DFC7D:
>> message-id=<20141025175425.D39B2DFC7D at xx.com>
>> Oct 25 19:54:25 xx postfix/bounce[11002]: 10585DFA63: sender
>> non-delivery notification: D39B2DFC7D
>> Oct 25 19:54:25 xx postfix/qmgr[9945]: D39B2DFC7D: from=<>, size=3937,
>> nrcpt=1 (queue active)
>> Oct 25 19:54:25 xx postfix/qmgr[9945]: 10585DFA63: removed
>> Oct 25 19:54:26 xx postfix/smtp[11004]: D39B2DFC7D: to=<xx at gmail.com>,
>> relay=gmail-smtp-in.l.google.com[74.125.195.27]:25, delay=0.24,
>> delays=0/0/0.16/0.07, dsn=2.0.0, status=sent (250 2.0.0 OK 1414259666
>> d8si5463492wiv.41 - gsmtp)
>> Oct 25 19:54:26 xx postfix/qmgr[9945]: D39B2DFC7D: removed
>>
>> The dovecot-sql.conf.ext file looks like this:
>>
>> driver = mysql
>> connect = host=127.0.0.1 dbname=mailcp user=mailcp password=xxx
>> default_pass_scheme = SHA512-CRYPT
>> password_query = SELECT CONCAT(user_alias.name, '@', domain.name) as
>> user, user.password as password, concat('*:bytes=', (CASE WHEN
>> user.quota  -1 THEN user.quota ELSE domain.quota END)*1000000) AS
>> userdb_quota_rule FROM user INNER JOIN user_alias ON user.id =
>> user_alias.userID AND user_alias.primary = 1 INNER JOIN domain ON
>> user_alias.domainID = domain.id WHERE CONCAT(user_alias.name, '@',
>> domain.name) ='%u' AND user.status = 1
>> user_query = SELECT CONCAT('/var/mail/vmail/', domain.name, '/',
>> user_alias.name) as home, 5000 AS uid, 5000 AS gid, concat('*:bytes=',
>> (CASE WHEN user.quota != -1 THEN user.quota ELSE domain.quota
>> END)*1000000) AS userdb_quota_rule FROM user INNER JOIN user_alias ON
>> user.id = user_alias.userID AND user_alias.primary = 1 INNER JOIN domain
>> ON user_alias.domainID = domain.id WHERE CONCAT(user_alias.name, '@',
>> domain.name) ='%u' AND user.status = 1
>
>
> Best Regards
> MfG Robert Schetterer
>



More information about the dovecot mailing list