For my sins, I built and continue to operate a website for a local adult
football association. Email services are provided via Exim and Dovecot
for a few positions, but most email is sent by the website itself.
To regularise access to email, I recently decided to move the users to
vmail and dispense with having home directories, etc. Only one internal
administrative user remains as a true local user. The necessary
information for the others resides in a MySQL database which is also
used by Dovecot.
In the process of making the transition, I have run afoul of the need to
sanitise $local_part and $domain. The result is that it is no longer
possible to send or receive emails involving those accounts. Users can
log in and read mail.
The exim configuration is monolithic: /etc/exim4/exim4.conf. I've been
using exim for the best part of 30 years, and cribbed the existing file
from one of my other sites. It has worked fine until now.
Here are the router, transport, and authenticator settings. Included at
the top is a set of macros that I found on a website during my frantic
Google searches. The actual display of $local_part and $domain varies
because I have been trying everything: this is just the current mess.
There are no error messages on starting exim.
Macros:
DETAINTFILE = /etc/exim4/detaint
BADCHARS = \N[^A-Za-z0-9_.-]+\N
SAFELOCALPART = ${lookup{${sg{$local_part}{BADCHARS}{_}}}
lsearch*,ret=key{DETAINTFILE}}
SAFEDOMAIN = ${lookup{${sg{$domain}{BADCHARS}{_}}}
lsearch*,ret=key{DETAINTFILE}}
begin routers
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
file_transport = address_file
pipe_transport = address_pipe
vmail_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT username FROM mailaliases WHERE
alias='SAFELOCALPART'}}
file_transport = address_file
pipe_transport = address_pipe
localuser:
driver = accept
check_local_user = yes
domains = +local_domains
transport = local_delivery
vmail_user:
driver = accept
domains = +local_domains
condition = ${lookup mysql{SELECT email_username FROM league WHERE
email_username='$local_part_data' AND domain='scasl.ca'}{$value}fail}
transport = dovecot_virtual_delivery
vmail_nonuser:
driver = redirect
allow_fail = true
data = :fail: Unknown user
more = false
begin transports
remote_smtp:
driver = smtp
authenticated_sender = $local_part_data
dkim_domain = scasl.ca
dkim_selector = 20230601
dkim_private_key = /etc/dkimkeys/20230601.private
dkim_canon = relaxed
message_linelength_limit = 1G
local_delivery:
debug_print = "T: local_delivery for $local_part_data@$domain_data"
driver = appendfile
file =
/var/mail/${lookup{$local_part_data}lsearch,ret=key{/etc/passwd}}
delivery_date_add = true
envelope_to_add = true
return_path_add = true
group = mail
dovecot_virtual_delivery:
driver = pipe
command = /usr/lib/dovecot/deliver -d $local_part_data@$domain_data
-f $sender_address
delivery_date_add = true
envelope_to_add = true
return_path_add = true
user = vmail
temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
begin authenticators
plain_saslauthd_server:
driver = plaintext
server_condition = ${if saslauthd{{$auth2}{$auth3}}{1}{0}}
server_set_id = $auth2
server_prompts = :
server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
dovecot_login:
driver = dovecot
public_name = LOGIN
server_socket = /var/run/dovecot/auth-client
server_condition = ${if and {{eq{$auth1}{${lookup mysql{select
email_username FROM league WHERE
email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}'}}}} \
{eq{$auth2}{${lookup mysql{select email_password FROM league
WHERE email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}'}}}}}}
server_set_id = ${lookup mysql{SELECT email_username FROM league
WHERE email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}' AND status!='ARCHIVE'}}
dovecot_plain:
driver = dovecot
public_name = PLAIN
server_socket = /var/run/dovecot/auth-client
server_condition = ${if and {{eq{$auth2}{${lookup mysql{select
email_username FROM league WHERE
email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}'}}}} \
{eq{$auth3}{${lookup mysql{select email_password FROM league
WHERE email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}'}}}}}}
server_set_id = ${lookup mysql{SELECT email_username FROM league
WHERE email_username='${quote_mysql:$local_part}' AND
domain='${quote_mysql:$domain}' AND status!='ARCHIVE'}}
I will greatly appreciate any insights.
Cam
--
## subscription configuration (requires account):
##
https://lists.exim.org/mailman3/postorius/lists/exim-users.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-users-unsubscribe@???
## Exim details at
http://www.exim.org/
## Please use the Wiki with this list -
http://wiki.exim.org/