Closed greenshrike closed 7 months ago
Thanks for the great description of the issue and the solution. I've linked to this from the Updating page on the wiki.
Note: this only works with existing alias domains. If alias domains are added after the "convert and insert into SQL" step, those alias domains won't work until a human comes along and adds an appropriate entry to the domainalias table.
I am updating the vpopmail build scripts to use a newer patched version of vpopmail from brunonymous/vpopmail. That version has support for alias domains and creates them in a similar aliasdomains
table. I'm accepting that as the solution, as it also keeps the table updated. The updated dovecot build script has a newer query which always returns the right info.
Anyone who (like me) deployed this version can convert their domainalias
table to an aliasdomains
table like so:
CREATE TABLE IF NOT EXISTS `aliasdomains` (
`alias` varchar(100) NOT NULL,
`domain` varchar(100) NOT NULL,
PRIMARY KEY (`alias`)
);
INSERT INTO aliasdomains SELECT * FROM domainalias;
After converting Dovecot from using the Vpopmail backend to using the SQL backend, users can no longer authenticate POP3/IMAP if they submit a username with an aliased domain. If they switch the username to using their primary domain, authentication works.
The basic issue is that Vpopmail doesn't store aliased domains in the database, so the Dovecot SQL query can't check them.
Adding them is fairly straightforward, however:
In MySQL:
To dump all aliased domains and generate SQL suitable for importing them into the table:
For Dovecot's SQL queries:
The left join will result in multiple rows in the resulting joined table for any primary domain with more than one alias -- one per aliased domain.
If the user auths with an aliased domain (i.e. one of the domainalias.alias entries), only the line matching the alias will be returned.
However, if the user auths with the primary domain (i.e. uses pw_domain), then there is nothing to distinguish between the multiple rows, as their only difference will be in the domainalias.alias column. As such, multiple lines will be returned, all identical.
While appending LIMIT 1 would be the usual choice to force the return of only a single row, Dovecot seems to object to the SQL command, even though MySQL obviously has no issue with it. Instead, SELECT DISTINCT is used to eliminate the duplicate rows.