Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lmtp_save_to_detail_mailbox and aliases #2988

Open
1 of 3 tasks
danfabi opened this issue Oct 16, 2023 · 5 comments
Open
1 of 3 tasks

lmtp_save_to_detail_mailbox and aliases #2988

danfabi opened this issue Oct 16, 2023 · 5 comments
Labels
priority/p2 Minor bug / Could have type/enhancement Enhances existing functionality

Comments

@danfabi
Copy link

danfabi commented Oct 16, 2023

Environment & Version

Environment

  • docker compose
  • kubernetes
  • docker swarm

Version

  • Version: 2.0

Description

Dovecot comes with the lmtp_save_to_detail_mailbox option, which directs incoming mails into the corresponding mailbox folder if such folder exists (e.g. user+test@domain.tld would be saved into the test folder), otherwise into INBOX.

If enabled (via lmtp_save_to_detail_mailbox in overrides/dovecot/dovecot.conf), this works fine, however not in case of alias+test@domain.tld - in this case, the mail is delivered to the INBOX.

The Delivered-To header shows user+test@domain.tld in case the mail is addressed to user+test@domain.tld, but only user@domain.tld in case the mail is addressed to alias+test@domain.tld, so the detail part after the recipient_delimiter gets thrown away.

Having looked around for a bit, I found that

  1. docker compose exec smtp curl http://admin:8080/internal/postfix/alias/user+test@domain.tld returns user+test@domain.tld and
  2. docker compose exec smtp curl http://admin:8080/internal/postfix/alias/alias+test@domain.tld returns user@domain.tld,

which is consistent with the behavior I observe.

Maybe the detail part should be included here:

if stripped_alias := Alias.resolve(localpart_stripped, domain_name):
return stripped_alias.destination

...as it is here (implicitely):

if not user and localpart_stripped:
user = User.query.get(f'{localpart_stripped}@{domain_name}')
if user:
email = f'{localpart}@{domain_name}'
if not user.forward_enabled:
return [email]

Replication Steps

  1. Set lmtp_save_to_detail_mailbox = yes in overrides/dovecot/dovecot.conf
  2. Create an IMAP folder named test
  3. Confirm that lmtp_save_to_detail_mailbox is working by sending a mail to any user with the respective detail part (e.g. yourusername+test@domain.tld - the mail should end up in the IMAP folder test.
  4. Send a mail to an alias of the user with the respective detail part (e.g. youralias+test@domain.tld).

Observed behaviour

The mail will end up in the INBOX.

Expected behaviour

The mail should be saved into test.

@danfabi
Copy link
Author

danfabi commented Oct 17, 2023

Ok, either my understanding of what should happen is very wrong here or /internal/postfix/alias resolves more than it should:

According to the postconf man page, propagate_unmatched_extensions (which includes "virtual" by default, also in Mailu) should lead to the desired behaviour:

For example, with a virtual(5) mapping of "joe@example.com => joe.user@example.net", the address "joe+foo@example.com" would rewrite to "joe.user+foo@example.net".

It looks to me like the fact that alias+test@domain.tld is resolved to user@domain.tld by the cited code (even if no such alias is explicitly set) leads to this behaviour. Maybe alias+test@domain.tld should not resolve at all (or only if explicitly set) so that Postfix tries to resolve alias@domain.tld (--> user@domain.tld) next and re-inserts the detail part afterwards?

The same (probably) applies to user+test@domain.tld - maybe this should not resolve at all (instead of returning user+test@domain.tld if the user exists) so that Postfix tries again with user@domain.tld? See virtual(5):

ADDRESS EXTENSION
       When a mail address localpart contains the optional recipient delimiter
       (e.g., user+foo@domain), the lookup order becomes: user+foo@domain,
       user@domain, user+foo, user, and @domain.

       The   propagate_unmatched_extensions parameter controls whether  an
       unmatched address extension (+foo) is propagated to the result of a ta-
       ble lookup.

@nextgens nextgens added priority/p2 Minor bug / Could have type/enhancement Enhances existing functionality labels Oct 17, 2023
@nextgens
Copy link
Contributor

As you have found out, supporting this requires a significant rewrite... which may not happen any time soon unless we get a PR (and tests!) for it.

@ghostwheel42
Copy link
Contributor

@nextgens I think this does not need new code. We only have to make it simpler by removing the split at the recipient delimiters.
This will make postfix do the rest.
But you are correct in that we need a PR for this.

@nextgens
Copy link
Contributor

nextgens commented May 9, 2024

The easiest is a sieve script; that would work with aliases, no?

https://doc.dovecot.org/configuration_manual/sieve/examples/#emulating-lmtp-save-to-detail-mailbox-yes

@danfabi
Copy link
Author

danfabi commented May 9, 2024

Yes, that's also my workaround for now.

require ["fileinto","regex","variables"];

if anyof (header :regex "to" "[+-]([A-z0-9]+)@", header :regex "Delivered-To" "[+-]([A-z0-9]+)@")
{
	set "suffix" "${1}";
	fileinto "${suffix}";
	stop;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority/p2 Minor bug / Could have type/enhancement Enhances existing functionality
Projects
None yet
Development

No branches or pull requests

3 participants