From 6ff2c5cf25f426bd43d0abb45acebc5adf562ac7 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Mon, 22 Mar 1999 00:00:00 -0500 Subject: [PATCH] snapshot-19990322 --- postfix/HISTORY | 34 +++++++++++++ postfix/RELEASE_NOTES | 18 +++++-- postfix/global/mail_params.h | 2 + postfix/global/mail_version.h | 2 +- postfix/html/uce.html | 23 ++++++--- postfix/makedefs | 4 +- postfix/master/multi_server.c | 20 -------- postfix/master/single_server.c | 18 ------- postfix/master/trigger_server.c | 18 ------- postfix/smtpd/smtpd.c | 34 +++++++------ postfix/smtpd/smtpd_check.c | 16 +++++- postfix/smtpd/smtpd_check.in2 | 10 ++++ postfix/smtpd/smtpd_check.ref2 | 19 +++++++ postfix/util/Makefile.in | 27 ++++++---- postfix/util/sendfd_test | Bin 140840 -> 0 bytes postfix/util/stream_connect.c | 45 ++++++++-------- postfix/util/stream_listen.c | 48 +++--------------- postfix/util/{sendfd_test.c => stream_test.c} | 41 +++++++-------- 18 files changed, 197 insertions(+), 182 deletions(-) delete mode 100755 postfix/util/sendfd_test rename postfix/util/{sendfd_test.c => stream_test.c} (64%) diff --git a/postfix/HISTORY b/postfix/HISTORY index 136a2c58c..f6750e5d3 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -2371,6 +2371,40 @@ Apologies for any names omitted. Bugfix: \username was broken. Frank Dziuba was the first to notice. +19990321 + + Workaround: from now on, Postfix on Solaris uses stream + pipes instead of UNIX-domain sockets. Despite workarounds, + the latter were causing more trouble than anything else on + all systems combined. + +19990322 + + Portability: the makedefs would mis-identify IRIX 6.5.x as + IRIX 5.x. Fix by Brian Truelsen of Maersk Mc-Kinney Moller + Institute for Production Technology, Denmark. + + Feature: reject_unknown_recipient_domain restriction for + recipient addresses. For the sake of symmetry, we now also + have reject_unknown_sender_domain. This means the old + reject_unknown_address restriction is being phased out. + Suggested by Rask Ingemann Lambertsen [XXX affiliation to + be determined]. + + Feature: unknown sender/recipient domain restrictions now + distinguish between soft errors (always: 450) and hard + errors (configurable with the unknown_address_reject_code + parameter, default: 450; use 550 at your own risk). + + Feature: no HELO junk mail restrictions means that no syntax + check will be done on HELO/EHLO hostname arguments. + + Bugfix: the initial Solaris workaround for UNIX-domain + sockets could cause the queue manager to block if Postfix + ran into a delivery agent process limit. After another code + rewrite that problem is eliminated. Thanks to Chris + Cappuccio, Empire Net, for assistance with testing. + Future: Planned: must be able to list the same hash table in diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 712ed3c0c..2a484bf80 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,5 +1,15 @@ -Incompatible changes with postfix-alpha-19990317: -================================================= +Major changes with snapshot-19990322: +===================================== + +- The UNIX-domain socket workaround for Solaris was fixed +after one day of review. More testing is welcome. + +- reject_unknown_{sender,recipient}_domain restrictions that +distinguish between hard (always 450) and soft (configurable, +default 450) lookup errors. + +Incompatible changes with postfix-19990317: +=========================================== - You MUST install the new version of /etc/postfix/postfix-script. @@ -7,8 +17,8 @@ Incompatible changes with postfix-alpha-19990317: MUST specify the R flag in order to generate a Return-Path: message header (as needed by, for example, cyrus). -Major changes since postfix-beta-19990122-pl01: -=============================================== +Major changes with postfix-19990317: +==================================== A detailed record of changes is given in the HISTORY file. diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index 420267830..b18de0e08 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -704,6 +704,8 @@ extern int var_unk_name_code; #define DEF_NON_FQDN_CODE 504 extern int var_non_fqdn_code; +#define REJECT_UNKNOWN_SENDDOM "reject_unknown_sender_domain" +#define REJECT_UNKNOWN_RCPTDOM "reject_unknown_recipient_domain" #define REJECT_UNKNOWN_ADDRESS "reject_unknown_address" #define VAR_UNK_ADDR_CODE "unknown_address_reject_code" #define DEF_UNK_ADDR_CODE 450 diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index 028e1e36b..5164dfe05 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-19990321" +#define DEF_MAIL_VERSION "Snapshot-19990322" extern char *var_mail_version; /* LICENSE diff --git a/postfix/html/uce.html b/postfix/html/uce.html index 86c81d8ed..8a93bbf86 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -353,7 +353,7 @@ network address.
Example: -
smtpd_sender_restrictions = reject_unknown_address +
smtpd_sender_restrictions = reject_unknown_sender_domain

