Hi Martijn, Thanks for the detailed solution!
I eventually solved my problem another way: I kept all dovecot virtual users under a single system user 'vmail', and I made Dovecot handle virtual address aliasing, i.e., Dovecot's LMTP accepts either virtual users or virtual aliases as the RCPT TO: recipient, and deliver in the actual Maildir. My smtpd.conf now looks like ----------------------- table virtual-users sqlite:/etc/smtpd-sqlite.conf action "lmtp_dovecot" lmtp "/run/dovecot/lmtp" rcpt-to user "vmail" userbase <virtual-users> match for rcpt-to <virtual-users> action "lmtp_dovecot" ----------------------- The `user "vmail"` clause on the "action" line prevents OpenSMTPd from querying userinfo at all, and the `rcpt-to <virtual-users>` in the match clause ensures that only those virtual users (or aliases) known by Dovecot will match (as opposed to the previous `for domain <virtual- users>` clause, which would match any address, known or otherwise, in a domain known to Dovecot). (note: system users and system aliases are handled by a different part of the OpenSMTPd config.) Regards, Albert. Le dimanche 14 décembre 2025 à 12:00 +0100, Martijn van Duren a écrit : > Hello Albert, > > My personal solution to this is to replace the '@' sign with an > underscore for the parts where a local user is needed. So via > query_alias I would map [email protected] to albert_aribaud.net. > From there the query_userinfo would take over and look for > albert_aribaud.net. > > Since the underscore is not a valid hostname character there's no > risk here. The specific queries need to be tailored to your database > situation (or the other way around). But my queries (which I wrote > over 10 years ago) look like this: > query_alias SELECT recipient FROM alias WHERE user=?; > query_userinfo SELECT uid, gid, home AS directory FROM users WHERE > REPLACE(email, '@', '_')=?; > > But if you don't have aliases per se you can do a similar REPLACE > inside query_alias, or if you want your aliases table a little shorter > you can probably use some union query, or you can come up with your > own unique solution. > > martijn@ > > On 11/28/25 22:13, Albert ARIBAUD wrote: > > Hello, > > > > I have set up OpenSMTPd to match on a SQLite databae of virtual users > > and invoke an lmtp action as follows: > > > > ---------------------- > > table virtual-users sqlite:/etc/smtpd-sqlite.conf > > > > action "lmtp_dovecot" lmtp "/run/dovecot/lmtp" rcpt-to userbase > > <virtual-users> > > > > match from any for domain <virtual-users> rcpt-to <virtual-users> > > action "lmtp_dovecot" > > ---------------------- > > > > Here an extract of the log showing the matches and subsequent > > expand_insert when receiving and "RCPT TO:<[email protected]>": > > > > --------------- > > lookup: match "aribaud.net" as domain in table proc:virtual-users -> > > true > > lookup: match "[email protected]" as mailaddr in table proc:virtual- > > users -> true > > rule #1 matched: match from any for domain virtual-users rcpt-to > > virtual-users action lmtp_dovecot > > expand: 0xaaaadba55578: expand_insert() called for > > username:albert[parent=0xaaaadb9f27e0, rule=0xaaaadb9ea490, > > dispatcher=0xaaaadb9ea560] > > expand: 0xaaaadba55578: inserted node 0xaaaadb9f2d50 > > expand: lka_expand: username: albert [depth=1, sameuser=0] > > lookup: lookup "albert" as userinfo in table proc:virtual-users -> none > > -------------- > > > > I can see that the virtual-users table properly returns success for the > > domain query on "aribaud.net", and also returning success for the > > mailaddr query on "[email protected]". > > > > But then, the userinfo query is done on "albert" alone, which won't > > work because the database contains user info for [email protected], > > not for albert. > > > > Is there a way to get OpenSMTPd to look up userinfo using the complete > > email address as the key? > > > > Regards, > > Albert. > >
