]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20010224
authorWietse Venema <wietse@porcupine.org>
Sat, 24 Feb 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:10 +0000 (06:27 +0000)
19 files changed:
postfix/BEWARE [new file with mode: 0644]
postfix/HISTORY
postfix/INSTALL
postfix/INSTALL.sh
postfix/RELEASE_NOTES
postfix/conf/main.cf
postfix/html/basic.html
postfix/src/global/Makefile.in
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/mynetworks.c
postfix/src/global/own_inet_addr.c
postfix/src/global/own_inet_addr.h
postfix/src/postconf/postconf.c
postfix/src/util/inet_addr_local.c
postfix/src/util/inet_addr_local.h
postfix/src/util/safe_open.c
postfix/src/util/sys_defs.h

diff --git a/postfix/BEWARE b/postfix/BEWARE
new file mode 100644 (file)
index 0000000..1b0c418
--- /dev/null
@@ -0,0 +1,11 @@
+LINUX SYSLOGD PERFORMANCE
+=========================
+
+LINUX syslogd uses synchronous writes by default, which is very
+expensive. For services such as mail it is recommended that you
+disable synchronous logfile writes by editing /etc/syslog.conf and
+by prepending a - to the logfile name:
+
+    mail.*                          -/var/log/mail.log
+
+Send a "kill -HUP" to the syslogd to make the change effective.
index 4613ef2c2a70e511c618b2ed203b74362ac41d52..813c90c6554b2d482ad84f4c230dc1a637b17e38 100644 (file)
@@ -4870,13 +4870,6 @@ Apologies for any names omitted.
        will give more insight into how Postfix uses its lookup
        tables. User interface comes later.  File:  util/dict_debug.c.
 
-20010215
-
-       The showq output format assumes queue IDs of up to 10
-       characters.  It can be more with large  file systems.
-       Workaround for 11 character queue IDs by Lamont Jones.
-       File: showq/showq.c.
-
 20010216
 
        Bugfix: the pipe delivery agent expanded $size as if it
@@ -4889,12 +4882,13 @@ Apologies for any names omitted.
        in $mydestination, because Postfix would send one recipient
        at a time, with multiple deliveries of recipients of the
        same message in parallel; a similar problem could exist
-       with firewall relay hosts that forward mail for $mydestination
-       to an inside machine. This behavior is now changed to depend
-       on the transport-specific xxx_destination_recipient_limit
-       parameter.  This also means that you can now get qmail behavior
-       for SMTP deliveries by setting smtp_destination_recipient_limit=1.
-       File:  {qmgr,nqmgr}/qmgr_message.c.
+       with virus scanning and with firewall relay hosts that
+       forward mail for $mydestination to an inside machine. This
+       behavior is now changed to depend on the transport-specific
+       xxx_destination_recipient_limit parameter.  This also means
+       that you can now get qmail behavior for SMTP deliveries by
+       setting smtp_destination_recipient_limit=1.  File:
+       {qmgr,nqmgr}/qmgr_message.c.
 
        Workaround: Solaris socketpair() can fail with EINTR. Added
        a sane_socketpair.c module that joins the ranks of the other
@@ -4912,3 +4906,29 @@ Apologies for any names omitted.
        configuration file edits" has a section that explains that
        mynetworks should be properly configured in order to reject
        unauthorized mail relay requests from strangers.
+
+20010223
+
+       Documentation: the basic.html document has a section that
+       explains that mynetworks should be properly configured in
+       order to reject unauthorized mail relay requests from
+       strangers.
+
+       Feature: new "mynetworks_style" parameter that controls
+       how mynetworks (trusted networks) is derived from the
+       inet_interfaces (machine interfaces) setting. Specify
+       "class" for entire class A, B, C networks; "subnet" for
+       the local subnets only; or "host" for maximal privacy.
+       Files:  util/inet_addr_local.[hc], global/own_inet_addr.[hc],
+       global/mynetworks.[hc], postconf/postconf.c.
+
+       Portability: MACOSX patches by Gerben Wierda.
+
+       Portability: Solaris /dev/null is a symlink, which tripped
+       up the code to safely open a file before delivery. We now
+       grudgingly allow symlinks owned by root. File: util/safe_open.c.
+
+20010224
+
+       Bugfix: "postconf mynetworks" ignored the inet_interfaces
+       setting. That was a very old one. File: postconf/postconf.c.
index c56c93055854991066901070caef240b8217b799..20d58268c25c1507b7b6186b7c587c1acc3f1962 100644 (file)
@@ -74,6 +74,7 @@ If your system is supported, it is one of
     Linux SuSE 6.x
     Linux SuSE 7.x
     Mac OS X server
