]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-19991120
authorWietse Venema <wietse@porcupine.org>
Sat, 20 Nov 1999 05:00:00 +0000 (00:00 -0500)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 23:09:47 +0000 (18:09 -0500)
34 files changed:
postfix/HISTORY
postfix/INSTALL.sh
postfix/RELEASE_NOTES
postfix/RESTRICTION_CLASS [new file with mode: 0644]
postfix/aux/rmail/rmail [new file with mode: 0755]
postfix/conf/master.cf
postfix/conf/sample-smtpd.cf
postfix/dns/dns_lookup.c
postfix/global/local_transport.c
postfix/global/local_transport.h
postfix/global/mail_addr_map.c
postfix/global/mail_params.c
postfix/global/mail_version.h
postfix/global/pipe_command.c
postfix/global/tok822_parse.c
postfix/html/postconf.1.html
postfix/html/smtpd.8.html
postfix/html/uce.html
postfix/local/resolve.c
postfix/man/man1/postconf.1
postfix/man/man8/smtpd.8
postfix/postconf/postconf.c
postfix/qmgr/qmgr_message.c
postfix/smtp/smtp_connect.c
postfix/smtpd/Makefile.in
postfix/smtpd/smtpd.h
postfix/smtpd/smtpd_check.c
postfix/smtpd/smtpd_check.in
postfix/smtpd/smtpd_check.in2
postfix/smtpd/smtpd_check.ref
postfix/smtpd/smtpd_check.ref2
postfix/smtpd/smtpd_check_access
postfix/smtpd/smtpd_peer.c
postfix/smtpd/smtpd_state.c

index 9acf0f127930a40a435951fb1f5b10ad208970d1..1c0e4895be7f96a42c901e8bd726eb8f89d1bede 100644 (file)
@@ -3226,11 +3226,11 @@ Apologies for any names omitted.
 19991116
 
        Code cleanup: a new "local_transports" configuration
-       parameter explicitly lists all transports that deliver
-       mail locally. The first name listed there is the default
-       local transport.  This is the end of the "empty next-hop
-       hostname" hack to indicate that a destination is local.
-       Files:  trivial-rewrite/resolve.c, global/local_transport.[hc]
+       parameter explicitly lists all transports that deliver mail
+       locally. The first name listed there is the default local
+       transport.  This is the end of the "empty next-hop hostname"
+       hack to indicate that a destination is local.  Files:
+       trivial-rewrite/resolve.c, global/local_transport.[hc]
 
        Feature: "postconf -m" shows what lookup table types are
        available.  Code by Scott Cotton, Internet Consultants
@@ -3243,6 +3243,8 @@ Apologies for any names omitted.
 
 19991117
 
