]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.6-20200511
authorWietse Venema <wietse@porcupine.org>
Mon, 11 May 2020 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 13 May 2020 19:26:14 +0000 (15:26 -0400)
15 files changed:
postfix/HISTORY
postfix/INSTALL
postfix/README_FILES/INSTALL
postfix/RELEASE_NOTES
postfix/html/INSTALL.html
postfix/html/makedefs.1.html
postfix/makedefs
postfix/man/man1/makedefs.1
postfix/proto/INSTALL.html
postfix/src/dns/dns_lookup.c
postfix/src/global/mail_params.c
postfix/src/global/mail_version.h
postfix/src/util/midna_domain.c
postfix/src/util/midna_domain.h
postfix/src/util/sys_defs.h

index f117d89a5d813542b3418191827029abad6e06cd..856b2db512c8e2cdf19122e6bc75dd756282e303 100644 (file)
@@ -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.
index 10e69408c8b71a92e7a729977930d484b6575b71..28a7e68a32e22c6e17eee809a8987414263c73d9 100644 (file)
@@ -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 |
index 14e61caf003d2e43e073154fa67d6ea1c688d34f..ffc738b523be5335b65180644392eaf5429f4424 100644 (file)
@@ -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.        |
 |_\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+||-DNO_RES_NCALLS              |Do not build with the threadsafe resolver(5) |
+||                              |API (res_ninit() etc.).                      |
+|_\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
 ||                              |Use setjmp()/longjmp() instead of sigsetjmp  |
 ||-DNO_SIGSETJMP                |()/siglongjmp(). By default, Postfix uses    |
 ||                              |sigsetjmp()/siglongjmp() when they are known |
index 204429d276b2ce280bdaba63d63cb8ea37fc2be4..1a9a2ce9d317f154ce188d6c841211f958d7866c 100644 (file)
@@ -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.
index 2ee35cdf943c70b8d19074a04b94a9c0c00414bd..c4875d4728b0c2cc7e3ddad256b26eae18286673 100644 (file)
@@ -863,6 +863,9 @@ support. By default, PCRE support is compiled in when the
 for POSIX <tt>getpwnam_r/getpwuid_r</tt>. By default Postfix uses
 these where they are known to be available. </td> </tr>
 
+<tr> <td> </td> <td> -DNO_RES_NCALLS </td> <td> Do not build with
+the threadsafe resolver(5) API (res_ninit() etc.). </td> </tr>
+
 <tr> <td> </td> <td> -DNO_SIGSETJMP </td> <td> Use
 <tt>setjmp()/longjmp()</tt> instead of <tt>sigsetjmp()/siglongjmp()</tt>.
 By default, Postfix uses <tt>sigsetjmp()/siglongjmp()</tt> when
index cf1f02c1743ab65cd842a199f8b8112ee22d2c23..62b29d9f67e4ce64c9101c92f3c2e2a4857d9768 100644 (file)
@@ -109,42 +109,46 @@ MAKEDEFS(1)                                                        MAKEDEFS(1)
               <b>-DNO_POSIX_GETPW_R</b>
                      Disable support for POSIX getpwnam_r/getpwuid_r.
 
+              <b>-DNO_RES_NCALLS</b>
+                     Do   not   build  with  the  threadsafe  resolver(5)  API
+                     (res_ninit() etc.).
+
               <b>-DNO_SIGSETJMP</b>
-                     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.
 
               <b>-DNO_SNPRINTF</b>
-                     Use  sprintf() instead of snprintf(). By default, Postfix
+                     Use sprintf() instead of snprintf(). By default,  Postfix
                      uses snprintf() except on ancient systems.
 
        <b>DEBUG=</b><i>debug</i><b>_</b><i>level</i>
-              Specifies a non-default debugging  level.  The  default  is  <b>-g</b>.
+              Specifies  a  non-default  debugging  level.  The default is <b>-g</b>.
               Specify <b>DEBUG=</b> to turn off debugging.
 
        <b>OPT=</b><i>optimization</i><b>_</b><i>level</i>
-              Specifies  a  non-default optimization level. The default is <b>-O</b>.
+              Specifies a non-default optimization level. The default  is  <b>-O</b>.
               Specify <b>OPT=</b> to turn off optimization.
 
        <b>POSTFIX_INSTALL_OPTS=</b><i>-option...</i>
-              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
               <b>-keep-build-mtime</b>.
 
        <b>SHLIB_CFLAGS=</b><i>flags</i>
-              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.
 
        <b>SHLIB_RPATH=</b><i>rpath</i>
-              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.
 
        <b>SHLIB_SUFFIX=</b><i>suffix</i>
-              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)
        <b>shared=yes</b>
 
        <b>shared=no</b>
-              Enable   (disable)   Postfix   builds   with  dynamically-linked
+              Enable  (disable)   Postfix   builds   with   dynamically-linked
               libraries typically named $<a href="postconf.5.html#shlib_directory">shlib_directory</a>/libpostfix-*.so.*.
 
               This feature was introduced with Postfix 3.0.
@@ -160,39 +164,39 @@ MAKEDEFS(1)                                                        MAKEDEFS(1)
        <b>dynamicmaps=yes</b>
 
        <b>dynamicmaps=no</b>
-              Enable (disable) Postfix  builds  with  the  configuration  file
+              Enable  (disable)  Postfix  builds  with  the configuration file
               $<a href="postconf.5.html#meta_directory">meta_directory</a>/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.
 
        <b>pie=yes</b>
 