+    Mac OS X Public Beta
     NEXTSTEP 3.x
     NetBSD 1.x
     OPENSTEP 4.x
@@ -416,10 +417,10 @@ Finally, if you haven't used Sendmail prior to using Postfix, you
 will have to build the alias database (with: sendmail -bi, or:
 newaliases). Be sure to set up aliases for root and postmaster that
 forward mail to a real person. Postfix has a sample aliases file
-the conf/aliases.
+conf/aliases that you can adapt to local conditions.
 
 11 - To chroot or not to chroot
-==============================
+===============================
 
 Postfix can run most daemon processes in a chroot jail, that is,
 the processes run at a fixed low privilege and with access only to
index 2dfbfcbe6b92204d8f6a87067e8628e0058af904..1ad76e988fb9c234c512ca38ff2e7eb65a47f949 100644 (file)
@@ -345,14 +345,18 @@ no) ;;
     )
 esac
 
-test "$need_config" = 1 && cat <<EOF 1>&2
+test "$need_config" = 1 || exit 0
+
+ALIASES=`bin/postconf -h alias_database | sed 's/^[^:]*://'`
+cat <<EOF 1>&2
     
-    Warning: you still need to edit myorigin/mydestination in
-    $CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup
+    Warning: you still need to edit myorigin/mydestination/mynetworks
+    in $CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup
     sites or for sites inside a firewalled network.
     
-    BTW: Edit your alias database and be sure to set up aliases
-    for root and postmaster, then run $NEWALIASES_PATH.
+    BTW: Check your $ALIASES file and be sure to set up aliases
+    for root and postmaster that direct mail to a real person, then
+    run $NEWALIASES_PATH.
 
 EOF
 
index 2b58ef71169e38d419719dea27f0d2840bc6fadc..1cfc98c8ec4a3e6a7c306671b641683865017fef 100644 (file)
@@ -8,9 +8,9 @@ load, at the cost of a small but noticeable slowdown when one runs
 
 Postfix no longer automatically delivers recipients one at a time
 when their domain is listed in $mydestination.  This change solves