+       Portability: SunOS 4 has no SA_RESTART. File: util/watchdog.c.
+
        Feature: on systems with h_errno, the "reject_unknown_client"
        restriction now distinguishes between soft errors (always
        reply with 450) and hard errors (use the user-specified
@@ -3256,3 +3258,25 @@ Apologies for any names omitted.
        Robustness: postconf no longer aborts when it can't figure
        out the local domain name; it prints a warning instead.
        This allows you to use "postconf -e" to fix the problem.
+
+19991118
+
+       Bugfix: the RFC822 address parser would misparse a leading
+       \ as an atom all by itself. Problem reported by Keith
+       Stevenson @ louisville.edu. File: global/tok822_parse.c.
+
+19991119
+
+       Bugfix: tiny memory leak in pipe_command() when fork()
+       fails.  File: global/pipe_command.c.
+
+19991120
+
+       Bugfix: reversed test for all-numerical results in SMTPD
+       access maps. File: smtpd/smtpd_check.c.
+
+19991121
+
+       Robustness: INSTALL.sh no longer uses postmap for sanity checks.
+
+       Feature: INSTALL.sh now has an install_root option.
index 9cebaaec8df075ccbdb1a049906edce31ca58005..50f4b83a0ab27c7df24ca088f6784f13a6dc7ea6 100644 (file)
@@ -6,31 +6,6 @@
 PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc
 umask 022
 
-# Default settings, edit to taste or change interactively. Once this
-# script has run it saves settings to $config_directory/install.cf.
-
-config_directory=/etc/postfix
-daemon_directory=/usr/libexec/postfix
-command_directory=/usr/sbin
-queue_directory=/var/spool/postfix
-sendmail_path=/usr/sbin/sendmail
-newaliases_path=/usr/bin/newaliases
-mailq_path=/usr/bin/mailq
-mail_owner=postfix
-setgid=no
-manpages=no
-
-# Load defaults from existing installation.
-
-test -f $config_directory/main.cf && {
-    for name in daemon_directory command_directory queue_directory mail_owner 
-    do
-       eval "$name=\"\`bin/postconf -h $name || kill \$\$\`\""
-    done
-}
-
-test -f $config_directory/install.cf && . $config_directory/install.cf
-
 cat <<EOF
 
 Warning: this script replaces existing sendmail or Postfix programs.
@@ -45,6 +20,8 @@ Before installing files, this script prompts you for some definitions.
 You can either edit this script ahead of time, or you can specify
 your changes interactively.
 
+    install_root - prepend to installed file names (for package building)
+
     config_directory - directory with Postfix configuration files.
     daemon_directory - directory with Postfix daemon programs.
     command_directory - directory with Postfix administrative commands.
@@ -65,6 +42,7 @@ EOF
 
 compare_or_replace() {
     cmp $2 $3 >/dev/null 2>&1 || {
+       rm -f junk || exit 1
        cp $2 junk || exit 1
        mv -f junk $3 || exit 1
        chmod $1 $3 || exit 1
@@ -73,6 +51,7 @@ compare_or_replace() {
 
 compare_or_symlink() {
     cmp $1 $2 >/dev/null 2>&1 || {
+       rm -f junk || exit 1
        ln -s $1 junk || exit 1
        mv -f junk $2 || exit 1
     }
@@ -92,6 +71,44 @@ case `echo -n` in
  *) n=; c='\c';;
 esac
 
+# Default settings, edit to taste or change interactively. Once this
+# script has run it saves settings to $config_directory/install.cf.
+
+config_directory=/etc/postfix
+daemon_directory=/usr/libexec/postfix
+command_directory=/usr/sbin
+queue_directory=/var/spool/postfix
+sendmail_path=/usr/sbin/sendmail
+newaliases_path=/usr/bin/newaliases
+mailq_path=/usr/bin/mailq
+mail_owner=postfix
+setgid=no
+manpages=no
+
+while :
+do
+    echo $n "install_root: [/] $c"
+    read ans
+    case $ans in
+""|/|no) install_root=; break;;
+     /*) install_root=$ans; break;;
+      *) echo "install_root should be an absolute path name" 1>&2; exit 1;;
+    esac
+done
+
+# Load defaults from existing installation.
+
+CONFIG_DIRECTORY=$install_root$config_directory
+
+test -f $CONFIG_DIRECTORY/main.cf && {
+    for name in daemon_directory command_directory queue_directory mail_owner 
+    do
+       eval "$name=\"\`bin/postconf -c $CONFIG_DIRECTORY -h $name || kill \$\$\`\""
+    done
+}
+
+test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf
+
 for name in config_directory daemon_directory command_directory \
     queue_directory sendmail_path newaliases_path mailq_path mail_owner \
     setgid manpages
@@ -109,6 +126,26 @@ done
 
 # Sanity checks
 
+rm -f foobar-
+touch foobar-
+
+chown $mail_owner foobar- >/dev/null 2>&1 || {
+    echo "Error: $mail_owner needs an entry in the passwd file" 1>&2
+    echo "Remember, $mail_owner must have a dedicated user id and group id." 1>&2
+    exit 1
+}
+
+case $setgid in
+no) ;;
+ *) chgrp "$setgid" foobar- >/dev/null 2>&1 || {
+        echo "Error: $setgid needs an entry in the group file" 1>&2
+        echo "Remember, $setgid must have a dedicated group id." 1>&2
+        exit 1
+    }
+esac
+
+rm -f foobar-
+
 for path in $config_directory $daemon_directory $command_directory \
     $queue_directory $sendmail_path $newaliases_path $mailq_path $manpages
 do
@@ -121,37 +158,54 @@ done
 
 # Create any missing directories.
 
-test -d $config_directory || mkdir -p $config_directory || exit 1
-test -d $daemon_directory || mkdir -p $daemon_directory || exit 1
-test -d $command_directory || mkdir -p $command_directory || exit 1
-test -d $queue_directory || mkdir -p $queue_directory || exit 1
+CONFIG_DIRECTORY=$install_root$config_directory
+DAEMON_DIRECTORY=$install_root$daemon_directory
+COMMAND_DIRECTORY=$install_root$command_directory
+QUEUE_DIRECTORY=$install_root$queue_directory
+SENDMAIL_PATH=$install_root$sendmail_path
+NEWALIASES_PATH=$install_root$newaliases_path
+MAILQ_PATH=$install_root$mailq_path
+MANPAGES=$install_root$manpages
+
+case $install_root in
+ /?*) test -d $install_root || mkdir -p $install_root || exit 1
+esac
+
+test -d $CONFIG_DIRECTORY || mkdir -p $CONFIG_DIRECTORY || exit 1
+test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
+test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
+test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
+for path in $SENDMAIL_PATH $NEWALIASES_PATH $MAILQ_PATH
+do
+    mkdir -p `echo $path|sed 's/[^/]*[/]*$//'`
+done
 
 # Install files. Be careful to not copy over running programs.
 
 for file in `ls libexec`
 do
-    compare_or_replace a+x,go-w libexec/$file $daemon_directory/$file || exit 1
+    compare_or_replace a+x,go-w libexec/$file $DAEMON_DIRECTORY/$file || exit 1
 done
 
 for file in `ls bin | grep '^post'`
 do
-    compare_or_replace a+x,go-w bin/$file $command_directory/$file || exit 1
+    compare_or_replace a+x,go-w bin/$file $COMMAND_DIRECTORY/$file || exit 1
 done
 
 test -f bin/sendmail && {
-    compare_or_replace a+x,go-w bin/sendmail $sendmail_path || exit 1
-    compare_or_symlink $sendmail_path $newaliases_path
-    compare_or_symlink $sendmail_path $mailq_path
+    compare_or_replace a+x,go-w bin/sendmail $SENDMAIL_PATH || exit 1
+    compare_or_symlink $sendmail_path $NEWALIASES_PATH
+    compare_or_symlink $sendmail_path $MAILQ_PATH
 }
 
-compare_or_replace a+r,go-w conf/LICENSE $config_directory/LICENSE || exit 1
+compare_or_replace a+r,go-w conf/LICENSE $CONFIG_DIRECTORY/LICENSE || exit 1
 
-test -f $config_directory/main.cf || {
-    cp conf/* $config_directory || exit 1
-    chmod a+r,go-w $config_directory/* || exit 1
+test -f $CONFIG_DIRECTORY/main.cf || {
+    cp conf/* $CONFIG_DIRECTORY || exit 1
+    chmod a+r,go-w $CONFIG_DIRECTORY/* || exit 1
 
     echo "Warning: you still need to edit myorigin/mydestination in" 1>&2
-    echo "$config_directory/main.cf. See also html/faq.html for dialup" 1>&2
+    echo "$CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup" 1>&2
     echo "sites or for sites inside a firewalled network." 1>&2
     echo "" 1>&2
     echo "BTW, Edit your alias database and be sure to set up aliases" 1>&2
@@ -173,32 +227,32 @@ for name in config_directory sendmail_path newaliases_path mailq_path \
 do
     eval echo $name=\$$name
 done) >junk || exit 1
-compare_or_move a+x,go-w junk $config_directory/install.cf || exit 1
+compare_or_move a+x,go-w junk $CONFIG_DIRECTORY/install.cf || exit 1
 rm -f junk
 
 # Use set-gid privileges instead of writable maildrop (optional).
 
-test -d $queue_directory/maildrop || {
-    mkdir -p $queue_directory/maildrop || exit 1
-    chown $owner $queue_directory/maildrop || exit 1
+test -d $QUEUE_DIRECTORY/maildrop || {
+    mkdir -p $QUEUE_DIRECTORY/maildrop || exit 1
+    chown $mail_owner $QUEUE_DIRECTORY/maildrop || exit 1
 }
 
 case $setgid in
 no)
-    chmod 1733 $queue_directory/maildrop || exit 1
-    chmod g-s $command_directory/postdrop || exit 1
+    chmod 1733 $QUEUE_DIRECTORY/maildrop || exit 1
+    chmod g-s $COMMAND_DIRECTORY/postdrop || exit 1
     postfix_script=conf/postfix-script-nosgid
     ;;
  *) 
-    chgrp $setgid $command_directory/postdrop || exit 1
-    chmod g+s $command_directory/postdrop || exit 1
-    chgrp $setgid $queue_directory/maildrop || exit 1
-    chmod 1730 $queue_directory/maildrop || exit 1
+    chgrp $setgid $COMMAND_DIRECTORY/postdrop || exit 1
+    chmod g+s $COMMAND_DIRECTORY/postdrop || exit 1
+    chgrp $setgid $QUEUE_DIRECTORY/maildrop || exit 1
+    chmod 1730 $QUEUE_DIRECTORY/maildrop || exit 1
     postfix_script=conf/postfix-script-sgid
     ;;
 esac
 
-compare_or_replace a+x,go-w $postfix_script $config_directory/postfix-script ||
+compare_or_replace a+x,go-w $postfix_script $CONFIG_DIRECTORY/postfix-script ||
     exit 1
 
 # Install manual pages (optional). We just clobber whatever is there.
@@ -208,13 +262,13 @@ no) ;;
  *) (
      cd man || exit 1
      for dir in man?
-        do mkdir -p $manpages/$dir || exit 1
+        do mkdir -p $MANPAGES/$dir || exit 1
      done
      for file in man?/*
      do
-        rm -f $manpages/$file
-        cp $file $manpages/$file || exit 1
-        chmod 644 $manpages/$file || exit 1
+        rm -f $MANPAGES/$file
+        cp $file $MANPAGES/$file || exit 1
+        chmod 644 $MANPAGES/$file || exit 1
      done
     )
 esac
index dee14e3e5c8872160cf6b6cfc1886fec780093aa..533cb6197902079d66cc289372417685722e7290 100644 (file)
@@ -1,62 +1,55 @@
-Incompatible changes with snapshot XXXXXXXX
+Incompatible changes with snapshot 19991120
 ===========================================
 
+- In an SMTPD access map, an all-numeric right-hand side now means
+OK.  This is for better cooperation with out-of-band authentication
+mechanisms such as POP before SMTP etc.
+
 - Recipient addresses may no longer begin with `-'. In order to
 reinstate the old behavior, specify "allow_min_user = yes" in
 main.cf.
 
-- You can not longer use virtual, canonical or aliases tables as
+- You can no longer use virtual, canonical or aliases tables as
 SMTPD access control tables. Use the permit_recipient_map feature
-instead. The loss is compensated for.
+instead. The loss is compensated for (see below).
 
-Major changes with snapshot XXXXXXXX
+Major changes with snapshot 19991120
 ====================================
 
-- Per-client/helo/sender/recipient UCE restrictions: you can now
-specify arbitrary restrictions on the right-hand side of SMTPD
-access tables.  The only anomalies in this scheme are (1) header
-checks are the same for every message, and (2) you must use a
-restriction class (see below) in order to specify a lookup table
-on the right-hand side of an access table.
-
-- Restriction classes allow you to conveniently group restrictions
-under one name. This is great for per-client/helo/sender/recipient
-UCE restrictions.  For example in main.cf:
-
-    smtpd_restriction_classes = restrictive, permissive
-    restrictive = reject_unknown_sender reject_unknown_client ...
-    permissive = permit
+- The Postfix SMTP server now understands a wider range of illegal
+address formats in MAIL FROM and RCPT TO commands. In order to
+disable those forms, specify "strict_rfc821_envelopes = yes".
 
-Then use "restrictive" or "permissive" on the right-hand side of
-your per-client/helo/sender/recipient SMTPD access tables.
+- Per-client/helo/sender/recipient UCE restrictions (fully-recursive
+UCE restriction parser). See the RESTRICTION_CLASS file for details.
 
-- Reject mail for non-existent local accounts. You can now use
-passwd/canonical/virtual/aliases tables for SMTPD access control.
-
-For example, a non-relaying site would specify in main.cf:
+- Block mail for non-existent users at the SMTP port. On a non-relay
+host, use the following to reject mail for non-existent users and
+for non-local destinations.
 
     smtpd_recipient_restrictions =
-       permit_recipient_map unix:passwd.byname
-       permit_recipient_map hash:/etc/canonical
+       permit_recipient_map unix:passwd .byname
+       permit_recipient_map hash:/etc/postfix/canonical
        permit_recipient_map hash:/etc/postfix/virtual
        permit_recipient_map hash:/etc/aliases
        reject
 
-That should stop a lot of the mail to non-existent recipients.  It
-won't stop mail to broken aliases or to users with broken .forward
-files, though.
+- "postconf -e name=value..." edits the main.cf file.  This is
+easier and safer than editing the main.cf file by hand. The edits
+are done on a temporary copy that is renamed into place.
+
+- "postconf -m" displays all supported lookup table types (Scott
+Cotton).
 
-For a relaying site, a good configuration with permit_recipient_map
-still needs to be found. Something that permits relaying to all
-sites except $mydestination.
+- It is now relatively safe to configure 550 status codes for the
+main.cf unknown_address_reject_code or unknown_client_reject_code
+parameters.  The SMTP server now always sends a 450 (try again)
+reply code when an UCE restriction fails due to a soft DNS error.
 
-Unfortunately, permit_recipient_map does not combine well with
-permit_mynetworks, because permit_mynetworks accepts mail for 
-non-existent local recipients.
+- The RBL checks now show the content of TXT records (Simon J Mudd).
 
-Unfortunately, permit_recipient_map does not combine well with
-check_relay_domains, because check_relay_domains either rejects
-mail, or accepts mail regardless of whether a recipient exists.
+- New "permit_auth_destination" UCE restriction for finer-grained
+control (Jesper Skriver).
 
 Incompatible changes with postfix-19990906
 ==========================================
diff --git a/postfix/RESTRICTION_CLASS b/postfix/RESTRICTION_CLASS
new file mode 100644 (file)
index 0000000..22f3d32
--- /dev/null
@@ -0,0 +1,24 @@
+Per client/helo/sender/recipient UCE restrictions
+=================================================
+
+The Postfix SMTP server allows you to specify UCE restrictions on
+the right-hand side of SMTPD access tables, so that you can have
+different UCE restrictions for different clients or users.
+
+The only anomalies in this scheme are that (1) message header checks
+are still the same for every message, and (2) you must use a
+restriction class name (see below) if you want to specify a lookup
+table on the right-hand side of an access table (this is because
+Postfix needs to open those tables ahead of time).
+
+Restriction classes allow you to give easy-to-remember names to
+groups of UCE restrictions (such as permissive, restrictive, and
+so on).  For example in main.cf:
+
+    smtpd_restriction_classes = restrictive, permissive
+    restrictive = reject_unknown_sender reject_unknown_client ...
+    permissive = permit
+
+With this in place, you can use "restrictive" or "permissive" on
+the right-hand side of your per-client/helo/sender/recipient SMTPD
+access tables.
diff --git a/postfix/aux/rmail/rmail b/postfix/aux/rmail/rmail
new file mode 100755 (executable)
index 0000000..44c999e
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Dummy UUCP rmail command for postfix/qmail systems
+
+SENDMAIL="/usr/sbin/sendmail"
+IFS=" " read junk from junk
+
+exec $SENDMAIL -f "$from" -- "$@"
index 454a4f713a3696703bdebc5ef46f9f2ebe6dc3e6..39ef93f26ef2d3269845b956c6ec5195c626eb78 100644 (file)
@@ -71,5 +71,5 @@ uucp    unix  -       n       n       -       -       pipe
 ifmail    unix  -       n       n       -       -       pipe
     flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
 bsmtp     unix  -       n       n       -       -       pipe
-    flags=F user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
+    flags=F. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
 
index b5cb6450893881a5ca9b2f018fdd5ec0e27d4f6b..b5551e6348fab7e849c05d477581cdae613d7f0f 100644 (file)
@@ -210,6 +210,7 @@ smtpd_sender_restrictions =
 #   reject_non_fqdn_recipient: reject recipient address that is not in FQDN form
 #   permit_recipient_map maptype:mapname: permit if the recipient matches
 #                  the table. Matching is as with virtual/canonical tables.
+#                  You can also use unix:passwd.byname or alias maps.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
 #
index 19e809dd25f81940cbf534cd29b186684f2baaae..fab7144a886e22e5427106cbf50434beda0480b5 100644 (file)
@@ -165,10 +165,7 @@ static int dns_query(const char *name, int type, int flags,
      * only if the name server told us so.
      */
     len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
-    reply_header = (HEADER *) reply->buf;
     if (len < 0) {
-       if (reply_header->rcode == SERVFAIL)
-           h_errno = NO_RECOVERY;
        if (why)
            vstring_sprintf(why, "Name service error for domain %s: %s",
                            name, dns_strerror(h_errno));
@@ -194,6 +191,7 @@ static int dns_query(const char *name, int type, int flags,
      */
     if ((reply->end = reply->buf + len) > reply->buf + sizeof(reply->buf))
        reply->end = reply->buf + sizeof(reply->buf);
+    reply_header = (HEADER *) reply->buf;
     reply->query_start = reply->buf + sizeof(HEADER);
     reply->answer_start = 0;
     reply->query_count = ntohs(reply_header->qdcount);
@@ -247,7 +245,7 @@ static int dns_get_fixed(unsigned char *pos, DNS_FIXED *fixed)
 static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
                                  char *rr_name, DNS_FIXED *fixed)
 {
-    unsigned char temp[DNS_NAME_LEN];
+    char    temp[DNS_NAME_LEN];
     int     data_len;
     unsigned pref = 0;
     unsigned char *src;
@@ -255,6 +253,7 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
     int     ch;
 
 #define MIN2(a, b)     ((unsigned)(a) < (unsigned)(b) ? (a) : (b))
+#define UC(x)          ((unsigned char *) (x))
 
     if (pos + fixed->length > reply->end)
        return (0);
@@ -296,7 +295,7 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
        break;
     case T_TXT:
        data_len = MIN2(fixed->length + 1, sizeof(temp));
-       for (src = pos, dst = temp; dst < temp + data_len - 1; /* void */ ) {
+       for (src = pos, dst = UC(temp); dst < UC(temp) + data_len - 1; /* */ ) {
            ch = *src++;
            *dst++ = (ISPRINT(ch) ? ch : ' ');
        }
index c555f3f5701da2b1671016649f38eb90d8c9a1cb..76783dd82a7bcdca29029c3e0e8cf512a4a5714a 100644 (file)
@@ -8,20 +8,26 @@
 /*
 /*     const char *def_local_transport()
 /*
-/*     int     local_transport(transport)
+/*     int     match_def_local_transport(transport)
+/*     const char *transport;
+/*
+/*     int     match_any_local_transport(transport)
 /*     const char *transport;
 /* DESCRIPTION
 /*     This module uses the information kept in the "local_transports"
 /*     configuration parameter, which lists the name of the default
-/*     local transport, followed by zero or more other transports that
-/*     deliver locally.
+/*     local transport, followed by the names of zero or more other
+/*     transports that deliver locally.
 /*
 /*     def_local_transport() returns the name of the default local
-/*     transport, that is, the first transport name specified with 
+/*     transport, that is, the first transport name specified with
 /*     the "local_transports" configuration parameter.
 /*
-/*     local_transport() determines if the named transport is listed
-/*     in the "local_transports" configuration parameter.
+/*     match_def_local_transport() determines if the named transport is
+/*     identical to the default local transport.
+/*
+/*     match_any_local_transport() determines if the named transport is
+/*     listed in the "local_transports" configuration parameter.
 /* SEE ALSO
 /*     resolve_local(3), see if address resolves locally.
 /* LICENSE
@@ -78,7 +84,7 @@ static void local_transport_init(void)
     /*
      * Sanity check.
      */
-    if (!local_transport(local_transport_name))
+    if (!match_any_local_transport(local_transport_name))
        msg_panic("%s: unable to intialize", myname);
 }
 
@@ -99,9 +105,27 @@ const char *def_local_transport(void)
     return (local_transport_name);
 }
 
-/* local_transport - match address against list of local destinations */
+/* match_def_local_transport - match against default local transport */
+
+int     match_def_local_transport(const char *transport)
+{
+
+    /*
+     * Initialize on the fly.
+     */
+    if (local_transport_list == 0)
+       local_transport_init();
+
+    /*
+     * Compare the transport against the list of transports that are listed
+     * as delivering locally.
+     */
+    return (strcmp(transport, local_transport_name) == 0);
+}
+
+/* match_any_local_transport - match against list of local transports */
 
-int     local_transport(const char *transport)
+int     match_any_local_transport(const char *transport)
 {
 
     /*
@@ -127,7 +151,7 @@ int     main(int argc, char **argv)
     if (argc != 2)
        msg_fatal("usage: %s transport", argv[0]);
     mail_conf_read();
-    vstream_printf("%s\n", local_transport(argv[1]) ? "yes" : "no");
+    vstream_printf("%s\n", match_any_local_transport(argv[1]) ? "yes" : "no");
     vstream_fflush(VSTREAM_OUT);
 }
 
index d3defdaa3fdbb56d69430b12fdd671786cd2525e..a1070c0921fefaf2d74af587154718c871f68da7 100644 (file)
@@ -15,7 +15,8 @@
   * External interface.
   */
 extern const char *def_local_transport(void);
-extern int local_transport(const char *);
+extern int match_def_local_transport(const char *);
+extern int match_any_local_transport(const char *);
 
 /* LICENSE
 /* .ad
index 508251f8b909c1b8eb865641953a41a650ad3f25..5146eb080e3e4f2b513fb6d42d5a8cfdcb49c242 100644 (file)
@@ -163,7 +163,7 @@ int     main(int argc, char **argv)
        msg_fatal("chdir %s: %m", var_queue_dir);
     path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK);
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
-       if ((result = mail_addr_map(path, STR(buffer))) != 0)
+       if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
            argv_free(result);
     }
     vstring_free(buffer);
index 7f65ef3dde0c39fb7e8b1fcdc89eda89119423b0..3a3c09779834b57a7b42208f1a6cd06541b2a3c4 100644 (file)
@@ -168,10 +168,16 @@ char   *var_local_transports;
 
 static const char *check_myhostname(void)
 {
-    const char *name;
+    static const char *name;
     const char *dot;
     const char *domain;
 
+    /*
+     * Use cached result.
+     */
+    if (name)
+       return (name);
+
     /*
      * If the local machine name is not in FQDN form, try to append the
      * contents of $mydomain.
index 042b353f9d38928f24dcc304c37000b049bba2fa..a0d5395500238069c8317e030e73d7259fe979c7 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-19991117"
+#define DEF_MAIL_VERSION       "Snapshot-19991120"
 extern char *var_mail_version;
 
 /* LICENSE
index f697a19e045f59c2d9f9b8ce8bf7b056c506aa8a..da1b37b7ba59c12d7f2a305f7fb5e9bd08b73754 100644 (file)
@@ -335,8 +335,6 @@ int     pipe_command(VSTREAM *src, VSTRING *why,...)
      */
     if (pipe(cmd_in_pipe) < 0 || pipe(cmd_out_pipe) < 0)
        msg_fatal("%s: pipe: %m", myname);
-    cmd_in_stream = vstream_fdopen(cmd_in_pipe[1], O_WRONLY);
-    cmd_out_stream = vstream_fdopen(cmd_out_pipe[0], O_RDONLY);
     non_blocking(cmd_out_pipe[1], NON_BLOCKING);
 
     /*
@@ -412,6 +410,9 @@ int     pipe_command(VSTREAM *src, VSTRING *why,...)
        close(cmd_in_pipe[0]);
        close(cmd_out_pipe[1]);
 
+       cmd_in_stream = vstream_fdopen(cmd_in_pipe[1], O_WRONLY);
+       cmd_out_stream = vstream_fdopen(cmd_out_pipe[0], O_RDONLY);
+
        /*
         * Give the command a limited amount of time to run, by enforcing
         * timeouts on all I/O from and to it.
index 798c096a554790e0dc6e0e60764272eab4d7f94d..cd745cf966ccb423ef0eb5f3ae3a410d7c42842a 100644 (file)
@@ -324,11 +324,11 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp)
        } else if (ch == '"') {
            tp = tok822_alloc(TOK822_QSTRING, (char *) 0);
            COLLECT_SKIP_LAST(tp, str, ch, ch != '"');
-       } else if (strchr(tok822_opchar, ch)) {
+       } else if (ch != '\\' && strchr(tok822_opchar, ch)) {
            tp = tok822_alloc(ch, (char *) 0);
        } else {
            tp = tok822_alloc(TOK822_ATOM, (char *) 0);
-           VSTRING_ADDCH(tp->vstr, ch);
+           str -= 1;                           /* \ may be first */
            COLLECT(tp, str, ch, !ISSPACE(ch) && !strchr(tok822_opchar, ch));
            tok822_quote_atom(tp);
        }
index 72b2186025435c48eb3d1b38e77469db327ee388..1455eec38444e04a1e1ac379246518d6c1e9ad62 100644 (file)
@@ -9,12 +9,15 @@ POSTCONF(1)                                           POSTCONF(1)
        postconf - Postfix configuration utility
 
 <b>SYNOPSIS</b>
-       <b>postconf</b> [<b>-c</b> <i>config_dir</i>] [<b>-d</b>] [<b>-h</b>] [<b>-n</b>] [<b>-v</b>] [<i>parameter</i>
-       <i>...</i>]
+       <b>postconf</b> [<b>-dhmnv</b>] [<b>-c</b> <i>config_dir</i>] [<i>parameter</i> <i>...</i>]
+
+       <b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config_dir</i>] [<i>parameter=value</i> <i>...</i>]
 
 <b>DESCRIPTION</b>
-       The <b>postconf</b> command prints the actual value of  <i>parameter</i>
-       (all known parameters by default), one parameter per line.
+       The  <b>postconf</b> command prints the actual value of <i>parameter</i>
+       (all known parameters by default), one parameter per line,
+       changes  its  value, or prints other information about the
+       Postfix mail system.
 
        Options:
 
@@ -25,20 +28,28 @@ POSTCONF(1)                                           POSTCONF(1)
        <b>-d</b>     Print  default parameter settings instead of actual
               settings.
 
+       <b>-e</b>     Edit the <b>main.cf</b> configuration file.  The  file  is
+              copied to a temporary file then renamed into place.
+              Parameters and values are specified on the  command
+              line.   Use   quotes  in  order  to  protect  shell
+              metacharacters and whitespace.
+
        <b>-h</b>     Show parameter values only, not  the  ``name  =  ''
               label that normally precedes the value.
 
+       <b>-m</b>     List the names of all supported lookup table types.
+
        <b>-n</b>     Print non-default parameter settings only.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple <b>-v</b> options  make  the  software  increasingly
+              tiple  <b>-v</b>  options  make  the software increasingly
               verbose.
 
 <b>DIAGNOSTICS</b>
        Problems are reported to the standard error stream.
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
@@ -51,17 +62,6 @@ POSTCONF(1)                                           POSTCONF(1)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
                                                                 1
 
 
index d4dbafc105f24ebb5e6c82b851cc11ba27533acb..8de52584ef86bca706366a6992328cc8183c6b78 100644 (file)
@@ -73,6 +73,12 @@ SMTPD(8)                                                 SMTPD(8)
 
        command after a configuration change.
 
+<b>Compatibility</b> <b>controls</b>
+       <b>strict</b><i>_</i><b>rfc821</b><i>_</i><b>envelopes</b>
+              Disallow  non-RFC 821 style addresses in envelopes.
+              For example, allow RFC822-style address forms  with
+              comments, like Sendmail does.
+
 <b>Miscellaneous</b>
        <b>always</b><i>_</i><b>bcc</b>
               Address  to send a copy of each message that enters
@@ -119,12 +125,6 @@ SMTPD(8)                                                 SMTPD(8)
 
        <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
               Restrict  the  number  of  recipients that the SMTP
-              server accepts per message delivery.
-
-       <b>smtpd</b><i>_</i><b>timeout</b>
-              Limit the time to send a  server  response  and  to
-              receive a client request.
-
 
 
 
@@ -137,6 +137,12 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+              server accepts per message delivery.
+
+       <b>smtpd</b><i>_</i><b>timeout</b>
+              Limit the time to send a  server  response  and  to
+              receive a client request.
+
 <b>Resource</b> <b>controls</b>
        <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
               Limit  the  amount  of memory in bytes used for the
@@ -186,12 +192,6 @@ SMTPD(8)                                                 SMTPD(8)
               Restrict  what  recipient  addresses are allowed in
               <b>RCPT</b> <b>TO</b> commands.
 
-       <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
-              Restrict what domain names can be used in <b>ETRN</b> com-
-              mands, and what clients may issue <b>ETRN</b> commands.
-
-
-
 
 
                                                                 3
@@ -203,6 +203,10 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+       <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
+              Restrict what domain names can be used in <b>ETRN</b> com-
+              mands, and what clients may issue <b>ETRN</b> commands.
+
        <b>restriction</b><i>_</i><b>classes</b>
               Declares  the  name of zero or more parameters that
               contain a list of UCE restrictions.  The  names  of
@@ -253,10 +257,6 @@ SMTPD(8)                                                 SMTPD(8)
 
 <b>SEE</b> <b>ALSO</b>
        <a href="cleanup.8.html">cleanup(8)</a> message canonicalization
-       <a href="master.8.html">master(8)</a> process manager
-       syslogd(8) system logging
-
-
 
 
 
@@ -269,6 +269,9 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+       <a href="master.8.html">master(8)</a> process manager
+       syslogd(8) system logging
+
 <b>LICENSE</b>
        The  Secure  Mailer  license must be distributed with this
        software.
@@ -319,9 +322,6 @@ SMTPD(8)                                                 SMTPD(8)
 
 
 
-
-
-
 
 
 
index fdabb0c01ebc855e5e5e90e482df91c3a5992f99..7b74063db7c573baa3f44cbc2932a5e14fd8bed3 100644 (file)
@@ -191,10 +191,10 @@ href="access.5.html">access database</a> for the client name, parent
 domains, client address, or networks obtained by stripping least
 significant octets.  Reject the request if the result is <b>REJECT</b>
 or "[<b>45</b>]<i>XX text</i>". Permit the request if the result
-is <b>OK</b> or <b>RELAY</b>. Otherwise, treat the result as another
-list of UCE restrictions.  The <b>access_map_reject_code</b>
-parameter specifies the response code for <b>REJECT</b> results
-(default:  <b>554</b>).
+is <b>OK</b> or <b>RELAY</b> or all-numerical. Otherwise, treat the
+result as another list of UCE restrictions.  The
+<b>access_map_reject_code</b> parameter specifies the response code for
+<b>REJECT</b> results (default:  <b>554</b>).
 
 <p>
 
@@ -339,10 +339,10 @@ response code to rejected requests (default:  <b>504</b>).
 href="access.5.html">access database</a> for the <b>HELO</b> hostname
 or parent domains in the specified table.  Reject the request if
 the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
-the request when the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
-treat the result as another list of UCE restrictions.  The
-<b>access_map_reject_code </b> parameter specifies the response
-code for <b>REJECT</b> results (default:  <b>554</b>).
+the request when the result is <b>OK</b> or <b>RELAY</b> or
+all-numerical. Otherwise, treat the result as another list of UCE
+restrictions.  The <b>access_map_reject_code </b> parameter specifies
+the response code for <b>REJECT</b> results (default:  <b>554</b>).
 
 <p>
 
@@ -431,10 +431,10 @@ is always <b>450</b> in case of a temporary DNS error.
 href="access.5.html">access database</a> for the sender mail address,
 parent domain, or <i>localpart</i>@. Reject the request if the
 result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the
-request if the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
-treat the result as another list of UCE restrictions.  The
-<b>access_map_reject_code </b> parameter specifies the result code
-for rejected requests (default: <b>554</b>).
+request if the result is <b>OK</b> or <b>RELAY</b> or all-numerical.
+Otherwise, treat the result as another list of UCE restrictions.  The
+<b>access_map_reject_code </b> parameter specifies the result code for
+rejected requests (default: <b>554</b>).
 
 <p>
 
@@ -579,12 +579,12 @@ $inet_interfaces</a>.
 
 <dt> <i>maptype</i>:<i>mapname</i> <dd> Search the named <a
 href="access.5.html">access database</a> for the resolved destination
-address, parent domain, or <i>localpart</i>@. Reject the request
-if the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".
-Permit the request if the result is <b>OK</b> or <b>RELAY</b>.
-Otherwise, treat the result as another list of UCE restrictions.
-The <b>access_map_reject_code </b> parameter specifies the result
-code for rejected requests (default: <b>554</b>).
+address, parent domain, or <i>localpart</i>@. Reject the request if the
+result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".  Permit the
+request if the result is <b>OK</b> or <b>RELAY</b> or all-numerical.
+Otherwise, treat the result as another list of UCE restrictions.  The
+<b>access_map_reject_code </b> parameter specifies the result code for
+rejected requests (default: <b>554</b>).
 
 <p>
 
@@ -715,10 +715,10 @@ address.
 href="access.5.html">access database</a> for the domain specified
 in the ETRN command, or its parent domains. Reject the request if
 the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".  Permit
-the request if the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
-treat the result as another list of UCE restrictions.  The
-<b>access_map_reject_code </b> parameter specifies the result code
-for rejected requests (default: <b>554</b>).
+the request if the result is <b>OK</b> or <b>RELAY</b> or
+all-numerical. Otherwise, treat the result as another list of UCE
+restrictions.  The <b>access_map_reject_code </b> parameter specifies
+the result code for rejected requests (default: <b>554</b>).
 
 <p>
 
index 2aa44a1ebafe43e09fa1b84c2452268bbc7d358c..e8b93fc64dbb778c4bb0d1df7a07247fa5d85709 100644 (file)
@@ -139,7 +139,7 @@ int     deliver_resolve_tree(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr
      * ugly code to force local recursive alias expansions on a host with no
      * authority over the local domain, but that code was just too unclean.
      */
-    if (local_transport(STR(reply.transport))) {
+    if (match_def_local_transport(STR(reply.transport))) {
        status = deliver_recipient(state, usr_attr);
     } else {
        status = deliver_indirect(state);
index 2e5bb2e0bbc990dee3582d02f41d5e5a93b12304..df036eb3c4a2d2350aeb9813c92b760bb8eca74a 100644 (file)
@@ -9,23 +9,34 @@ Postfix configuration utility
 .na
 .nf
 .fi
-\fBpostconf\fR [\fB-c \fIconfig_dir\fR] [\fB-d\fR] [\fB-h\fR]
-[\fB-n\fR] [\fB-v\fR] [\fIparameter ...\fR]
+\fBpostconf\fR [\fB-dhmnv\fR] [\fB-c \fIconfig_dir\fR]
+[\fIparameter ...\fR]
+
+\fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
+[\fIparameter=value ...\fR]
 .SH DESCRIPTION
 .ad
 .fi
 The \fBpostconf\fR command prints the actual value of
 \fIparameter\fR (all known parameters by default), one
-parameter per line.
+parameter per line, changes its value, or prints other
+information about the Postfix mail system.
 
 Options:
 .IP "\fB-c \fIconfig_dir\fR"
 The \fBmain.cf\fR configuration file is in the named directory.
 .IP \fB-d\fR
 Print default parameter settings instead of actual settings.
+.IP \fB-e\fR
+Edit the \fBmain.cf\fR configuration file. The file is copied
+to a temporary file then renamed into place. Parameters and
+values are specified on the command line. Use quotes in order
+to protect shell metacharacters and whitespace.
 .IP \fB-h\fR
 Show parameter values only, not the ``name = '' label
 that normally precedes the value.
+.IP \fB-m\fR
+List the names of all supported lookup table types.
 .IP \fB-n\fR
 Print non-default parameter settings only.
 .IP \fB-v\fR
index 58050d44f93f60de35305f0ddb38587d9d50bd7a..6396131a18f630ec7880148d720804fb9e5787d4 100644 (file)
@@ -68,6 +68,12 @@ The following \fBmain.cf\fR parameters are especially relevant to
 this program. See the Postfix \fBmain.cf\fR file for syntax details
 and for default values. Use the \fBpostfix reload\fR command after
 a configuration change.
+.SH "Compatibility controls"
+.ad
+.fi
+.IP \fBstrict_rfc821_envelopes\fR
+Disallow non-RFC 821 style addresses in envelopes. For example,
+allow RFC822-style address forms with comments, like Sendmail does.
 .SH Miscellaneous
 .ad
 .fi
index dce3e75d74018c1a789c73deea30eda49bef527b..064a5c698f50f16927d03ca0c41b0e12389b8c15 100644 (file)
@@ -5,7 +5,7 @@
 /*     Postfix configuration utility
 /* SYNOPSIS
 /* .fi
-/*     \fBpostconf\fR [\fB-dhnv\fR] [\fB-c \fIconfig_dir\fR]
+/*     \fBpostconf\fR [\fB-dhmnv\fR] [\fB-c \fIconfig_dir\fR]
 /*             [\fIparameter ...\fR]
 /*
 /*     \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
@@ -175,10 +175,16 @@ static int mode = SHOW_NAME;
 
 static const char *check_myhostname(void)
 {
-    const char *name;
+    static const char *name;
     const char *dot;
     const char *domain;
 
+    /*
+     * Use cached result.
+     */
+    if (name)
+       return (name);
+
     /*
      * If the local machine name is not in FQDN form, try to append the
      * contents of $mydomain.
@@ -697,7 +703,7 @@ int     main(int argc, char **argv)
     /*
      * Edit main.cf.
      */
-    if (mode & EDIT_MAIN) {
+    else if (mode & EDIT_MAIN) {
        edit_parameters(argc - optind, argv + optind);
     }
 
index c3ba5e8e9fa8647d7ab60c14c5e35e3a17242350..a6a89b4303059431bbbfa3cd72c026fe6e4ace2f 100644 (file)
@@ -477,7 +477,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
        /*
         * Bounce mail to non-existent users in virtual domains.
         */
-       if (!local_transport(STR(reply.transport))
+       if (!match_def_local_transport(STR(reply.transport))
            && qmgr_virtual != 0
            && (at = strrchr(recipient->address, '@')) != 0) {
            domain = lowercase(mystrdup(at + 1));
@@ -516,7 +516,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         * job requires knowledge of local aliases. Yuck! I don't want to
         * duplicate delivery-agent specific knowledge in the queue manager.
         */
-       if (local_transport(STR(reply.transport))) {
+       if (match_def_local_transport(STR(reply.transport))) {
            vstring_strcpy(reply.nexthop, STR(reply.recipient));
            (void) split_at_right(STR(reply.nexthop), '@');
 #if 0
index ac011a2db3c90e7c24cfe9625937005d8468a3c3..50ce89135094b040f1b3cf0a473fd318fce363d4 100644 (file)
@@ -277,8 +277,7 @@ SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why)
            session->best = (addr->pref == addr_list->pref);
            break;
        }
-       msg_info("%s; address %s port %d", vstring_str(why),
-                inet_ntoa(*((struct in_addr *) addr->data)), ntohs(port));
+       msg_info("%s (port %d)", vstring_str(why), ntohs(port));
     }
     dns_rr_free(addr_list);
     return (session);
index f253df57160f6f51e932121877fa5eeb9f4c98ba..bfbc0e7a98af59d2dd6965e90082545bd585c7c8 100644 (file)
@@ -66,7 +66,7 @@ depend: $(MAKES)
        done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
        @make -f Makefile.in Makefile
 
-tests: smtpd_check_test smtpd_check_test2 smtpd_token_test
+tests: smtpd_check_test smtpd_check_test2 smtpd_check_test3 smtpd_token_test
 
 smtpd_check_test: smtpd_check smtpd_check.in smtpd_check.ref
        ../postmap/postmap smtpd_check_access
@@ -80,6 +80,12 @@ smtpd_check_test2: smtpd_check smtpd_check.in2 smtpd_check.ref2
        diff smtpd_check.ref2 smtpd_check.tmp
        rm -f smtpd_check.tmp smtpd_check_access.*
 
+smtpd_check_test3: smtpd_check smtpd_check.in3 smtpd_check.ref3
+       ../postmap/postmap smtpd_check_access
+       ./smtpd_check <smtpd_check.in3 >smtpd_check.tmp 2>&1
+       diff smtpd_check.ref3 smtpd_check.tmp
+       rm -f smtpd_check.tmp smtpd_check_access.*
+
 smtpd_token_test: smtpd_token smtpd_token.in smtpd_token.ref
        ./smtpd_token <smtpd_token.in >smtpd_token.tmp 2>&1
        diff smtpd_token.ref smtpd_token.tmp
index cf934f141ba49c053f9459e875cb3a75123a143f..32b7dec7b28aea6e64bc49dd2972447b4b292d67 100644 (file)
@@ -51,6 +51,7 @@ typedef struct SMTPD_STATE {
     char   *etrn_name;
     char   *protocol;
     char   *where;
+    int     recursion;
 } SMTPD_STATE;
 
 extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
index 48eaac71ae4be76b62c36992d2e027f2faf02db4..03a8a92f491e16b25805d85eddfa64776dc56fbd 100644 (file)
@@ -305,19 +305,19 @@ static VSTRING *error_text;
  /*
   * Pre-opened access control lists.
   */
-static DOMAIN_LIST *relay_domains;
-static NAMADR_LIST *mynetworks;
+static  DOMAIN_LIST *relay_domains;
+static  NAMADR_LIST *mynetworks;
 
  /*
   * Pre-parsed restriction lists.
   */
-static ARGV *client_restrctions;
+static  ARGV *client_restrctions;
 static ARGV *helo_restrctions;
 static ARGV *mail_restrctions;
 static ARGV *rcpt_restrctions;
 static ARGV *etrn_restrctions;
 
-static HTABLE *smtpd_rest_classes;
+static  HTABLE *smtpd_rest_classes;
 
 static HTABLE *smtpd_rcpt_maps;
 
@@ -433,7 +433,7 @@ void    smtpd_check_init(void)
 
 /* smtpd_check_reject - do the boring things that must be done */
 
-static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
+static int smtpd_check_reject(SMTPD_STATE * state, int error_class,
                                      char *format,...)
 {
     va_list ap;
@@ -486,7 +486,7 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
 
 /* reject_unknown_client - fail if client hostname is unknown */
 
-static int reject_unknown_client(SMTPD_STATE *state)
+static int reject_unknown_client(SMTPD_STATE * state)
 {
     char   *myname = "reject_unknown_client";
 
@@ -504,7 +504,7 @@ static int reject_unknown_client(SMTPD_STATE *state)
 
 /* permit_mynetworks - succeed if client is in a trusted network */
 
-static int permit_mynetworks(SMTPD_STATE *state)
+static int permit_mynetworks(SMTPD_STATE * state)
 {
     char   *myname = "permit_mynetworks";
 
@@ -537,7 +537,7 @@ static char *dup_if_truncate(char *name)
 
 /* reject_invalid_hostaddr - fail if host address is incorrect */
 
-static int reject_invalid_hostaddr(SMTPD_STATE *state, char *addr,
+static int reject_invalid_hostaddr(SMTPD_STATE * state, char *addr,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_invalid_hostaddr";
@@ -574,7 +574,7 @@ static int reject_invalid_hostaddr(SMTPD_STATE *state, char *addr,
 
 /* reject_invalid_hostname - fail if host/domain syntax is incorrect */
 
-static int reject_invalid_hostname(SMTPD_STATE *state, char *name,
+static int reject_invalid_hostname(SMTPD_STATE * state, char *name,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_invalid_hostname";
@@ -610,7 +610,7 @@ static int reject_invalid_hostname(SMTPD_STATE *state, char *name,
 
 /* reject_non_fqdn_hostname - fail if host name is not in fqdn form */
 
-static int reject_non_fqdn_hostname(SMTPD_STATE *state, char *name,
+static int reject_non_fqdn_hostname(SMTPD_STATE * state, char *name,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_non_fqdn_hostname";
@@ -646,7 +646,7 @@ static int reject_non_fqdn_hostname(SMTPD_STATE *state, char *name,
 
 /* reject_unknown_hostname - fail if name has no A or MX record */
 
-static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
+static int reject_unknown_hostname(SMTPD_STATE * state, char *name,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_unknown_hostname";
@@ -668,7 +668,7 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
 
 /* reject_unknown_mailhost - fail if name has no A or MX record */
 
-static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
+static int reject_unknown_mailhost(SMTPD_STATE * state, char *name,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_unknown_mailhost";
@@ -690,7 +690,7 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
 
 /* check_relay_domains - OK/FAIL for message relaying */
 
-static int check_relay_domains(SMTPD_STATE *state, char *recipient,
+static int check_relay_domains(SMTPD_STATE * state, char *recipient,
                                       char *reply_name, char *reply_class)
 {
     char   *myname = "check_relay_domains";
@@ -715,7 +715,7 @@ static int check_relay_domains(SMTPD_STATE *state, char *recipient,
      * Permit if destination is local. XXX This must be generalized for
      * per-domain user tables and for non-UNIX local delivery agents.
      */
-    if (local_transport(STR(reply.transport))
+    if (match_any_local_transport(STR(reply.transport))
        || (domain = strrchr(STR(reply.recipient), '@')) == 0)
        return (SMTPD_CHECK_OK);
     domain += 1;
@@ -754,7 +754,7 @@ static int permit_auth_destination(char *recipient)
      * Permit if destination is local. XXX This must be generalized for
      * per-domain user tables and for non-UNIX local delivery agents.
      */
-    if (local_transport(STR(reply.transport))
+    if (match_any_local_transport(STR(reply.transport))
        || (domain = strrchr(STR(reply.recipient), '@')) == 0)
        return (SMTPD_CHECK_OK);
     domain += 1;
@@ -773,7 +773,7 @@ static int permit_auth_destination(char *recipient)
 
 /* reject_unauth_destination - FAIL for message relaying */
 
-static int reject_unauth_destination(SMTPD_STATE *state, char *recipient)
+static int reject_unauth_destination(SMTPD_STATE * state, char *recipient)
 {
     char   *myname = "reject_unauth_destination";
     char   *domain;
@@ -791,7 +791,7 @@ static int reject_unauth_destination(SMTPD_STATE *state, char *recipient)
      * Pass if destination is local. XXX This must be generalized for
      * per-domain user tables and for non-UNIX local delivery agents.
      */
-    if (local_transport(STR(reply.transport))
+    if (match_any_local_transport(STR(reply.transport))
        || (domain = strrchr(STR(reply.recipient), '@')) == 0)
        return (SMTPD_CHECK_DUNNO);
     domain += 1;
@@ -812,7 +812,7 @@ static int reject_unauth_destination(SMTPD_STATE *state, char *recipient)
 
 /* reject_unauth_pipelining - reject improper use of SMTP command pipelining */
 
-static int reject_unauth_pipelining(SMTPD_STATE *state)
+static int reject_unauth_pipelining(SMTPD_STATE * state)
 {
     char   *myname = "reject_unauth_pipelining";
 
@@ -872,10 +872,11 @@ static int has_my_addr(char *host)
 
 /* permit_mx_backup - permit use of me as MX backup for recipient domain */
 
-static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
+static int permit_mx_backup(SMTPD_STATE * unused_state, const char *recipient)
 {
     char   *myname = "permit_mx_backup";
     char   *domain;
+
     DNS_RR *mx_list;
     DNS_RR *mx;
     int     dns_status;
@@ -893,7 +894,7 @@ static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
      * If the destination is local, it is acceptable, because we are
      * supposedly MX for our own address.
      */
-    if (local_transport(STR(reply.transport))
+    if (match_any_local_transport(STR(reply.transport))
        || (domain = strrchr(STR(reply.recipient), '@')) == 0)
        return (SMTPD_CHECK_OK);
     domain += 1;
@@ -956,7 +957,7 @@ static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
 
 /* reject_non_fqdn_address - fail if address is not in fqdn form */
 
-static int reject_non_fqdn_address(SMTPD_STATE *state, char *addr,
+static int reject_non_fqdn_address(SMTPD_STATE * state, char *addr,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_non_fqdn_address";
@@ -1009,7 +1010,7 @@ static int reject_non_fqdn_address(SMTPD_STATE *state, char *addr,
 
 /* reject_unknown_address - fail if address does not resolve */
 
-static int reject_unknown_address(SMTPD_STATE *state, char *addr,
+static int reject_unknown_address(SMTPD_STATE * state, char *addr,
                                        char *reply_name, char *reply_class)
 {
     char   *myname = "reject_unknown_address";
@@ -1027,7 +1028,7 @@ static int reject_unknown_address(SMTPD_STATE *state, char *addr,
     /*
      * Skip local destinations and non-DNS forms.
      */
-    if (local_transport(STR(reply.transport))
+    if (match_any_local_transport(STR(reply.transport))
        || (domain = strrchr(STR(reply.recipient), '@')) == 0)
        return (SMTPD_CHECK_DUNNO);
     domain += 1;
@@ -1048,8 +1049,9 @@ static int permit_rcpt_map(char *table, char *reply_name)
 {
     char   *myname = "permit_rcpt_map";
     char   *domain;
-    MAPS   *map;
-    DICT   *dict;
+
+    MAPS *map;
+    DICT *dict;
 
     if (msg_verbose)
        msg_info("%s: %s %s", myname, table, reply_name);
@@ -1067,7 +1069,7 @@ static int permit_rcpt_map(char *table, char *reply_name)
        return (SMTPD_CHECK_DUNNO);
     domain += 1;
     if (domain[0] == '#' || domain[0] == '[')
-       if (!local_transport(STR(reply.transport)))
+       if (!match_any_local_transport(STR(reply.transport)))
            return (SMTPD_CHECK_DUNNO);
 
     /*
@@ -1075,6 +1077,10 @@ static int permit_rcpt_map(char *table, char *reply_name)
      * canonical and virtual maps. Be sure this map was declared in a main.cf
      * restriction or restriction class. The maps must be opened before the
      * process enters a chroot jail.
+     * 
+     * XXX What follows is a kludge to wrap up the recipient map in a form
+     * usable by mail_addr_find(). Perhaps we should have a mail_addr_find()
+     * interface that will search just one map instead of a list of maps.
      */
     if ((map = (MAPS *) htable_find(smtpd_rcpt_maps, table)) == 0) {
        if ((dict = dict_handle(table)) == 0)
@@ -1093,14 +1099,14 @@ static int permit_rcpt_map(char *table, char *reply_name)
 
 /* check_table_result - translate table lookup result into pass/reject */
 
-static int check_table_result(SMTPD_STATE *state, char *table,
+static int check_table_result(SMTPD_STATE * state, char *table,
                                      const char *value, const char *datum,
                                      char *reply_name, char *reply_class,
                                      char *def_acl)
 {
     char   *myname = "check_table_result";
     int     code;
-    ARGV   *restrictions;
+    ARGV *restrictions;
     int     status;
 
     if (msg_verbose)
@@ -1124,7 +1130,7 @@ static int check_table_result(SMTPD_STATE *state, char *table,
      * All-numeric result probably means OK - some out-of-band authentication
      * mechanism uses this as time stamp.
      */
-    if (value[strcspn(value, "0123456789")] == 0)
+    if (*value && value[strspn(value, "0123456789")] == 0)
        return (SMTPD_CHECK_OK);
 
     /*
@@ -1161,6 +1167,19 @@ static int check_table_result(SMTPD_STATE *state, char *table,
        msg_warn("define a restriction class and specify its name instead");
        longjmp(smtpd_check_buf, -1);
     }
+
+    /*
+     * Don't get carried away with recursion.
+     */
+    if (state->recursion++ > 100) {
+       msg_warn("SMTPD access map %s entry %s causes unreasonable recursion",
+                table, value);
+       longjmp(smtpd_check_buf, -1);
+    }
+
+    /*
+     * Recursively evaluate the restrictions given in the right-hand side.
+     */
     restrictions = argv_split(value, " \t\r\n,");
     status = generic_checks(state, restrictions, reply_name,
                            reply_class, def_acl);
@@ -1170,7 +1189,7 @@ static int check_table_result(SMTPD_STATE *state, char *table,
 
 /* check_access - table lookup without substring magic */
 
-static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
+static int check_access(SMTPD_STATE * state, char *table, char *name, int flags,
                         char *reply_name, char *reply_class, char *def_acl)
 {
     char   *myname = "check_access";
@@ -1200,7 +1219,7 @@ static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
 
 /* check_domain_access - domainname-based table lookup */
 
-static int check_domain_access(SMTPD_STATE *state, char *table,
+static int check_domain_access(SMTPD_STATE * state, char *table,
                                       char *domain, int flags,
                                       char *reply_name, char *reply_class,
                                       char *def_acl)
@@ -1240,7 +1259,7 @@ static int check_domain_access(SMTPD_STATE *state, char *table,
 
 /* check_addr_access - address-based table lookup */
 
-static int check_addr_access(SMTPD_STATE *state, char *table,
+static int check_addr_access(SMTPD_STATE * state, char *table,
                                     char *address, int flags,
                                     char *reply_name, char *reply_class,
                                     char *def_acl)
@@ -1277,7 +1296,7 @@ static int check_addr_access(SMTPD_STATE *state, char *table,
 
 /* check_namadr_access - OK/FAIL based on host name/address lookup */
 
-static int check_namadr_access(SMTPD_STATE *state, char *table,
+static int check_namadr_access(SMTPD_STATE * state, char *table,
                                       char *name, char *addr, int flags,
                                       char *reply_name, char *reply_class,
                                       char *def_acl)
@@ -1313,7 +1332,7 @@ static int check_namadr_access(SMTPD_STATE *state, char *table,
 
 /* check_mail_access - OK/FAIL based on mail address lookup */
 
-static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
+static int check_mail_access(SMTPD_STATE * state, char *table, char *addr,
                                     char *reply_name, char *reply_class,
                                     char *def_acl)
 {
@@ -1373,7 +1392,7 @@ static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
 
 /* reject_maps_rbl - reject if client address in real-time blackhole list */
 
-static int reject_maps_rbl(SMTPD_STATE *state)
+static int reject_maps_rbl(SMTPD_STATE * state)
 {
     char   *myname = "reject_maps_rbl";
     ARGV   *octets = argv_split(state->addr, ".");
@@ -1469,7 +1488,7 @@ static int is_map_command(char *name, char *command, char ***argp)
 
 /* generic_checks - generic restrictions */
 
-static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
+static int generic_checks(SMTPD_STATE * state, ARGV *restrictions,
                         char *reply_name, char *reply_class, char *def_acl)
 {
     char   *myname = "generic_checks";
@@ -1671,7 +1690,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
 
 /* smtpd_check_client - validate client name or address */
 
-char   *smtpd_check_client(SMTPD_STATE *state)
+char   *smtpd_check_client(SMTPD_STATE * state)
 {
     int     status;
 
@@ -1684,6 +1703,7 @@ char   *smtpd_check_client(SMTPD_STATE *state)
     /*
      * Apply restrictions in the order as specified.
      */
+    state->recursion = 0;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && client_restrctions->argc)
        status = generic_checks(state, client_restrctions, state->namaddr,
@@ -1694,7 +1714,7 @@ char   *smtpd_check_client(SMTPD_STATE *state)
 
 /* smtpd_check_helo - validate HELO hostname */
 
-char   *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
+char   *smtpd_check_helo(SMTPD_STATE * state, char *helohost)
 {
     int     status;
     char   *saved_helo;
@@ -1729,6 +1749,7 @@ char   *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
     /*
      * Apply restrictions in the order as specified.
      */
+    state->recursion = 0;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && helo_restrctions->argc)
        status = generic_checks(state, helo_restrctions, state->helo_name,
@@ -1739,7 +1760,7 @@ char   *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
 
 /* smtpd_check_mail - validate sender address, driver */
 
-char   *smtpd_check_mail(SMTPD_STATE *state, char *sender)
+char   *smtpd_check_mail(SMTPD_STATE * state, char *sender)
 {
     int     status;
     char   *saved_sender;
@@ -1764,6 +1785,7 @@ char   *smtpd_check_mail(SMTPD_STATE *state, char *sender)
     /*
      * Apply restrictions in the order as specified.
      */
+    state->recursion = 0;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && mail_restrctions->argc)
        status = generic_checks(state, mail_restrctions, sender,
@@ -1774,7 +1796,7 @@ char   *smtpd_check_mail(SMTPD_STATE *state, char *sender)
 
 /* smtpd_check_rcpt - validate recipient address, driver */
 
-char   *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
+char   *smtpd_check_rcpt(SMTPD_STATE * state, char *recipient)
 {
     int     status;
     char   *saved_recipient;
@@ -1809,6 +1831,7 @@ char   *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
     /*
      * Apply restrictions in the order as specified.
      */
+    state->recursion = 0;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && rcpt_restrctions->argc)
        status = generic_checks(state, rcpt_restrctions,
@@ -1819,7 +1842,7 @@ char   *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
 
 /* smtpd_check_etrn - validate ETRN request */
 
-char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
+char   *smtpd_check_etrn(SMTPD_STATE * state, char *domain)
 {
     int     status;
     char   *saved_etrn_name;
@@ -1853,6 +1876,7 @@ char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
     /*
      * Apply restrictions in the order as specified.
      */
+    state->recursion = 0;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && etrn_restrctions->argc)
        status = generic_checks(state, etrn_restrctions, domain,
@@ -1863,7 +1887,7 @@ char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
 
 /* smtpd_check_size - check optional SIZE parameter value */
 
-char   *smtpd_check_size(SMTPD_STATE *state, off_t size)
+char   *smtpd_check_size(SMTPD_STATE * state, off_t size)
 {
     char   *myname = "smtpd_check_size";
     struct fsspace fsbuf;
@@ -1939,7 +1963,7 @@ typedef struct {
     char   *name;
     char   *defval;
     char  **target;
-} STRING_TABLE;
+}       STRING_TABLE;
 
 static STRING_TABLE string_table[] = {
     VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains,
@@ -1984,7 +2008,7 @@ typedef struct {
     char   *name;
     int     defval;
     int    *target;
-} INT_TABLE;
+}       INT_TABLE;
 
 int     var_unk_client_code;
 int     var_bad_name_code;
@@ -2072,9 +2096,29 @@ static int rest_update(char **argv)
     return (0);
 }
 
+/* rest_class - (re)define a restriction class */
+
+static void rest_class(char *class)
+{
+    char   *cp = class;
+    char   *name;
+    HTABLE_INFO *entry;
+
+    if (smtpd_rest_classes == 0)
+       smtpd_rest_classes = htable_create(1);
+
+    if ((name = mystrtok(&cp, " \t\r\n,")) == 0)
+       msg_panic("rest_class: null class name");
+    if ((entry = htable_locate(smtpd_rest_classes, name)) != 0)
+       argv_free((ARGV *) entry->value);
+    else
+       entry = htable_enter(smtpd_rest_classes, name, (char *) 0);
+    entry->value = (char *) smtpd_check_parse(cp);
+}
+
 /* resolve_clnt_init - initialize reply */
 
-void    resolve_clnt_init(RESOLVE_REPLY *reply)
+void    resolve_clnt_init(RESOLVE_REPLY * reply)
 {
     reply->transport = vstring_alloc(100);
     reply->nexthop = vstring_alloc(100);
@@ -2083,7 +2127,7 @@ void    resolve_clnt_init(RESOLVE_REPLY *reply)
 
 /* canon_addr_internal - stub */
 
-VSTRING *canon_addr_internal(VSTRING *result, const char *addr)
+VSTRING *canon_addr_internal(VSTRING * result, const char *addr)
 {
     if (addr == STR(result))
        msg_panic("canon_addr_internal: result clobbers input");
@@ -2094,7 +2138,7 @@ VSTRING *canon_addr_internal(VSTRING *result, const char *addr)
 
 /* resolve_clnt_query - stub */
 
-void    resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
+void    resolve_clnt_query(const char *addr, RESOLVE_REPLY * reply)
 {
     if (addr == STR(reply->recipient))
        msg_panic("resolve_clnt_query: result clobbers input");
@@ -2107,7 +2151,7 @@ void    resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
 
 /* smtpd_chat_reset - stub */
 
-void    smtpd_chat_reset(SMTPD_STATE *unused_state)
+void    smtpd_chat_reset(SMTPD_STATE * unused_state)
 {
 }
 
@@ -2206,6 +2250,11 @@ main(int argc, char **argv)
                resp = 0;
                break;
            }
+           if (strcasecmp(args->argv[0], "restriction_class") == 0) {
+               rest_class(args->argv[1]);
+               resp = 0;
+               break;
+           }
            if (int_update(args->argv)
                || string_update(args->argv)
                || rest_update(args->argv)) {
@@ -2244,6 +2293,7 @@ main(int argc, char **argv)
                helo_restrictions <restrictions>\n\
                sender_restrictions <restrictions>\n\
                recipient_restrictions <restrictions>\n\
+               restriction_class name,<restrictions>\n\
                \n\
                Note: no address rewriting \n";
            break;
index 02e11e9e9e568fbce9b7e91509caf97151ec6cdc..fd827324bd98e8b030ead0d43b5a36ac63141075 100644 (file)
@@ -9,7 +9,7 @@ relay_domains porcupine.org
 #
 # Test the client restrictions.
 #
-client_restrictions permit_mynetworks,reject_unknown_client,hash:./smtpd_check_access
+client_restrictions permit_mynetworks,reject_unknown_client,dbm:./smtpd_check_access
 client unknown 131.155.210.17
 client unknown 168.100.189.13
 client random.bad.domain 123.123.123.123
@@ -21,14 +21,14 @@ client_restrictions permit_mynetworks
 #
 # Test the helo restrictions
 #
-helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,hash:./smtpd_check_access
+helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,dbm:./smtpd_check_access
 client unknown 131.155.210.17
 helo foo.
 client foo 123.123.123.123
 helo foo.
 helo foo
 helo spike.porcupine.org
-helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
+helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,dbm:./smtpd_check_access
 helo random.bad.domain
 helo friend.bad.domain
 helo_restrictions reject_invalid_hostname,reject_unknown_hostname
@@ -48,7 +48,7 @@ mail foo@watson.ibm.com
 sender_restrictions reject_unknown_address
 mail foo@watson.ibm.com
 mail foo@bad.domain
-sender_restrictions hash:./smtpd_check_access
+sender_restrictions dbm:./smtpd_check_access
 mail bad-sender@any.domain
 mail bad-sender@good.domain
 mail reject@this.address
@@ -75,7 +75,7 @@ rcpt foo@porcupine.org
 client foo 123.123.123.123
 rcpt foo@watson.ibm.com
 rcpt foo@porcupine.org
-recipient_restrictions hash:./smtpd_check_access
+recipient_restrictions dbm:./smtpd_check_access
 mail bad-sender@any.domain
 mail bad-sender@good.domain
 mail reject@this.address
@@ -94,16 +94,16 @@ client foo 127.0.0.2
 recipient_restrictions check_relay_domains
 client foo 131.155.210.17
 rcpt foo@watson.ibm.com
-recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
+recipient_restrictions check_client_access,dbm:./smtpd_check_access,check_relay_domains
 client foo 131.155.210.17
 rcpt foo@porcupine.org
-helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
-recipient_restrictions check_helo_access,hash:./smtpd_check_access,check_relay_domains
+helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,dbm:./smtpd_check_access
+recipient_restrictions check_helo_access,dbm:./smtpd_check_access,check_relay_domains
 helo bad.domain
 rcpt foo@porcupine.org
 helo 131.155.210.17
 rcpt foo@porcupine.org
-recipient_restrictions check_sender_access,hash:./smtpd_check_access,check_relay_domains
+recipient_restrictions check_sender_access,dbm:./smtpd_check_access,check_relay_domains
 mail foo@bad.domain
 rcpt foo@porcupine.org
 mail foo@friend.bad.domain
@@ -123,7 +123,7 @@ rcpt wietse@porcupine.org
 client_restrictions permit
 helo_restrictions permit
 sender_restrictions permit
-recipient_restrictions check_helo_access,hash:./smtpd_check_access,check_sender_access,hash:./smtpd_check_access
+recipient_restrictions check_helo_access,dbm:./smtpd_check_access,check_sender_access,dbm:./smtpd_check_access
 helo bad.domain
 mail foo@good.domain
 rcpt foo@porcupine.org
index 0eaf8c02b9e217d00952db882d41ef46226cd494..9dbfd36f79aec7fcbc61f014c368fa49af8c2b96 100644 (file)
@@ -9,7 +9,7 @@ relay_domains porcupine.org
 #
 # Test the client restrictions.
 #
-client_restrictions permit_mynetworks,reject_unknown_client,check_client_access,hash:./smtpd_check_access
+client_restrictions permit_mynetworks,reject_unknown_client,check_client_access,dbm:./smtpd_check_access
 client unknown 131.155.210.17
 client unknown 168.100.189.13
 client random.bad.domain 123.123.123.123
@@ -21,14 +21,14 @@ client_restrictions permit_mynetworks
 #
 # Test the helo restrictions
 #
-helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,check_helo_access,hash:./smtpd_check_access
+helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,check_helo_access,dbm:./smtpd_check_access
 client unknown 131.155.210.17
 helo foo.
 client foo 123.123.123.123
 helo foo.
 helo foo
 helo spike.porcupine.org
-helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,check_helo_access,hash:./smtpd_check_access
+helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,check_helo_access,dbm:./smtpd_check_access
 helo random.bad.domain
 helo friend.bad.domain
 #
@@ -44,7 +44,7 @@ mail foo@watson.ibm.com
 sender_restrictions reject_unknown_address
 mail foo@watson.ibm.com
 mail foo@bad.domain
-sender_restrictions check_sender_access,hash:./smtpd_check_access
+sender_restrictions check_sender_access,dbm:./smtpd_check_access
 mail bad-sender@any.domain
 mail bad-sender@good.domain
 mail reject@this.address
@@ -71,7 +71,7 @@ rcpt foo@porcupine.org
 client foo 123.123.123.123
 rcpt foo@watson.ibm.com
 rcpt foo@porcupine.org
-recipient_restrictions check_recipient_access,hash:./smtpd_check_access
+recipient_restrictions check_recipient_access,dbm:./smtpd_check_access
 mail bad-sender@any.domain
 mail bad-sender@good.domain
 mail reject@this.address
index 1ed6fca90777876534dd4ad9ad0075e7e75b5d06..6e9e1b3515f9e1ace83d02998a2673d6b63e8772 100644 (file)
@@ -12,7 +12,7 @@ OK
 >>> #
 >>> # Test the client restrictions.
 >>> #
->>> client_restrictions permit_mynetworks,reject_unknown_client,hash:./smtpd_check_access
+>>> client_restrictions permit_mynetworks,reject_unknown_client,dbm:./smtpd_check_access
 OK
 >>> client unknown 131.155.210.17
 ./smtpd_check: reject: CONNECT from unknown[131.155.210.17]: 450 Client host rejected: cannot find your hostname, [131.155.210.17]
@@ -37,7 +37,7 @@ OK
 >>> #
 >>> # Test the helo restrictions
 >>> #
->>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,hash:./smtpd_check_access
+>>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,dbm:./smtpd_check_access
 OK
 >>> client unknown 131.155.210.17
 OK
@@ -54,7 +54,7 @@ OK
 450 <foo>: Helo command rejected: Host not found
 >>> helo spike.porcupine.org
 OK
->>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
+>>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,dbm:./smtpd_check_access
 OK
 >>> helo random.bad.domain
 ./smtpd_check: reject: HELO from foo[123.123.123.123]: 554 <random.bad.domain>: Helo command rejected: match bad.domain
@@ -96,7 +96,7 @@ OK
 >>> mail foo@bad.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 450 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain>
 450 <foo@bad.domain>: Sender address rejected: Domain not found
->>> sender_restrictions hash:./smtpd_check_access
+>>> sender_restrictions dbm:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 <bad-sender@any.domain>: Sender address rejected: match bad-sender@; from=<bad-sender@any.domain>
@@ -156,7 +156,7 @@ OK
 554 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
->>> recipient_restrictions hash:./smtpd_check_access
+>>> recipient_restrictions dbm:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 <bad-sender@any.domain>: Sender address rejected: match bad-sender@; from=<bad-sender@any.domain>
@@ -194,15 +194,15 @@ OK
 >>> rcpt foo@watson.ibm.com
 ./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com>
 554 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
->>> recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
+>>> recipient_restrictions check_client_access,dbm:./smtpd_check_access,check_relay_domains
 OK
 >>> client foo 131.155.210.17
 OK
 >>> rcpt foo@porcupine.org
 OK
->>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
+>>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,dbm:./smtpd_check_access
 OK
->>> recipient_restrictions check_helo_access,hash:./smtpd_check_access,check_relay_domains
+>>> recipient_restrictions check_helo_access,dbm:./smtpd_check_access,check_relay_domains
 OK
 >>> helo bad.domain
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 554 <bad.domain>: Helo command rejected: match bad.domain; from=<foo@friend.bad.domain>
@@ -215,7 +215,7 @@ OK
 OK
 >>> rcpt foo@porcupine.org
 OK
->>> recipient_restrictions check_sender_access,hash:./smtpd_check_access,check_relay_domains
+>>> recipient_restrictions check_sender_access,dbm:./smtpd_check_access,check_relay_domains
 OK
 >>> mail foo@bad.domain
 ./smtpd_check: reject: MAIL from foo[131.155.210.17]: 554 <foo@bad.domain>: Sender address rejected: match bad.domain; from=<foo@bad.domain>
@@ -252,7 +252,7 @@ OK
 OK
 >>> sender_restrictions permit
 OK
->>> recipient_restrictions check_helo_access,hash:./smtpd_check_access,check_sender_access,hash:./smtpd_check_access
+>>> recipient_restrictions check_helo_access,dbm:./smtpd_check_access,check_sender_access,dbm:./smtpd_check_access
 OK
 >>> helo bad.domain
 OK
index 55143b69cd2bc5de5d34fed6ff08373956f465ab..17573ff4e9145fb9b253fb99c00553ede7ef31af 100644 (file)
@@ -12,7 +12,7 @@ OK
 >>> #
 >>> # Test the client restrictions.
 >>> #
->>> client_restrictions permit_mynetworks,reject_unknown_client,check_client_access,hash:./smtpd_check_access
+>>> client_restrictions permit_mynetworks,reject_unknown_client,check_client_access,dbm:./smtpd_check_access
 OK
 >>> client unknown 131.155.210.17
 ./smtpd_check: reject: CONNECT from unknown[131.155.210.17]: 450 Client host rejected: cannot find your hostname, [131.155.210.17]
@@ -37,7 +37,7 @@ OK
 >>> #
 >>> # Test the helo restrictions
 >>> #
->>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,check_helo_access,hash:./smtpd_check_access
+>>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,reject_unknown_hostname,check_helo_access,dbm:./smtpd_check_access
 OK
 >>> client unknown 131.155.210.17
 OK
@@ -54,7 +54,7 @@ OK
 450 <foo>: Helo command rejected: Host not found
 >>> helo spike.porcupine.org
 OK
->>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,check_helo_access,hash:./smtpd_check_access
+>>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,check_helo_access,dbm:./smtpd_check_access
 OK
 >>> helo random.bad.domain
 ./smtpd_check: reject: HELO from foo[123.123.123.123]: 554 <random.bad.domain>: Helo command rejected: match bad.domain
@@ -86,7 +86,7 @@ OK
 >>> mail foo@bad.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 450 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain>
 450 <foo@bad.domain>: Sender address rejected: Domain not found
->>> sender_restrictions check_sender_access,hash:./smtpd_check_access
+>>> sender_restrictions check_sender_access,dbm:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 <bad-sender@any.domain>: Sender address rejected: match bad-sender@; from=<bad-sender@any.domain>
@@ -146,7 +146,7 @@ OK
 554 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
->>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access
+>>> recipient_restrictions check_recipient_access,dbm:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
 ./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 <bad-sender@any.domain>: Sender address rejected: match bad-sender@; from=<bad-sender@any.domain>
index b03f3a50d59438287ac78e4fab63c4328496b029..f7f6e42d7fc34b79c01b1f9482dc557c17a1241c 100644 (file)
@@ -5,3 +5,6 @@ bad-sender@good.domain  OK
 131.155.210            554 match 131.155.210
 131.155.210.17         OK
 reject@this.address    554 match reject@this.address
+open_user@some.site    open
+strict_user@some.site  strict
+auth_client            123456
index 059e250f2be8d9f01f02da8ff25bc510c442e635..23a44a853569fb72010b3f3ad699750f2796e363 100644 (file)
@@ -36,7 +36,7 @@
 /*     error (no address->name mapping or no name->address mapping).
 /* .IP 5
 /*     The name lookup or verification failed with an unrecoverable
-/*     error (no address->name mapping, bad hostname syntax, no 
+/*     error (no address->name mapping, bad hostname syntax, no
 /*     name->address mapping, client address not listed for hostname).
 /* .RE
 /* .PP
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <stdio.h>                     /* strerror() */
+#include <errno.h>
 #include <netdb.h>
 #include <string.h>
 
+ /*
+  * Older systems don't have h_errno. Even modern systems don't have
+  * hstrerror().
+  */
 #ifdef NO_HERRNO
+
 static int h_errno = TRY_AGAIN;
-define  hstrerror(x) "Host not found"
+
+#define  HSTRERROR(err) "Host not found"
+
+#else
+
+#define  HSTRERROR(err) (\
+       err == TRY_AGAIN ? "Host not found, try again" : \
+       err == HOST_NOT_FOUND ? "Host not found" : \
+       err == NO_DATA ? "Host name has no address" : \
+       err == NO_RECOVERY ? "Name server failure" : \
+       strerror(errno) \
+    )
 #endif
 
 /* Utility library. */
@@ -82,7 +100,7 @@ define  hstrerror(x) "Host not found"
 
 /* smtpd_peer_init - initialize peer information */
 
-void    smtpd_peer_init(SMTPD_STATE *state)
+void    smtpd_peer_init(SMTPD_STATE * state)
 {
     struct sockaddr_in sin;
     SOCKADDR_SIZE len = sizeof(sin);
@@ -90,93 +108,97 @@ void    smtpd_peer_init(SMTPD_STATE *state)
     int     i;
 
     /*
-     * If it's not networked assume local.
+     * Look up the peer address information.
      */
     if (getpeername(vstream_fileno(state->client),
-                   (struct sockaddr *) & sin, &len) < 0)
-       sin.sin_family = AF_UNSPEC;
-
-    switch (sin.sin_family) {
+                   (struct sockaddr *) & sin, &len) >= 0) {
+       errno = 0;
+    }
 
-       /*
-        * If it's not Internet, assume the client is local, and avoid using
-        * the naming service because that can hang when the machine is
-        * disconnected.
-        */
-    default:
-       state->name = mystrdup("localhost");
-       state->addr = mystrdup("127.0.0.1");    /* XXX bogus. */
-       state->peer_code = 2;
-       break;
+    /*
+     * If peer went away, give up.
+     */
+    if (errno == ECONNRESET || errno == ECONNABORTED) {
+       msg_info("errno %d %m", errno);
+       state->name = mystrdup("unknown");
+       state->addr = mystrdup("unknown");
+       state->peer_code = 5;
+    }
 
-       /*
-        * Look up and "verify" the client hostname.
-        */
-    case AF_INET:
+    /*
+     * Look up and "verify" the client hostname.
+     */
+    else if (errno == 0 && sin.sin_family == AF_INET) {
        state->addr = mystrdup(inet_ntoa(sin.sin_addr));
        hp = gethostbyaddr((char *) &(sin.sin_addr),
                           sizeof(sin.sin_addr), AF_INET);
        if (hp == 0) {
            state->name = mystrdup("unknown");
            state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
-           break;
-       }
-       if (!valid_hostname(hp->h_name)) {
+       } else if (!valid_hostname(hp->h_name)) {
            state->name = mystrdup("unknown");
            state->peer_code = 5;
-           break;
-       }
-       state->name = mystrdup(hp->h_name);     /* hp->name is clobbered!! */
-       state->peer_code = 2;
+       } else {
+           state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
+           state->peer_code = 2;
+
+           /*
+            * Reject the hostname if it does not list the peer address.
+            */
+#define REJECT_PEER_NAME(state, code) { \
+       myfree(state->name); \
+       state->name = mystrdup("unknown"); \
+       state->peer_code = 5; \
+    }
 
-       /*
-        * Reject the hostname if it does not list the peer address.
-        */
-       hp = gethostbyname(state->name);        /* clobbers hp->name!! */
-       if (hp == 0) {
-           msg_warn("hostname %s verification failed: %s",
-                    state->name, hstrerror(h_errno));
-           myfree(state->name);
-           state->name = mystrdup("unknown");
-           state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
-           break;
-       }
-       if (hp->h_length != sizeof(sin.sin_addr)) {
-           msg_warn("hostname %s verification failed: bad address size %d",
-                    state->name, hp->h_length);
-           myfree(state->name);
-           state->name = mystrdup("unknown");
-           state->peer_code = 5;
-           break;
+           hp = gethostbyname(state->name);    /* clobbers hp->name!! */
+           if (hp == 0) {
+               msg_warn("%s: hostname %s verification failed: %s",
+                        state->addr, state->name, HSTRERROR(h_errno));
+               REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
+           } else if (hp->h_length != sizeof(sin.sin_addr)) {
+               msg_warn("%s: hostname %s verification failed: bad address size %d",
+                        state->addr, state->name, hp->h_length);
+               REJECT_PEER_NAME(state, 5);
+           } else {
+               for (i = 0; /* void */ ; i++) {
+                   if (hp->h_addr_list[i] == 0) {
+                       msg_warn("%s: address not listed for hostname %s",
+                                state->addr, state->name);
+                       REJECT_PEER_NAME(state, 5);
+                       break;
+                   }
+                   if (memcmp(hp->h_addr_list[i],
+                              (char *) &sin.sin_addr,
+                              sizeof(sin.sin_addr)) == 0)
+                       break;                  /* keep peer name */
+               }
+           }
        }
-       for (i = 0; hp->h_addr_list[i]; i++) {
-           if (memcmp(hp->h_addr_list[i],
-                      (char *) &sin.sin_addr,
-                      sizeof(sin.sin_addr)) == 0)
-               break;
-       }
-       if (hp->h_addr_list[i] == 0) {
-           msg_warn("address %s not listed for name %s",
-                    state->addr, state->name);
-           myfree(state->name);
-           state->name = mystrdup("unknown");
-           state->peer_code = 5;
-           break;
-       }
-       break;
     }
+
+    /*
+     * If it's not Internet, assume the client is local, and avoid using the
+     * naming service because that can hang when the machine is disconnected.
+     */
+    else {
+       state->name = mystrdup("localhost");
+       state->addr = mystrdup("127.0.0.1");    /* XXX bogus. */
+       state->peer_code = 2;
+    }
+
+    /*
+     * Do the name[addr] formatting for pretty reports.
+     */
     state->namaddr =
        concatenate(state->name, "[", state->addr, "]", (char *) 0);
 }
 
 /* smtpd_peer_reset - destroy peer information */
 
-void    smtpd_peer_reset(SMTPD_STATE *state)
+void    smtpd_peer_reset(SMTPD_STATE * state)
 {
-    if (state->name)
-       myfree(state->name);
-    if (state->addr)
-       myfree(state->addr);
-    if (state->namaddr)
-       myfree(state->namaddr);
+    myfree(state->name);
+    myfree(state->addr);
+    myfree(state->namaddr);
 }
index 6199b7583eeafb4b0b0ac9d05f82996912accfb1..a14b64216b6b275073484410dd00986a377891d2 100644 (file)
@@ -85,6 +85,7 @@ void    smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
     state->etrn_name = 0;
     state->protocol = "SMTP";
     state->where = SMTPD_AFTER_CONNECT;
+    state->recursion = 0;
 
     /*
      * Initialize peer information.