From: Christian Schulte Subject: Add match option 'from domain' to smtpd.conf(5) To: tech@openbsd.org Date: Sun, 22 Sep 2024 08:11:30 +0200 smtpd.conf(5) currently supports a "for domain" match option. This diff adds an additional "from domain" option. Example configuration for a backup MX case: table aliases file:/etc/mail/aliases table domains { "lots-of-domains.com", "large-list.com" } listen on socket listen on all action "local_mail" mbox alias action "outbound" relay action "backup" relay backup match from domain for any !auth reject match from any for domain action "backup" match from any action "local_mail" match for any action "outbound" Without "from domain", something similar currently can be achieved by using "from mail-from regex", but this would require an additional table I would like to avoid. Primary use case for me is to restrict sending mail for the non relay case - e.g. when the MSA on port 587 requires auth and tls for submission, the MTA on port 25 still allows sending mail to each other @lots-of-domains.com or @large-list.com for the non relay case. Makes things easier when that list of domains is quite large or changes frequently. With the diff applied and that match from domain for any !auth reject line in the configuration, OpenSMTPD will reject such mails. Index: usr.sbin/smtpd//parse.y =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v retrieving revision 1.299 diff -u -p -u -r1.299 parse.y --- usr.sbin/smtpd//parse.y 19 Feb 2024 21:00:19 -0000 1.299 +++ usr.sbin/smtpd//parse.y 22 Sep 2024 05:47:51 -0000 @@ -1228,6 +1228,43 @@ negation TAG REGEX tables { rule->flag_from = $1 ? -1 : 1; rule->table_from = strdup(t->t_name); } +| negation FROM DOMAIN tables { + struct table *t = $4; + + if (rule->flag_from) { + yyerror("from already specified for this rule"); + YYERROR; + } + + if (!table_check_use(t, T_DYNAMIC|T_LIST, K_DOMAIN)) { + yyerror("table \"%s\" may not be used for 'from' lookups", + t->t_name); + YYERROR; + } + + rule->flag_from = $1 ? -1 : 1; + rule->flag_from_domain = 1; + rule->table_from = strdup(t->t_name); +} +| negation FROM DOMAIN REGEX tables { + struct table *t = $5; + + if (rule->flag_from) { + yyerror("from already specified for this rule"); + YYERROR; + } + + if (!table_check_use(t, T_DYNAMIC|T_LIST, K_REGEX)) { + yyerror("table \"%s\" may not be used for 'from' lookups", + t->t_name); + YYERROR; + } + + rule->flag_from = $1 ? -1 : 1; + rule->flag_from_domain = 1; + rule->flag_from_regex = 1; + rule->table_from = strdup(t->t_name); +} | negation FROM SRC tables { struct table *t = $4; Index: usr.sbin/smtpd//ruleset.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/ruleset.c,v retrieving revision 1.48 diff -u -p -u -r1.48 ruleset.c --- usr.sbin/smtpd//ruleset.c 14 Jun 2021 17:58:16 -0000 1.48 +++ usr.sbin/smtpd//ruleset.c 22 Sep 2024 05:47:51 -0000 @@ -70,6 +70,10 @@ ruleset_match_from(struct rule *r, const return 0; key = evp->hostname; } + else if (r->flag_from_domain) { + key = evp->sender.domain; + service = K_DOMAIN; + } else { key = ss_to_text(&evp->ss); if (r->flag_from_socket) { Index: usr.sbin/smtpd//smtpd.conf.5 =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v retrieving revision 1.272 diff -u -p -u -r1.272 smtpd.conf.5 --- usr.sbin/smtpd//smtpd.conf.5 26 Jul 2024 06:24:52 -0000 1.272 +++ usr.sbin/smtpd//smtpd.conf.5 22 Sep 2024 05:47:51 -0000 @@ -668,6 +668,23 @@ Specify that session may originate from no matter the source IP address. .It Xo .Op Ic \&! +.Cm from domain +.Ar domain | Pf < Ar domain Ns > +.Xc +Specify that session may originate from sender domain or sender domain list +.Ar domain , +no matter the source IP address. +.It Xo +.Op Ic \&! +.Cm from domain regex +.Ar domain | Pf < Ar domain Ns > +.Xc +Specify that session may originate from sender domain regex or sender domain +regex list +.Ar domain , +no matter the source IP address. +.It Xo +.Op Ic \&! .Cm from local .Xc Specify that session may only originate from a local IP address, Index: usr.sbin/smtpd//smtpd.h =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v retrieving revision 1.688 diff -u -p -u -r1.688 smtpd.h --- usr.sbin/smtpd//smtpd.h 3 Sep 2024 12:07:40 -0000 1.688 +++ usr.sbin/smtpd//smtpd.h 22 Sep 2024 05:47:51 -0000 @@ -1226,6 +1226,7 @@ struct rule { int8_t flag_tag; int8_t flag_from; int8_t flag_for; + int8_t flag_from_domain; int8_t flag_from_rdns; int8_t flag_from_socket;