-delivery performance problems with delivery via LMTP, and with
-firewall relays that forward all mail for $mydestination to an
-inside host.
+delivery performance problems with delivery via LMTP, with virus
+scanning, and with firewall relays that forward all mail for
+$mydestination to an inside host.
 
 The "one recipient at a time" delivery behavior is now controlled
 by the per-transport recipient limit (xxx_destination_recipient_limit,
index b170c6c54f8fe5faa42ddeb14cd9372a96890aac..b6476b6c5f049fc489d3ad6da57a4390848da0c3 100644 (file)
@@ -123,21 +123,34 @@ mail_owner = postfix
 # RELAY CONTROL
 
 # The mynetworks parameter specifies the list of networks that make
-# up the local neighborhood. The list is used by the anti-UCE software
-# to distinguish local clients from strangers. See permit_mynetworks
-# and smtpd_recipient_restrictions in the file sample-smtpd.cf file.
+# up the local neighborhood. The list is used by the anti-UCE
+# software to relay authorize clients. See the check_relay_domains
+# and and smtpd_recipient_restrictions in the sample-smtpd.cf file.
 #
-# The default is a list of all networks attached to the machine:  a
-# complete class A network (X.0.0.0/8), a complete class B network
-# (X.X.0.0/16), and so on.
+# By default, Postfix derives the mynetworks setting from the local
+# machine network addresses.
+
+# The mynetworks_style parameter specifies how Postfix computes the
+# mynetworks default value from the local machine network addresses.
+#
+# By default (mynetworks_style = subnet), Postfix relay authorizes
+# all clients in the subnets that are attached to this machine.
 # 
-# YOU MUST CHANGE THIS DEFAULT SETTING IF YOUR ADDRESS BLOCK IS PART
-# OF A LARGER ADDRESS RANGE THAT IS OWNED BY YOUR PROVIDER - IT WOULD
-# CAUSE POSTFIX TO RELAY MAIL FROM ALL THEIR CUSTOMERS.
+# Specify "mynetworks_style = class" when you want to relay authorize
+# all clients in the class A, B or C networks that are attached to
+# to this machine.
+#  
+# Specify "mynetworks_style = host" if you do not want to relay
+# authorize clients other than the local machine.
 # 
-# If you need stricter control than the default, specify a list of
-# network/mask patterns, where the mask specifies the number of bits
-# in the network part of a host address.
+# mynetworks_style = class
+# mynetworks_style = subnet
+# mynetworks_style = host
+
+# Instead of implicitly deriving the mynetworks value from local
+# machine addresses, you can specify an explicit list of network/mask
+# patterns, where the mask specifies the number of bits in the network
+# part of a host address.
 #
 # You can also specify the absolute pathname of a pattern file instead
 # of listing the patterns here.
index 19635f6f9bc32d4b9f71b3c7bb81515c088982c2..a769d5619c79b87d3dbfcdc80cca4621755b953d 100644 (file)
@@ -32,6 +32,9 @@ three parameters before you can use the Postfix mail system:
 
 <li> <a href="#mydestination"> What domains to receive mail for
 </a>
+<p>
+
+<li> <a href="#relaying"> What clients to relay mail for </a>
 
 </ul>
 
@@ -158,6 +161,32 @@ hostnames of the machine, including $myhostname, and localhost.$mydomain.
 
 </dl>
 
+<a name="relaying"> <h2> What clients to relay mail for </h2> </a>
+
+By default, Postfix will relay mail for clients in relay authorized
+networks and in relay authorized domains.
+
+<p>
+
+Relay authorized client networks are defined by the <a
+href="#mynetworks">mynetworks</a> parameter. The default is to
+relay authorize all clients in all class A, B or C networks that
+are attached to the machine.  
+
+<p>
+
+<b>YOU MUST <a href="#mynetworks">CHANGE</a> THIS DEFAULT SETTING
+IF YOUR ADDRESS BLOCK IS PART OF A LARGER ADDRESS RANGE THAT IS
+OWNED BY YOUR PROVIDER - IT WOULD CAUSE POSTFIX TO RELAY MAIL FROM
+ALL THEIR CUSTOMERS</b>.
+
+<p>
+
+Relay authorized client domains are by defined by the <a
+href="uce.html#relay_domains"> relay_domains</a> comfiguration
+parameter. The default setting trusts clients with hostnames below
+the domain(s) listed in <a href="#mydestination">mydestination</a>.
+
 <a name="notify"> <h2> What trouble to report to the postmaster
 </h2> </a>
 
@@ -287,8 +316,8 @@ top-level domain).
 
 The <b>mynetworks</b> parameter lists all networks that this machine
 is attached to. This information can be used by the <a href="uce.html">
-anti-UCE</a> features to distinguish between local systems and
-strangers.
+anti-UCE</a> features to distinguish between relay authorized
+clients and relay unauthorized strangers.
 
 <p>
 
@@ -296,7 +325,8 @@ By default, <b>mynetworks</b> is set to the class A, B or C networks
 that the machine is attached to. For example, for my machines at
 home, the result is: <b>168.100.0.0/16 127.0.0.0/8.  </b> However,
 network <b>168.100</b> is owned by my ISP. Of course I do not want
-to consider all their customer systems as local, so I use instead:
+to consider all their customer systems as relay authorized clients,
+so I use instead:
 
 <dl>
 
index 99b16fc42cf20c56fc3b34760dff2576e2fa6cbe..43d75aed068bd2a9273837c2e84fc1f3285cf091 100644 (file)
@@ -781,7 +781,9 @@ mynetworks.o: ../../include/msg.h
 mynetworks.o: ../../include/vstring.h
 mynetworks.o: ../../include/vbuf.h
 mynetworks.o: ../../include/inet_addr_list.h
+mynetworks.o: ../../include/name_mask.h
 mynetworks.o: own_inet_addr.h
