182 #include <sys/socket.h>
183 #include <netinet/in.h>
184 #include <arpa/inet.h>
194 #ifdef STRCASECMP_IN_STRINGS_H
266 static jmp_buf smtpd_check_buf;
271 #define SMTPD_CHECK_DUNNO 0
272 #define SMTPD_CHECK_OK 1
273 #define SMTPD_CHECK_REJECT 2
280 static CTABLE *smtpd_rbl_cache;
281 static CTABLE *smtpd_rbl_byte_cache;
288 static MAPS *local_rcpt_maps;
289 static MAPS *send_canon_maps;
290 static MAPS *rcpt_canon_maps;
291 static MAPS *canonical_maps;
292 static MAPS *virt_alias_maps;
293 static MAPS *virt_mailbox_maps;
294 static MAPS *relay_rcpt_maps;
306 static MAPS *rbl_reply_maps;
311 static MAPS *smtpd_sender_login_maps;
322 static MAPS *relay_ccerts;
329 static int access_parent_style;
334 static ARGV *client_restrctions;
335 static ARGV *helo_restrctions;
336 static ARGV *mail_restrctions;
337 static ARGV *relay_restrctions;
338 static ARGV *fake_relay_restrctions;
339 static ARGV *rcpt_restrctions;
340 static ARGV *etrn_restrctions;
341 static ARGV *data_restrctions;
342 static ARGV *eod_restrictions;
344 static HTABLE *smtpd_rest_classes;
345 static HTABLE *policy_clnt_table;
346 static HTABLE *map_command_table;
348 static ARGV *local_rewrite_clients;
353 static int generic_checks(
SMTPD_STATE *,
ARGV *,
const char *,
const char *,
const char *);
358 static int check_sender_rcpt_maps(
SMTPD_STATE *,
const char *);
359 static int check_recipient_rcpt_maps(
SMTPD_STATE *,
const char *);
360 static int check_rcpt_maps(
SMTPD_STATE *,
const char *,
const char *,
366 static int unk_name_tf_act;
367 static int unk_addr_tf_act;
368 static int unv_rcpt_tf_act;
369 static int unv_from_tf_act;
379 #define STR vstring_str
380 #define CONST_STR(x) ((const char *) vstring_str(x))
381 #define UPDATE_STRING(ptr,val) { if (ptr) myfree(ptr); ptr = mystrdup(val); }
408 static
int PRINTFLIKE(5, 6) smtpd_check_reject(
SMTPD_STATE *,
int,
int, const
char *, const
char *,...);
410 #define DEFER_IF_REJECT2(state, class, code, dsn, fmt, a1, a2) \
411 defer_if(&(state)->defer_if_reject, (class), (code), (dsn), (fmt), (a1), (a2))
412 #define DEFER_IF_REJECT3(state, class, code, dsn, fmt, a1, a2, a3) \
413 defer_if(&(state)->defer_if_reject, (class), (code), (dsn), (fmt), (a1), (a2), (a3))
414 #define DEFER_IF_REJECT4(state, class, code, dsn, fmt, a1, a2, a3, a4) \
415 defer_if(&(state)->defer_if_reject, (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4))
422 #define DEFER_ALL_ACT 0
423 #define DEFER_IF_PERMIT_ACT 1
425 #define DEFER_IF_PERMIT2(type, state, class, code, dsn, fmt, a1, a2) \
426 (((state)->warn_if_reject == 0 && (type) != 0) ? \
427 defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2)) \
429 smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2)))
430 #define DEFER_IF_PERMIT3(type, state, class, code, dsn, fmt, a1, a2, a3) \
431 (((state)->warn_if_reject == 0 && (type) != 0) ? \
432 defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3)) \
434 smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3)))
435 #define DEFER_IF_PERMIT4(type, state, class, code, dsn, fmt, a1, a2, a3, a4) \
436 (((state)->warn_if_reject == 0 && (type) != 0) ? \
437 defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)) \
439 smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)))
449 static void *rbl_pagein(
const char *,
void *);
450 static void rbl_pageout(
void *,
void *);
451 static void *rbl_byte_pagein(
const char *,
void *);
452 static void rbl_byte_pageout(
void *,
void *);
503 #define link_override_table_to_variable(table, var) \
504 do { table[var##_offset].target = &var; } while (0)
506 #define smtpd_policy_tmout_offset 0
507 #define smtpd_policy_idle_offset 1
508 #define smtpd_policy_ttl_offset 2
509 #define smtpd_policy_try_delay_offset 3
511 #define smtpd_policy_req_limit_offset 0
512 #define smtpd_policy_try_limit_offset 1
514 #define smtpd_policy_def_action_offset 0
515 #define smtpd_policy_context_offset 1
519 static void policy_client_register(
const char *name)
521 static const char myname[] =
"policy_client_register";
523 char *saved_name = 0;
524 const char *policy_name = 0;
530 if (policy_clnt_table == 0)
556 if (*name == parens[0]) {
559 msg_fatal(
"policy service syntax error: %s", cp);
560 if ((policy_name =
mystrtok(&cp, sep)) == 0)
561 msg_fatal(
"empty policy service: \"%s\"", name);
571 msg_info(
"%s: name=\"%s\" default_action=\"%s\" max_idle=%d "
572 "max_ttl=%d request_limit=%d retry_delay=%d "
573 "timeout=%d try_limit=%d policy_context=\"%s\"",
574 myname, policy_name, smtpd_policy_def_action,
575 smtpd_policy_idle, smtpd_policy_ttl,
576 smtpd_policy_req_limit, smtpd_policy_try_delay,
577 smtpd_policy_tmout, smtpd_policy_try_limit,
578 smtpd_policy_context);
596 htable_enter(policy_clnt_table, name, (
void *) policy_client);
604 static void command_map_register(
const char *name)
608 if (map_command_table == 0)
615 (void)
htable_enter(map_command_table, name, (
void *) maps);
621 static ARGV *smtpd_check_parse(
int flags,
const char *checks)
623 char *saved_checks =
mystrdup(checks);
625 char *bp = saved_checks;
634 #define SMTPD_CHECK_PARSE_POLICY (1<<0)
635 #define SMTPD_CHECK_PARSE_MAPS (1<<1)
636 #define SMTPD_CHECK_PARSE_ALL (~0)
642 policy_client_register(name);
644 command_map_register(name);
661 static int has_required(
ARGV *restrictions,
const char **required)
670 for (rest = restrictions->
argv; *rest; rest++) {
677 msg_warn(
"restriction `%s' after `%s' is ignored",
681 for (reqd = required; *reqd; reqd++)
685 if ((expansion = (
ARGV *)
htable_find(smtpd_rest_classes, *rest)) != 0)
686 if (has_required(expansion, required))
694 static void fail_required(
const char *name,
const char **required)
696 const char *myname =
"fail_required";
703 if (required[0] == 0)
704 msg_panic(
"%s: null required list", myname);
710 for (reqd = required; *reqd; reqd++)
712 reqd[1] == 0 ?
"" : reqd[2] == 0 ?
" or " :
", ");
713 msg_fatal(
"in parameter %s, specify at least one working instance of: %s",
729 static const char *rcpt_required[] = {
833 smtpd_rbl_cache =
ctable_create(100, rbl_pagein, rbl_pageout, (
void *) 0);
835 rbl_byte_pageout, (
void *) 0);
869 msg_fatal(
"restriction class `%s' needs a definition", name);
885 "permit_mydomain reject_unauth_destination"));
899 if (!has_required(rcpt_restrctions, rcpt_required)
900 && !has_required(relay_restrctions, rcpt_required))
907 local_rewrite_clients = smtpd_check_parse(SMTPD_CHECK_PARSE_MAPS,
949 static void log_whatsup(SMTPD_STATE *state,
const char *whatsup,
971 static int PRINTFLIKE(5, 6) smtpd_acl_permit(SMTPD_STATE *state,
973 const
char *reply_class,
974 const
char *reply_name,
975 const
char *format,...)
977 const char myname[] =
"smtpd_acl_permit";
982 #define NO_PRINT_ARGS ""
984 #define NO_PRINT_ARGS "%s", ""
993 if (state->defer_if_permit.active) {
1005 action, reply_class, reply_name);
1006 if (format && *format) {
1008 va_start(ap, format);
1012 log_whatsup(state, whatsup,
STR(error_text));
1022 static int smtpd_check_reject(SMTPD_STATE *state,
int error_class,
1023 int code,
const char *dsn,
1024 const char *format,...)
1028 const char *whatsup;
1038 whatsup =
"reject_warning";
1053 va_start(ap, format);
1062 if (code < 400 || code > 599) {
1063 msg_warn(
"SMTP reply code configuration error: %s",
STR(error_text));
1067 msg_warn(
"DSN detail code configuration error: %s",
STR(error_text));
1111 STR(error_text)[0] =
'4';
1117 STR(error_text)[4] =
STR(error_text)[0];
1124 log_whatsup(state, whatsup,
STR(error_text));
1131 static int defer_if(SMTPD_DEFER *defer,
int error_class,
1132 int code,
const char *dsn,
1133 const char *
fmt,...)
1141 if (defer->
active == 0) {
1143 defer->
class = error_class;
1145 if (defer->
dsn == 0)
1159 static NORETURN reject_dict_retry(SMTPD_STATE *state,
const char *reply_name)
1163 "<%s>: Temporary lookup failure",
1169 static NORETURN reject_server_error(SMTPD_STATE *state)
1173 "Server configuration error"));
1178 static const char *check_mail_addr_find(SMTPD_STATE *state,
1179 const char *reply_name,
1180 MAPS *maps,
const char *key,
1189 reject_dict_retry(state, reply_name);
1191 reject_server_error(state);
1196 static int reject_unknown_reverse_name(SMTPD_STATE *state)
1198 const char *myname =
"reject_unknown_reverse_name";
1207 "Client host rejected: cannot find your reverse hostname, [%s]",
1214 static int reject_unknown_client(SMTPD_STATE *state)
1216 const char *myname =
"reject_unknown_client";
1225 var_unk_client_code : 450,
"4.7.25",
1226 "Client host rejected: cannot find your hostname, [%s]",
1233 static int reject_plaintext_session(SMTPD_STATE *state)
1235 const char *myname =
"reject_plaintext_session";
1241 if (state->tls_context == 0)
1245 "Session encryption is required"));
1251 static int permit_inet_interfaces(SMTPD_STATE *state)
1253 const char *myname =
"permit_inet_interfaces";
1266 static int permit_mynetworks(SMTPD_STATE *state)
1268 const char *myname =
"permit_mynetworks";
1276 msg_info(
"using backwards-compatible default setting "
1281 }
else if (mynetworks_curr->error == 0)
1284 return (mynetworks_curr->error);
1289 static char *dup_if_truncate(
char *name)
1301 if ((len = strlen(name)) > 1
1302 && name[len - 1] ==
'.'
1303 && name[len - 2] !=
'.') {
1312 static int reject_invalid_hostaddr(SMTPD_STATE *state,
char *addr,
1313 char *reply_name,
char *reply_class)
1315 const char *myname =
"reject_invalid_hostaddr";
1323 if (addr[0] ==
'[' && (len = strlen(addr)) > 2 && addr[len - 1] ==
']') {
1324 test_addr =
mystrndup(addr + 1, len - 2);
1334 "<%s>: %s rejected: invalid ip address",
1335 reply_name, reply_class);
1342 if (test_addr != addr)
1350 static int reject_invalid_hostname(SMTPD_STATE *state,
char *name,
1351 char *reply_name,
char *reply_class)
1353 const char *myname =
"reject_invalid_hostname";
1363 test_name = dup_if_truncate(name);
1372 "<%s>: %s rejected: Invalid name",
1373 reply_name, reply_class);
1380 if (test_name != name)
1388 static int reject_non_fqdn_hostname(SMTPD_STATE *state,
char *name,
1389 char *reply_name,
char *reply_class)
1391 const char *myname =
"reject_non_fqdn_hostname";
1401 test_name = dup_if_truncate(name);
1408 test_name,
DONT_GRIPE) == 0 || strchr(test_name,
'.') == 0)
1411 "<%s>: %s rejected: need fully-qualified hostname",
1412 reply_name, reply_class);
1419 if (test_name != name)
1427 static int reject_unknown_hostname(SMTPD_STATE *state,
char *name,
1428 char *reply_name,
char *reply_class)
1430 const char *myname =
"reject_unknown_hostname";
1438 #define RR_ADDR_TYPES T_A, T_AAAA
1440 #define RR_ADDR_TYPES T_A
1451 msg_warn(
"%s: address or MX lookup error: %s",
1452 name,
"DNS reply filter drops all results");
1458 "<%s>: %s rejected: %s",
1459 reply_name, reply_class,
1461 "Malformed DNS server reply" :
1466 "<%s>: %s rejected: Host not found",
1467 reply_name, reply_class));
1474 static int reject_unknown_mailhost(SMTPD_STATE *state,
const char *name,
1475 const char *reply_name,
const char *reply_class)
1477 const char *myname =
"reject_unknown_mailhost";
1491 msg_info(
"%s asciified to %s", name, aname);
1496 #define MAILHOST_LOOKUP_FLAGS \
1497 (DNS_REQ_FLAG_STOP_OK | DNS_REQ_FLAG_STOP_INVAL | \
1498 DNS_REQ_FLAG_STOP_NULLMX | DNS_REQ_FLAG_STOP_MX_POLICY)
1505 if (dns_status !=
DNS_OK) {
1507 msg_warn(
"%s: MX or address lookup error: %s",
1508 name,
"DNS reply filter drops all results");
1516 "4.7.27" :
"4.1.10",
1517 "<%s>: %s rejected: Domain %s "
1518 "does not accept mail (nullMX)",
1519 reply_name, reply_class, name));
1525 "<%s>: %s rejected: %s",
1526 reply_name, reply_class,
1528 "Malformed DNS server reply" :
1529 "Domain not found"));
1534 "<%s>: %s rejected: Domain not found",
1535 reply_name, reply_class));
1540 static int permit_auth_destination(SMTPD_STATE *state,
char *recipient);
1544 static int permit_tls_clientcerts(SMTPD_STATE *state,
int permit_all_certs)
1547 const char *found = 0;
1549 if (!state->tls_context)
1552 if (TLS_CERT_IS_TRUSTED(state->tls_context) && permit_all_certs) {
1554 msg_info(
"Relaying allowed for all verified client certificates");
1563 if (TLS_CERT_IS_PRESENT(state->tls_context)) {
1567 prints[0] = state->tls_context->peer_cert_fprint;
1568 prints[1] = state->tls_context->peer_pkey_fprint;
1571 for (i = 0; i < 2; ++i) {
1575 msg_info(
"Relaying allowed for certified client: %s", found);
1578 }
else if (relay_ccerts->
error != 0) {
1579 msg_warn(
"relay_clientcerts: lookup error for fingerprint '%s', "
1580 "pkey fingerprint %s", prints[0], prints[1]);
1581 return (relay_ccerts->
error);
1585 msg_info(
"relay_clientcerts: No match for fingerprint '%s', "
1586 "pkey fingerprint %s", prints[0], prints[1]);
1594 static int check_relay_domains(SMTPD_STATE *state,
char *recipient,
1595 char *reply_name,
char *reply_class)
1597 const char *myname =
"check_relay_domains";
1604 msg_warn(
"support for restriction \"%s\" will be removed from %s; "
1605 "use \"%s\" instead",
1611 msg_info(
"%s: %s", myname, recipient);
1618 msg_info(
"using backwards-compatible default setting "
1620 "request from client \"%s\"", state->
name);
1635 "<%s>: %s rejected: Relay access denied",
1636 reply_name, reply_class));
1641 static int permit_auth_destination(SMTPD_STATE *state,
char *recipient)
1643 const char *myname =
"permit_auth_destination";
1648 msg_info(
"%s: %s", myname, recipient);
1655 reject_dict_retry(state, recipient);
1682 msg_info(
"using backwards-compatible default setting "
1684 "for domain \"%s\"", domain);
1696 static int reject_unauth_destination(SMTPD_STATE *state,
char *recipient,
1697 int reply_code,
const char *reply_dsn)
1699 const char *myname =
"reject_unauth_destination";
1702 msg_info(
"%s: %s", myname, recipient);
1714 reply_code, reply_dsn,
1715 "<%s>: Relay access denied",
1721 static int reject_unauth_pipelining(SMTPD_STATE *state,
1722 const char *reply_name,
const char *reply_class)
1724 const char *myname =
"reject_unauth_pipelining";
1732 "<%s>: %s rejected: Improper use of SMTP command pipelining",
1733 reply_name, reply_class));
1740 static int all_auth_mx_addr(SMTPD_STATE *state,
char *host,
1741 const char *reply_name,
const char *reply_class)
1743 const char *myname =
"all_auth_mx_addr";
1750 msg_info(
"%s: host %s", myname, host);
1764 if (dns_status !=
DNS_OK) {
1767 "<%s>: %s rejected: Unable to look up host "
1768 "%s as mail exchanger: %s",
1769 reply_name, reply_class, host,
1774 for (rr = addr_list; rr != 0; rr = rr->
next) {
1776 msg_warn(
"%s: skipping record type %s for host %s: %m",
1781 msg_info(
"%s: checking: %s", myname, hostaddr.
buf);
1784 if (perm_mx_networks->error == 0) {
1791 msg_info(
"%s: address %s for %s does not match %s",
1794 msg_warn(
"%s: %s lookup error for address %s for %s",
1798 "<%s>: %s rejected: Unable to verify host %s as mail exchanger",
1799 reply_name, reply_class, host);
1811 static int has_my_addr(SMTPD_STATE *state,
const char *host,
1812 const char *reply_name,
const char *reply_class)
1814 const char *myname =
"has_my_addr";
1815 struct addrinfo *res;
1816 struct addrinfo *res0;
1822 msg_info(
"%s: host %s", myname, host);
1834 "<%s>: %s rejected: Unable to look up mail exchanger host %s: %s",
1838 #define HAS_MY_ADDR_RETURN(x) { freeaddrinfo(res0); return (x); }
1840 for (res = res0; res != 0; res = res->ai_next) {
1841 if (strchr((
char *) proto_info->
sa_family_list, res->ai_family) == 0) {
1843 msg_info(
"skipping address family %d for host %s",
1844 res->ai_family, host);
1858 msg_info(
"%s: host %s: no match", myname, host);
1865 static int i_am_mx(SMTPD_STATE *state,
DNS_RR *mx_list,
1866 const char *reply_name,
const char *reply_class)
1868 const char *myname =
"i_am_mx";
1875 for (mx = mx_list; mx != 0; mx = mx->
next) {
1877 msg_info(
"%s: resolve hostname: %s", myname, (
char *) mx->
data);
1886 for (mx = mx_list; mx != 0; mx = mx->
next) {
1888 msg_info(
"%s: address lookup: %s", myname, (
char *) mx->
data);
1889 if (has_my_addr(state, (
char *) mx->
data, reply_name, reply_class))
1897 msg_info(
"%s: I am not listed as MX relay", myname);
1903 static int permit_mx_primary(SMTPD_STATE *state,
DNS_RR *mx_list,
1904 const char *reply_name,
const char *reply_class)
1906 const char *myname =
"permit_mx_primary";
1916 for (mx = mx_list; mx != 0; mx = mx->
next) {
1917 if (!all_auth_mx_addr(state, (
char *) mx->
data, reply_name, reply_class))
1930 static int permit_mx_backup(SMTPD_STATE *state,
const char *recipient,
1931 const char *reply_name,
const char *reply_class)
1933 const char *myname =
"permit_mx_backup";
1936 const char *adomain;
1943 msg_info(
"%s: %s", myname, recipient);
1950 reject_dict_retry(state, recipient);
1970 msg_info(
"using backwards-compatible default setting "
1972 "for domain \"%s\"", domain);
1976 msg_info(
"%s: not local: %s", myname, recipient);
1981 if (domain[0] ==
'[' && domain[strlen(domain) - 1] ==
']')
1990 msg_info(
"%s asciified to %s", domain, adomain);
2001 dns_status =
dns_lookup(domain, T_MX, 0, &mx_list,
2005 return (has_my_addr(state, domain, reply_name, reply_class) ?
2008 if (dns_status !=
DNS_OK) {
2013 "<%s>: %s rejected: Unable to look up mail "
2014 "exchanger information: %s",
2015 reply_name, reply_class, dns_status ==
DNS_POLICY ?
2017 return (SMTPD_CHECK_DUNNO);
2024 for (middle = mx_list; ; middle = rest) {
2025 rest = middle->
next;
2035 #define PERMIT_MX_BACKUP_RETURN(x) do { \
2036 middle->next = rest; \
2037 dns_rr_free(mx_list); \
2044 if (i_am_mx(state, mx_list, reply_name, reply_class))
2050 if (rest == 0 || !i_am_mx(state, rest, reply_name, reply_class))
2058 && !permit_mx_primary(state, mx_list, reply_name, reply_class))
2069 static int reject_non_fqdn_address(SMTPD_STATE *state,
char *addr,
2070 char *reply_name,
char *reply_class)
2072 const char *myname =
"reject_non_fqdn_address";
2083 if ((domain = strrchr(addr,
'@')) != 0)
2091 if (domain[0] ==
'[' && domain[strlen(domain) - 1] ==
']')
2092 return (SMTPD_CHECK_DUNNO);
2097 test_dom = dup_if_truncate(domain);
2104 test_dom,
DONT_GRIPE) || !strchr(test_dom,
'.'))
2107 "<%s>: %s rejected: need fully-qualified address",
2108 reply_name, reply_class);
2115 if (test_dom != domain)
2123 static int reject_unknown_address(SMTPD_STATE *state,
const char *addr,
2124 const char *reply_name,
const char *reply_class)
2126 const char *myname =
"reject_unknown_address";
2139 reject_dict_retry(state, addr);
2145 return (SMTPD_CHECK_DUNNO);
2148 return (SMTPD_CHECK_DUNNO);
2149 if (domain[0] ==
'[' && domain[strlen(domain) - 1] ==
']')
2150 return (SMTPD_CHECK_DUNNO);
2155 return (reject_unknown_mailhost(state, domain, reply_name, reply_class));
2160 static int reject_unverified_address(SMTPD_STATE *state,
const char *addr,
2161 const char *reply_name,
const char *reply_class,
2162 int unv_addr_dcode,
int unv_addr_rcode,
2163 int unv_addr_tf_act,
2164 const char *alt_reply)
2166 const char *myname =
"reject_unverified_address";
2172 int reject_code = 0;
2180 for (count = 0; ; ) {
2194 "<%s>: %s rejected: address verification problem",
2195 reply_name, reply_class);
2197 switch (rcpt_status) {
2199 msg_warn(
"unknown address verification status %d", rcpt_status);
2203 reject_code = unv_addr_dcode;
2208 reject_code = unv_addr_rcode;
2211 if (reject_code >= 400 && *alt_reply)
2213 switch (reject_code / 100) {
2222 "<%s>: %s rejected: unverified address: %.250s",
2223 reply_name, reply_class,
STR(why));
2226 if (reject_code != 0)
2232 "<%s>: %s rejected: undeliverable address: %s",
2233 reply_name, reply_class,
STR(why));
2238 return (rqst_status);
2245 static int not_in_client_helo(SMTPD_STATE *,
const char *,
const char *,
const char *);
2247 static int can_delegate_action(SMTPD_STATE *state,
const char *table,
2248 const char *action,
const char *reply_class)
2257 msg_warn(
"access table %s: with %s specified, action %s is unavailable",
2266 msg_warn(
"access table %s: action %s is unavailable in %s",
2270 return (not_in_client_helo(state, table, action, reply_class));
2275 static int not_in_client_helo(SMTPD_STATE *state,
const char *table,
2277 const char *unused_reply_class)
2290 if (state->
sender == 0) {
2291 msg_warn(
"access table %s: with %s=%s, "
2292 "action %s is always skipped in %s or %s restrictions",
2305 static int check_table_result(SMTPD_STATE *state,
const char *table,
2306 const char *value,
const char *datum,
2307 const char *reply_name,
2308 const char *reply_class,
2309 const char *def_acl)
2311 const char *myname =
"check_table_result";
2316 const char *cmd_text;
2318 static char def_dsn[] =
"5.7.1";
2333 cmd_text = value + strcspn(value,
" \t");
2334 cmd_len = cmd_text - value;
2336 while (*cmd_text &&
ISSPACE(*cmd_text))
2340 msg_info(
"%s: %s %s %s", myname, table, value, datum);
2342 #define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0)
2347 if (
STREQUAL(value,
"DUNNO", cmd_len))
2348 return (SMTPD_CHECK_DUNNO);
2354 if (
STREQUAL(value,
"REJECT", cmd_len)) {
2360 "<%s>: %s rejected: %s",
2361 reply_name, reply_class,
2362 *dp.
text ? dp.
text :
"Access denied"));
2369 if (
STREQUAL(value,
"DEFER", cmd_len)) {
2375 "<%s>: %s rejected: %s",
2376 reply_name, reply_class,
2377 *dp.
text ? dp.
text :
"Access denied"));
2390 if (
STREQUAL(value,
"HANGUP", cmd_len)) {
2392 log_whatsup(state,
"hangup", cmd_text);
2399 if (
STREQUAL(value,
"INFO", cmd_len)) {
2400 log_whatsup(state,
"info", cmd_text);
2401 return (SMTPD_CHECK_DUNNO);
2407 if (
STREQUAL(value,
"WARN", cmd_len)) {
2408 log_whatsup(state,
"warn", cmd_text);
2409 return (SMTPD_CHECK_DUNNO);
2416 if (
STREQUAL(value,
"FILTER", cmd_len)) {
2418 if (can_delegate_action(state, table,
"FILTER", reply_class) == 0)
2419 return (SMTPD_CHECK_DUNNO);
2421 if (*cmd_text == 0) {
2422 msg_warn(
"access table %s entry \"%s\" has FILTER entry without value",
2424 return (SMTPD_CHECK_DUNNO);
2425 }
else if (strchr(cmd_text,
':') == 0) {
2426 msg_warn(
"access table %s entry \"%s\" requires transport:destination",
2428 return (SMTPD_CHECK_DUNNO);
2431 reply_name, reply_class, cmd_text);
2432 log_whatsup(state,
"filter",
STR(error_text));
2436 return (SMTPD_CHECK_DUNNO);
2444 if (
STREQUAL(value,
"HOLD", cmd_len)) {
2446 if (can_delegate_action(state, table,
"HOLD", reply_class) == 0
2448 return (SMTPD_CHECK_DUNNO);
2451 *cmd_text ? cmd_text :
"triggers HOLD action");
2452 log_whatsup(state,
"hold",
STR(error_text));
2456 return (SMTPD_CHECK_DUNNO);
2469 if (
STREQUAL(value,
"DELAY", cmd_len)) {
2471 if (can_delegate_action(state, table,
"DELAY", reply_class) == 0)
2472 return (SMTPD_CHECK_DUNNO);
2474 if (*cmd_text == 0) {
2475 msg_warn(
"access table %s entry \"%s\" has DELAY entry without value",
2477 return (SMTPD_CHECK_DUNNO);
2479 if (
conv_time(cmd_text, &defer_delay,
's') == 0) {
2480 msg_warn(
"access table %s entry \"%s\" has invalid DELAY argument \"%s\"",
2481 table, datum, cmd_text);
2482 return (SMTPD_CHECK_DUNNO);
2485 *cmd_text ? cmd_text :
"triggers DELAY action");
2486 log_whatsup(state,
"delay",
STR(error_text));
2488 state->saved_delay = defer_delay;
2490 return (SMTPD_CHECK_DUNNO);
2497 if (
STREQUAL(value,
"DISCARD", cmd_len)) {
2499 if (can_delegate_action(state, table,
"DISCARD", reply_class) == 0)
2500 return (SMTPD_CHECK_DUNNO);
2503 *cmd_text ? cmd_text :
"triggers DISCARD action");
2504 log_whatsup(state,
"discard",
STR(error_text));
2509 return (smtpd_acl_permit(state,
STR(buf), reply_class, reply_name,
2517 if (
STREQUAL(value,
"REDIRECT", cmd_len)) {
2519 if (can_delegate_action(state, table,
"REDIRECT", reply_class) == 0)
2520 return (SMTPD_CHECK_DUNNO);
2522 if (strchr(cmd_text,
'@') == 0) {
2523 msg_warn(
"access table %s entry \"%s\" requires user@domain target",
2525 return (SMTPD_CHECK_DUNNO);
2528 reply_name, reply_class, cmd_text);
2529 log_whatsup(state,
"redirect",
STR(error_text));
2533 return (SMTPD_CHECK_DUNNO);
2541 if (
STREQUAL(value,
"BCC", cmd_len)) {
2543 if (can_delegate_action(state, table,
"BCC", reply_class) == 0)
2544 return (SMTPD_CHECK_DUNNO);
2546 if (strchr(cmd_text,
'@') == 0) {
2547 msg_warn(
"access table %s entry \"%s\" requires user@domain target",
2549 return (SMTPD_CHECK_DUNNO);
2552 reply_name, reply_class, cmd_text);
2553 log_whatsup(state,
"bcc",
STR(error_text));
2559 return (SMTPD_CHECK_DUNNO);
2572 "<%s>: %s rejected: %s",
2573 reply_name, reply_class,
2574 *dp.
text ? dp.
text :
"Service unavailable"));
2586 "<%s>: %s rejected: %s",
2587 reply_name, reply_class,
2588 *dp.
text ? dp.
text :
"Service unavailable");
2589 return (SMTPD_CHECK_DUNNO);
2595 if (
STREQUAL(value,
"PREPEND", cmd_len)) {
2598 if (not_in_client_helo(state, table,
"PREPEND", reply_class) == 0)
2599 return (SMTPD_CHECK_DUNNO);
2602 msg_warn(
"access table %s: action PREPEND must be used before %s",
2604 return (SMTPD_CHECK_DUNNO);
2606 if (*cmd_text == 0 ||
is_header(cmd_text) == 0) {
2607 msg_warn(
"access table %s entry \"%s\" requires header: text",
2609 return (SMTPD_CHECK_DUNNO);
2614 return (SMTPD_CHECK_DUNNO);
2623 return (smtpd_acl_permit(state,
STR(buf), reply_class, reply_name,
2633 if (cmd_len == 3 && *cmd_text
2634 && (value[0] ==
'4' || value[0] ==
'5')
2637 def_dsn[0] = value[0];
2643 "<%s>: %s rejected: %s",
2644 reply_name, reply_class,
2645 *dp.
text ? dp.
text :
"Access denied"));
2652 return (smtpd_acl_permit(state,
STR(buf), reply_class, reply_name,
2663 if (strchr(value,
':') != 0) {
2664 msg_warn(
"access table %s has entry with lookup table: %s",
2666 msg_warn(
"do not specify lookup tables inside SMTPD access maps");
2667 msg_warn(
"define a restriction class and specify its name instead.");
2668 reject_server_error(state);
2675 msg_warn(
"access table %s entry %s causes unreasonable recursion",
2677 reject_server_error(state);
2688 #define ADDROF(x) ((char *) &(x))
2691 memcpy(
ADDROF(savebuf),
ADDROF(smtpd_check_buf),
sizeof(savebuf));
2692 status = setjmp(smtpd_check_buf);
2696 sizeof(smtpd_check_buf));
2697 longjmp(smtpd_check_buf, status);
2699 if (restrictions->
argc == 0) {
2700 msg_warn(
"access table %s entry %s has empty value",
2704 status = generic_checks(state, restrictions, reply_name,
2705 reply_class, def_acl);
2708 memcpy(
ADDROF(smtpd_check_buf),
ADDROF(savebuf),
sizeof(smtpd_check_buf));
2714 static int check_access(SMTPD_STATE *state,
const char *table,
const char *name,
2715 int flags,
int *found,
const char *reply_name,
2716 const char *reply_class,
const char *def_acl)
2718 const char *myname =
"check_access";
2722 #define CHK_ACCESS_RETURN(x,y) \
2723 { *found = y; return(x); }
2725 #define PARTIAL DICT_FLAG_FIXED
2733 msg_warn(
"%s: unexpected dictionary: %s", myname, table);
2734 value =
"451 4.3.5 Server configuration error";
2736 reply_name, reply_class,
2739 if ((value =
maps_find(maps, name, flags)) != 0)
2741 reply_name, reply_class,
2743 if (maps->
error != 0) {
2745 value =
"451 4.3.5 Server configuration error";
2747 reply_name, reply_class,
2755 static int check_domain_access(SMTPD_STATE *state,
const char *table,
2756 const char *domain,
int flags,
2757 int *found,
const char *reply_name,
2758 const char *reply_class,
2759 const char *def_acl)
2761 const char *myname =
"check_domain_access";
2766 int maybe_numerical = 1;
2769 msg_info(
"%s: %s", myname, domain);
2780 #define CHK_DOMAIN_RETURN(x,y) { *found = y; return(x); }
2783 msg_warn(
"%s: unexpected dictionary: %s", myname, table);
2784 value =
"451 4.3.5 Server configuration error";
2786 domain, reply_name, reply_class,
2789 for (name = domain; *name != 0; name = next) {
2790 if ((value =
maps_find(maps, name, flags)) != 0)
2792 domain, reply_name, reply_class,
2794 if (maps->
error != 0) {
2796 value =
"451 4.3.5 Server configuration error";
2798 domain, reply_name, reply_class,
2805 if ((next = strchr(name + 1,
'.')) == 0)
2816 static int check_addr_access(SMTPD_STATE *state,
const char *table,
2817 const char *address,
int flags,
2818 int *found,
const char *reply_name,
2819 const char *reply_class,
2820 const char *def_acl)
2822 const char *myname =
"check_addr_access";
2829 msg_info(
"%s: %s", myname, address);
2836 #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
2840 if (strchr(addr,
':') != 0)
2847 msg_warn(
"%s: unexpected dictionary: %s", myname, table);
2848 value =
"451 4.3.5 Server configuration error";
2850 reply_name, reply_class,
2854 if ((value =
maps_find(maps, addr, flags)) != 0)
2856 reply_name, reply_class,
2858 if (maps->
error != 0) {
2860 value =
"451 4.3.5 Server configuration error";
2862 reply_name, reply_class,
2873 static int check_namadr_access(SMTPD_STATE *state,
const char *table,
2874 const char *name,
const char *addr,
2875 int flags,
int *found,
2876 const char *reply_name,
2877 const char *reply_class,
2878 const char *def_acl)
2880 const char *myname =
"check_namadr_access";
2884 msg_info(
"%s: name %s addr %s", myname, name, addr);
2890 if ((status = check_domain_access(state, table, name, flags,
2891 found, reply_name, reply_class,
2892 def_acl)) != 0 || *found)
2898 if ((status = check_addr_access(state, table, addr, flags,
2899 found, reply_name, reply_class,
2900 def_acl)) != 0 || *found)
2906 return (SMTPD_CHECK_DUNNO);
2911 static int check_server_access(SMTPD_STATE *state,
const char *table,
2914 const char *reply_name,
2915 const char *reply_class,
2916 const char *def_acl)
2918 const char *myname =
"check_server_access";
2920 const char *adomain;
2927 struct addrinfo *res0;
2928 struct addrinfo *res;
2935 if (type != T_MX && type != T_NS && type != T_A
2940 msg_panic(
"%s: unexpected resource type \"%s\" in request",
2949 if ((domain = strrchr(name,
'@')) != 0)
2959 if (*domain ==
'[') {
2961 const char *bare_addr;
2964 if (type != T_A && type != T_MX)
2965 return (SMTPD_CHECK_DUNNO);
2966 len = strlen(domain);
2967 if (domain[len - 1] !=
']')
2968 return (SMTPD_CHECK_DUNNO);
2970 saved_addr =
mystrndup(domain + 1, len - 2);
2974 status = check_addr_access(state, table, bare_addr,
FULL,
2975 &found, reply_name, reply_class,
2987 msg_info(
"%s asciified to %s", domain, adomain);
3012 server_list =
dns_rr_create(domain, domain, T_MX, C_IN, 0, 0,
3013 domain, strlen(domain) + 1);
3015 dns_status =
dns_lookup(domain, type, 0, &server_list,
3018 return (SMTPD_CHECK_DUNNO);
3021 server_list =
dns_rr_create(domain, domain, type, C_IN, 0, 0,
3022 domain, strlen(domain) + 1);
3024 }
else if (type == T_NS ) {
3025 while ((domain = strchr(domain,
'.')) != 0 && domain[1]) {
3027 dns_status =
dns_lookup(domain, type, 0, &server_list,
3034 if (dns_status !=
DNS_OK) {
3036 domain && domain[1] ? domain : name, dns_status ==
DNS_POLICY ?
3038 return (SMTPD_CHECK_DUNNO);
3045 #define CHECK_SERVER_RETURN(x) { dns_rr_free(server_list); return(x); }
3051 for (server = server_list; server != 0; server = server->
next) {
3053 msg_info(
"%s: %s hostname check: %s",
3056 if ((status = check_addr_access(state, table, (
char *) server->
data,
3057 FULL, &found, reply_name, reply_class,
3058 def_acl)) != 0 || found)
3062 if (type != T_A && type != T_AAAA
3063 && ((status = check_domain_access(state, table, (
char *) server->
data,
3064 FULL, &found, reply_name, reply_class,
3065 def_acl)) != 0 || found))
3068 (
char *) 0, 0, &res0)) != 0) {
3069 if (type != T_A && type != T_AAAA)
3070 msg_warn(
"Unable to look up %s host %s for %s %s: %s",
3077 msg_info(
"%s: %s host address check: %s",
3079 for (res = res0; res != 0; res = res->ai_next) {
3080 if (strchr((
char *) proto_info->
sa_family_list, res->ai_family) == 0) {
3082 msg_info(
"skipping address family %d for host %s",
3083 res->ai_family, server->
data);
3088 status = check_addr_access(state, table, addr_string.
buf,
FULL,
3089 &found, reply_name, reply_class,
3091 if (status != 0 || found) {
3104 static int check_ccert_access(SMTPD_STATE *state,
const char *table,
3105 const char *def_acl)
3110 const char *myname =
"check_ccert_access";
3117 if (TLS_CERT_IS_PRESENT(state->tls_context)) {
3121 prints[0] = state->tls_context->peer_cert_fprint;
3122 prints[1] = state->tls_context->peer_pkey_fprint;
3124 for (i = 0; i < 2; ++i) {
3126 msg_info(
"%s: %s", myname, prints[i]);
3138 result = check_access(state, table, prints[i],
3140 state->tls_context->peer_CN,
3142 if (result != SMTPD_CHECK_DUNNO)
3152 #ifdef USE_SASL_AUTH
3154 static int check_sasl_access(SMTPD_STATE *state,
const char *table,
3155 const char *def_acl)
3161 result = check_access(state, table, state->sasl_username,
3172 static int check_mail_access(SMTPD_STATE *state,
const char *table,
3173 const char *addr,
int *found,
3174 const char *reply_name,
3175 const char *reply_class,
3176 const char *def_acl)
3178 const char *myname =
"check_mail_access";
3181 int lookup_strategy;
3194 reject_dict_retry(state, addr);
3201 msg_warn(
"%s: no @domain in address: %s", myname,
3212 #define SUSPICIOUS(reply, reply_class) \
3213 (var_allow_untrust_route == 0 \
3214 && (reply->flags & RESOLVE_FLAG_ROUTED) \
3215 && strcmp(reply_class, SMTPD_NAME_RECIPIENT) == 0)
3227 msg_warn(
"%s: unexpected dictionary: %s", myname, table);
3228 value =
"451 4.3.5 Server configuration error";
3229 return (check_table_result(state, table, value,
3231 reply_name, reply_class,
3235 (
char **) 0, lookup_strategy)) != 0) {
3237 status = check_table_result(state, table, value,
3239 reply_name, reply_class, def_acl);
3241 SMTPD_CHECK_DUNNO : status);
3242 }
else if (maps->
error != 0) {
3244 value =
"451 4.3.5 Server configuration error";
3245 return (check_table_result(state, table, value,
3247 reply_name, reply_class,
3254 return (SMTPD_CHECK_DUNNO);
3261 #define SMTPD_DNSXL_STAT_SOFT(dnsxl_res) ((dnsxl_res) == dnsxl_stat_soft)
3262 #define SMTPD_DNXSL_STAT_HARD(dnsxl_res) ((dnsxl_res) == 0)
3263 #define SMTPD_DNSXL_STAT_OK(dnsxl_res) \
3264 !(SMTPD_DNXSL_STAT_HARD(dnsxl_res) || SMTPD_DNSXL_STAT_SOFT(dnsxl_res))
3268 static void *rbl_pagein(
const char *query,
void *unused_context)
3290 msg_warn(
"%s: RBL lookup error: %s", query,
STR(why));
3291 rbl = dnsxl_stat_soft;
3294 if (dns_status !=
DNS_OK)
3295 return ((
void *) rbl);
3301 #define RBL_TXT_LIMIT 500
3306 if (dns_status ==
DNS_OK) {
3309 for (rr = txt_list; rr != 0 && space_left > 0; rr = next) {
3314 if (next && space_left > 3) {
3323 msg_warn(
"%s: TXT lookup error: %s",
3324 query,
"DNS reply filter drops all results");
3328 return ((
void *) rbl);
3333 static void rbl_pageout(
void *data,
void *unused_context)
3348 static void *rbl_byte_pagein(
const char *query,
void *unused_context)
3351 char *saved_query =
mystrdup(query);
3352 char *saved_byte_codes;
3360 return (saved_byte_codes);
3365 static void rbl_byte_pageout(
void *data,
void *unused_context)
3372 static const char *rbl_expand_lookup(
const char *name,
int mode,
3376 SMTPD_STATE *state = rbl_exp->
state;
3378 #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
3384 msg_info(
"rbl_expand_lookup: ${%s}", name);
3393 return (rbl_exp->
domain);
3395 return (rbl_exp->
txt);
3397 return (rbl_exp->
txt);
3399 return (rbl_exp->
what);
3401 return (rbl_exp->
class);
3409 static int rbl_reject_reply(SMTPD_STATE *state,
const SMTPD_RBL_STATE *rbl,
3410 const char *rbl_domain,
3412 const char *reply_class)
3414 const char *myname =
"rbl_reject_reply";
3416 const char *
template = 0;
3427 if (rbl_reply_maps->
error)
3428 reject_server_error(state);
3431 rbl_exp.
state = state;
3434 rbl_exp.
what = what;
3435 rbl_exp.
class = reply_class;
3436 rbl_exp.
txt = (rbl->txt == 0 ?
"" : rbl->txt);
3443 (
void *) &rbl_exp) == 0)
3446 msg_fatal(
"%s: bad default rbl reply template: %s",
3448 msg_warn(
"%s: bad rbl reply template for domain %s: %s",
3449 myname, rbl_domain,
template);
3460 if ((
STR(why)[0] !=
'4' &&
STR(why)[0] !=
'5')
3462 ||
STR(why)[3] !=
' ') {
3463 msg_warn(
"rbl response code configuration error: %s",
STR(why));
3465 450,
"4.7.1",
"Service unavailable");
3467 code = atoi(
STR(why));
3474 dp.
text :
"Service unavailable");
3488 static int rbl_match_addr(
SMTPD_RBL_STATE *rbl,
const char *byte_codes)
3490 const char *myname =
"rbl_match_addr";
3493 for (rr = rbl->a; rr != 0; rr = rr->
next) {
3494 if (rr->
type == T_A) {
3498 msg_warn(
"%s: skipping record type %s for query %s",
3508 const char *rbl_domain,
3511 const char *myname =
"find_dnsxl_addr";
3516 const char *reply_addr;
3517 const char *byte_codes;
3518 struct addrinfo *res;
3519 unsigned char *ipv6_addr;
3532 || res->ai_family != PF_INET6)
3533 msg_fatal(
"%s: unable to convert address %s", myname, addr);
3534 ipv6_addr = (
unsigned char *) &SOCK_ADDR_IN6_ADDR(res->ai_addr);
3535 for (i =
sizeof(SOCK_ADDR_IN6_ADDR(res->ai_addr)) - 1; i >= 0; i--)
3537 ipv6_addr[i] & 0xf, ipv6_addr[i] >> 4);
3548 for (i = octets->
argc - 1; i >= 0; i--) {
3561 if (reply_addr != 0)
3562 byte_codes =
ctable_locate(smtpd_rbl_byte_cache, reply_addr);
3568 && !rbl_match_addr(rbl, byte_codes))
3576 static int reject_rbl_addr(SMTPD_STATE *state,
const char *rbl_domain,
3577 const char *addr,
const char *reply_class)
3579 const char *myname =
"reject_rbl_addr";
3583 msg_info(
"%s: %s %s", myname, reply_class, addr);
3585 rbl = find_dnsxl_addr(state, rbl_domain, addr);
3587 return (SMTPD_CHECK_DUNNO);
3589 return (rbl_reject_reply(state, rbl, rbl_domain, addr, reply_class));
3595 static int permit_dnswl_addr(SMTPD_STATE *state,
const char *dnswl_domain,
3596 const char *addr,
const char *reply_class)
3598 const char *myname =
"permit_dnswl_addr";
3607 return (SMTPD_CHECK_DUNNO);
3609 dnswl_result = find_dnsxl_addr(state, dnswl_domain, addr);
3611 return (SMTPD_CHECK_DUNNO);
3616 "<%s>: %s rejected: %s",
3618 "Service unavailable");
3619 return (SMTPD_CHECK_DUNNO);
3624 msg_panic(
"%s: find_dnsxl_addr API failure", myname);
3631 const char *rbl_domain,
const char *what)
3636 const char *reply_addr;
3637 const char *byte_codes;
3639 const char *adomain;
3645 if ((domain = strrchr(what,
'@')) != 0) {
3647 if (domain[0] ==
'[')
3648 return (SMTPD_CHECK_DUNNO);
3658 return (SMTPD_CHECK_DUNNO);
3659 suffix = strrchr(domain,
'.');
3660 if (
alldig(suffix == 0 ? domain : suffix + 1))
3661 return (SMTPD_CHECK_DUNNO);
3669 msg_info(
"%s asciified to %s", domain, adomain);
3674 return (SMTPD_CHECK_DUNNO);
3680 if (reply_addr != 0)
3681 byte_codes =
ctable_locate(smtpd_rbl_byte_cache, reply_addr);
3687 && !rbl_match_addr(rbl, byte_codes))
3695 static int reject_rbl_domain(SMTPD_STATE *state,
const char *rbl_domain,
3696 const char *what,
const char *reply_class)
3698 const char *myname =
"reject_rbl_domain";
3702 msg_info(
"%s: %s %s", myname, rbl_domain, what);
3704 rbl = find_dnsxl_domain(state, rbl_domain, what);
3706 return (SMTPD_CHECK_DUNNO);
3708 return (rbl_reject_reply(state, rbl, rbl_domain, what, reply_class));
3714 static int permit_dnswl_domain(SMTPD_STATE *state,
const char *dnswl_domain,
3715 const char *what,
const char *reply_class)
3717 const char *myname =
"permit_dnswl_domain";
3726 return (SMTPD_CHECK_DUNNO);
3728 dnswl_result = find_dnsxl_domain(state, dnswl_domain, what);
3730 return (SMTPD_CHECK_DUNNO);
3735 "<%s>: %s rejected: %s",
3737 "Service unavailable");
3738 return (SMTPD_CHECK_DUNNO);
3743 msg_panic(
"%s: find_dnsxl_addr API failure", myname);
3749 static int reject_maps_rbl(SMTPD_STATE *state)
3751 const char *myname =
"reject_maps_rbl";
3753 char *bp = saved_domains;
3763 msg_warn(
"support for restriction \"%s\" will be removed from %s; "
3764 "use \"%s domain-name\" instead",
3768 result = reject_rbl_addr(state, rbl_domain, state->
addr,
3770 if (result != SMTPD_CHECK_DUNNO)
3782 #ifdef USE_SASL_AUTH
3786 static int reject_auth_sender_login_mismatch(SMTPD_STATE *state,
const char *sender,
int allow_unknown_sender)
3795 #define ALLOW_UNKNOWN_SENDER 1
3796 #define FORBID_UNKNOWN_SENDER 0
3801 if (smtpd_sender_login_maps && state->sasl_username) {
3804 reject_dict_retry(state, sender);
3805 if ((owners = check_mail_addr_find(state, sender, smtpd_sender_login_maps,
3807 cp = saved_owners =
mystrdup(owners);
3815 }
else if (allow_unknown_sender)
3816 return (SMTPD_CHECK_DUNNO);
3819 "<%s>: Sender address rejected: not owned by user %s",
3820 sender, state->sasl_username));
3822 return (SMTPD_CHECK_DUNNO);
3827 static int reject_unauth_sender_login_mismatch(SMTPD_STATE *state,
const char *sender)
3835 if (smtpd_sender_login_maps && !state->sasl_username) {
3838 reject_dict_retry(state, sender);
3839 if (check_mail_addr_find(state, sender, smtpd_sender_login_maps,
3842 "<%s>: Sender address rejected: not logged in", sender));
3844 return (SMTPD_CHECK_DUNNO);
3851 static int valid_utf8_action(
const char *server,
const char *action)
3856 msg_warn(
"malformed UTF-8 in policy server %s response: \"%s\"",
3863 static int check_policy_service(SMTPD_STATE *state,
const char *server,
3864 const char *reply_name,
const char *reply_class,
3865 const char *def_acl)
3873 const char *subject;
3882 if (!policy_clnt_table
3885 msg_panic(
"check_policy_service: no client endpoint for server %s",
3895 #define ENCODE_CN(coded_CN, coded_CN_buf, CN) do { \
3896 if (!TLS_CERT_IS_TRUSTED(state->tls_context) || *(CN) == 0) { \
3900 coded_CN_buf = vstring_alloc(strlen(CN) + 1); \
3901 xtext_quote(coded_CN_buf, CN, ""); \
3902 coded_CN = STR(coded_CN_buf); \
3906 ENCODE_CN(subject, subject_buf, state->tls_context->peer_CN);
3907 ENCODE_CN(issuer, issuer_buf, state->tls_context->issuer_CN);
3939 (
unsigned long) (state->
act_size > 0 ?
3944 #ifdef USE_SASL_AUTH
3946 state->sasl_method ? state->sasl_method :
""),
3948 state->sasl_username ? state->sasl_username :
""),
3950 state->sasl_sender ? state->sasl_sender :
""),
3953 #define IF_ENCRYPTED(x, y) ((state->tls_context && ((x) != 0)) ? (x) : (y))
3962 IF_ENCRYPTED(state->tls_context->peer_cert_fprint,
"")),
3964 IF_ENCRYPTED(state->tls_context->peer_pkey_fprint,
"")),
3966 IF_ENCRYPTED(state->tls_context->
protocol,
"")),
3968 IF_ENCRYPTED(state->tls_context->cipher_name,
"")),
3970 IF_ENCRYPTED(state->tls_context->cipher_usebits, 0)),
3987 memcpy(
ADDROF(savebuf),
ADDROF(smtpd_check_buf),
sizeof(savebuf));
3988 status = setjmp(smtpd_check_buf);
3992 sizeof(smtpd_check_buf));
3993 longjmp(smtpd_check_buf, status);
3995 ret = check_table_result(state, server, nesting_level == 1 ?
3998 "policy query", reply_name,
3999 reply_class, def_acl);
4002 sizeof(smtpd_check_buf));
4009 ret = check_table_result(state, server,
STR(action),
4010 "policy query", reply_name,
4011 reply_class, def_acl);
4024 static int is_map_command(SMTPD_STATE *state,
const char *name,
4025 const char *command,
char ***argp)
4037 }
else if (*(*argp + 1) == 0 || strchr(*(*argp += 1),
':') == 0) {
4038 msg_warn(
"restriction %s: bad argument \"%s\": need maptype:mapname",
4040 reject_server_error(state);
4048 static void forbid_whitelist(SMTPD_STATE *state,
const char *name,
4049 int status,
const char *target)
4052 msg_warn(
"restriction %s returns OK for %s", name, target);
4053 msg_warn(
"this is not allowed for security reasons");
4054 msg_warn(
"use DUNNO instead of OK if you want to make an exception");
4055 reject_server_error(state);
4061 static int generic_checks(SMTPD_STATE *state,
ARGV *restrictions,
4062 const char *reply_name,
4063 const char *reply_class,
4064 const char *def_acl)
4066 const char *myname =
"generic_checks";
4072 int saved_recursion = state->
recursion++;
4075 msg_info(
">>> START %s RESTRICTIONS <<<", reply_class);
4077 for (cpp = restrictions->
argv; (name = *cpp) != 0; cpp++) {
4083 msg_info(
"%s: name=%s", myname, name);
4098 #define NO_DEF_ACL 0
4100 if (strchr(name,
':') != 0) {
4102 msg_warn(
"specify one of (%s, %s, %s, %s, %s, %s) before %s restriction \"%s\"",
4105 reject_server_error(state);
4115 status = smtpd_acl_permit(state, name, reply_class,
4118 msg_warn(
"restriction `%s' after `%s' is ignored",
4123 "<%s>: %s rejected: Try again later",
4124 reply_name, reply_class);
4126 msg_warn(
"restriction `%s' after `%s' is ignored",
4131 "<%s>: %s rejected: Access denied",
4132 reply_name, reply_class);
4134 msg_warn(
"restriction `%s' after `%s' is ignored",
4137 status = reject_unauth_pipelining(state, reply_name, reply_class);
4139 if (cpp[1] == 0 || strchr(cpp[1],
':') == 0) {
4140 msg_warn(
"restriction %s must be followed by transport:server",
4142 reject_server_error(state);
4144 status = check_policy_service(state, *++cpp, reply_name,
4145 reply_class, def_acl);
4150 "<%s>: %s rejected: defer_if_permit requested",
4151 reply_name, reply_class);
4155 "<%s>: %s rejected: defer_if_reject requested",
4156 reply_name, reply_class);
4158 if (cpp[1] == 0 ||
alldig(cpp[1]) == 0) {
4159 msg_warn(
"restriction %s must be followed by number",
SLEEP);
4160 reject_server_error(state);
4162 sleep(atoi(*++cpp));
4164 status = reject_plaintext_session(state);
4172 status = reject_unknown_client(state);
4174 status = reject_unknown_reverse_name(state);
4176 status = permit_inet_interfaces(state);
4181 status = permit_mynetworks(state);
4186 status = check_namadr_access(state, *cpp, state->
name, state->
addr,
4190 status = check_namadr_access(state, *cpp, state->
reverse_name, state->
addr,
4193 forbid_whitelist(state, name, status, state->
reverse_name);
4195 status = reject_maps_rbl(state);
4199 msg_warn(
"restriction %s requires domain name argument", name);
4201 status = reject_rbl_addr(state, *(cpp += 1), state->
addr,
4205 msg_warn(
"restriction %s requires domain name argument", name);
4207 status = permit_dnswl_addr(state, *(cpp += 1), state->
addr,
4215 msg_warn(
"restriction %s requires domain name argument",
4220 status = reject_rbl_domain(state, *cpp, state->
name,
4225 msg_warn(
"restriction %s requires domain name argument",
4230 status = permit_dnswl_domain(state, *cpp, state->
name,
4233 status = smtpd_acl_permit(state, name,
4239 msg_warn(
"restriction %s requires domain name argument",
4244 status = reject_rbl_domain(state, *cpp, state->
reverse_name,
4248 status = check_ccert_access(state, *cpp, def_acl);
4249 #ifdef USE_SASL_AUTH
4252 if (state->sasl_username && state->sasl_username[0])
4253 status = check_sasl_access(state, *cpp, def_acl);
4256 msg_warn(
"restriction `%s' ignored: no SASL support", name);
4259 status = check_server_access(state, *cpp, state->
name,
4262 forbid_whitelist(state, name, status, state->
name);
4266 status = check_server_access(state, *cpp, state->
name,
4269 forbid_whitelist(state, name, status, state->
name);
4273 status = check_server_access(state, *cpp, state->
name,
4276 forbid_whitelist(state, name, status, state->
name);
4280 status = check_server_access(state, *cpp, state->
reverse_name,
4283 forbid_whitelist(state, name, status, state->
reverse_name);
4287 status = check_server_access(state, *cpp, state->
reverse_name,
4290 forbid_whitelist(state, name, status, state->
reverse_name);
4294 status = check_server_access(state, *cpp, state->
reverse_name,
4297 forbid_whitelist(state, name, status, state->
reverse_name);
4306 status = check_domain_access(state, *cpp, state->
helo_name,
4313 status = reject_invalid_hostname(state, state->
helo_name,
4316 status = reject_invalid_hostaddr(state, state->
helo_name,
4323 status = reject_unknown_hostname(state, state->
helo_name,
4326 status = reject_invalid_hostaddr(state, state->
helo_name,
4330 msg_warn(
"restriction %s is deprecated. Use %s or %s instead",
4334 && (status = reject_invalid_hostaddr(state, state->
helo_name,
4341 status = check_server_access(state, *cpp, state->
helo_name,
4344 forbid_whitelist(state, name, status, state->
helo_name);
4348 status = check_server_access(state, *cpp, state->
helo_name,
4351 forbid_whitelist(state, name, status, state->
helo_name);
4355 status = check_server_access(state, *cpp, state->
helo_name,
4358 forbid_whitelist(state, name, status, state->
helo_name);
4364 status = reject_non_fqdn_hostname(state, state->
helo_name,
4367 status = reject_invalid_hostaddr(state, state->
helo_name,
4372 msg_warn(
"restriction %s requires domain name argument",
4377 status = reject_rbl_domain(state, *cpp, state->
helo_name,
4387 status = check_mail_access(state, *cpp, state->
sender,
4396 status = reject_unknown_address(state, state->
sender,
4400 status = reject_unknown_address(state, state->
sender,
4404 status = reject_unverified_address(state, state->
sender,
4411 status = reject_non_fqdn_address(state, state->
sender,
4414 #ifdef USE_SASL_AUTH
4417 status = reject_auth_sender_login_mismatch(state,
4418 state->
sender, FORBID_UNKNOWN_SENDER);
4421 msg_warn(
"restriction `%s' ignored: no SASL support", name);
4423 #ifdef USE_SASL_AUTH
4426 if (state->sasl_username)
4427 status = reject_auth_sender_login_mismatch(state,
4428 state->
sender, ALLOW_UNKNOWN_SENDER);
4430 status = reject_unauth_sender_login_mismatch(state, state->
sender);
4434 msg_warn(
"restriction `%s' ignored: no SASL support", name);
4436 #ifdef USE_SASL_AUTH
4439 status = reject_unauth_sender_login_mismatch(state, state->
sender);
4442 msg_warn(
"restriction `%s' ignored: no SASL support", name);
4445 status = check_server_access(state, *cpp, state->
sender,
4448 forbid_whitelist(state, name, status, state->
sender);
4452 status = check_server_access(state, *cpp, state->
sender,
4455 forbid_whitelist(state, name, status, state->
sender);
4459 status = check_server_access(state, *cpp, state->
sender,
4462 forbid_whitelist(state, name, status, state->
sender);
4466 msg_warn(
"restriction %s requires domain name argument", name);
4470 status = reject_rbl_domain(state, *cpp, state->
sender,
4475 status = check_sender_rcpt_maps(state, state->
sender);
4483 status = check_mail_access(state, *cpp, state->
recipient,
4488 status = permit_mx_backup(state, state->
recipient,
4496 status = permit_auth_destination(state, state->
recipient);
4503 status = reject_unauth_destination(state, state->
recipient,
4507 status = reject_unauth_destination(state, state->
recipient,
4511 status = check_relay_domains(state, state->
recipient,
4517 msg_warn(
"restriction `%s' after `%s' is ignored",
4520 #ifdef USE_SASL_AUTH
4530 status = permit_tls_clientcerts(state, 1);
4535 status = permit_tls_clientcerts(state, 0);
4541 status = reject_unknown_address(state, state->
recipient,
4545 status = reject_non_fqdn_address(state, state->
recipient,
4549 status = check_server_access(state, *cpp, state->
recipient,
4552 forbid_whitelist(state, name, status, state->
recipient);
4556 status = check_server_access(state, *cpp, state->
recipient,
4559 forbid_whitelist(state, name, status, state->
recipient);
4563 status = check_server_access(state, *cpp, state->
recipient,
4566 forbid_whitelist(state, name, status, state->
recipient);
4570 msg_warn(
"restriction %s requires domain name argument", name);
4574 status = reject_rbl_domain(state, *cpp, state->
recipient,
4580 status = check_recipient_rcpt_maps(state, state->
recipient);
4586 "<%s>: %s rejected: Multi-recipient bounce",
4587 reply_name, reply_class);
4590 status = reject_unverified_address(state, state->
recipient,
4602 status = check_domain_access(state, *cpp, state->
etrn_name,
4610 else if ((list = (
ARGV *)
htable_find(smtpd_rest_classes, name)) != 0) {
4611 status = generic_checks(state, list, reply_name,
4612 reply_class, def_acl);
4619 msg_warn(
"unknown smtpd restriction: \"%s\"", name);
4620 reject_server_error(state);
4623 msg_info(
"%s: name=%s status=%d", myname, name, status);
4627 reject_dict_retry(state, reply_name);
4629 reject_server_error(state);
4641 msg_info(
">>> END %s RESTRICTIONS <<<", reply_class);
4657 const char *myname =
"smtpd_check_addr";
4661 msg_info(
"%s: addr=%s", myname, addr);
4668 if (addr == 0 || *addr == 0)
4681 && (domain = strrchr(
STR(resolve_reply->
recipient),
'@')) != 0
4682 && *(domain += 1) != 0 && !
allascii(domain))
4692 const char *myname =
"smtpd_check_rewrite";
4702 for (cpp = local_rewrite_clients->
argv; *cpp != 0; cpp++) {
4704 msg_info(
"%s: trying: %s", myname, *cpp);
4706 if (strchr(name = *cpp,
':') != 0) {
4711 status = permit_inet_interfaces(state);
4713 status = permit_mynetworks(state);
4716 msg_panic(
"%s: dictionary not found: %s", myname, *cpp);
4719 else if (maps->
error != 0) {
4721 status = maps->
error;
4724 #ifdef USE_SASL_AUTH
4730 status = permit_tls_clientcerts(state, 1);
4732 status = permit_tls_clientcerts(state, 0);
4734 msg_warn(
"parameter %s: invalid request: %s",
4741 log_whatsup(state,
"reject",
4742 "451 4.3.0 Temporary lookup error");
4743 return (
"451 4.3.0 Temporary lookup error");
4746 log_whatsup(state,
"reject",
4747 "451 4.3.5 Server configuration error");
4748 return (
"451 4.3.5 Server configuration error");
4769 if (state->
name == 0 || state->
addr == 0)
4772 #define SMTPD_CHECK_RESET() { \
4773 state->recursion = 0; \
4774 state->warn_if_reject = 0; \
4775 state->defer_if_reject.active = 0; \
4787 status = setjmp(smtpd_check_buf);
4788 if (status == 0 && client_restrctions->
argc)
4789 status = generic_checks(state, client_restrctions, state->
namaddr,
4813 #define SMTPD_CHECK_PUSH(backup, current, new) { \
4815 current = (new ? mystrdup(new) : 0); \
4818 #define SMTPD_CHECK_POP(current, backup) { \
4819 if (current) myfree(current); \
4825 #define SMTPD_CHECK_HELO_RETURN(x) { \
4826 SMTPD_CHECK_POP(state->helo_name, saved_helo); \
4841 status = setjmp(smtpd_check_buf);
4842 if (status == 0 && helo_restrctions->
argc)
4843 status = generic_checks(state, helo_restrctions, state->
helo_name,
4869 #define SMTPD_CHECK_MAIL_RETURN(x) { \
4870 SMTPD_CHECK_POP(state->sender, saved_sender); \
4887 status = setjmp(smtpd_check_buf);
4888 if (status == 0 && mail_restrctions->
argc)
4889 status = generic_checks(state, mail_restrctions, sender,
4899 && state->
discard == 0 && *sender)
4900 status = check_sender_rcpt_maps(state, sender);
4910 char *saved_recipient;
4912 ARGV *restrctions[2];
4925 if (
strcasecmp(recipient,
"postmaster") == 0)
4934 #define SMTPD_CHECK_RCPT_RETURN(x) { \
4935 SMTPD_CHECK_POP(state->recipient, saved_recipient); \
4975 restrctions[0] = rcpt_restrctions;
4977 fake_relay_restrctions : relay_restrctions;
4978 for (n = 0; n < 2; n++) {
4979 status = setjmp(smtpd_check_buf);
4980 if (status == 0 && restrctions[n]->argc)
4981 status = generic_checks(state, restrctions[n],
4984 && status == SMTPD_CHECK_DUNNO) {
4985 msg_info(
"using backwards-compatible default setting \""
4987 "access denied\" error for recipient \"%s\" from "
5012 status = check_recipient_rcpt_maps(state, recipient);
5022 char *saved_etrn_name;
5037 #define SMTPD_CHECK_ETRN_RETURN(x) { \
5038 SMTPD_CHECK_POP(state->etrn_name, saved_etrn_name); \
5062 status = setjmp(smtpd_check_buf);
5063 if (status == 0 && etrn_restrctions->
argc)
5064 status = generic_checks(state, etrn_restrctions, domain,
5082 static int check_recipient_rcpt_maps(SMTPD_STATE *state,
const char *recipient)
5096 return (check_rcpt_maps(state, state->
sender, recipient,
5102 static int check_sender_rcpt_maps(SMTPD_STATE *state,
const char *sender)
5116 return (check_rcpt_maps(state, state->
recipient, sender,
5122 static int check_rcpt_maps(SMTPD_STATE *state,
const char *sender,
5123 const char *recipient,
5124 const char *reply_class)
5130 msg_info(
">>> CHECKING %s VALIDATION MAPS <<<", reply_class);
5137 reject_dict_retry(state, recipient);
5142 #define MATCH(map, rcpt) \
5143 check_mail_addr_find(state, recipient, map, rcpt, (char **) 0)
5145 #define NOMATCH(map, rcpt) (MATCH(map, rcpt) == 0)
5178 "<%s>: %s rejected: %s",
5179 recipient, reply_class,
5188 "<%s>: %s rejected: %s",
5189 recipient, reply_class,
5204 #define MATCH_LEFT(l, r, n) \
5205 (strncasecmp_utf8((l), (r), (n)) == 0 && (r)[n] == '@')
5229 "<%s>: %s rejected: User unknown%s",
5230 recipient, reply_class,
5232 " in local recipient table" :
""));
5245 "<%s>: %s rejected: User unknown%s",
5246 recipient, reply_class,
5248 " in virtual mailbox table" :
""));
5261 "<%s>: %s rejected: User unknown%s",
5262 recipient, reply_class,
5264 " in relay recipient table" :
""));
5266 msg_info(
"using backwards-compatible default setting "
5268 "for address \"%s\"", recipient);
5289 if ((status = setjmp(smtpd_check_buf)) != 0)
5298 "Message size exceeds fixed limit");
5299 return (
STR(error_text));
5308 const char *myname =
"smtpd_check_queue";
5316 if ((status = setjmp(smtpd_check_buf)) != 0)
5323 #define BLOCKS(x) ((x) / fsbuf.block_size)
5327 msg_info(
"%s: blocks %lu avail %lu min_free %lu msg_size_limit %lu",
5337 "Insufficient system storage");
5338 msg_warn(
"not enough free space in mail queue: %lu bytes < "
5339 "%g*message size limit",
5342 return (
STR(error_text));
5377 status = setjmp(smtpd_check_buf);
5378 if (status == 0 && data_restrctions->
argc)
5379 status = generic_checks(state, data_restrctions,
5428 status = setjmp(smtpd_check_buf);
5429 if (status == 0 && eod_restrictions->
argc)
5430 status = generic_checks(state, eod_restrictions,
5486 char *var_relay_ccerts =
"";
5541 #undef DEF_VIRT_ALIAS_MAPS
5542 #define DEF_VIRT_ALIAS_MAPS ""
5544 #undef DEF_LOCAL_RCPT_MAPS
5545 #define DEF_LOCAL_RCPT_MAPS ""
5547 static const STRING_TABLE string_table[] = {
5594 static void string_init(
void)
5596 const STRING_TABLE *sp;
5598 for (sp = string_table; sp->name; sp++)
5599 sp->target[0] =
mystrdup(sp->defval);
5604 static int string_update(
char **argv)
5606 const STRING_TABLE *sp;
5608 for (sp = string_table; sp->name; sp++) {
5666 #define int_table test_int_table
5668 static const INT_TABLE int_table[] = {
5704 static void int_init(
void)
5706 const INT_TABLE *sp;
5708 for (sp = int_table; sp->name; sp++)
5709 sp->target[0] = sp->defval;
5714 static int int_update(
char **argv)
5716 const INT_TABLE *ip;
5718 for (ip = int_table; ip->name; ip++) {
5721 msg_fatal(
"bad number: %s %s", ip->name, argv[1]);
5722 ip->target[0] = atoi(argv[1]);
5737 static const REST_TABLE rest_table[] = {
5738 "client_restrictions", &client_restrctions,
5739 "helo_restrictions", &helo_restrctions,
5740 "sender_restrictions", &mail_restrctions,
5741 "relay_restrictions", &relay_restrctions,
5742 "recipient_restrictions", &rcpt_restrctions,
5743 "etrn_restrictions", &etrn_restrctions,
5749 static int rest_update(
char **argv)
5751 const REST_TABLE *rp;
5753 for (rp = rest_table; rp->name; rp++) {
5765 static void rest_class(
char *
class)
5771 if (smtpd_rest_classes == 0)
5775 msg_panic(
"rest_class: null class name");
5779 entry =
htable_enter(smtpd_rest_classes, name, (
void *) 0);
5802 #ifdef USE_SASL_AUTH
5807 const char *opts_var)
5809 msg_panic(
"smtpd_sasl_activate was called");
5816 msg_panic(
"smtpd_sasl_deactivate was called");
5830 state->sasl_username = 0;
5831 state->sasl_method = 0;
5832 state->sasl_sender = 0;
5850 if (addr ==
STR(result))
5851 msg_panic(
"rewrite_clnt_internal: result clobbers input");
5852 if (*addr && strchr(addr,
'@') == 0)
5853 msg_fatal(
"%s: address rewriting is disabled", addr);
5860 void resolve_clnt(
const char *
class,
const char *unused_sender,
const char *addr,
5867 msg_panic(
"resolve_clnt_query: result clobbers input");
5868 if (strchr(addr,
'%'))
5869 msg_fatal(
"%s: address rewriting is disabled", addr);
5870 if ((domain = strrchr(addr,
'@')) == 0)
5871 msg_fatal(
"%s: unqualified address", addr);
5877 }
else if (rc < 0) {
5883 }
else if (virt_alias_doms->error) {
5889 }
else if (virt_mailbox_doms->error) {
5895 }
else if (relay_domains->error) {
5913 static NORETURN usage(
char *myname)
5918 int main(
int argc,
char **argv)
5968 resp =
"bad command";
5969 switch (args->
argc) {
5991 if (smtpd_rbl_cache) {
5996 rbl_pageout, (
void *) 0);
5998 rbl_byte_pageout, (
void *) 0);
6013 if (args->
argc == 4)
6016 atoi(args->
argv[3]);
6017 else if (strcmp(state.
name,
"unknown") == 0)
6036 #define UPDATE_MAPS(ptr, var, val, lock) \
6037 { if (ptr) maps_free(ptr); ptr = maps_create(var, val, lock); }
6039 #define UPDATE_LIST(ptr, var, val) \
6040 { if (ptr) string_list_free(ptr); \
6041 ptr = string_list_init(var, MATCH_FLAG_NONE, val); }
6062 var_virt_alias_doms);
6078 var_virt_mailbox_doms);
6179 rest_class(args->
argv[1]);
6186 local_rewrite_clients = smtpd_check_parse(SMTPD_CHECK_PARSE_MAPS,
6187 var_local_rwr_clients);
6189 if (int_update(args->
argv)
6190 || string_update(args->
argv)
6191 || rest_update(args->
argv)) {
6199 #define TRIM_ADDR(src, res) { \
6200 if (*(res = src) == '<') { \
6201 res += strlen(res) - 1; \
6209 state.
where =
"HELO";
6213 state.
where =
"MAIL";
6214 TRIM_ADDR(args->
argv[1], addr);
6218 state.
where =
"RCPT";
6219 TRIM_ADDR(args->
argv[1], addr);
6223 if (state.tls_context == 0) {
6225 (TLS_SESS_STATE *)
mymalloc(
sizeof(*state.tls_context));
6226 memset((
void *) state.tls_context, 0,
6227 sizeof(*state.tls_context));
6228 state.tls_context->peer_cert_fprint =
6229 state.tls_context->peer_pkey_fprint = 0;
6231 state.tls_context->peer_status |= TLS_CERT_FLAG_PRESENT;
6234 state.tls_context->peer_pkey_fprint =
6235 state.tls_context->peer_cert_fprint;
6251 resp =
"Commands...\n\
6252 client <name> <address> [<code>]\n\
6255 recipient <address>\n\
6257 msg_verbose <level>\n\
6258 client_restrictions <restrictions>\n\
6259 helo_restrictions <restrictions>\n\
6260 sender_restrictions <restrictions>\n\
6261 recipient_restrictions <restrictions>\n\
6262 restriction_class name,<restrictions>\n\
6263 flush_dnsxl_cache\n\
6265 Note: no address rewriting \n";
6274 #define FREE_STRING(s) { if (s) myfree(s); }
6276 FREE_STRING(state.
sender);
6278 if (state.tls_context) {
6279 FREE_STRING(state.tls_context->peer_cert_fprint);
6280 myfree((
void *) state.tls_context);
#define CHECK_SENDER_NS_ACL
#define DEF_UNK_ADDR_CODE
int valid_hostaddr(const char *addr, int gripe)
#define ATTR_CLNT_CTL_TRY_LIMIT
#define CHECK_HELO_NS_ACL
const char * dns_strtype(unsigned)
#define vstring_fgets_nonl(s, p)
#define MAIL_ATTR_ACT_HELO_NAME
int valid_ipv6_hostaddr(const char *addr, int gripe)
#define RESOLVE_FLAG_FAIL
#define MAIL_ATTR_PROTO_STATE
char * var_unv_from_tf_act
const char * valid_mailhost_addr(const char *addr, int gripe)
int warn_compat_break_relay_domains
#define VAR_RELAY_RCPT_CODE
int defer_if_permit_sender
#define DEF_RBL_REPLY_MAPS
#define MATCH_FLAG_RETURN
#define SMTPD_NAME_REV_CLIENT
#define STREQUAL(x, y, l)
#define VAR_SMTPD_POLICY_TRY_LIMIT
#define MAIL_ERROR_RESOURCE
#define DEF_UNV_FROM_RCODE
HTABLE_INFO * htable_locate(HTABLE *table, const char *key)
#define VAR_UNK_ADDR_TF_ACT
void freeaddrinfo(struct addrinfo *ai)
bool var_smtpd_rej_unl_from
int match_parent_style(const char *name)
#define VAR_SMTPD_CLIENT_PORT_LOG
#define DEF_MAP_DEFER_CODE
#define MAIL_ATTR_RBL_WHAT
#define SMTPD_PEER_CODE_PERM
#define MAIL_ATTR_RBL_REASON
#define VAR_DEF_RBL_REPLY
#define CA_ATTR_OVER_INT_TABLE(v)
#define MAIL_ATTR_CCERT_CERT_FPRINT
DSN_SPLIT * dsn_split(DSN_SPLIT *dp, const char *def_dsn, const char *text)
size_t dsn_valid(const char *text)
#define MAIL_ADDR_POSTMASTER
#define SMTPD_DNSXL_STAT_SOFT(dnsxl_res)
char * mystrdup(const char *str)
#define VAR_UNV_FROM_DCODE
int mac_expand(VSTRING *result, const char *pattern, int flags, const char *filter, MAC_EXP_LOOKUP_FN lookup, void *context)
#define VAR_PROXY_INTERFACES
char * extpar(char **bp, const char *parens, int flags)
char * smtpd_check_mail(SMTPD_STATE *state, char *sender)
#define CHECK_POLICY_SERVICE
#define CHECK_CLIENT_A_ACL
char * var_smtpd_snd_auth_maps
bool var_smtpd_sasl_enable
char * smtpd_check_eod(SMTPD_STATE *state)
#define MAIL_SERVICE_ERROR
char * var_perm_mx_networks
ARGV * argv_free(ARGV *argvp)
#define USE_SMTPD_PROXY(state)
char * smtpd_check_etrn(SMTPD_STATE *state, char *domain)
char * var_local_rwr_clients
#define MATCH_LEFT(l, r, n)
#define DEF_SHOW_UNK_RCPT_TABLE
NORETURN msg_panic(const char *fmt,...)
#define MAIL_ATTR_CRYPTO_CIPHER
void smtpd_expand_init(void)
const char * smtpd_expand_lookup(const char *name, int unused_mode, void *context)
#define VAR_RELAY_DOMAINS
#define DEF_MAPS_RBL_CODE
#define MAIL_ATTR_RBL_CLASS
#define DEF_VIRT_ALIAS_DOMS
#define DEL_RCPT_STAT_TODO
#define MAIL_SERVICE_VIRTUAL
#define PERMIT_NAKED_IP_ADDR
#define ATTR_FLAG_MISSING
#define ATTR_CLNT_CTL_END
int var_verify_poll_count
#define SMTPD_CHECK_PUSH(backup, current, new)
#define inet_proto_info()
#define DEF_SMTPD_DNS_RE_FILTER
char * var_smtpd_dns_re_filter
#define domain_list_match
#define DEF_LOCAL_RCPT_MAPS
int main(int argc, char **argv)
#define REJECT_UNAUTH_DEST
#define REJECT_NON_FQDN_HELO_HOSTNAME
int valid_utf8_string(const char *, ssize_t)
INET_PROTO_INFO * inet_proto_init(const char *context, const char *protocols)
VSTRING * rewrite_clnt_internal(const char *ruleset, const char *addr, VSTRING *result)
#define DEF_NON_FQDN_CODE
VSTRING * vstring_strncat(VSTRING *vp, const char *src, ssize_t len)
void attr_override(char *cp, const char *sep, const char *parens,...)
#define VAR_MAPS_RBL_DOMAINS
bool var_smtpd_peername_lookup
int conv_time(const char *strval, int *timval, int def_unit)
#define hostname_to_sockaddr(host, serv, sock, res)
#define VAR_UNV_RCPT_TF_ACT
const void * ctable_locate(CTABLE *cache, const char *key)
#define vstream_longjmp(stream, val)
#define PERMIT_TLS_ALL_CLIENTCERTS
#define MAIL_ERROR_BOUNCE
#define REJECT_SENDER_LOGIN_MISMATCH
#define DEF_BAD_NAME_CODE
#define VAR_SMTPD_NULL_KEY
#define MAIL_SERVICE_SMTP
#define PERMIT_RHSWL_CLIENT
#define DEF_VERIFY_SENDER
VSTRING * vstring_truncate(VSTRING *vp, ssize_t len)
int resolve_local(const char *addr)
#define MAIL_ATTR_RBL_TXT
#define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock)
#define dns_lookup_l(name, rflags, list, fqdn, why, lflags,...)
#define DEF_SMTPD_NULL_KEY
void resolve_clnt_free(RESOLVE_REPLY *reply)
int var_smtpd_delay_reject
#define CLEANUP_FLAG_DISCARD
#define MAIL_ATTR_RWR_LOCAL
#define MAIL_ATTR_ACT_CLIENT_ADDR
void argv_add(ARGV *argvp,...)
#define SMTPD_CHECK_HELO_RETURN(x)
#define DEF_PROXY_INTERFACES
#define MAIL_ATTR_ACT_SERVER_ADDR
char * smtpd_check_helo(SMTPD_STATE *state, char *helohost)
#define DEF_INET_INTERFACES
char * mystrtokq(char **src, const char *sep, const char *parens)
#define DSN_STATUS(dsn_buf)
#define VAR_INET_INTERFACES
#define DICT_FLAG_UTF8_REQUEST
int ip_match_execute(const char *byte_codes, const char *addr_bytes)
#define VAR_SMTPD_REJ_UNL_FROM
#define MAIL_ATTR_SASL_METHOD
int own_inet_addr(struct sockaddr *addr)
char * var_virt_alias_doms
int var_smtpd_policy_idle
#define MAIL_ATTR_RWR_REMOTE
#define DEL_RCPT_STAT_BOUNCE
#define SMTPD_AFTER_CONNECT
char * var_verify_service
#define strcasecmp_utf8(s1, s2)
void smtpd_chat_reset(SMTPD_STATE *state)
int alldig(const char *string)
char * var_smtpd_sasl_opts
#define DEF_SMTPD_REJ_UNL_FROM
int var_smtpd_policy_try_delay
#define MAIL_ERROR_POLICY
#define CHECK_SERVER_RETURN(x)
char * mystrtok(char **src, const char *sep)
ARGV * argv_alloc(ssize_t len)
#define smtpd_sasl_is_active(s)
#define VAR_SEND_CANON_MAPS
#define RESOLVE_CLASS_FINAL
#define VAR_SMTPD_POLICY_DEF_ACTION
#define CA_ATTR_OVER_TIME_TABLE(v)
#define VAR_UNV_RCPT_DCODE
#define DEF_SMTPD_POLICY_TRY_DELAY
#define CLEANUP_FLAG_HOLD
#define DICT_FLAG_FOLD_FIX
char * smtpd_check_data(SMTPD_STATE *state)
#define VAR_SMTPD_PEERNAME_LOOKUP
#define RESOLVE_FLAG_ROUTED
#define CHK_DOMAIN_RETURN(x, y)
#define RESOLVE_CLASS_VIRTUAL
#define DEF_MAPS_RBL_DOMAINS
#define PERMIT_DNSWL_CLIENT
#define VAR_MAP_REJECT_CODE
int hostaddr_to_sockaddr(const char *hostaddr, const char *service, int socktype, struct addrinfo **res)
#define REJECT_UNKNOWN_REVERSE_HOSTNAME
char * var_send_canon_maps
#define DEF_SMTPD_POLICY_TMOUT
#define VAR_VIRT_ALIAS_MAPS
ATTR_CLNT * attr_clnt_create(const char *service, int timeout, int max_idle, int max_ttl)
bool var_allow_untrust_route
#define dns_lookup_v(name, rflags, list, fqdn, why, lflags, ltype)
#define VAR_VIRT_MAILBOX_DOMS
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
const char * dns_rr_to_pa(DNS_RR *, MAI_HOSTADDR_STR *)
#define VAR_VIRT_ALIAS_DOMS
#define VAR_UNK_ADDR_CODE
#define VAR_UNK_NAME_CODE
#define VAR_UNV_FROM_TF_ACT
#define string_list_init(o, f, p)
#define DEF_SMTPD_ACL_PERM_LOG
char * var_relay_rcpt_maps
#define DEF_SMTPD_POLICY_DEF_ACTION
HTABLE * htable_create(ssize_t size)
#define VAR_VIRT_MAILBOX_MAPS
DNS_RR * dns_rr_create(const char *, const char *, ushort, ushort, unsigned, unsigned, const char *, size_t)
const char * smtpd_dsn_fix(const char *status, const char *reply_class)
#define RESOLVE_CLASS_LOCAL
int permit_sasl_auth(SMTPD_STATE *, int, int)
int valid_hostname(const char *name, int gripe)
const char * mynetworks_host(void)
char * ip_match_save(const VSTRING *byte_codes)
#define string_list_match
#define REJECT_UNAUTH_SENDER_LOGIN_MISMATCH
char * var_smtpd_policy_context
#define VAR_ALLOW_UNTRUST_ROUTE
const char * dns_strerror(unsigned)
int warn_compat_break_mynetworks_style
int sender_rcptmap_checked
#define VAR_CANONICAL_MAPS
#define VAR_LOCAL_RCPT_MAPS
#define DEFER_IF_PERMIT_ACT
#define DEFER_UNAUTH_DEST
char buf[MAI_HOSTADDR_STRSIZE]
int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
#define UPDATE_STRING(ptr, val)
VSTRING * vstring_sprintf_append(VSTRING *vp, const char *format,...)
#define DEF_SMTPD_POLICY_IDLE
VSTRING * vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
#define SMTPD_CHECK_ETRN_RETURN(x)
char * var_unv_rcpt_tf_act
#define SUSPICIOUS(reply, reply_class)
#define SMTPD_CHECK_PARSE_MAPS
#define MAIL_ATTR_ACT_CLIENT_PORT
#define DEF_RELAY_RCPT_CODE
#define VAR_UNV_RCPT_RCODE
#define CHECK_REVERSE_CLIENT_ACL
#define MAC_EXP_FLAG_NONE
#define DEF_CANONICAL_MAPS
#define MAIL_ATTR_CRYPTO_KEYSIZE
#define SMTPD_CHECK_PARSE_POLICY
#define RESOLVE_FLAG_ERROR
#define REJECT_INVALID_HOSTNAME
ARGV * argv_splitq(const char *, const char *, const char *)
#define SMTPD_CHECK_RESET()
int valid_utf8_hostname(int enable_utf8, const char *name, int gripe)
void attr_clnt_control(ATTR_CLNT *client, int name,...)
SMTPD_DEFER defer_if_permit
#define MATCH_FLAG_PARENT
char * var_notify_classes
#define DNS_REQ_FLAG_STOP_OK
#define ATTR_CLNT_CTL_TRY_DELAY
MAPS * maps_create(const char *title, const char *map_names, int dict_flags)
void resolve_clnt_init(RESOLVE_REPLY *reply)
#define VAR_DOUBLE_BOUNCE
#define CHECK_REVERSE_CLIENT_A_ACL
void smtpd_sasl_deactivate(SMTPD_STATE *)
char * var_double_bounce_sender
bool var_show_unk_rcpt_table
void smtpd_sasl_state_init(SMTPD_STATE *)
#define mail_addr_find(maps, address, extension)
#define ATTR_CLNT_CTL_REQ_LIMIT
#define DEF_VIRT_ALIAS_MAPS
#define REJECT_RHSBL_REVERSE_CLIENT
#define DEFER_IF_PERMIT3(type, state, class, code, dsn, fmt, a1, a2, a3)
VSTREAM * vstream_printf(const char *fmt,...)
#define REJECT_RHSBL_HELO
int smtpd_check_addr(const char *sender, const char *addr, int smtputf8)
#define MAIL_ATTR_SASL_SENDER
#define VAR_SHOW_UNK_RCPT_TABLE
#define CHECK_HELO_MX_ACL
#define DEF_SMTPD_SND_AUTH_MAPS
char * var_rcpt_canon_maps
#define DEF_PAR_DOM_MATCH
#define CA_ATTR_OVER_STR_TABLE(v)
#define VAR_PERM_MX_NETWORKS
char * var_unk_name_tf_act
bool var_smtpd_rej_unl_rcpt
#define MAIL_ADDR_MAIL_DAEMON
char * var_smtpd_exp_filter
void msg_warn(const char *fmt,...)
#define DEF_SMTPD_PEERNAME_LOOKUP
#define DEF_UNK_CLIENT_CODE
#define MAIL_ATTR_ACT_CLIENT_NAME
char * var_maps_rbl_domains
#define DEF_LOC_RWR_CLIENTS
#define CHECK_REVERSE_CLIENT_MX_ACL
CTABLE * ctable_create(ssize_t limit, CTABLE_CREATE_FN create, CTABLE_DELETE_FN delete, void *context)
#define DEF_SMTPD_SASL_OPTS
#define REJECT_UNKNOWN_ADDRESS
#define MAIL_ERROR_SOFTWARE
void resolve_local_init(void)
#define REJECT_NON_FQDN_RCPT
VSTRING * vstring_alloc(ssize_t len)
#define CHECK_RECIP_MX_ACL
#define VAR_RBL_REPLY_MAPS
#define SMTPD_FLAG_SMTPUTF8
#define REJECT_MUL_RCPT_BOUNCE
#define NAME_CODE_FLAG_NONE
void smtpd_resolve_init(int cache_size)
#define REJECT_NON_FQDN_SENDER
const RESOLVE_REPLY * smtpd_resolve_addr(const char *sender, const char *addr)
#define DEF_SMTPD_REJ_UNL_RCPT
unsigned char * sa_family_list
#define DEF_RCPT_CANON_MAPS
#define MAIL_ATTR_ACT_REVERSE_CLIENT_NAME
int warn_compat_break_relay_restrictions
#define SMTPD_NAME_SENDER
#define VAR_MAP_DEFER_CODE
#define CHECK_CLIENT_MX_ACL
void * htable_find(HTABLE *table, const char *key)
#define DEF_DOUBLE_BOUNCE
#define VAR_MAPS_RBL_CODE
#define MAIL_ATTR_CCERT_PKEY_FPRINT
#define DEF_SMTPD_CLIENT_PORT_LOG
#define CHECK_RELAY_DOMAINS
#define VAR_NON_FQDN_CODE
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
#define VAR_UNV_FROM_RCODE
#define DEF_UNV_RCPT_RCODE
char * var_canonical_maps
#define SMTPD_CHECK_PARSE_ALL
#define SMTPD_CHECK_DUNNO
#define DEF_ALLOW_UNTRUST_ROUTE
#define DEF_VIRT_MAILBOX_DOMS
int var_smtpd_policy_try_limit
#define SEND_ATTR_INT(name, val)
#define VAR_SMTPD_DELAY_REJECT
char * smtpd_check_size(SMTPD_STATE *state, off_t size)
#define MAIL_ATTR_ACT_SERVER_PORT
int name_code(const NAME_CODE *table, int flags, const char *name)
#define VAR_UNK_NAME_TF_ACT
#define VAR_RCPT_CANON_MAPS
#define SMTPD_ACCESS_MAPS
#define SEND_ATTR_LONG(name, val)
int proxy_inet_addr(struct sockaddr *addr)
#define CHECK_SENDER_MX_ACL
NORETURN msg_fatal(const char *fmt,...)
#define VAR_SMTPD_DNS_RE_FILTER
char * var_smtpd_acl_perm_log
#define VAR_PAR_DOM_MATCH
const char * mail_conf_lookup_eval(const char *name)
#define VAR_SMTPD_PROXY_FILT
#define REJECT_INVALID_HELO_HOSTNAME
#define SMTPD_DNXSL_STAT_HARD(dnsxl_res)
SMTPD_DEFER defer_if_reject
#define DEF_LOCAL_RCPT_CODE
#define VAR_LOCAL_RCPT_CODE
char * var_smtpd_relay_ccerts
int dns_rr_compare_pref_any(DNS_RR *, DNS_RR *)
#define DEF_PLAINTEXT_CODE
char * smtpd_check_client(SMTPD_STATE *state)
#define VAR_VERIFY_POLL_COUNT
#define domain_list_init(o, f, p)
#define RESOLVE_CLASS_MASK
#define VAR_SMTPD_REJ_UNL_RCPT
#define VAR_SMTPD_POLICY_TTL
int vstream_fflush(VSTREAM *stream)
#define namadr_list_match
char * var_virt_mailbox_doms
char * var_virt_alias_maps
#define MAIL_SERVICE_RETRY
int defer_if_permit_client
#define VAR_SMTPD_ACL_PERM_LOG
char * concatenate(const char *arg0,...)
#define DEF_UNK_NAME_CODE
char * mystrndup(const char *str, ssize_t len)
#define SMTPD_FLAG_ILL_PIPELINING
#define REJECT_UNKNOWN_CLIENT
#define REJECT_UNKNOWN_HELO_HOSTNAME
#define MAIL_ATTR_RBL_CODE
#define DEFER_IF_PERMIT2(type, state, class, code, dsn, fmt, a1, a2)
ARGV * argv_split(const char *, const char *)
#define MAIL_ATTR_CRYPTO_PROTOCOL
char * var_virt_mailbox_maps
#define REJECT_UNKNOWN_HOSTNAME
#define HAS_MY_ADDR_RETURN(x)
#define DEF_MUL_RCPT_CODE
char * smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
#define MAIL_ATTR_SASL_USERNAME
#define MAIL_ATTR_RCPT_COUNT
VSTRING * smtpd_expand_filter
#define VAR_SMTPD_EXP_FILTER
#define MA_FIND_LOCALPART_AT
#define MAIL_ATTR_CCERT_ISSUER
#define VAR_SMTPD_POLICY_CONTEXT
#define link_override_table_to_variable(table, var)
char * smtpd_check_queue(SMTPD_STATE *state)
#define MAIL_ATTR_INSTANCE
void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *)
#define DEF_SMTPD_DELAY_REJECT
char * ip_match_parse(VSTRING *byte_codes, char *pattern)
int var_smtpd_policy_req_limit
#define SMTPD_NAME_SASL_USER
#define CHECK_REVERSE_CLIENT_NS_ACL
#define RESOLVE_CLASS_RELAY
int var_virt_mailbox_code
#define VAR_SMTPD_POLICY_REQ_LIMIT
#define REJECT_UNVERIFIED_SENDER
#define REJECT_UNKNOWN_RCPTDOM
int strcasecmp(const char *s1, const char *s2)
int attr_clnt_request(ATTR_CLNT *client, int send_flags,...)
#define REJECT_RHSBL_SENDER
#define RESOLVE_CLASS_ALIAS
void resolve_clnt(const char *class, const char *sender, const char *addr, RESOLVE_REPLY *reply)
#define DEF_PERM_MX_NETWORKS
#define DEFER_IF_REJECT3(state, class, code, dsn, fmt, a1, a2, a3)
VSTRING * vstring_vsprintf_append(VSTRING *vp, const char *format, va_list ap)
#define SMTPD_CHECK_REJECT
#define MAIL_ATTR_RBL_DOMAIN
#define DEF_UNV_FROM_DCODE
const char * midna_domain_to_ascii(const char *name)
#define DEF_VIRT_MAILBOX_CODE
#define REJECT_AUTH_SENDER_LOGIN_MISMATCH
#define VAR_VERIFY_SENDER
#define VAR_MYNETWORKS_STYLE
#define MAIL_ERROR_PROTOCOL
#define VAR_SMTPD_POLICY_TMOUT
VSTRING * vstring_free(VSTRING *vp)
char * var_rbl_reply_maps
#define FAKE_RELAY_CHECKS
#define MAIL_ATTR_ETRN_DOMAIN
#define MAIL_ATTR_CCERT_SUBJECT
int var_smtpd_policy_tmout
#define REJECT_UNLISTED_RCPT
#define NOMATCH(map, rcpt)
char * var_smtpd_null_key
char * split_at(char *string, int delimiter)
#define vstream_fileno(vp)
void msg_vstream_init(const char *name, VSTREAM *vp)
DNS_RR * dns_rr_sort(DNS_RR *, int(*)(DNS_RR *, DNS_RR *))
int var_smtpd_uproxy_tmout
#define CHK_ADDR_RETURN(x, y)
#define SMTPD_DNSXL_STAT_OK(dnsxl_res)
#define REJECT_UNVERIFIED_RECIP
#define VAR_PLAINTEXT_CODE
#define PERMIT_MX_BACKUP_RETURN(x)
char * var_proxy_interfaces
#define MAILHOST_LOOKUP_FLAGS
#define DEF_VIRT_ALIAS_CODE
#define REJECT_RHSBL_RECIPIENT
#define MAIL_SERVICE_RELAY
#define VAR_SMTPD_POLICY_IDLE
char * var_unk_addr_tf_act
#define VAR_BAD_NAME_CODE
#define mail_addr_find_strategy(maps, address, extension, strategy)
#define DNS_REQ_FLAG_NONE
#define PERMIT_TLS_CLIENTCERTS
#define DEF_VIRT_MAILBOX_MAPS
#define CHK_ACCESS_RETURN(x, y)
#define MAIL_ATTR_ACT_PROTO_NAME
#define SMTPD_NAME_RECIPIENT
#define DEFER_IF_REJECT4(state, class, code, dsn, fmt, a1, a2, a3, a4)
#define MAIL_ATTR_QUEUEID
#define RESOLVE_CLASS_DEFAULT
#define MAIL_SERVICE_LOCAL
#define CHECK_RECIP_NS_ACL
#define CHECK_RECIP_A_ACL
char * smtpd_check_rewrite(SMTPD_STATE *state)
char * printable(char *string, int replacement)
#define SMTPD_CHECK_MAIL_RETURN(x)
void smtpd_sasl_activate(SMTPD_STATE *, const char *, const char *)
#define DEFER_IF_REJECT2(state, class, code, dsn, fmt, a1, a2)
bool var_smtpd_client_port_log
#define REJECT_NON_FQDN_HOSTNAME
#define DEF_SMTPD_EXP_FILTER
#define PERMIT_INET_INTERFACES
#define SMTPD_PEER_CODE_TEMP
#define VAR_SMTPD_SASL_OPTS
#define REJECT_UNLISTED_SENDER
#define VAR_UNK_CLIENT_CODE
#define DEF_MAP_REJECT_CODE
void smtpd_check_init(void)
int recipient_rcptmap_checked
#define REJECT_UNKNOWN_CLIENT_HOSTNAME
#define SMTPD_NAME_CLIENT
void ctable_free(CTABLE *cache)
#define VAR_SMTPD_SND_AUTH_MAPS
const char * maps_find(MAPS *maps, const char *name, int flags)
void dns_rr_free(DNS_RR *)
#define INET_PROTO_NAME_IPV4
int var_verify_poll_delay
#define VAR_MUL_RCPT_CODE
#define CHECK_SENDER_A_ACL
#define DEL_RCPT_STAT_DEFER
char * var_inet_interfaces
VSTRING * vstring_strncpy(VSTRING *vp, const char *src, ssize_t len)
void fsspace(const char *path, struct fsspace *sp)
char * var_local_rcpt_maps
int smtpd_input_transp_mask
#define VAR_SMTPD_POLICY_TRY_DELAY
#define SEND_ATTR_STR(name, val)
char * split_at_right(char *string, int delimiter)
#define REJECT_UNKNOWN_SENDDOM
#define dns_lookup(name, type, rflags, list, fqdn, why)
#define MAIL_ATTR_POL_CONTEXT
#define DEF_UNV_RCPT_DCODE
#define DEF_REJECT_TMPF_ACT
#define REJECT_RBL_CLIENT
char * var_smtpd_policy_def_action
#define DEF_RELAY_RCPT_MAPS
char * var_smtpd_uproxy_proto
#define REJECT_PLAINTEXT_SESSION
#define VAR_LOC_RWR_CLIENTS
char * var_mynetworks_style
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
#define CHECK_CLIENT_NS_ACL
char * vstring_export(VSTRING *vp)
#define REJECT_KNOWN_SENDER_LOGIN_MISMATCH
#define REJECT_RHSBL_CLIENT
struct sockaddr_storage sockaddr
#define DEF_DEF_RBL_REPLY
#define VAR_RELAY_RCPT_MAPS
void dns_rr_filter_compile(const char *, const char *)
#define DEF_SEND_CANON_MAPS
#define SMTPD_PEER_CODE_OK
#define PERMIT_MYNETWORKS
#define RECV_ATTR_STR(name, val)
void * mymalloc(ssize_t len)
#define REJECT_UNAUTH_PIPE
void argv_terminate(ARGV *argvp)
#define DEF_SMTPD_POLICY_TTL
#define SMTPD_CHECK_RCPT_RETURN(x)
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
void msg_info(const char *fmt,...)
void smtpd_state_reset(SMTPD_STATE *)
#define VAR_VIRT_MAILBOX_CODE
#define namadr_list_init(o, f, p)
#define VAR_VIRT_ALIAS_CODE