mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 18:07:41 +00:00
postfix-2.7-20090603
This commit is contained in:
parent
0e408b8ff3
commit
7e11e3103a
@ -15268,3 +15268,13 @@ Apologies for any names omitted.
|
|||||||
and broke reject_unauthenticated_sender_login_mismatch and
|
and broke reject_unauthenticated_sender_login_mismatch and
|
||||||
reject_sender_login_mismatch. Based on fix by Victor
|
reject_sender_login_mismatch. Based on fix by Victor
|
||||||
Duchovni. File: smtpd/smtpd_check.c.
|
Duchovni. File: smtpd/smtpd_check.c.
|
||||||
|
|
||||||
|
20090603
|
||||||
|
|
||||||
|
Cleanup: Postfix 2.3 adopted a file descriptor passing
|
||||||
|
workaround for OpenBSD. This workaround was hard-coded for
|
||||||
|
all platforms because there were no have adverse effects.
|
||||||
|
This is no longer the case: OpenBSD is fixed, and NetBSD
|
||||||
|
does not like the workaround. We now default back to the
|
||||||
|
non-workaround code and turn on the workaround dynamically.
|
||||||
|
Files: util/unix_send_fd.c, unix_recv_fd.c, unix_pass_fd_fix.c.
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20090528"
|
#define MAIL_RELEASE_DATE "20090603"
|
||||||
#define MAIL_VERSION_NUMBER "2.7"
|
#define MAIL_VERSION_NUMBER "2.7"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -31,7 +31,8 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
|
|||||||
vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
|
vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
|
||||||
write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \
|
write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \
|
||||||
allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
|
allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
|
||||||
upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c
|
upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \
|
||||||
|
unix_pass_fd_fix.c
|
||||||
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||||
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
||||||
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
||||||
@ -64,7 +65,8 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
|||||||
vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
|
vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
|
||||||
write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \
|
write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \
|
||||||
allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
|
allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
|
||||||
upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o
|
upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \
|
||||||
|
unix_pass_fd_fix.o
|
||||||
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
||||||
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
|
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
|
||||||
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
|
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
|
||||||
@ -86,7 +88,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
|||||||
vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
|
vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
|
||||||
edit_file.h
|
edit_file.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 dup2_pass_on_exec.c
|
stream_test.c dup2_pass_on_exec.c test_send_fd test_recv_fd
|
||||||
DEFS = -I. -D$(SYSTYPE)
|
DEFS = -I. -D$(SYSTYPE)
|
||||||
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
||||||
FILES = Makefile $(SRCS) $(HDRS)
|
FILES = Makefile $(SRCS) $(HDRS)
|
||||||
@ -101,7 +103,8 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
|||||||
inet_addr_list attr_print64 attr_scan64 base64_code attr_print0 \
|
inet_addr_list attr_print64 attr_scan64 base64_code attr_print0 \
|
||||||
attr_scan0 host_port attr_scan_plain attr_print_plain htable \
|
attr_scan0 host_port attr_scan_plain attr_print_plain htable \
|
||||||
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
|
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
|
||||||
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv
|
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
|
||||||
|
test_send_fd test_recv_fd
|
||||||
|
|
||||||
LIB_DIR = ../../lib
|
LIB_DIR = ../../lib
|
||||||
INC_DIR = ../../include
|
INC_DIR = ../../include
|
||||||
@ -568,8 +571,8 @@ argv.o: mymalloc.h
|
|||||||
argv.o: sys_defs.h
|
argv.o: sys_defs.h
|
||||||
argv_split.o: argv.h
|
argv_split.o: argv.h
|
||||||
argv_split.o: argv_split.c
|
argv_split.o: argv_split.c
|
||||||
argv_split.o: mymalloc.h
|
|
||||||
argv_split.o: msg.h
|
argv_split.o: msg.h
|
||||||
|
argv_split.o: mymalloc.h
|
||||||
argv_split.o: stringops.h
|
argv_split.o: stringops.h
|
||||||
argv_split.o: sys_defs.h
|
argv_split.o: sys_defs.h
|
||||||
argv_split.o: vbuf.h
|
argv_split.o: vbuf.h
|
||||||
@ -1552,6 +1555,12 @@ unix_listen.o: msg.h
|
|||||||
unix_listen.o: sane_accept.h
|
unix_listen.o: sane_accept.h
|
||||||
unix_listen.o: sys_defs.h
|
unix_listen.o: sys_defs.h
|
||||||
unix_listen.o: unix_listen.c
|
unix_listen.o: unix_listen.c
|
||||||
|
unix_pass_fd_fix.o: iostuff.h
|
||||||
|
unix_pass_fd_fix.o: name_mask.h
|
||||||
|
unix_pass_fd_fix.o: sys_defs.h
|
||||||
|
unix_pass_fd_fix.o: unix_pass_fd_fix.c
|
||||||
|
unix_pass_fd_fix.o: vbuf.h
|
||||||
|
unix_pass_fd_fix.o: vstring.h
|
||||||
unix_recv_fd.o: iostuff.h
|
unix_recv_fd.o: iostuff.h
|
||||||
unix_recv_fd.o: msg.h
|
unix_recv_fd.o: msg.h
|
||||||
unix_recv_fd.o: sys_defs.h
|
unix_recv_fd.o: sys_defs.h
|
||||||
|
@ -45,6 +45,12 @@ extern void set_inet_windowsize(int, int);
|
|||||||
#define CLOSE_ON_EXEC 1
|
#define CLOSE_ON_EXEC 1
|
||||||
#define PASS_ON_EXEC 0
|
#define PASS_ON_EXEC 0
|
||||||
|
|
||||||
|
extern int unix_pass_fd_fix;
|
||||||
|
extern void set_unix_pass_fd_fix(const char *);
|
||||||
|
|
||||||
|
#define UNIX_PASS_FD_FIX_NONE (0)
|
||||||
|
#define UNIX_PASS_FD_FIX_CMSG_LEN (1<<0)
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
|
67
postfix/src/util/unix_pass_fd_fix.c
Normal file
67
postfix/src/util/unix_pass_fd_fix.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* unix_pass_fd_fix 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* file descriptor passing bug workarounds
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <iostuff.h>
|
||||||
|
/*
|
||||||
|
/* void set_unix_pass_fd_fix(workarounds)
|
||||||
|
/* const char *workarounds;
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* This module supports programmatic control over workarounds
|
||||||
|
/* for sending or receiving file descriptors over UNIX-domain
|
||||||
|
/* sockets.
|
||||||
|
/*
|
||||||
|
/* set_unix_pass_fd_fix() takes a list of workarouds in external
|
||||||
|
/* form, and stores their internal representation. The result
|
||||||
|
/* is used by unix_send_fd() and unix_recv_fd().
|
||||||
|
/*
|
||||||
|
/* Arguments:
|
||||||
|
/* .IP workarounds
|
||||||
|
/* List of zero or more of the following, separated by comma
|
||||||
|
/* or whitespace.
|
||||||
|
/* .RS
|
||||||
|
/* .IP cmsg_len
|
||||||
|
/* Send the CMSG_LEN of the file descriptor, instead of
|
||||||
|
/* the total message buffer length.
|
||||||
|
/* .RE
|
||||||
|
/* SEE ALSO
|
||||||
|
/* unix_send_fd(3) send file descriptor
|
||||||
|
/* unix_recv_fd(3) receive file descriptor
|
||||||
|
/* DIAGNOSTICS
|
||||||
|
/* Fatal errors: non-existent workaround.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/* System library. */
|
||||||
|
|
||||||
|
#include <sys_defs.h>
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include <iostuff.h>
|
||||||
|
#include <name_mask.h>
|
||||||
|
|
||||||
|
int unix_pass_fd_fix = 0;
|
||||||
|
|
||||||
|
/* set_unix_pass_fd_fix - set workaround programmatically */
|
||||||
|
|
||||||
|
void set_unix_pass_fd_fix(const char *workarounds)
|
||||||
|
{
|
||||||
|
const static NAME_MASK table[] = {
|
||||||
|
"cmsg_len", UNIX_PASS_FD_FIX_CMSG_LEN,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
unix_pass_fd_fix = name_mask("descriptor passing workarounds",
|
||||||
|
table, workarounds);
|
||||||
|
}
|
@ -63,7 +63,7 @@ int unix_recv_fd(int fd)
|
|||||||
/*
|
/*
|
||||||
* Adapted from: W. Richard Stevens, UNIX Network Programming, Volume 1,
|
* Adapted from: W. Richard Stevens, UNIX Network Programming, Volume 1,
|
||||||
* Second edition. Except that we use CMSG_LEN instead of CMSG_SPACE, for
|
* Second edition. Except that we use CMSG_LEN instead of CMSG_SPACE, for
|
||||||
* portability to LP64 environments.
|
* portability to some LP64 environments. See also unix_send_fd.c.
|
||||||
*/
|
*/
|
||||||
#if defined(CMSG_SPACE) && !defined(NO_MSGHDR_MSG_CONTROL)
|
#if defined(CMSG_SPACE) && !defined(NO_MSGHDR_MSG_CONTROL)
|
||||||
union {
|
union {
|
||||||
@ -74,7 +74,11 @@ int unix_recv_fd(int fd)
|
|||||||
|
|
||||||
memset((char *) &msg, 0, sizeof(msg)); /* Fix 200512 */
|
memset((char *) &msg, 0, sizeof(msg)); /* Fix 200512 */
|
||||||
msg.msg_control = control_un.control;
|
msg.msg_control = control_un.control;
|
||||||
|
if (unix_pass_fd_fix & UNIX_PASS_FD_FIX_CMSG_LEN) {
|
||||||
msg.msg_controllen = CMSG_LEN(sizeof(newfd)); /* Fix 200506 */
|
msg.msg_controllen = CMSG_LEN(sizeof(newfd)); /* Fix 200506 */
|
||||||
|
} else {
|
||||||
|
msg.msg_controllen = sizeof(control_un.control); /* normal */
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
msg.msg_accrights = (char *) &newfd;
|
msg.msg_accrights = (char *) &newfd;
|
||||||
msg.msg_accrightslen = sizeof(newfd);
|
msg.msg_accrightslen = sizeof(newfd);
|
||||||
@ -141,10 +145,10 @@ int main(int argc, char **argv)
|
|||||||
ssize_t read_count;
|
ssize_t read_count;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
if (argc != 2
|
if (argc < 2 || argc > 3
|
||||||
|| (endpoint = split_at(transport = argv[1], ':')) == 0
|
|| (endpoint = split_at(transport = argv[1], ':')) == 0
|
||||||
|| *endpoint == 0 || *transport == 0)
|
|| *endpoint == 0 || *transport == 0)
|
||||||
msg_fatal("usage: %s transport:endpoint", argv[0]);
|
msg_fatal("usage: %s transport:endpoint [workaround]", argv[0]);
|
||||||
|
|
||||||
if (strcmp(transport, "unix") == 0) {
|
if (strcmp(transport, "unix") == 0) {
|
||||||
listen_sock = unix_listen(endpoint, 10, BLOCKING);
|
listen_sock = unix_listen(endpoint, 10, BLOCKING);
|
||||||
@ -158,8 +162,10 @@ int main(int argc, char **argv)
|
|||||||
if (client_sock < 0)
|
if (client_sock < 0)
|
||||||
msg_fatal("accept: %m");
|
msg_fatal("accept: %m");
|
||||||
|
|
||||||
|
set_unix_pass_fd_fix(argv[2] ? argv[2] : "");
|
||||||
|
|
||||||
while ((client_fd = unix_recv_fd(client_sock)) >= 0) {
|
while ((client_fd = unix_recv_fd(client_sock)) >= 0) {
|
||||||
msg_info("client_fd = %d", client_fd);
|
msg_info("client_fd = %d, fix=%d", client_fd, unix_pass_fd_fix);
|
||||||
while ((read_count = read(client_fd, buf, sizeof(buf))) > 0)
|
while ((read_count = read(client_fd, buf, sizeof(buf))) > 0)
|
||||||
write(1, buf, read_count);
|
write(1, buf, read_count);
|
||||||
if (read_count < 0)
|
if (read_count < 0)
|
||||||
|
@ -64,8 +64,8 @@ int unix_send_fd(int fd, int sendfd)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Adapted from: W. Richard Stevens, UNIX Network Programming, Volume 1,
|
* Adapted from: W. Richard Stevens, UNIX Network Programming, Volume 1,
|
||||||
* Second edition. Except that we use CMSG_LEN instead of CMSG_SPACE; the
|
* Second edition. Except that we use CMSG_LEN instead of CMSG_SPACE, for
|
||||||
* latter breaks on LP64 systems.
|
* portability to some LP64 environments. See also unix_recv_fd.c.
|
||||||
*/
|
*/
|
||||||
#if defined(CMSG_SPACE) && !defined(NO_MSGHDR_MSG_CONTROL)
|
#if defined(CMSG_SPACE) && !defined(NO_MSGHDR_MSG_CONTROL)
|
||||||
union {
|
union {
|
||||||
@ -76,8 +76,11 @@ int unix_send_fd(int fd, int sendfd)
|
|||||||
|
|
||||||
memset((char *) &msg, 0, sizeof(msg)); /* Fix 200512 */
|
memset((char *) &msg, 0, sizeof(msg)); /* Fix 200512 */
|
||||||
msg.msg_control = control_un.control;
|
msg.msg_control = control_un.control;
|
||||||
|
if (unix_pass_fd_fix & UNIX_PASS_FD_FIX_CMSG_LEN) {
|
||||||
msg.msg_controllen = CMSG_LEN(sizeof(sendfd)); /* Fix 200506 */
|
msg.msg_controllen = CMSG_LEN(sizeof(sendfd)); /* Fix 200506 */
|
||||||
|
} else {
|
||||||
|
msg.msg_controllen = sizeof(control_un.control); /* normal */
|
||||||
|
}
|
||||||
cmptr = CMSG_FIRSTHDR(&msg);
|
cmptr = CMSG_FIRSTHDR(&msg);
|
||||||
cmptr->cmsg_len = CMSG_LEN(sizeof(sendfd));
|
cmptr->cmsg_len = CMSG_LEN(sizeof(sendfd));
|
||||||
cmptr->cmsg_level = SOL_SOCKET;
|
cmptr->cmsg_level = SOL_SOCKET;
|
||||||
@ -101,7 +104,34 @@ int unix_send_fd(int fd, int sendfd)
|
|||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
|
||||||
return (sendmsg(fd, &msg, 0));
|
/*
|
||||||
|
* The CMSG_LEN workaround was originally developed for OpenBSD 3.6 on
|
||||||
|
* 64-bit SPARC (later also confirmed on AMD64). It was hard-coded with
|
||||||
|
* Postfix 2.3 for all platforms because of increasing pressure to work
|
||||||
|
* on other things.
|
||||||
|
*
|
||||||
|
* The investigation was reopened with Postfix 2.7 because the workaround
|
||||||
|
* broke on NetBSD 5.0. This time it was found that OpenBSD on AMD64
|
||||||
|
* needs the workaround for sending only. We assume that OpenBSD on AMD64
|
||||||
|
* and SPARC64 are similar, and turn on the workaround on-the-fly. The
|
||||||
|
* OpenBSD problem was fixed for AMD64 and SPARC64 with OpenBSD 4.4 or
|
||||||
|
* 4.5.
|
||||||
|
*
|
||||||
|
* The workaround was made run-time configurable to make the investigation
|
||||||
|
* possible on many different platforms. Though the code is over-kill for
|
||||||
|
* this particular problem, it is left in place so that it can serve as
|
||||||
|
* an example of how to add run-time configurable workarounds to Postfix.
|
||||||
|
*/
|
||||||
|
if (sendmsg(fd, &msg, 0) >= 0)
|
||||||
|
return (0);
|
||||||
|
if (unix_pass_fd_fix == 0) {
|
||||||
|
if (msg_verbose)
|
||||||
|
msg_info("sendmsg error (%m). Trying CMSG_LEN workaround.");
|
||||||
|
unix_pass_fd_fix = UNIX_PASS_FD_FIX_CMSG_LEN;
|
||||||
|
return (unix_send_fd(fd, sendfd));
|
||||||
|
} else {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +156,8 @@ int main(int argc, char **argv)
|
|||||||
int server_sock;
|
int server_sock;
|
||||||
int client_fd;
|
int client_fd;
|
||||||
|
|
||||||
|
msg_verbose = 1;
|
||||||
|
|
||||||
if (argc < 3
|
if (argc < 3
|
||||||
|| (endpoint = split_at(transport = argv[1], ':')) == 0
|
|| (endpoint = split_at(transport = argv[1], ':')) == 0
|
||||||
|| *endpoint == 0 || *transport == 0)
|
|| *endpoint == 0 || *transport == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user