+mynetworks.o: mail_params.h
 mynetworks.o: mynetworks.h
 mypwd.o: mypwd.c
 mypwd.o: ../../include/sys_defs.h
index d300ece4de008769aa7912812062d02bf62e1d8d..52cf7e61b16fa3385cb41c4b344b349678c25c37 100644 (file)
@@ -60,6 +60,7 @@
 /*     char    *var_relay_domains;
 /*     char    *var_fflush_domains;
 /*     char    *var_def_transport;
+/*     char    *var_mynetworks_style;
 /*
 /*     char    *var_import_environ;
 /*     char    *var_export_environ;
@@ -172,6 +173,7 @@ char   *var_syslog_facility;
 char   *var_relay_domains;
 char   *var_fflush_domains;
 char   *var_def_transport;
+char   *var_mynetworks_style;
 
 char   *var_import_environ;
 char   *var_export_environ;
@@ -290,6 +292,7 @@ void    mail_params_init()
        VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0,
        VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0,
        VAR_DEF_TRANSPORT, DEF_DEF_TRANSPORT, &var_def_transport, 0, 0,
+       VAR_MYNETWORKS_STYLE, DEF_MYNETWORKS_STYLE, &var_mynetworks_style, 1, 0,
        0,
     };
     static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
index cf789375ea11d0f391b542e44aa5623286df6fd4..02eb7fd6a6b441145b5dd37b94930305dd2dbc7d 100644 (file)
@@ -990,6 +990,14 @@ extern int var_trigger_timeout;
 #define VAR_MYNETWORKS         "mynetworks"
 extern char *var_mynetworks;
 
+#define VAR_MYNETWORKS_STYLE   "mynetworks_style"
+#define DEF_MYNETWORKS_STYLE   MYNETWORKS_STYLE_SUBNET
+extern char *var_mynetworks_style;
+
+#define        MYNETWORKS_STYLE_CLASS  "class"
+#define        MYNETWORKS_STYLE_SUBNET "subnet"
+#define        MYNETWORKS_STYLE_HOST   "host"
+
 #define VAR_RELAY_DOMAINS      "relay_domains"
 #define DEF_RELAY_DOMAINS      "$mydestination"
 extern char *var_relay_domains;
index 7482f815ee8c33b9efcb5c1ead1b3d8e96753739..291dc89bd2b3cf6b88ff377916d8c217b45e685b 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20010222"
+#define DEF_MAIL_VERSION       "Snapshot-20010224"
 extern char *var_mail_version;
 
 /* LICENSE
index cd1f54f671f4721480827a22e43e041618bd5551..5eb649ba344d6584a740e89ba5bf099ff833395d 100644 (file)
 /* DESCRIPTION
 /*     This routine uses the address list built by own_inet_addr()
 /*     to produce a list of patterns that match the corresponding
-/*     networks. The patterns are conservative: they match whole
-/*     class A, B, C or D networks. This is usually sufficient to
-/*     distinguish between organizations.
+/*     networks.
+/*
+/*     The interface list is specified with the "inet_interfaces"
+/*     configuration parameter.
+/*
+/*     The address to netblock conversion style is specified with
+/*     the "mynetworks_style" parameter: one of "class" (match
+/*     whole class A, B, C or D networks), "subnet" (match local
+/*     subnets), or "host" (match local interfaces only).
 /* LICENSE
 /* .ad
 /* .fi
 #include <msg.h>
 #include <vstring.h>
 #include <inet_addr_list.h>
+#include <name_mask.h>
 
 /* Global library. */
 
 #include <own_inet_addr.h>
+#include <mail_params.h>
 #include <mynetworks.h>
 
+/* Application-specific. */
+
+#define MASK_STYLE_CLASS       (1 << 0)
+#define MASK_STYLE_SUBNET      (1 << 1)
+#define MASK_STYLE_HOST                (1 << 2)
+
+static NAME_MASK mask_styles[] = {
+    MYNETWORKS_STYLE_CLASS, MASK_STYLE_CLASS,
+    MYNETWORKS_STYLE_SUBNET, MASK_STYLE_SUBNET,
+    MYNETWORKS_STYLE_HOST, MASK_STYLE_HOST,
+    0,
+};
+
 /* mynetworks - return patterns that match my own networks */
 
 const char *mynetworks(void)
