From: Wietse Venema Date: Mon, 11 May 2020 05:00:00 +0000 (-0500) Subject: postfix-3.6-20200511 X-Git-Tag: v3.6.0-RC1~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8dec727b26e61d949a6e91fce40c241675e59010;p=thirdparty%2Fpostfix.git postfix-3.6-20200511 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index f117d89a5..856b2db51 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -24731,14 +24731,32 @@ Apologies for any names omitted. Portability: declaration should be before executable statement. File: util/msg_logger.c. + Portability: replace res_xxx() calls with res_nxxx() not + because those are threadsafe, but because new features are + being added there. To build old style, build with "make + makefiles CCARGS="-DNO_RES_NCALLS...". Files: makedefs. + util/sys_defs.h, dns/dns_lookup.c. + + Portability: libc-musl does not have res_nxxx() support, + so it builds with -DNO_RES_NCALLS. + 20200505 Noise suppression: shut up a compiler that special-cases string literals. Viktor Dukhovni. File smtpd/smtpd_check.c. + Portability: not all supported systems have ldd(1). Viktor + Dukhovni. File: makedefs. + 20200509 Bugfix (introduced: Postfix 3.5): maillog_file_rotate_suffix default value used the minute instead of the month. Reported by Larry Stone. Files: conf/postfix-tls-script, proto/MAILLOG_README.html, proto/postconf.proto. + +20200510 + + Bitrot: avoid U_FILE_ACCESS_ERROR after chroot(), by + initializing the ICU library before making the chroot() + call. Files: util/midna_domain.[hc], global/mail_params.c. diff --git a/postfix/INSTALL b/postfix/INSTALL index 10e69408c..28a7e68a3 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -593,6 +593,9 @@ The following is an extensive list of names and values. ||-DNO_POSIX_GETPW_R |getpwuid_r. By default Postfix uses these | || |where they are known to be available. | ||______________________________|_____________________________________________| +||-DNO_RES_NCALLS |Do not build with the threadsafe resolver(5) | +|| |API (res_ninit() etc.). | +||______________________________|_____________________________________________| || |Use setjmp()/longjmp() instead of sigsetjmp | ||-DNO_SIGSETJMP |()/siglongjmp(). By default, Postfix uses | || |sigsetjmp()/siglongjmp() when they are known | diff --git a/postfix/README_FILES/INSTALL b/postfix/README_FILES/INSTALL index 14e61caf0..ffc738b52 100644 --- a/postfix/README_FILES/INSTALL +++ b/postfix/README_FILES/INSTALL @@ -593,6 +593,9 @@ The following is an extensive list of names and values. ||-DNO_POSIX_GETPW_R |getpwuid_r. By default Postfix uses these | || |where they are known to be available. | |_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | +||-DNO_RES_NCALLS |Do not build with the threadsafe resolver(5) | +|| |API (res_ninit() etc.). | +|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | || |Use setjmp()/longjmp() instead of sigsetjmp | ||-DNO_SIGSETJMP |()/siglongjmp(). By default, Postfix uses | || |sigsetjmp()/siglongjmp() when they are known | diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 204429d27..1a9a2ce9d 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -24,3 +24,17 @@ historical IBM Public License 1.0, it is now also distributed with the more recent Eclipse Public License 2.0. Recipients can choose to take the software under the license of their choice. Those who are more comfortable with the IPL can continue with that license. + +Major changes with snapshot 20200509 +==================================== + +The threadsafe resolver API (res_nxxx() calls) is now the default, +not because the API is threadsafe, but because new features are +being added there. + +To build old style, build with: + + make makefiles CCARGS="-DNO_RES_NCALLS..." + +This is also the default for systems that are known not to support +the threadsafe resolver API, such systems that use libc-musl. diff --git a/postfix/html/INSTALL.html b/postfix/html/INSTALL.html index 2ee35cdf9..c4875d472 100644 --- a/postfix/html/INSTALL.html +++ b/postfix/html/INSTALL.html @@ -863,6 +863,9 @@ support. By default, PCRE support is compiled in when the for POSIX getpwnam_r/getpwuid_r. By default Postfix uses these where they are known to be available. + -DNO_RES_NCALLS Do not build with +the threadsafe resolver(5) API (res_ninit() etc.). + -DNO_SIGSETJMP Use setjmp()/longjmp() instead of sigsetjmp()/siglongjmp(). By default, Postfix uses sigsetjmp()/siglongjmp() when diff --git a/postfix/html/makedefs.1.html b/postfix/html/makedefs.1.html index cf1f02c17..62b29d9f6 100644 --- a/postfix/html/makedefs.1.html +++ b/postfix/html/makedefs.1.html @@ -109,42 +109,46 @@ MAKEDEFS(1) MAKEDEFS(1) -DNO_POSIX_GETPW_R Disable support for POSIX getpwnam_r/getpwuid_r. + -DNO_RES_NCALLS + Do not build with the threadsafe resolver(5) API + (res_ninit() etc.). + -DNO_SIGSETJMP - Use setjmp()/longjmp() instead of sigsetjmp()/sig- - longjmp(). By default, Postfix uses sigsetjmp()/sig- + Use setjmp()/longjmp() instead of sigsetjmp()/sig- + longjmp(). By default, Postfix uses sigsetjmp()/sig- longjmp() when they appear to work. -DNO_SNPRINTF - Use sprintf() instead of snprintf(). By default, Postfix + Use sprintf() instead of snprintf(). By default, Postfix uses snprintf() except on ancient systems. DEBUG=debug_level - Specifies a non-default debugging level. The default is -g. + Specifies a non-default debugging level. The default is -g. Specify DEBUG= to turn off debugging. OPT=optimization_level - Specifies a non-default optimization level. The default is -O. + Specifies a non-default optimization level. The default is -O. Specify OPT= to turn off optimization. POSTFIX_INSTALL_OPTS=-option... - Specifies options for the postfix-install command, separated by - whitespace. Currently, the only supported option is + Specifies options for the postfix-install command, separated by + whitespace. Currently, the only supported option is -keep-build-mtime. SHLIB_CFLAGS=flags - Override the compiler flags (typically, "-fPIC") for Postfix + Override the compiler flags (typically, "-fPIC") for Postfix dynamically-linked libraries and database plugins. This feature was introduced with Postfix 3.0. SHLIB_RPATH=rpath - Override the runpath (typically, "'-Wl,-rpath,${SHLIB_DIR}'") + Override the runpath (typically, "'-Wl,-rpath,${SHLIB_DIR}'") for Postfix dynamically-linked libraries. This feature was introduced with Postfix 3.0. SHLIB_SUFFIX=suffix - Override the filename suffix (typically, ".so") for Postfix + Override the filename suffix (typically, ".so") for Postfix dynamically-linked libraries and database plugins. This feature was introduced with Postfix 3.0. @@ -152,7 +156,7 @@ MAKEDEFS(1) MAKEDEFS(1) shared=yes shared=no - Enable (disable) Postfix builds with dynamically-linked + Enable (disable) Postfix builds with dynamically-linked libraries typically named $shlib_directory/libpostfix-*.so.*. This feature was introduced with Postfix 3.0. @@ -160,39 +164,39 @@ MAKEDEFS(1) MAKEDEFS(1) dynamicmaps=yes dynamicmaps=no - Enable (disable) Postfix builds with the configuration file + Enable (disable) Postfix builds with the configuration file $meta_directory/dynamicmaps.cf and dynamically-loadable database - plugins typically named postfix-*.so.*. The setting "dynam- - icmaps=yes" implicitly enables Postfix dynamically-linked + plugins typically named postfix-*.so.*. The setting "dynam- + icmaps=yes" implicitly enables Postfix dynamically-linked libraries. This feature was introduced with Postfix 3.0. pie=yes - pie=no Enable (disable) Postfix builds with position-independent exe- + pie=no Enable (disable) Postfix builds with position-independent exe- cutables, on platforms where this is supported. This feature was introduced with Postfix 3.0. installation_parameter=value... - Override the compiled-in default value of the specified instal- - lation parameter(s). The following parameters are supported in + Override the compiled-in default value of the specified instal- + lation parameter(s). The following parameters are supported in this context: - command_directory config_directory daemon_directory data_direc- - tory default_database_type html_directory mail_spool_directory - mailq_path manpage_directory meta_directory newaliases_path - queue_directory readme_directory sendmail_path shlib_directory + command_directory config_directory daemon_directory data_direc- + tory default_database_type html_directory mail_spool_directory + mailq_path manpage_directory meta_directory newaliases_path + queue_directory readme_directory sendmail_path shlib_directory openssl_path - See the postconf(5) manpage for a description of these parame- + See the postconf(5) manpage for a description of these parame- ters. This feature was introduced with Postfix 3.0. WARN=warning_flags - Specifies non-default gcc compiler warning options for use when + Specifies non-default gcc compiler warning options for use when "make" is invoked in a source subdirectory only. LICENSE diff --git a/postfix/makedefs b/postfix/makedefs index 6f436f4c0..148f173a8 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -94,6 +94,8 @@ # utility is installed. # .IP \fB-DNO_POSIX_GETPW_R\fR # Disable support for POSIX getpwnam_r/getpwuid_r. +# .IP \fB-DNO_RES_NCALLS\fR +# Do not build with the threadsafe resolver(5) API (res_ninit() etc.). # .IP \fB-DNO_SIGSETJMP\fR # Use setjmp()/longjmp() instead of sigsetjmp()/siglongjmp(). # By default, Postfix uses sigsetjmp()/siglongjmp() when they @@ -237,6 +239,12 @@ case "$SYSTEM" in *) echo Warning: libc-musl breaks DANE/TLSA security. 1>&2 echo This build will not support DANE/TLSA. 1>&2 CCARGS="$CCARGS -DNO_DNSSEC";; + esac + case "$CCARGS" in + *-DNO_RES_NCALLS*) ;; + *) echo Warning: libc-musl does not support res_ninit etc. 1>&2 + echo This build will not support modern resolver features. 1>&2 + CCARGS="$CCARGS -DNO_RES_NCALLS";; esac;; esac;; esac @@ -311,6 +319,15 @@ case "$SYSTEM.$RELEASE" in : ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"} : ${PLUGIN_LD="${CC} -shared"} ;; + FreeBSD.12*) SYSTYPE=FREEBSD12 + : ${CC=cc} + : ${SHLIB_SUFFIX=.so} + : ${SHLIB_CFLAGS=-fPIC} + : ${SHLIB_LD="${CC} -shared"' -Wl,-soname,${LIB}'} + : ${SHLIB_RPATH='-Wl,-rpath,${SHLIB_DIR}'} + : ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"} + : ${PLUGIN_LD="${CC} -shared"} + ;; DragonFly.*) SYSTYPE=DRAGONFLY ;; OpenBSD.2*) SYSTYPE=OPENBSD2 diff --git a/postfix/man/man1/makedefs.1 b/postfix/man/man1/makedefs.1 index 34c9d013a..adc2af2f9 100644 --- a/postfix/man/man1/makedefs.1 +++ b/postfix/man/man1/makedefs.1 @@ -97,6 +97,8 @@ By default, PCRE support is compiled in when the \fBpcre\-config\fR utility is installed. .IP \fB\-DNO_POSIX_GETPW_R\fR Disable support for POSIX getpwnam_r/getpwuid_r. +.IP \fB\-DNO_RES_NCALLS\fR +Do not build with the threadsafe resolver(5) API (res_ninit() etc.). .IP \fB\-DNO_SIGSETJMP\fR Use setjmp()/longjmp() instead of sigsetjmp()/siglongjmp(). By default, Postfix uses sigsetjmp()/siglongjmp() when they diff --git a/postfix/proto/INSTALL.html b/postfix/proto/INSTALL.html index 984528cbe..8c9a23d7e 100644 --- a/postfix/proto/INSTALL.html +++ b/postfix/proto/INSTALL.html @@ -863,6 +863,9 @@ support. By default, PCRE support is compiled in when the for POSIX getpwnam_r/getpwuid_r. By default Postfix uses these where they are known to be available. + -DNO_RES_NCALLS Do not build with +the threadsafe resolver(5) API (res_ninit() etc.). + -DNO_SIGSETJMP Use setjmp()/longjmp() instead of sigsetjmp()/siglongjmp(). By default, Postfix uses sigsetjmp()/siglongjmp() when diff --git a/postfix/src/dns/dns_lookup.c b/postfix/src/dns/dns_lookup.c index 11c928134..d4d494f61 100644 --- a/postfix/src/dns/dns_lookup.c +++ b/postfix/src/dns/dns_lookup.c @@ -282,6 +282,43 @@ typedef struct DNS_REPLY { #define INET_ADDR_LEN 4 /* XXX */ #define INET6_ADDR_LEN 16 /* XXX */ + /* + * Use the theadsafe resolver API if available, not because it is theadsafe, + * but because it has more functionality. + */ +#ifdef USE_RES_NCALLS +static struct __res_state dns_res_state; + +#define DNS_RES_NINIT res_ninit +#define DNS_RES_NMKQUERY res_nmkquery +#define DNS_RES_NSEARCH res_nsearch +#define DNS_RES_NSEND res_nsend +#define DNS_GET_H_ERRNO(statp) ((statp)->res_h_errno) + + /* + * Alias new resolver API calls to the legacy resolver API which stores + * resolver and error state in global variables. + */ +#else +#define dns_res_state _res +#define DNS_RES_NINIT(statp) res_init() +#define DNS_RES_NMKQUERY(statp, op, dname, class, type, data, datalen, \ + newrr, buf, buflen) \ + res_mkquery((op), (dname), (class), (type), (data), (datalen), \ + (newrr), (buf), (buflen)) +#define DNS_RES_NSEARCH(statp, dname, class, type, answer, anslen) \ + res_search((dname), (class), (type), (answer), (anslen)) +#define DNS_RES_NSEND(statp, msg, msglen, answer, anslen) \ + res_send((msg), (msglen), (answer), (anslen)) +#define DNS_GET_H_ERRNO(statp) (h_errno) +#endif + +#ifdef USE_SET_H_ERRNO +#define DNS_SET_H_ERRNO(statp, err) (set_h_errno(err)) +#else +#define DNS_SET_H_ERRNO(statp, err) (DNS_GET_H_ERRNO(statp) = (err)) +#endif + /* * To improve postscreen's whitelisting support, we need to know how long a * DNSBL "not found" answer is valid. The 2010 implementation assumed it was @@ -312,9 +349,9 @@ typedef struct DNS_REPLY { */ #ifdef HAVE_RES_SEND -/* dns_res_query - a res_query() clone that can return negative replies */ +/* dns_neg_query - a res_query() clone that can return negative replies */ -static int dns_res_query(const char *name, int class, int type, +static int dns_neg_query(const char *name, int class, int type, unsigned char *answer, int anslen) { unsigned char msg_buf[MAX_DNS_QUERY_SIZE]; @@ -343,34 +380,36 @@ static int dns_res_query(const char *name, int class, int type, #define NO_MKQUERY_DATA_LEN ((int) 0) #define NO_MKQUERY_NEWRR ((unsigned char *) 0) - if ((len = res_mkquery(QUERY, name, class, type, NO_MKQUERY_DATA_BUF, - NO_MKQUERY_DATA_LEN, NO_MKQUERY_NEWRR, - msg_buf, sizeof(msg_buf))) < 0) { - SET_H_ERRNO(NO_RECOVERY); + if ((len = DNS_RES_NMKQUERY(&dns_res_state, + QUERY, name, class, type, NO_MKQUERY_DATA_BUF, + NO_MKQUERY_DATA_LEN, NO_MKQUERY_NEWRR, + msg_buf, sizeof(msg_buf))) < 0) { + DNS_SET_H_ERRNO(&dns_res_state, NO_RECOVERY); if (msg_verbose) - msg_info("res_mkquery() failed"); + msg_info("res_nmkquery() failed"); return (len); - } else if ((len = res_send(msg_buf, len, answer, anslen)) < 0) { - SET_H_ERRNO(TRY_AGAIN); + } else if ((len = DNS_RES_NSEND(&dns_res_state, + msg_buf, len, answer, anslen)) < 0) { + DNS_SET_H_ERRNO(&dns_res_state, TRY_AGAIN); if (msg_verbose) - msg_info("res_send() failed"); + msg_info("res_nsend() failed"); return (len); } else { switch (reply_header->rcode) { case NXDOMAIN: - SET_H_ERRNO(HOST_NOT_FOUND); + DNS_SET_H_ERRNO(&dns_res_state, HOST_NOT_FOUND); break; case NOERROR: if (reply_header->ancount != 0) - SET_H_ERRNO(0); + DNS_SET_H_ERRNO(&dns_res_state, 0); else - SET_H_ERRNO(NO_DATA); + DNS_SET_H_ERRNO(&dns_res_state, NO_DATA); break; case SERVFAIL: - SET_H_ERRNO(TRY_AGAIN); + DNS_SET_H_ERRNO(&dns_res_state, TRY_AGAIN); break; default: - SET_H_ERRNO(NO_RECOVERY); + DNS_SET_H_ERRNO(&dns_res_state, NO_RECOVERY); break; } return (len); @@ -379,9 +418,9 @@ static int dns_res_query(const char *name, int class, int type, #endif -/* dns_res_search - res_search() that can return negative replies */ +/* dns_neg_search - res_search() that can return negative replies */ -static int dns_res_search(const char *name, int class, int type, +static int dns_neg_search(const char *name, int class, int type, unsigned char *answer, int anslen, int keep_notfound) { int len; @@ -404,18 +443,19 @@ static int dns_res_search(const char *name, int class, int type, if (keep_notfound) /* Prepare for returning a null-padded server reply. */ memset(answer, 0, anslen); - len = res_search(name, class, type, answer, anslen); + len = DNS_RES_NSEARCH(&dns_res_state, name, class, type, answer, anslen); /* Begin API creep workaround. */ - if (len < 0 && h_errno == 0) { - SET_H_ERRNO(TRY_AGAIN); - msg_warn("res_query(\"%s\", %d, %d, %p, %d) returns %d with h_errno==0" - " -- setting h_errno=TRY_AGAIN", + if (len < 0 && DNS_GET_H_ERRNO(&dns_res_state) == 0) { + DNS_SET_H_ERRNO(&dns_res_state, TRY_AGAIN); + msg_warn("res_nsearch(state, \"%s\", %d, %d, %p, %d) returns %d" + " with h_errno==0 -- setting h_errno=TRY_AGAIN", name, class, type, answer, anslen, len); } /* End API creep workaround. */ if (len > 0) { - SET_H_ERRNO(0); - } else if (keep_notfound && NOT_FOUND_H_ERRNO(h_errno)) { + DNS_SET_H_ERRNO(&dns_res_state, 0); + } else if (keep_notfound + && NOT_FOUND_H_ERRNO(DNS_GET_H_ERRNO(&dns_res_state))) { /* Expect to return a null-padded server reply. */ len = anslen; } @@ -443,7 +483,8 @@ static int dns_query(const char *name, int type, unsigned flags, /* * Initialize the name service. */ - if ((_res.options & RES_INIT) == 0 && res_init() < 0) { + if ((dns_res_state.options & RES_INIT) == 0 + && DNS_RES_NINIT(&dns_res_state) < 0) { if (why) vstring_strcpy(why, "Name service initialization failure"); return (DNS_FAIL); @@ -482,43 +523,45 @@ static int dns_query(const char *name, int type, unsigned flags, */ #define SAVE_FLAGS (USER_FLAGS | XTRA_FLAGS) - saved_options = (_res.options & SAVE_FLAGS); + saved_options = (dns_res_state.options & SAVE_FLAGS); /* * Perform the lookup. Claim that the information cannot be found if and * only if the name server told us so. */ for (;;) { - _res.options &= ~saved_options; - _res.options |= flags; + dns_res_state.options &= ~saved_options; + dns_res_state.options |= flags; if (keep_notfound && var_dns_ncache_ttl_fix) { #ifdef HAVE_RES_SEND - len = dns_res_query((char *) name, C_IN, type, reply->buf, + len = dns_neg_query((char *) name, C_IN, type, reply->buf, reply->buf_len); #else var_dns_ncache_ttl_fix = 0; msg_warn("system library does not support %s=yes" " -- ignoring this setting", VAR_DNS_NCACHE_TTL_FIX); - len = dns_res_search((char *) name, C_IN, type, reply->buf, + len = dns_neg_search((char *) name, C_IN, type, reply->buf, reply->buf_len, keep_notfound); #endif } else { - len = dns_res_search((char *) name, C_IN, type, reply->buf, + len = dns_neg_search((char *) name, C_IN, type, reply->buf, reply->buf_len, keep_notfound); } - _res.options &= ~flags; - _res.options |= saved_options; + dns_res_state.options &= ~flags; + dns_res_state.options |= saved_options; reply_header = (HEADER *) reply->buf; reply->rcode = reply_header->rcode; - if (h_errno != 0) { + if (DNS_GET_H_ERRNO(&dns_res_state) != 0) { if (why) vstring_sprintf(why, "Host or domain name not found. " "Name service error for name=%s type=%s: %s", - name, dns_strtype(type), dns_strerror(h_errno)); + name, dns_strtype(type), + dns_strerror(DNS_GET_H_ERRNO(&dns_res_state))); if (msg_verbose) msg_info("dns_query: %s (%s): %s", - name, dns_strtype(type), dns_strerror(h_errno)); - switch (h_errno) { + name, dns_strtype(type), + dns_strerror(DNS_GET_H_ERRNO(&dns_res_state))); + switch (DNS_GET_H_ERRNO(&dns_res_state)) { case NO_RECOVERY: return (DNS_FAIL); case HOST_NOT_FOUND: @@ -548,7 +591,7 @@ static int dns_query(const char *name, int type, unsigned flags, */ if (len < 0) msg_panic("dns_query: bad length %d (h_errno=%s)", - len, dns_strerror(h_errno)); + len, dns_strerror(DNS_GET_H_ERRNO(&dns_res_state))); /* * Paranoia. @@ -582,13 +625,13 @@ static int dns_query(const char *name, int type, unsigned flags, * Future proofing. If this reaches the panic call, then some code change * introduced a bug. */ - if (h_errno == 0) { + if (DNS_GET_H_ERRNO(&dns_res_state) == 0) { return (DNS_OK); } else if (keep_notfound) { return (DNS_NOTFOUND); } else { msg_panic("dns_query: unexpected reply status: %s", - dns_strerror(h_errno)); + dns_strerror(DNS_GET_H_ERRNO(&dns_res_state))); } } @@ -966,7 +1009,7 @@ int dns_lookup_x(const char *name, unsigned type, unsigned flags, name); if (rcode) *rcode = NXDOMAIN; - SET_H_ERRNO(HOST_NOT_FOUND); + DNS_SET_H_ERRNO(&dns_res_state, HOST_NOT_FOUND); return (DNS_NOTFOUND); } @@ -980,7 +1023,7 @@ int dns_lookup_x(const char *name, unsigned type, unsigned flags, name); if (rcode) *rcode = NXDOMAIN; - SET_H_ERRNO(HOST_NOT_FOUND); + DNS_SET_H_ERRNO(&dns_res_state, HOST_NOT_FOUND); return (DNS_NOTFOUND); } @@ -1030,7 +1073,7 @@ int dns_lookup_x(const char *name, unsigned type, unsigned flags, if (why) vstring_sprintf(why, "Domain %s does not accept mail (nullMX)", name); - SET_H_ERRNO(NO_DATA); + DNS_SET_H_ERRNO(&dns_res_state, NO_DATA); return (status); case DNS_OK: if (rrlist && dns_rr_filter_maps) { @@ -1099,7 +1142,7 @@ int dns_lookup_rl(const char *name, unsigned flags, DNS_RR **rrlist, vstring_strcpy(hpref_rtext ? hpref_rtext : \ (hpref_rtext = vstring_alloc(VSTRING_LEN(why))), \ vstring_str(why)); \ - hpref_h_errno = h_errno; \ + hpref_h_errno = DNS_GET_H_ERRNO(&dns_res_state); \ } while (0) /* Restore intermediate highest-priority result. */ @@ -1109,7 +1152,7 @@ int dns_lookup_rl(const char *name, unsigned flags, DNS_RR **rrlist, *rcode = hpref_rcode; \ if (why && status != DNS_OK) \ vstring_strcpy(why, vstring_str(hpref_rtext)); \ - SET_H_ERRNO(hpref_h_errno); \ + DNS_SET_H_ERRNO(&dns_res_state, hpref_h_errno); \ } while (0) if (rrlist) diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index 8b4ad0ba4..91c70f75e 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -871,6 +871,8 @@ void mail_params_init() var_smtputf8_enable = 0; #else midna_domain_transitional = var_idna2003_compat; + if (var_smtputf8_enable) + midna_domain_pre_chroot(); #endif util_utf8_enable = var_smtputf8_enable; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9bfbcf7cd..2edd10252 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20200509" +#define MAIL_RELEASE_DATE "20200511" #define MAIL_VERSION_NUMBER "3.6" #ifdef SNAPSHOT diff --git a/postfix/src/util/midna_domain.c b/postfix/src/util/midna_domain.c index 667e75e59..333a5c91d 100644 --- a/postfix/src/util/midna_domain.c +++ b/postfix/src/util/midna_domain.c @@ -20,6 +20,8 @@ /* /* const char *midna_domain_suffix_to_utf8( /* const char *name) +/* AUXILIARY FUNCTIONS +/* void midna_domain_pre_chroot(void) /* DESCRIPTION /* The functions in this module transform domain names from/to /* ASCII and UTF-8 form. The result is cached to avoid repeated @@ -52,6 +54,8 @@ /* /* midna_domain_transitional enables transitional conversion /* between UTF8 and ASCII labels. +/* +/* midna_domain_pre_chroot() does some pre-chroot initialization. /* SEE ALSO /* http://unicode.org/reports/tr46/ Unicode IDNA Compatibility processing /* msg(3) diagnostics interface @@ -144,6 +148,22 @@ static const char *midna_domain_strerror(UErrorCode error, int info_errors) } } +/* midna_domain_pre_chroot - pre-chroot initialization */ + +void midna_domain_pre_chroot(void) +{ + UErrorCode error = U_ZERO_ERROR; + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + UIDNA *idna; + + idna = uidna_openUTS46(midna_domain_transitional ? UIDNA_DEFAULT + : UIDNA_NONTRANSITIONAL_TO_ASCII, &error); + if (U_FAILURE(error)) + msg_warn("ICU library initialization failed: %s", + midna_domain_strerror(error, info.errors)); + uidna_close(idna); +} + /* midna_domain_to_ascii_create - convert domain to ASCII */ static void *midna_domain_to_ascii_create(const char *name, void *unused_context) @@ -327,6 +347,7 @@ const char *midna_domain_suffix_to_utf8(const char *name) /* * Test program - reads names from stdin, reports invalid names to stderr. */ +#include #include #include @@ -350,6 +371,11 @@ int main(int argc, char **argv) /* msg_verbose = 1; */ util_utf8_enable = 1; + if (geteuid() == 0) { + midna_domain_pre_chroot(); + if (chroot(".") != 0) + msg_fatal("chroot(\".\"): %m"); + } while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { bp = STR(buffer); msg_info("> %s", bp); diff --git a/postfix/src/util/midna_domain.h b/postfix/src/util/midna_domain.h index 03d875b10..1abe2a173 100644 --- a/postfix/src/util/midna_domain.h +++ b/postfix/src/util/midna_domain.h @@ -18,6 +18,7 @@ extern const char *midna_domain_to_ascii(const char *); extern const char *midna_domain_to_utf8(const char *); extern const char *midna_domain_suffix_to_ascii(const char *); extern const char *midna_domain_suffix_to_utf8(const char *); +extern void midna_domain_pre_chroot(void); extern int midna_domain_cache_size; extern int midna_domain_transitional; diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 17e52b229..c491b2203 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -30,7 +30,7 @@ #if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \ || defined(FREEBSD5) || defined(FREEBSD6) || defined(FREEBSD7) \ || defined(FREEBSD8) || defined(FREEBSD9) || defined(FREEBSD10) \ - || defined(FREEBSD11) \ + || defined(FREEBSD11) || defined(FREEBSD12) \ || defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \ || defined(OPENBSD2) || defined(OPENBSD3) || defined(OPENBSD4) \ || defined(OPENBSD5) || defined(OPENBSD6) \ @@ -520,7 +520,7 @@ extern int opterr; #define USE_STATVFS #define STATVFS_IN_SYS_STATVFS_H #define STRCASECMP_IN_STRINGS_H -#define SET_H_ERRNO(err) (set_h_errno(err)) +#define USE_SET_H_ERRNO #endif #ifdef UW21 /* UnixWare 2.1.x */ @@ -1700,11 +1700,11 @@ typedef int pid_t; #define ENFORCING_SIZE_LIMIT(param) ((param) > 0) /* - * Setting globals like h_errno can be problematic when Postfix is linked - * with multi-threaded libraries. + * The threadsafe resolver(5) API came out before 2002, and should be on by + * default. */ -#ifndef SET_H_ERRNO -#define SET_H_ERRNO(err) (h_errno = (err)) +#ifndef NO_RES_NCALLS +#define USE_RES_NCALLS #endif /*