From: op@omarpolo.com Subject: smtpd: independant match and action order To: tech@openbsd.org Cc: "Gilles Chehade" Date: Sat, 17 May 2025 17:06:34 +0200 After an issue on github[1], I realized that we don't seem to document that an action needs to be defined prior its use in a match statement. [1]: https://github.com/OpenSMTPD/OpenSMTPD/issues/1285 However, do we need this restriction? Diff belows moves the action check after the configuration has been fully parsed. The downside is that now you get a generic "referenced unknown action foo" error without a line number, but the plus side is that action and matches can be put in any order. The alternative would just be a man page diff to highlight the ordering requirement. Thoughts? diff /usr/src path + /usr/src commit - 26403af47fcfb92c30d7cca9d0ea2e1019abe6fb blob - aa4dd7f06254e5bdd9ba58d609d357a82fedb45e file + usr.sbin/smtpd/parse.y --- usr.sbin/smtpd/parse.y +++ usr.sbin/smtpd/parse.y @@ -1508,21 +1508,13 @@ match_option match_options | /* empty */ ; -match_dispatcher: -STRING { - if (dict_get(conf->sc_dispatchers, $1) == NULL) { - yyerror("no such dispatcher: %s", $1); - YYERROR; - } - rule->dispatcher = $1; -} -; - action: REJECT { rule->reject = 1; } -| ACTION match_dispatcher +| ACTION STRING { + rule->dispatcher = $2; +} ; match: @@ -3140,6 +3132,15 @@ parse_config(struct smtpd *x_conf, const char *filenam popfile(); endservent(); + /* Make sure no unknown actions were referenced */ + TAILQ_FOREACH(rule, conf->sc_rules, r_entry) { + if (dict_get(conf->sc_dispatchers, rule->dispatcher) == NULL) { + log_warnx("error: referenced unknown action %s", + rule->dispatcher); + errors++; + } + } + /* If the socket listener was not configured, create a default one. */ if (!conf->sc_sock_listener) { memset(&listen_opts, 0, sizeof listen_opts);