@@ -361,12 +361,13 @@ network address.

- + -
reject_unknown_address
Reject the request when -the sender mail address has no DNS A or MX record. The +
reject_unknown_sender_domain
Reject the request +when the sender mail address has no DNS A or MX record. The unknown_address_reject_code parameter specifies the response -code for rejected requests (default: 450). +code for rejected requests (default: 450). The response +is always 450 in case of a temporary DNS error.

@@ -506,6 +507,16 @@ for rejected requests (default: 550).

+ + +

reject_unknown_recipient_domain
Reject the request +when the recipient mail address has no DNS A or MX record. The +unknown_address_reject_code parameter specifies the response +code for rejected requests (default: 450). The response +is always 450 in case of a temporary DNS error. + +

+

reject_non_fqdn_recipient
Reject the request when @@ -515,7 +526,7 @@ response code to rejected requests (default: 504).

-

reject_unknown_address +
reject_unknown_sender_domain
reject_non_fqdn_sender diff --git a/postfix/makedefs b/postfix/makedefs index 61274aebf..49512a2ee 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -137,12 +137,12 @@ case "$SYSTEM.$RELEASE" in CCARGS="$CCARGS -DPATH_DB_H=''" fi ;; - IRIX*.5*) SYSTYPE=IRIX5 + IRIX*.5.*) SYSTYPE=IRIX5 # Use the native compiler by default : ${CC=cc} RANLIB=echo ;; - IRIX*.6*) SYSTYPE=IRIX6 + IRIX*.6.*) SYSTYPE=IRIX6 # Use the native compiler by default, and allow nested comments. : ${CC="cc -woff 1009,1116,1412"} RANLIB=echo diff --git a/postfix/master/multi_server.c b/postfix/master/multi_server.c index 4fcad413c..3ec04e42a 100644 --- a/postfix/master/multi_server.c +++ b/postfix/master/multi_server.c @@ -133,10 +133,8 @@ #include #include #include -#ifndef NO_SELECT_COLLISION #include #include -#endif #include /* Global library. */ @@ -167,12 +165,8 @@ static char *multi_server_name; static char **multi_server_argv; static void (*multi_server_accept) (int, char *); static void (*multi_server_onexit) (void); - -#ifndef NO_SELECT_COLLISION static VSTREAM *multi_server_lock; -#endif - /* multi_server_exit - normal termination */ static NORETURN multi_server_exit(void) @@ -231,11 +225,9 @@ static void multi_server_execute(int unused_event, char *context) { VSTREAM *stream = (VSTREAM *) context; -#ifndef NO_SELECT_COLLISION if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif /* * Do not bother the application when the client disconnected. @@ -290,11 +282,9 @@ static void multi_server_accept_local(int unused_event, char *context) time_left = event_cancel_timer(multi_server_timeout, (char *) 0); fd = LOCAL_ACCEPT(listen_fd); -#ifndef NO_SELECT_COLLISION if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (fd < 0) { if (errno != EAGAIN) msg_fatal("accept connection: %m"); @@ -331,11 +321,9 @@ static void multi_server_accept_inet(int unused_event, char *context) time_left = event_cancel_timer(multi_server_timeout, (char *) 0); fd = inet_accept(listen_fd); -#ifndef NO_SELECT_COLLISION if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (fd < 0) { if (errno != EAGAIN) msg_fatal("accept connection: %m"); @@ -366,12 +354,8 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) MAIL_SERVER_LOOP_FN loop = 0; int key; char *transport = 0; - -#ifndef NO_SELECT_COLLISION char *lock_path; VSTRING *why; - -#endif int alone = 0; /* @@ -519,7 +503,6 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) * Illustrated volume 2 page 532. We avoid select() collisions with an * external lock file. */ -#ifndef NO_SELECT_COLLISION if (stream == 0 && !alone) { lock_path = concatenate(DEF_PID_DIR, "/", transport, ".", service_name, (char *) 0); @@ -531,7 +514,6 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) myfree(lock_path); vstring_free(why); } -#endif /* * Run pre-jail initialization. @@ -587,11 +569,9 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC); while (var_use_limit == 0 || use_count < var_use_limit || client_count > 0) { delay = loop ? loop() : -1; -#ifndef NO_SELECT_COLLISION if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), MYFLOCK_EXCLUSIVE) < 0) msg_fatal("select lock: %m"); -#endif event_loop(delay); } multi_server_exit(); diff --git a/postfix/master/single_server.c b/postfix/master/single_server.c index eca04871d..cee0426bb 100644 --- a/postfix/master/single_server.c +++ b/postfix/master/single_server.c @@ -124,10 +124,8 @@ #include #include #include -#ifndef NO_SELECT_COLLISION #include #include -#endif #include /* Global library. */ @@ -157,12 +155,8 @@ static char *single_server_name; static char **single_server_argv; static void (*single_server_accept) (int, char *); static void (*single_server_onexit) (void); - -#ifndef NO_SELECT_COLLISION static VSTREAM *single_server_lock; -#endif - /* single_server_exit - normal termination */ static NORETURN single_server_exit(void) @@ -258,11 +252,9 @@ static void single_server_accept_local(int unused_event, char *context) time_left = event_cancel_timer(single_server_timeout, (char *) 0); fd = LOCAL_ACCEPT(listen_fd); -#ifndef NO_SELECT_COLLISION if (single_server_lock != 0 && myflock(vstream_fileno(single_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (fd < 0) { if (errno != EAGAIN) msg_fatal("accept connection: %m"); @@ -297,11 +289,9 @@ static void single_server_accept_inet(int unused_event, char *context) time_left = event_cancel_timer(single_server_timeout, (char *) 0); fd = inet_accept(listen_fd); -#ifndef NO_SELECT_COLLISION if (single_server_lock != 0 && myflock(vstream_fileno(single_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (fd < 0) { if (errno != EAGAIN) msg_fatal("accept connection: %m"); @@ -332,12 +322,8 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) MAIL_SERVER_LOOP_FN loop = 0; int key; char *transport = 0; - -#ifndef NO_SELECT_COLLISION char *lock_path; VSTRING *why; - -#endif int alone = 0; /* @@ -485,7 +471,6 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) * Illustrated volume 2 page 532. We avoid select() collisions with an * external lock file. */ -#ifndef NO_SELECT_COLLISION if (stream == 0 && !alone) { lock_path = concatenate(DEF_PID_DIR, "/", transport, ".", service_name, (char *) 0); @@ -497,7 +482,6 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) myfree(lock_path); vstring_free(why); } -#endif /* * Run pre-jail initialization. @@ -553,11 +537,9 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC); while (var_use_limit == 0 || use_count < var_use_limit) { delay = loop ? loop() : -1; -#ifndef NO_SELECT_COLLISION if (single_server_lock != 0 && myflock(vstream_fileno(single_server_lock), MYFLOCK_EXCLUSIVE) < 0) msg_fatal("select lock: %m"); -#endif event_loop(delay); } single_server_exit(); diff --git a/postfix/master/trigger_server.c b/postfix/master/trigger_server.c index 261a9dabc..245780c70 100644 --- a/postfix/master/trigger_server.c +++ b/postfix/master/trigger_server.c @@ -132,10 +132,8 @@ #include #include #include -#ifndef NO_SELECT_COLLISION #include #include -#endif #include /* Global library. */ @@ -164,12 +162,8 @@ static char *trigger_server_name; static char **trigger_server_argv; static void (*trigger_server_accept) (int, char *); static void (*trigger_server_onexit) (void); - -#ifndef NO_SELECT_COLLISION static VSTREAM *trigger_server_lock; -#endif - /* trigger_server_exit - normal termination */ static NORETURN trigger_server_exit(void) @@ -239,11 +233,9 @@ static void trigger_server_accept_fifo(int unused_event, char *context) char *myname = "trigger_server_accept_fifo"; int listen_fd = (int) context; -#ifndef NO_SELECT_COLLISION if (trigger_server_lock != 0 && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (msg_verbose) msg_info("%s: trigger arrived", myname); @@ -291,11 +283,9 @@ static void trigger_server_accept_local(int unused_event, char *context) time_left = event_cancel_timer(trigger_server_timeout, (char *) 0); fd = LOCAL_ACCEPT(listen_fd); -#ifndef NO_SELECT_COLLISION if (trigger_server_lock != 0 && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_NONE) < 0) msg_fatal("select unlock: %m"); -#endif if (fd < 0) { if (errno != EAGAIN) msg_fatal("accept connection: %m"); @@ -333,12 +323,8 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. char buf[TRIGGER_BUF_SIZE]; int len; char *transport = 0; - -#ifndef NO_SELECT_COLLISION char *lock_path; VSTRING *why; - -#endif int alone = 0; /* @@ -500,7 +486,6 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. * Illustrated volume 2 page 532. We avoid select() collisions with an * external lock file. */ -#ifndef NO_SELECT_COLLISION if (stream == 0 && !alone) { lock_path = concatenate(DEF_PID_DIR, "/", transport, ".", service_name, (char *) 0); @@ -512,7 +497,6 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. myfree(lock_path); vstring_free(why); } -#endif /* * Run pre-jail initialization. @@ -565,11 +549,9 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC); while (var_use_limit == 0 || use_count < var_use_limit) { delay = loop ? loop() : -1; -#ifndef NO_SELECT_COLLISION if (trigger_server_lock != 0 && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_EXCLUSIVE) < 0) msg_fatal("select lock: %m"); -#endif event_loop(delay); } trigger_server_exit(); diff --git a/postfix/smtpd/smtpd.c b/postfix/smtpd/smtpd.c index 5f57eced0..e3689662d 100644 --- a/postfix/smtpd/smtpd.c +++ b/postfix/smtpd/smtpd.c @@ -280,13 +280,26 @@ char *var_always_bcc; */ char *smtpd_path; +/* collapse_args - put arguments together again */ + +static void collapse_args(int argc, SMTPD_TOKEN *argv) +{ + int i; + + for (i = 2; i < argc; i++) { + vstring_strcat(argv[1].vstrval, " "); + vstring_strcat(argv[1].vstrval, argv[i].strval); + } + argv[1].strval = vstring_str(argv[1].vstrval); +} + /* helo_cmd - process HELO command */ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { char *err; - if (argc != 2) { + if (argc < 2) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Syntax: HELO hostname"); return (-1); @@ -296,6 +309,7 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "503 Duplicate HELO/EHLO"); return (-1); } + collapse_args(argc, argv); if (SMTPD_STAND_ALONE(state) == 0 && (err = smtpd_check_helo(state, argv[1].strval)) != 0) { smtpd_chat_reply(state, "%s", err); @@ -313,7 +327,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { char *err; - if (argc != 2) { + if (argc < 2) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Syntax: EHLO hostname"); return (-1); @@ -323,6 +337,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "503 Error: duplicate HELO/EHLO"); return (-1); } + collapse_args(argc, argv); if (SMTPD_STAND_ALONE(state) == 0 && (err = smtpd_check_helo(state, argv[1].strval)) != 0) { smtpd_chat_reply(state, "%s", err); @@ -758,9 +773,7 @@ static int noop_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { - VSTRING *buf; char *err = 0; - int i; /* * The SMTP standard (RFC 821) disallows unquoted special characters in @@ -772,18 +785,9 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "501 Syntax: VRFY address"); return (-1); } - - /* - * Yuck. All input is tokenized. Now put it back together again. - */ - buf = vstring_alloc(100); - for (i = 1; i < argc; i++) { - vstring_strcat(buf, " "); - vstring_strcat(buf, argv[i].strval); - } + collapse_args(argc, argv); if (SMTPD_STAND_ALONE(state) == 0) - err = smtpd_check_rcpt(state, vstring_str(buf)); - vstring_free(buf); + err = smtpd_check_rcpt(state, argv[1].strval); /* * End untokenize. diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c index c59fe1e92..6c1b2f916 100644 --- a/postfix/smtpd/smtpd_check.c +++ b/postfix/smtpd/smtpd_check.c @@ -108,11 +108,16 @@ /* Reject the request when the HELO/EHLO hostname has no A or MX record. /* The \fIunknown_hostname_reject_code\fR configuration /* parameter specifies the reject status code (default: 450). -/* .IP reject_unknown_address +/* .IP reject_unknown_sender_domain /* Reject the request when the resolved sender address has no /* DNS A or MX record. /* The \fIunknown_address_reject_code\fR configuration parameter /* specifies the reject status code (default: 450). +/* .IP reject_unknown_recipient_domain +/* Reject the request when the resolved recipient address has no +/* DNS A or MX record. +/* The \fIunknown_address_reject_code\fR configuration parameter +/* specifies the reject status code (default: 450). /* .IP check_relay_domains /* Allow the request when either the client hostname or the resolved /* recipient domain matches the \fIrelay_domains\fR configuration @@ -577,7 +582,8 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name) if (dns_status != DNS_OK) return (smtpd_check_reject(state, MAIL_ERROR_POLICY, "%d <%s>: Domain not found", - var_unk_addr_code, name)); + dns_status == DNS_NOTFOUND ? + var_unk_addr_code : 450, name)); return (SMTPD_CHECK_DUNNO); } @@ -1197,6 +1203,10 @@ static int generic_checks(SMTPD_STATE *state, char *name, *status = reject_unknown_address(state, state->sender); return (1); } + if (strcasecmp(name, REJECT_UNKNOWN_SENDDOM) == 0) { + *status = reject_unknown_address(state, state->sender); + return (1); + } if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) { if (*state->sender) *status = reject_non_fqdn_address(state, state->sender); @@ -1336,6 +1346,8 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) status = permit_mx_backup(state, recipient); } else if (strcasecmp(name, CHECK_RELAY_DOMAINS) == 0) { status = check_relay_domains(state, recipient); + } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) { + status = reject_unknown_address(state, recipient); } else if (strcasecmp(name, REJECT_NON_FQDN_RCPT) == 0) { status = reject_non_fqdn_address(state, recipient); } else if (generic_checks(state, name, &cpp, &status, recipient) == 0) { diff --git a/postfix/smtpd/smtpd_check.in2 b/postfix/smtpd/smtpd_check.in2 index 467251307..f779a6e91 100644 --- a/postfix/smtpd/smtpd_check.in2 +++ b/postfix/smtpd/smtpd_check.in2 @@ -83,3 +83,13 @@ mail foo@friend.bad.domain client_restrictions reject_maps_rbl client spike.porcupine.org 168.100.189.2 client foo 127.0.0.2 +# +# unknown sender/recipient domain +# +unknown_address_reject_code 550 +recipient_restrictions reject_unknown_recipient_domain,reject_unknown_sender_domain +mail wietse@porcupine.org +rcpt wietse@porcupine.org +rcpt wietse@no.recipient.domain +mail wietse@no.sender.domain +rcpt wietse@porcupine.org diff --git a/postfix/smtpd/smtpd_check.ref2 b/postfix/smtpd/smtpd_check.ref2 index 78b1f2bda..8009cdb2e 100644 --- a/postfix/smtpd/smtpd_check.ref2 +++ b/postfix/smtpd/smtpd_check.ref2 @@ -172,3 +172,22 @@ OK >>> client foo 127.0.0.2 ./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com 550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com +>>> # +>>> # unknown sender/recipient domain +>>> # +>>> unknown_address_reject_code 550 +OK +>>> recipient_restrictions reject_unknown_recipient_domain,reject_unknown_sender_domain +OK +>>> mail wietse@porcupine.org +OK +>>> rcpt wietse@porcupine.org +OK +>>> rcpt wietse@no.recipient.domain +./smtpd_check: reject: RCPT from foo[127.0.0.2]: 550 : Domain not found +550 : Domain not found +>>> mail wietse@no.sender.domain +OK +>>> rcpt wietse@porcupine.org +./smtpd_check: reject: RCPT from foo[127.0.0.2]: 550 : Domain not found +550 : Domain not found diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in index 0c332472c..b9e7a1268 100644 --- a/postfix/util/Makefile.in +++ b/postfix/util/Makefile.in @@ -55,7 +55,8 @@ HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \ vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \ dict_unix.h dict_pcre.h -TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c +TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ + stream_test.c WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ -Wunused @@ -68,7 +69,7 @@ TESTPROG= dict_open events exec_command fifo_open fifo_rdonly_bug \ fifo_rdwr_bug fifo_trigger fsspace fullname inet_addr_host \ inet_addr_local mac_parse make_dirs msg_syslog \ mystrtok peer_name sigdelay translit valid_hostname vstream_popen \ - vstring vstring_vstream doze select_bug + vstring vstring_vstream doze select_bug stream_test LIB_DIR = ../lib INC_DIR = ../include @@ -237,6 +238,9 @@ depend: $(MAKES) done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in @make Makefile +stream_test: stream_test.c $(LIB) + $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS) + tests: valid_hostname_test valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref @@ -664,15 +668,6 @@ select_bug.o: msg.h select_bug.o: vstream.h select_bug.o: vbuf.h select_bug.o: msg_vstream.h -sendfd_test.o: sendfd_test.c -sendfd_test.o: sys_defs.h -sendfd_test.o: sendfd_test.c -sendfd_test.o: iostuff.h -sendfd_test.o: msg.h -sendfd_test.o: msg_vstream.h -sendfd_test.o: vstream.h -sendfd_test.o: vbuf.h -sendfd_test.o: listen.h set_eugid.o: set_eugid.c set_eugid.o: sys_defs.h set_eugid.o: msg.h @@ -707,6 +702,16 @@ stream_listen.o: sys_defs.h stream_listen.o: msg.h stream_listen.o: listen.h stream_listen.o: iostuff.h +stream_test.o: stream_test.c +stream_test.o: sys_defs.h +stream_test.o: stream_test.c +stream_test.o: iostuff.h +stream_test.o: msg.h +stream_test.o: msg_vstream.h +stream_test.o: vstream.h +stream_test.o: vbuf.h +stream_test.o: listen.h +stream_test.o: connect.h stream_trigger.o: stream_trigger.c stream_trigger.o: sys_defs.h stream_trigger.o: msg.h diff --git a/postfix/util/sendfd_test b/postfix/util/sendfd_test deleted file mode 100755 index 20900647e105945b1402fb543588258a5d9e5d72..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 140840 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 diff --git a/postfix/util/stream_connect.c b/postfix/util/stream_connect.c index f15dea51b..be270c93d 100644 --- a/postfix/util/stream_connect.c +++ b/postfix/util/stream_connect.c @@ -41,10 +41,16 @@ /* System library. */ #include + +#ifdef STREAM_CONNECTIONS + #include #include #include #include +#include + +#endif /* Utility library. */ @@ -57,46 +63,41 @@ int stream_connect(const char *path, int block_mode, int unused_timeout) { #ifdef STREAM_CONNECTIONS char *myname = "stream_connect"; - struct stat st; - int fd; - int flags; + int pair[2]; + int fifo; /* * The requested file system object must exist, otherwise we can't reach * the server. */ - if (block_mode == NON_BLOCKING) - flags = O_RDWR | O_NONBLOCK; - else - flags = O_RDWR; - if ((fd = open(path, flags, 0)) < 0) + if ((fifo = open(path, O_WRONLY | O_NONBLOCK, 0)) < 0) return (-1); /* - * XXX Horror. If the open() result is a regular file, no server was - * listening. In this case we simulate what would have happened with - * UNIX-domain sockets. + * Create a pipe, and send one pipe end to the server. */ - if (fstat(fd, &st) < 0) - msg_fatal("%s: fstat: %m", myname); - if (S_ISREG(st.st_mode)) { - close(fd); - errno = ECONNREFUSED; - return (-1); - } + if (pipe(pair) < 0) + msg_fatal("%s: pipe: %m", myname); + if (ioctl(fifo, I_SENDFD, pair[1]) < 0) + msg_fatal("%s: send file descriptor: %m", myname); + close(pair[1]); /* * This is for {unix,inet}_connect() compatibility. */ if (block_mode == NON_BLOCKING) - non_blocking(fd, NON_BLOCKING); + non_blocking(pair[0], NON_BLOCKING); /* - * No trouble detected, so far. + * Cleanup. */ - return (fd); + close(fifo); + + /* + * Keep the other end of the pipe. + */ + return (pair[0]); #else msg_fatal("stream connections are not implemented"); #endif } - diff --git a/postfix/util/stream_listen.c b/postfix/util/stream_listen.c index 0c71c8451..dbbe1a095 100644 --- a/postfix/util/stream_listen.c +++ b/postfix/util/stream_listen.c @@ -29,16 +29,13 @@ /* .IP backlog /* This argument exists for compatibility and is ignored. /* .IP block_mode -/* This argument exists for compatibility and is ignored. -/* blocking mode. +/* Either NON_BLOCKING or BLOCKING. This does not affect the +/* mode of accepted connections. /* .IP fd /* File descriptor returned by stream_listen(). /* DIAGNOSTICS /* Fatal errors: stream_listen() aborts upon any system call failure. /* stream_accept() leaves all error handling up to the caller. -/* BUGS -/* This implementation leaks one file descriptor. This is fixed when -/* endpoints become objects rather than file descriptors. /* LICENSE /* .ad /* .fi @@ -71,46 +68,15 @@ /* stream_listen - create stream listener */ -int stream_listen(const char *path, int unused_backlog, -int unused_block_mode) +int stream_listen(const char *path, int unused_backlog, int block_mode) { #ifdef STREAM_CONNECTIONS - char *myname = "stream_listen"; - static int pair[2]; - int fd; - - /* - * Initialize: create the specified endpoint with the right permissions. - */ -#define PERMS 0666 - if (unlink(path) && errno != ENOENT) - msg_fatal("%s: remove %s: %m", myname, path); - if ((fd = open(path, PERMS, O_CREAT | O_TRUNC | O_WRONLY)) < 0) - msg_fatal("%s: create file %s: %m", myname, path); - if (fchmod(fd, PERMS) < 0) - msg_fatal("%s: chmod 0%o: %m", myname, PERMS); - if (close(fd) < 0) - msg_fatal("%s: close file %s: %m", myname, path); /* - * Associate one pipe end with the file just created. See: Richard - * Stevens, Advanced Programming in the UNIX Environment Ch. 15.5.1 - * - * On Solaris 2.4/SPARC, this gives us a "listen queue" of some 460 - * connections. + * We can't specify a listen backlog, however, sending file descriptors + * across a FIFO gives us a backlog buffer of 460 on Solaris 2.4/SPARC. */ - if (pipe(pair) < 0) - msg_fatal("%s: create pipe: %m", myname); - if (ioctl(pair[1], I_PUSH, "connld") < 0) - msg_fatal("%s: push connld module: %m", myname); - if (fattach(pair[1], path) < 0) - msg_fatal("%s: fattach %s: %m", myname, path); - - /* - * Return one end, and leak the other. This will be fixed when all - * endpoints are objects instead of bare file descriptors. - */ - return (pair[0]); + return (fifo_listen(path, 0666, block_mode)); #else msg_fatal("stream connections are not implemented"); #endif @@ -131,6 +97,6 @@ int stream_accept(int fd) return (-1); return (fdinfo.fd); #else - msg_fatal("stream connections are not implemented"); + msg_fatal("stream connections are not implemented"); #endif } diff --git a/postfix/util/sendfd_test.c b/postfix/util/stream_test.c similarity index 64% rename from postfix/util/sendfd_test.c rename to postfix/util/stream_test.c index d7b148142..1d51f31f4 100644 --- a/postfix/util/sendfd_test.c +++ b/postfix/util/stream_test.c @@ -9,6 +9,7 @@ #include "msg.h" #include "msg_vstream.h" #include "listen.h" +#include "connect.h" #define FIFO "/tmp/test-fifo" @@ -33,9 +34,9 @@ static NORETURN usage(void) main(int argc, char **argv) { - struct strrecvfd fdinfo; int server_fd; int client_fd; + int fd; int print_fstats = 0; int count = 1; int ch; @@ -63,43 +64,39 @@ main(int argc, char **argv) break; } } - server_fd = fifo_listen(FIFO, 0600, NON_BLOCKING); + server_fd = stream_listen(FIFO, 0, 0); if (readable(server_fd)) msg_fatal("server fd is readable after create"); /* * Connect in client. */ - if ((client_fd = open(FIFO, O_RDWR, NON_BLOCKING)) < 0) - msg_fatal("open %s as client: %m", FIFO); - if (readable(server_fd)) - msg_warn("server fd is readable after client open"); - if (print_fstats) - print_fstat(0); - if (ioctl(client_fd, I_RECVFD, &fdinfo) < 0) - msg_fatal("receive fd: %m"); for (i = 0; i < count; i++) { - msg_info("send attempt %d", i); - while (!writable(client_fd)) - msg_info("wait for client fd to become writable"); - if (ioctl(client_fd, I_SENDFD, 0) < 0) - msg_fatal("send fd to server: %m"); + msg_info("connect attempt %d", i); + if ((client_fd = stream_connect(FIFO, 0, 0)) < 0) + msg_fatal("open %s as client: %m", FIFO); + if (readable(server_fd)) + msg_info("server fd is readable after client open"); + if (close(client_fd) < 0) + msg_fatal("close client fd: %m"); } - if (close(client_fd) < 0) - msg_fatal("close client fd: %m"); /* * Accept in server. */ for (i = 0; i < count; i++) { msg_info("receive attempt %d", i); - while (!readable(server_fd)) - msg_info("wait for server fd to become writable"); - if (ioctl(server_fd, I_RECVFD, &fdinfo) < 0) + if (!readable(server_fd)) { + msg_info("wait for server fd to become readable"); + read_wait(server_fd, -1); + } + if ((fd = stream_accept(server_fd)) < 0) msg_fatal("receive fd: %m"); if (print_fstats) - print_fstat(fdinfo.fd); - if (close(fdinfo.fd) < 0) + print_fstat(fd); + if (close(fd) < 0) msg_fatal("close received fd: %m"); } + if (close(server_fd) < 0) + msg_fatal("close server fd"); } -- 2.47.3