@@ -58,32 +79,71 @@ const char *mynetworks(void)
     if (result == 0) {
        char   *myname = "mynetworks";
        INET_ADDR_LIST *my_addr_list;
+       INET_ADDR_LIST *my_mask_list;
        unsigned long addr;
        unsigned long mask;
        struct in_addr net;
        int     shift;
+       int     junk;
        int     i;
+       int     mask_style;
+
+       mask_style = name_mask("mynetworks mask style", mask_styles,
+                              var_mynetworks_style);
 
        result = vstring_alloc(20);
        my_addr_list = own_inet_addr_list();
+       my_mask_list = own_inet_mask_list();
 
        for (i = 0; i < my_addr_list->used; i++) {
            addr = ntohl(my_addr_list->addrs[i].s_addr);
-           if (IN_CLASSA(addr)) {
-               mask = IN_CLASSA_NET;
-               shift = IN_CLASSA_NSHIFT;
-           } else if (IN_CLASSB(addr)) {
-               mask = IN_CLASSB_NET;
-               shift = IN_CLASSB_NSHIFT;
-           } else if (IN_CLASSC(addr)) {
-               mask = IN_CLASSC_NET;
-               shift = IN_CLASSC_NSHIFT;
-           } else if (IN_CLASSD(addr)) {
-               mask = IN_CLASSD_NET;
-               shift = IN_CLASSD_NSHIFT;
-           } else {
-               msg_fatal("%s: bad address class: %s",
-                         myname, inet_ntoa(my_addr_list->addrs[i]));
+           mask = ntohl(my_mask_list->addrs[i].s_addr);
+
+           switch (mask_style) {
+
+               /*
+                * Natural mask. This is dangerous if you're customer of an
+                * ISP who gave you a small portion of their network.
+                */
+           case MASK_STYLE_CLASS:
+               if (IN_CLASSA(addr)) {
+                   mask = IN_CLASSA_NET;
+                   shift = IN_CLASSA_NSHIFT;
+               } else if (IN_CLASSB(addr)) {
+                   mask = IN_CLASSB_NET;
+                   shift = IN_CLASSB_NSHIFT;
+               } else if (IN_CLASSC(addr)) {
+                   mask = IN_CLASSC_NET;
+                   shift = IN_CLASSC_NSHIFT;
+               } else if (IN_CLASSD(addr)) {
+                   mask = IN_CLASSD_NET;
+                   shift = IN_CLASSD_NSHIFT;
+               } else {
+                   msg_fatal("%s: bad address class: %s",
+                             myname, inet_ntoa(my_addr_list->addrs[i]));
+               }
+               break;
+
+               /*
+                * Subnet mask. This is safe, but breaks backwards
+                * compatibility when used as default setting.
+                */
+           case MASK_STYLE_SUBNET:
+               for (junk = mask, shift = BITS_PER_ADDR; junk != 0; shift--, (junk <<= 1))
+                    /* void */ ;
+               break;
+
+               /*
+                * Host only. Do not relay authorize other hosts.
+                */
+           case MASK_STYLE_HOST:
+               mask = ~0;
+               shift = 0;
+               break;
+
+           default:
+               msg_panic("unknown mynetworks mask style: %s",
+                         var_mynetworks_style);
            }
            net.s_addr = htonl(addr & mask);
            vstring_sprintf_append(result, "%s/%d ",
@@ -98,13 +158,15 @@ const char *mynetworks(void)
 #ifdef TEST
 
 char   *var_inet_interfaces;
+char   *var_mynetworks_style;
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
-    if (argc != 2)
-       msg_fatal("usage: %s interface_list", argv[0]);
+    if (argc != 3)
+       msg_fatal("usage: %s mask_style interface_list", argv[0]);
     msg_verbose = 10;
-    var_inet_interfaces = argv[1];
+    var_inet_interfaces = argv[2];
+    var_mynetworks_style = argv[1];
     mynetworks();
 }
 
index d33a25009cdfe5470a846d1fdebd6a6c85dae31e..f06232989c641b615553efa78a2a25cda901e5f0 100644 (file)
@@ -10,6 +10,8 @@
 /*     struct in_addr *addr;
 /*
 /*     INET_ADDR_LIST *own_inet_addr_list()
+/*
+/*     INET_ADDR_LIST *own_inet_mask_list()
 /* DESCRIPTION
 /*     own_inet_addr() determines if the specified IP address belongs
 /*     to this mail system instance, i.e. if this mail system instance
@@ -17,6 +19,9 @@
 /*
 /*     own_inet_addr_list() returns the list of all addresses that
 /*     belong to this mail system instance.
+/*
+/*     own_inet_mask_list() returns the list of all corresponding
+/*     netmasks.
 /* LICENSE
 /* .ad
 /* .fi
 /* Application-specific. */
 
 static INET_ADDR_LIST addr_list;
+static INET_ADDR_LIST mask_list;
 
 /* own_inet_addr_init - initialize my own address list */
 
-static void own_inet_addr_init(INET_ADDR_LIST *addr_list)
+static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
+                                      INET_ADDR_LIST *mask_list)
 {
+    INET_ADDR_LIST local_addrs;
+    INET_ADDR_LIST local_masks;
     char   *hosts;
     char   *host;
     char   *sep = " \t,";
     char   *bufp;
+    int     nvirtual;
+    int     nlocal;
 
     inet_addr_list_init(addr_list);
+    inet_addr_list_init(mask_list);
 
     /*
      * If we are listening on all interfaces (default), ask the system what
      * the interfaces are.
      */
     if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
-       if (inet_addr_local(addr_list) == 0)
+       if (inet_addr_local(addr_list, mask_list) == 0)
            msg_fatal("could not find any active network interfaces");
 #if 0
        if (addr_list->used == 1)
@@ -94,6 +106,26 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list)
                msg_fatal("config variable %s: host not found: %s",
                          VAR_INET_INTERFACES, host);
        myfree(hosts);
+
+       inet_addr_list_init(&local_addrs);
+       inet_addr_list_init(&local_masks);
+       if (inet_addr_local(&local_addrs, &local_masks) == 0)
+           msg_fatal("could not find any active network interfaces");
+       for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
+           for (nlocal = 0; /* see below */ ; nlocal++) {
+               if (nlocal >= local_addrs.used)
+                   msg_fatal("parameter %s: no local interface found for %s",
+                             VAR_INET_INTERFACES,
+                             inet_ntoa(addr_list->addrs[nvirtual]));
+               if (addr_list->addrs[nvirtual].s_addr
+                   == local_addrs.addrs[nlocal].s_addr) {
+                   inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
+                   break;
+               }
+           }
+       }
+       inet_addr_list_free(&local_addrs);
+       inet_addr_list_free(&local_masks);
     }
 }
 