-       <b>pie=no</b> Enable (disable) Postfix builds with  position-independent  exe-
+       <b>pie=no</b> Enable  (disable)  Postfix builds with position-independent exe-
               cutables, on platforms where this is supported.
 
               This feature was introduced with Postfix 3.0.
 
        <i>installation</i><b>_</b><i>parameter</i><b>=</b><i>value</i>...
-              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:
 
-              <a href="postconf.5.html#command_directory">command_directory</a>  <a href="postconf.5.html#config_directory">config_directory</a> <a href="postconf.5.html#daemon_directory">daemon_directory</a> <a href="postconf.5.html#data_directory">data_direc</a>-
-              <a href="postconf.5.html#data_directory">tory</a> <a href="postconf.5.html#default_database_type">default_database_type</a>  <a href="postconf.5.html#html_directory">html_directory</a>  <a href="postconf.5.html#mail_spool_directory">mail_spool_directory</a>
-              <a href="postconf.5.html#mailq_path">mailq_path</a>   <a href="postconf.5.html#manpage_directory">manpage_directory</a>   <a href="postconf.5.html#meta_directory">meta_directory</a>  <a href="postconf.5.html#newaliases_path">newaliases_path</a>
-              <a href="postconf.5.html#queue_directory">queue_directory</a> <a href="postconf.5.html#readme_directory">readme_directory</a>  <a href="postconf.5.html#sendmail_path">sendmail_path</a>  <a href="postconf.5.html#shlib_directory">shlib_directory</a>
+              <a href="postconf.5.html#command_directory">command_directory</a> <a href="postconf.5.html#config_directory">config_directory</a> <a href="postconf.5.html#daemon_directory">daemon_directory</a>  <a href="postconf.5.html#data_directory">data_direc</a>-
+              <a href="postconf.5.html#data_directory">tory</a>  <a href="postconf.5.html#default_database_type">default_database_type</a>  <a href="postconf.5.html#html_directory">html_directory</a> <a href="postconf.5.html#mail_spool_directory">mail_spool_directory</a>
+              <a href="postconf.5.html#mailq_path">mailq_path</a>  <a href="postconf.5.html#manpage_directory">manpage_directory</a>   <a href="postconf.5.html#meta_directory">meta_directory</a>   <a href="postconf.5.html#newaliases_path">newaliases_path</a>
+              <a href="postconf.5.html#queue_directory">queue_directory</a>  <a href="postconf.5.html#readme_directory">readme_directory</a>  <a href="postconf.5.html#sendmail_path">sendmail_path</a> <a href="postconf.5.html#shlib_directory">shlib_directory</a>
               <a href="postconf.5.html#openssl_path">openssl_path</a>
 
-              See  the  <a href="postconf.5.html">postconf(5)</a> manpage for a description of these parame-
+              See the <a href="postconf.5.html">postconf(5)</a> manpage for a description of  these  parame-
               ters.
 
               This feature was introduced with Postfix 3.0.
 
        <b>WARN=</b><i>warning</i><b>_</b><i>flags</i>
-              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.
 
 <b>LICENSE</b>
index 6f436f4c08173087f4218cfd22cb554f7202f311..148f173a86d1b50c7bce9618b20a06be10476a75 100644 (file)
@@ -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
index 34c9d013ad288c6823e170f7c6995de184099fdc..adc2af2f94fa2cebdbc66e48ad575bdadd2feb57 100644 (file)
@@ -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
index 984528cbe8130ba3b43ac1ae3fa41ef483497e90..8c9a23d7e0751fd7ac4f8c974fd887b09e7142dd 100644 (file)
@@ -863,6 +863,9 @@ support. By default, PCRE support is compiled in when the
 for POSIX <tt>getpwnam_r/getpwuid_r</tt>. By default Postfix uses
 these where they are known to be available. </td> </tr>
 
+<tr> <td> </td> <td> -DNO_RES_NCALLS </td> <td> Do not build with
+the threadsafe resolver(5) API (res_ninit() etc.). </td> </tr>
+
 <tr> <td> </td> <td> -DNO_SIGSETJMP </td> <td> Use
 <tt>setjmp()/longjmp()</tt> instead of <tt>sigsetjmp()/siglongjmp()</tt>.
 By default, Postfix uses <tt>sigsetjmp()/siglongjmp()</tt> when
index 11c92813437d05d27cde8b50a3b3923edb69bba2..d4d494f6184fcc600268d6c07e2f7e50fb6efac6 100644 (file)
@@ -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)
index 8b4ad0ba4c563597080e415b8ac2b754f4a26adb..91c70f75e21ed2012f6a971589e4e6298083e176 100644 (file)
@@ -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;
 
index 9bfbcf7cd146b7eedfa4e332332a4edac3e4cde9..2edd10252321bf0b81bdc340f11adb4f2c842f9c 100644 (file)
@@ -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
index 667e75e59f0c5415a9903faae5631e222ac18647..333a5c91d74819c10297ca7907e29bd556e881dc 100644 (file)
@@ -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 <unistd.h>
 #include <stdlib.h>
 #include <locale.h>
 
@@ -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);
index 03d875b106c4a0b4a944118e50652dfa09a36536..1abe2a173b7e70b064df67756c6368ddebe4c371 100644 (file)
@@ -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;
index 17e52b229cb3303188619111a1c5ca4a68491777..c491b2203ecd9e89f7c412aaf172b2c1519547ee 100644 (file)
@@ -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
 
  /*