[2026-01-07 12:02] Sidney Cadot <[email protected]>
> As expected, opensmtpd now complains that there is no test14 user.
>
> Let me quote from my first email:
> >
> > > But after you fix this, I think you would indeed run into the problem
> > described by Crystal that the user test9 probably doesn't exist. For
> > example, the man page of smtpd.conf says that your python script will
> > receive an environment variable HOME which is set to the delivery user's
> > login directory. But if the user doesn't exist, how should opensmtpd know
> > the login directory of the user?
> >
>
> My surprise is not so much that this doesn't work; it is that the mail
> doesn't enter the queue. The mail is rejected with the connection still in
> progress (550 Invalid recipient), after the match test passed. The
> description in the man page doesn't mention this possibility; it says:
>
> When mail arrives, each “RCPT TO:” command generates a mail
> envelope. If an envelope matches any of a pre-designated set of criteria
> (using the match directive), the message is accepted
> for delivery. A copy of the message, as well as its associated
> envelopes, is saved in the mail queue and later dispatched according to an
> associated set of actions (using the action direc‐
> tive). If an envelope does not match any options, it is rejected.
> The match rules are evaluated sequentially, with the first match winning.
>
> The way I read this is that if the match succeeds, the mail is entered into
> the queue. And then, the queue runner will try actions. But that's not what
> happens; already in the decision process about whether the mail will be
> accepted, the follow-up action (in my case, an mda action) is considered,
> and it is determined if all prerequisites for that action are in place; and
> if not, the incoming mail is immediately rejected.
It's a bit more complicated:
First of all, your understanding of the match is correct with an
extra: When the target rule is a delivery (or local) rule and all
relevant tables (alias and userbase) are not external (static, file or
db backed), then before accepting the recipient opensmtpd also checks[0]
if there is a way the rule can deliver this mail. This is the behavior
you see.
But even without this, opensmtpd wouldn't behave like you expected. So
lets asume your mail would be accepted and put in the queue. Now smtpd
will get your mail out of the queue and and call the action handler.
This handler will then try to handle your mail according the action.
In your case it's a local action. Which means the action handler will
search[1] for the local part in the userbase. Because you don't have
a userbase configured the system users are used. There is no "test9"
user so the action would fail and create a bounce.
Philipp
[0] This check doesn't change the match rule which is used, it is only
used to generate an early error instand of generating a bounce
[1] You have no virtual or alias table so no aliasing is done
>
> I now have a hypothesis of what is really happening, though. I've browsed
> through the presentation found on the opensmtpd website:
>
>
> https://www.opensmtpd.org/presentations/eurobsdcon2017-smtpd/eurobsdcon2017-opensmtpd.pdf
>
> Reading page 61/62 of that presentation, it looks like the config file
> format used to be different 10 years ago, with rules; and that the split in
> "match" and "action" was introduced later. This decoupling solved a bunch
> of issues, according to the presentation.
>
> This suggests that what is going on is a bit different than what the man
> page suggests. Already when the decision is made if incoming mail is
> accepted, not only the "match" is considered, but also its associated
> "action". So, information that is required for the action (such as the
> ability to find a local user, in case of method mda) can influence if the
> mail is accepted.
>
> If that is correct, matches and actions are much more tightly coupled than
> I would expect from reading the description in the man page quoted above. I
> would go so far as to say that the description is wrong; it tripped me up,
> anyway, leading me to the wrong mental model.
>
> > I think you could use the "user <username>" option for your mda delivery
> > action in order to specify one existing user that handles mail for everyone.
> >
>
> That doesn't seem to work, the mail still gets rejected.
>
> But I have enough information now to proceed with experimentation.
>
> Cheers, Sidney