@@ -104,7 +136,7 @@ int     own_inet_addr(struct in_addr * addr)
     int     i;
 
     if (addr_list.used == 0)
-       own_inet_addr_init(&addr_list);
+       own_inet_addr_init(&addr_list, &mask_list);
 
     for (i = 0; i < addr_list.used; i++)
        if (addr->s_addr == addr_list.addrs[i].s_addr)
@@ -117,7 +149,17 @@ int     own_inet_addr(struct in_addr * addr)
 INET_ADDR_LIST *own_inet_addr_list(void)
 {
     if (addr_list.used == 0)
-       own_inet_addr_init(&addr_list);
+       own_inet_addr_init(&addr_list, &mask_list);
 
     return (&addr_list);
 }
+
+/* own_inet_mask_list - return list of addresses */
+
+INET_ADDR_LIST *own_inet_mask_list(void)
+{
+    if (addr_list.used == 0)
+       own_inet_addr_init(&addr_list, &mask_list);
+
+    return (&mask_list);
+}
index ad984c818c3b352eb6521c20b79ef25dbb220500..5a38b58f789926612ddc2f2b1dcf28373368e3d1 100644 (file)
@@ -21,6 +21,7 @@
   */
 extern int own_inet_addr(struct in_addr *);
 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
+extern struct INET_ADDR_LIST *own_inet_mask_list(void);
 
 /* LICENSE
 /* .ad
index c40200727479e455e31361baa5e7a5d276d4876f..512ed8ed96a0e42befd8faa26f0cca443700a303 100644 (file)
@@ -253,8 +253,20 @@ static const char *check_mydomainname(void)
 
 static const char *check_mynetworks(void)
 {
-    if (var_inet_interfaces == 0)
-       var_inet_interfaces = mystrdup(DEF_INET_INTERFACES);
+    const char *junk;
+
+    if (var_inet_interfaces == 0) {
+       if ((mode & SHOW_DEFS)
+           || !(junk = mail_conf_lookup(VAR_INET_INTERFACES)))
+           junk = DEF_INET_INTERFACES;
+       var_inet_interfaces = mystrdup(junk);
+    }
+    if (var_mynetworks_style == 0) {
+       if ((mode & SHOW_DEFS)
+           || !(junk = mail_conf_lookup(VAR_MYNETWORKS_STYLE)))
+           junk = DEF_MYNETWORKS_STYLE;
+       var_mynetworks_style = mystrdup(junk);
+    }
     return (mynetworks());
 }
 
index 9a53d8d6f8a40b4e94965b24585916094929cbc3..5eca343978a64750b621f10812030f16c0bcb07b 100644 (file)
@@ -6,13 +6,17 @@
 /* SYNOPSIS
 /*     #include <inet_addr_local.h>
 /*
-/*     int     inet_addr_local(list)
-/*     INET_ADDR_LIST *list;
+/*     int     inet_addr_local(addr_list, mask_list)
+/*     INET_ADDR_LIST *addr_list;
+/*     INET_ADDR_LIST *mask_list;
 /* DESCRIPTION
 /*     inet_addr_local() determines all active IP interface addresses
 /*     of the local system. Any address found is appended to the
 /*     specified address list. The result value is the number of
 /*     active interfaces found.
+/*
+/*     The mask_list is either a null pointer, or it is an list
+/*     that receives the netmasks corresponding to the address list.
 /* DIAGNOSTICS
 /*     Fatal errors: out of memory.
 /* SEE ALSO
@@ -68,7 +72,7 @@
 
 /* inet_addr_local - find all IP addresses for this host */
 
