I got an Exim 4.80 server on Ubuntu 14.04. I want to switch from Dovecot Auth to MySQL. The passwords are stored as crypt (with sha256, beginning with $5$). The expansion looks like this:
server_condition = ${if crypteq{$3}{${lookup mysql{SELECT password FROM accounts LEFT JOIN domains ON accounts.domain=domains.id AND domains.domain='${quote_mysql:${domain:$2}}' WHERE accounts.name='${quote_mysql:${local_part:$2}}'}}}{yes}{no}}
When I turn on debug logging on, I get something like this:
10 subject=$5$fBzbQG0FRF1Lt2QI$Nhmrw5gKq62vmHDD8Eov9WCoGRPkk-----REDACTED----
10 crypted=$5$fBzbQG0FRF1Lt2QI$Nhmrw5gKq62vmHDD8Eov9WCoGRPkk-----REDACTED----
Both REDACTED are exactly equal. Then the following happens:
10 expanded string: no
I dug around in the Exim source code and found that the following code is responsible for the debug message and the result of crypteq
#define STR(s) # s
#define XSTR(s) STR(s)
DEBUG(D_auth) debug_printf("crypteq: using %s()\n"
" subject=%s\n crypted=%s\n",
(which == 0)? XSTR(DEFAULT_CRYPT) : (which == 1)? "crypt" : "crypt16",
coded, sub[1]);
#undef STR
#undef XSTR
/* If the encrypted string contains fewer than two characters (for the
salt), force failure. Otherwise we get false positives: with an empty
string the yield of crypt() is an empty string! */
tempcond = (Ustrlen(sub[1]) < 2)? FALSE :
(Ustrcmp(coded, sub[1]) == 0);
}
So subject= is the coded variable, which is generated by the crypt function, while crypted= is the sub[1]. These are both the same. The success of the operator is only dependant on weather sub[1] is longer than two characters (which apparently is true) and they are the same (which SHOULD also be true).
Does anybody know why this happens?
Edit: It doesn't happen if I put a hash directly in the brackets without MySQL lookup. There seems to be an expansion failure with MySQL.