-int     inet_addr_local(INET_ADDR_LIST *addr_list)
+int     inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
 {
     char   *myname = "inet_addr_local";
     struct ifconf ifc;
@@ -119,8 +123,15 @@ int     inet_addr_local(INET_ADDR_LIST *addr_list)
     for (ifr = ifc.ifc_req; ifr < the_end;) {
        if (ifr->ifr_addr.sa_family == AF_INET) {       /* IP interface */
            addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
-           if (addr.s_addr != INADDR_ANY)      /* has IP address */
+           if (addr.s_addr != INADDR_ANY) {    /* has IP address */
                inet_addr_list_append(addr_list, &addr);
+               if (mask_list) {
+                   if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
+                       msg_fatal("%s: ioctl SIOCGIFNETMASK: %m", myname);
+                   addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
+                   inet_addr_list_append(mask_list, &addr);
+               }
+           }
        }
        ifr = NEXT_INTERFACE(ifr);
     }
@@ -137,12 +148,14 @@ int     inet_addr_local(INET_ADDR_LIST *addr_list)
 int     main(int unused_argc, char **argv)
 {
     INET_ADDR_LIST addr_list;
+    INET_ADDR_LIST mask_list;
     int     i;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
     inet_addr_list_init(&addr_list);
-    inet_addr_local(&addr_list);
+    inet_addr_list_init(&mask_list);
+    inet_addr_local(&addr_list, &mask_list);
 
     if (addr_list.used == 0)
        msg_fatal("cannot find any active network interfaces");
@@ -150,10 +163,13 @@ int     main(int unused_argc, char **argv)
     if (addr_list.used == 1)
        msg_warn("found only one active network interface");
 
-    for (i = 0; i < addr_list.used; i++)
-       vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
+    for (i = 0; i < addr_list.used; i++) {
+       vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
+       vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
+    }
     vstream_fflush(VSTREAM_OUT);
     inet_addr_list_free(&addr_list);
+    inet_addr_list_free(&mask_list);
 }
 
 #endif
index f48ca1eb0fc312247ca1628d64a6d3ca6291cc3a..969264fe2e6712185246df780ecac6bf386fe248 100644 (file)
@@ -19,7 +19,7 @@
  /*
   * External interface.
   */
-extern int inet_addr_local(INET_ADDR_LIST *);
+extern int inet_addr_local(INET_ADDR_LIST *, INET_ADDR_LIST *);
 
 /* LICENSE
 /* .ad
index f582cc1f09c20915190cb985330cf370c55595bd..e1e88f8b475da1699336a1d3f8114350570293a5 100644 (file)
@@ -87,7 +87,7 @@
 /* safe_open_exist - open existing file */
 
 static VSTREAM *safe_open_exist(const char *path, int flags,
-                                     struct stat * fstat_st, VSTRING * why)
+                                       struct stat * fstat_st, VSTRING *why)
 {
     struct stat local_statbuf;
     struct stat lstat_st;
@@ -127,17 +127,26 @@ static VSTREAM *safe_open_exist(const char *path, int flags,
      * slowed down by arbitrary amounts, and there it would make sense to
      * compare even more file attributes, such as the inode generation number
      * on systems that have one.
+     * 
+     * Grr. Solaris /dev/whatever is a symlink. We'll have to make an exception
+     * for symlinks owned by root. NEVER, NEVER, make exceptions for symlinks
+     * owned by a non-root user. This would open a security hole when
+     * delivering mail to a world-writable mailbox directory.
      */
-    else if (lstat(path, &lstat_st) < 0
-            || fstat_st->st_dev != lstat_st.st_dev
-            || fstat_st->st_ino != lstat_st.st_ino
+    else if (lstat(path, &lstat_st) < 0) {
+       vstring_sprintf(why, "file status changed unexpectedly: %m");
+    } else if (S_ISLNK(lstat_st.st_mode)) {
+       if (lstat_st.st_uid == 0)
+           return (fp);
+       vstring_sprintf(why, "file is a symbolic link");
+    } else if (fstat_st->st_dev != lstat_st.st_dev
+              || fstat_st->st_ino != lstat_st.st_ino
 #ifdef HAS_ST_GEN
-            || fstat_st->st_gen != lstat_st.st_gen
+              || fstat_st->st_gen != lstat_st.st_gen
 #endif
-            || fstat_st->st_nlink != lstat_st.st_nlink
-            || fstat_st->st_mode != lstat_st.st_mode) {
-       vstring_sprintf(why, "%s", S_ISLNK(lstat_st.st_mode) ?
-           "file is a symbolic link" : "file status changed unexpectedly");
+              || fstat_st->st_nlink != lstat_st.st_nlink
+              || fstat_st->st_mode != lstat_st.st_mode) {
+       vstring_sprintf(why, "file status changed unexpectedly");
     }
 
     /*
@@ -159,7 +168,7 @@ static VSTREAM *safe_open_exist(const char *path, int flags,
 /* safe_open_create - create new file */
 
 static VSTREAM *safe_open_create(const char *path, int flags, int mode,
-                  struct stat * st, uid_t user, uid_t group, VSTRING * why)
+                   struct stat * st, uid_t user, uid_t group, VSTRING *why)
 {
     VSTREAM *fp;
 
@@ -207,7 +216,7 @@ static VSTREAM *safe_open_create(const char *path, int flags, int mode,
 /* safe_open - safely open or create file */
 
 VSTREAM *safe_open(const char *path, int flags, int mode,
-                  struct stat * st, uid_t user, gid_t group, VSTRING * why)
+                   struct stat * st, uid_t user, gid_t group, VSTRING *why)
 {
     VSTREAM *fp;
 
index f7c118624c5e3c12056184f3806f940a3f03cc34..1b1d3df54ce75db4a71f9f3488a575157e010652 100644 (file)
@@ -853,6 +853,7 @@ typedef int pid_t;
 #define S_ISSOCK(mode) (((mode) & (_S_IFMT)) == (_S_IFSOCK))
 #define S_ISFIFO(mode) (((mode) & (_S_IFMT)) == (_S_IFIFO))
 #define S_ISREG(mode)  (((mode) & (_S_IFMT)) == (_S_IFREG))
+#define S_ISLNK(mode)  (((mode) & (_S_IFMT)) == (_S_IFLNK))
 #endif
 
 #ifdef MISSING_POSIX_S_MODES